?RCS: $Id: Signal.U 1 2006-08-24 12:32:52Z rmanfredi $
?RCS:
?RCS: Copyright (c) 1991-1997, 2004-2006, Raphael Manfredi
?RCS:
?RCS: You may redistribute only under the terms of the Artistic License,
?RCS: as specified in the README file that comes with the distribution.
?RCS: You may reuse parts of this distribution only within the terms of
?RCS: that same Artistic License; a copy of which may be found at the root
?RCS: of the source tree for dist 4.0.
?RCS:
?RCS: $Log: Signal.U,v $
?RCS: Revision 3.0.1.1  1997/02/28  15:20:01  ram
?RCS: patch61: created
?RCS:
?X:
?X: This unit produces three files:
?X: 1- A signal.c file, which, when compiled and run, produces an output like:
?X:
?X:   HUP 1
?X:   INT 2
?X:   QUIT 3
?X:   etc...
?X:
?X: 2- A signal.awk script to parse the output of signal.c, fill
?X: in gaps (up to NSIG) and move duplicates to the end.
?X: 3- A signal_cmd script to compile signal.c and run it
?X: through sort -n -k 2 | uniq | awk -f signal.awk.
?X: (we try also sort -n +1 since some old hosts don't grok sort -k)
?X: (This is called signal_cmd to avoid OS/2 confusion with
?X: signal.cmd vs. signal.
?X: The signal_cmd script also falls back on checking signals one at a
?X: time in case the signal.c program fails.  On at least one version of
?X: Linux 2.1.x, the header file #define'd SIGRTMAX to a symbol that
?X: is not defined by the compiler/linker. :-(.  Further, on that same
?X: version of Linux, the user had a defective C-shell that gave an
?X: incorrect list for kill -l, so the fall-back didn't work.
?X:
?X: This unit is then used by sig_name.U.
?X:
?MAKE:Signal: test tr rm awk cat grep startsh eunicefix sed sort uniq \
	Findhdr cppstdin +cppflags cppminus Compile _o _exe trnl run i_stdlib \
	sysroot
?MAKE:	-pick add $@ %<
?X:all files declared as "public" since they're used from other units
?F:signal.c signal_cmd signal.lst signal signal.awk
?T: xx xxx xxxfiles
?LINT:use rm run _o _exe
?LINT:extern sig_num_init
: Trace out the files included by signal.h, then look for SIGxxx names.
?X: Remove SIGARRAYSIZE used by HPUX.
?X: Remove SIGSTKSIZE used by Linux.
?X: Remove SIGSTKSZ used by POSIX.
?X: Remove SIGTYP void lines used by OS2.
?X: Some cpps, like os390, do not give the file name anywhere
case "$sig_num_init" in
'')
if [ "X$fieldn" = X ]; then
	: Just make some guesses.  We check them later.
	xxx="$sysroot/usr/include/signal.h $sysroot/usr/include/sys/signal.h"
else
	xxx=`echo '#include <signal.h>' |
	$cppstdin $cppminus $cppflags 2>/dev/null |
	$grep '^[ 	]*#.*include' |
	$awk "{print \\$$fieldn}" | $sed 's!"!!g' |\
		$sed 's!\\\\\\\\!/!g' | $sort | $uniq`
fi
?X: Check this list of files to be sure we have parsed the cpp output ok.
?X: This will also avoid potentially non-existent files, such
?X: as ../foo/bar.h
xxxfiles=''
?X: Add /dev/null in case the $xxx list is empty.
for xx in $xxx /dev/null ; do
	$test -f "$xx" && xxxfiles="$xxxfiles $xx"
done
?X: If we have found no files, at least try signal.h
case "$xxxfiles" in
'')	xxxfiles=`./findhdr signal.h` ;;
esac
xxx=`awk '
$1 ~ /^#define$/ && $2 ~ /^SIG[A-Z0-9]*$/ && $2 !~ /SIGARRAYSIZE/ && $2 !~ /SIGSTKSIZE/ && $2 !~ /SIGSTKSZ/ && $3 !~ /void/ {
	print substr($2, 4, 20)
}
$1 == "#" && $2 ~ /^define$/ && $3 ~ /^SIG[A-Z0-9]*$/ && $3 !~ /SIGARRAYSIZE/ && $4 !~ /void/ {
	print substr($3, 4, 20)
}' $xxxfiles`
: Append some common names just in case the awk scan failed.
xxx="$xxx ABRT ALRM BUS CANCEL CHLD CLD CONT DIL EMT FPE"
xxx="$xxx FREEZE HUP ILL INT IO IOT KILL LOST LWP PHONE"
xxx="$xxx PIPE POLL PROF PWR QUIT RTMAX RTMIN SEGV STKFLT STOP"
xxx="$xxx SYS TERM THAW TRAP TSTP TTIN TTOU URG USR1 USR2"
xxx="$xxx USR3 USR4 VTALRM WAITING WINCH WIND WINDOW XCPU XFSZ"

: generate a few handy files for later
$cat > signal.c <<EOCP
#include <sys/types.h>
#include <signal.h>
#$i_stdlib I_STDLIB
#ifdef I_STDLIB
#include <stdlib.h>
#endif
#include <stdio.h>
int main() {

/* Strange style to avoid deeply-nested #if/#else/#endif */
#ifndef NSIG
#  ifdef _NSIG
#    define NSIG (_NSIG)
#  endif
#endif

#ifndef NSIG
#  ifdef SIGMAX
#    define NSIG (SIGMAX+1)
#  endif
#endif

#ifndef NSIG
#  ifdef SIG_MAX
#    define NSIG (SIG_MAX+1)
#  endif
#endif

#ifndef NSIG
#  ifdef _SIG_MAX
#    define NSIG (_SIG_MAX+1)
#  endif
#endif

#ifndef NSIG
#  ifdef MAXSIG
#    define NSIG (MAXSIG+1)
#  endif
#endif

#ifndef NSIG
#  ifdef MAX_SIG
#    define NSIG (MAX_SIG+1)
#  endif
#endif

#ifndef NSIG
#  ifdef SIGARRAYSIZE
#    define NSIG SIGARRAYSIZE /* Assume ary[SIGARRAYSIZE] */
#  endif
#endif

#ifndef NSIG
#  ifdef _sys_nsig
#    define NSIG (_sys_nsig) /* Solaris 2.5 */
#  endif
#endif

/* Default to some arbitrary number that's big enough to get most
   of the common signals.
*/
#ifndef NSIG
#    define NSIG 50
#endif

printf("NSIG %d\n", NSIG);

#ifndef JUST_NSIG

EOCP

echo $xxx | $tr ' ' $trnl | $sort | $uniq | $awk '
{
	printf "#ifdef SIG"; printf $1; printf "\n"
	printf "printf(\""; printf $1; printf " %%d\\n\",SIG";
	printf $1; printf ");\n"
	printf "#endif\n"
}
END {
	printf "#endif /* JUST_NSIG */\n";
	printf "exit(0);\n}\n";
}
' >>signal.c
$cat >signal.awk <<'EOP'
BEGIN { ndups = 0 }
$1 ~ /^NSIG$/ { nsig = $2 }
($1 !~ /^NSIG$/) && (NF == 2) && ($2 ~ /^[0-9][0-9]*$/) {
    if ($2 > maxsig) { maxsig = $2 }
    if (sig_name[$2]) {
	dup_name[ndups] = $1
	dup_num[ndups] = $2
	ndups++
    }
    else {
	sig_name[$2] = $1
	sig_num[$2] = $2
    }
}
END {
    if (nsig == 0) {
    	nsig = maxsig + 1
    }
    printf("NSIG %d\n", nsig);
    for (n = 1; n < nsig; n++) {
 	if (sig_name[n]) {
 	    printf("%s %d\n", sig_name[n], sig_num[n])
	}
 	else {
 	    printf("NUM%d %d\n", n, n)
 	}
    }
    for (n = 0; n < ndups; n++) {
 	printf("%s %d\n", dup_name[n], dup_num[n])
    }
}
EOP
$cat >signal_cmd <<EOS
$startsh
if $test -s signal.lst; then
    echo "Using your existing signal.lst file"
	exit 0
fi
xxx="$xxx"
EOS
?X: Avoid variable interpolation problems, especially with
?X: xxx, which contains newlines.
$cat >>signal_cmd <<'EOS'

set signal
if eval $compile_ok; then
	$run ./signal$_exe | ($sort -n -k 2 2>/dev/null || $sort -n +1) |\
		$uniq | $awk -f signal.awk >signal.lst
else
	echo "(I can't seem be able to compile the whole test program)" >&4
	echo "(I'll try it in little pieces.)" >&4
	set signal -DJUST_NSIG
	if eval $compile_ok; then
		$run ./signal$_exe > signal.nsg
		$cat signal.nsg
	else
		echo "I can't seem to figure out how many signals you have." >&4
		echo "Guessing 50." >&4
		echo 'NSIG 50' > signal.nsg
	fi
	: Now look at all the signal names, one at a time.
	for xx in `echo $xxx | $tr ' ' $trnl | $sort | $uniq`; do
		$cat > signal.c <<EOCP
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
int main() {
printf("$xx %ld\n", (long) SIG${xx});
return 0;
}
EOCP
		set signal
		if eval $compile; then
			echo "SIG${xx} found."
			$run ./signal$_exe  >> signal.ls1
		else
			echo "SIG${xx} NOT found."
		fi
	done
	if $test -s signal.ls1; then
		$cat signal.nsg signal.ls1 |
			$sort -n | $uniq | $awk -f signal.awk >signal.lst
	fi

fi
if $test -s signal.lst; then
	:
else
	echo "(AAK! I can't compile the test programs -- Guessing)" >&4
	echo 'kill -l' >signal
	set X `csh -f <signal`
	$rm -f signal
	shift
	case $# in
	0) set HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM;;
	esac
	echo $@ | $tr ' ' $trnl | \
 	    $awk '{ printf "%s %d\n", $1, ++s; }
 		  END { printf "NSIG %d\n", ++s }' >signal.lst
fi
$rm -f signal.c signal$_exe signal$_o signal.nsg signal.ls1
EOS
chmod a+x signal_cmd
$eunicefix signal_cmd
;;
esac

