[comp.sources.misc] v17i064: quacko - quality check .o files, Part01/01

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.