brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/23/91)
Submitted-by: Dan Bernstein <brnstnd@kramden.acf.nyu.edu> Posting-number: Volume 17, Issue 64 Archive-name: quacko/part01 quacko 1.01, 3/21/91, Daniel J. Bernstein. Public domain. Basically, quacko tells you if any external symbols defined in foo.o aren't declared in foo.h. Such symbols should be either declared in foo.h or defined in foo.c. quacko won't work unless foo.h can be included (twice!) without any preparation. So it should help encourage good include-file-writing practices. quacko was developed on a BSD system and won't work on systems with a different nm output format. ---Dan ----------- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: README quacko # Wrapped by brnstnd@kramden on Thu Mar 21 14:38:15 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(2168 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' Xquacko - quality check .o files X Xquacko 1.01, 3/21/91, Daniel J. Bernstein. Public domain. X XBasically, quacko tells you if any external symbols defined in foo.o Xaren't declared in foo.h. Such symbols should be either declared in Xfoo.h or defined in foo.c. quacko won't work unless foo.h can be Xincluded (twice!) without any preparation. So it should help encourage Xgood include-file-writing practices. X Xquacko was developed on a BSD system and won't work on systems with a Xdifferent nm output format. X XExample: command.o versus command.h in the expect distribution. X X% quacko command -DVERSION=2.7 -sun4 XSuccessfully compiled after including command.h twice. XSuccessfully compiled after including command.h once. XcmdSystem defined in command.o... Aack! cmdSystem not declared in command.h! Xflush_streams defined in command.o... Okay. Xinit_cmd_interpreter defined in command.o... Aack! init_cmd_interpreter not declared in command.h! Xinit_spawn defined in command.o... Aack! init_spawn not declared in command.h! Xloguser defined in command.o... Okay. Xmaster defined in command.o... Okay. Xtcl_error defined in command.o... Okay. Xtcl_tracer defined in command.o... Aack! tcl_tracer not declared in command.h! Xupdate_master defined in command.o... Aack! update_master not declared in command.h! X Xquacko should take the same command-line definitions as the cc that Xproduced this .o; otherwise it may give inaccurate results when foo.h Xdepends on those definitions. This quacko run took about thirty seconds, Xand a quick check through the source reveals that Don should have Xdeclared update_master in command.h; made tcl_tracer a static function; Xetc. A few minutes with quacko can eliminate any linking problems in an Xentire distribution. X Xquacko will always report ``Okay'' for main. (The problem is that some Xcompilers don't like to produce output files with no symbols.) X XI was tempted to integrate this into the Poor Man's series as pmlint, Xbut somehow I think it needs a few more features first. I hope that Xpeople find it useful for sources they send out on the net; this way I Xwon't have to catch the mistakes myself. :-) Feel free to distribute a XSystem V version. END_OF_FILE if test 2168 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'quacko' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'quacko'\" else echo shar: Extracting \"'quacko'\" \(1277 characters\) sed "s/^X//" >'quacko' <<'END_OF_FILE' X#!/bin/sh X# quacko 1.01, 3/21/91, Daniel J. Bernstein. Public domain. Xlib="$1" Xshift Xcat > .qcko$$.c <<EOF X#include "$lib.h" X#include "$lib.h" Xint main() { ; } XEOF Xif cc ${1+"$@"} -c .qcko$$.c Xthen echo "Successfully compiled after including $lib.h twice." Xelse echo "Cannot compile after including $lib.h twice. Exiting." X rm -f .qcko$$.c .qcko$$.o X exit 1 Xfi Xcat > .qcko$$.c <<EOF X#include "$lib.h" Xint main() { ; } XEOF Xif cc ${1+"$@"} -c .qcko$$.c Xthen echo "Successfully compiled after including $lib.h once." Xelse echo "Cannot compile after including $lib.h once. Exiting." X rm -f .qcko$$.c X exit 1 Xfi Xfor i in `nm .qcko$$.o | sed -n 's/[^_]* _//p' | grep -v main` Xdo # this probably shouldn't ever happen X echo "$i" defined after inclusion. Xdone Xfor i in `nm "$lib".o | sed -n 's/[^_]*\([^_] \)_/\1/p' \ X | sed -n 's/^[^abcdftuU].//p'` Xdo X echo -n "$i defined in $lib.o... " X cat > .qcko$$.c <<EOF X#include "$lib.h" Xdouble $i; Xint main() { ; } XEOF X cat > .qckp$$.c <<EOF X#include "$lib.h" Xlong $i; Xint main() { ; } XEOF X if cc ${1+"$@"} -c .qckp$$.c 2>/dev/null \ X && cc ${1+"$@"} -c .qcko$$.c 2>/dev/null X then echo "Aack! $i not declared in $lib.h!" X else echo "Okay." X fi Xdone Xrm -f .qcko$$.c .qckp$$.c .qcko$$.o .qckp$$.o END_OF_FILE if test 1277 -ne `wc -c <'quacko'`; then echo shar: \"'quacko'\" unpacked with wrong size! fi chmod +x 'quacko' # end of 'quacko' fi echo shar: End of shell archive. exit 0 exit 0 # Just in case... -- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM Sterling Software, IMD UUCP: uunet!sparky!kent Phone: (402) 291-8300 FAX: (402) 291-4362 Please send comp.sources.misc-related mail to kent@uunet.uu.net.