?RCS: $Id: Protochk.U,v $ ?RCS: ?RCS: Copyright (c) 1998 Andy Dougherty ?RCS: ?RCS: You may distribute under the terms of either the GNU General Public ?RCS: License or the Artistic License, as specified in the README file. ?RCS: ?X: This unit generates a ./protochk script that is used internally ?X: by Configure to check if this system will accept a particular ?X: prototype. ?X: ?X: To use it, say something like: ?X: hdrs="$define sys/types.h ?X: $i_systime sys/time.h ?X: $i_sysselct sys/select.h ?X: $d_socket sys/socket.h" ?X: $xxx='fd_set *' ?X: try='extern int select _((int, $xxx, $xxx, $xxx, struct timeval *'));' ?X: if ./protochk "$try" $hdrs; then ?X: echo "Your system accepts $xxx for the arguments to select." ?X: fi ?X: (Of course select is harder, since the first arg can be int, ?X: size_t, or unsigned long, and the last arg may or may not have a ?X: 'const' before the 'struct timeval' :-(. Also SunOS 4.1.3 doesn't ?X: provide a select prototype so the compiler accepts anything :-). ?X: ?X: The C compiler on QNX warns about invalid pointer types, but ?X: still exits with a 0 exit status, so it's not much help here. ?X: (It does correctly detect incorrect non-pointer arguments). ?X: Still, since QNX is a POSIX-ish system, just make your first ?X: a POSIX-ish one, and QNX will probably accept it. ?X: ?X: For determining argument types, your compiler must support ?X: prototypes, and the header files must use them. Determining ?X: return types, however, is easier. Just give an ridiculuous ?X: return type, something like ?X: ./protochk 'extern int atof _((void));' $i_stdlib stdlib.h ?X: that should surely fail if atof() is defined in ?X: ?X: There is also an 'escape' hatch built in. If you have a pair ?X: of args 'literal 'stuff' then 'stuff' gets included literally ?X: into the test program. This could be useful for doing something ?X: like ?X: hdrs="$define stdio.h ?X: $define sys/types.h" ?X: ./protochk 'extern int fsetpos(FILE *, Fpos_t);' $args \ ?X: 'literal' '#define Fpos_t long long' ?X: but you have to be really careful about the spaces in "literal". ?X: ?X: Andy Dougherty Feb. 1998 ?MAKE:Protochk: cat rm startsh eunicefix +cc +optimize +ccflags \ prototype ?MAKE: -pick add $@ %< ?F:./protochk ?X: Comfort metalint. All these are actually used in the protochk script. ?T:foo status ?LINT: change cc optimize ccflags prototype define rm : define a fucntion to check prototypes $cat > protochk <> protochk <<'EOSH' $rm -f try.c foo="$1" shift while test $# -ge 2; do case "$1" in $define) echo "#include <$2>" >> try.c ;; literal) echo "$2" >> try.c ;; esac shift 2 done test "$prototype" = "$define" && echo '#define CAN_PROTOTYPE' >> try.c cat >> try.c <<'EOCP' #ifdef CAN_PROTOTYPE #define _(args) args #else #define _(args) () #endif EOCP echo "$foo" >> try.c ?X: Just so we have something to compile. echo 'int no_real_function_has_this_name _((void)) { return 0; }' >> try.c $cc $optimize $ccflags -c try.c > /dev/null 2>&1 status=$? $rm -f try.[co] exit $status EOSH chmod +x protochk $eunicefix protochk