[net.lang.c] Linting

garry@batcomputer.TN.CORNELL.EDU (Garry Wiegand) (04/02/86)

A couple months ago, I posted an article that asked about PL/1 -> C
and about applying Lint to the (thousands of lines of) results. I've just 
sent the PL/1 -> C stuff to net.lang, and here's the expert discussion on Lint:


** Laura Creighton (ihnp4!l5!laura) said:

This may not work on your environment, but on a unix environment
here is what you would use:

------begin makefile-------------

# makefile
#
# This is a generic makefile for a c program with many src modules. If
# you want to make a lot of c programs each out of their own src module
# withing a directory, you have the wrong boilerplate. What you want is
# makefile.cdir

DESTDIR=	<supply your own here>
BIN=		$(DESTDIR)/bin
TEXTFILES=	$(DESTDIR)/lib/prog
SRC=	<a list of .c files goes here>
OBJ=	<a list of .o files goes here>
HDRS=	<a list of .h giles goes here>
FILES=	makefile $(HDRS) $(SRC)
DEFS=	-DTEXTFILES=\"$(TEXTFILES)\" -DDEBUG
CFLAGS=	$(DEFS) -g

LFLAGS=	-ha
P=	lpr

prog:	$(OBJ)
	$(CC) $(CFLAGS) -o prog $(OBJ)

$(OBJ):	defs.h

lint:	$(SRC)
	lint $(LFLAGS) $(DEFS) $(SRC) >lint.out

clean:
	rm -f lint.out $(OBJ) prog 

printall: $(FILES) # Print files off line.
	-pr $(FILES) | $P
	touch print

print:  $(FILES)	# print recently changed files
	-pr $? | $P
	touch print
------------end makefile------------------------

This is a boilerplate. You plug in your own values.  Then you can
say ``make lint'' and it will all work.



** Alexis Dimitriadis ({decvax,ihnp4,ucbcad,uw-beaver}!tektronix!reed)
   at Reed College said:

  To begin with, you can skip the concatenating step (it would take all night
just to preen out the multiple #include's, static definitions, and what
have you anyway.  You can call lint with a number of files, and it will 
assume they make up a multi-module program.  

  More usefully, you can lint your code incrementally, as follows:

	- Run lint to a module until satisfied that it passes.
	- Make a copy of the module, and turn function definitions into stubs,
	  sort of like the definitions in /usr/lib/lint/llib-lc.  You want to
	  leave all function calls intact, though, so they can be checked
	  later.
	- Make sure the stub version does not generate any new complaints.
	- Run lint -C to make a "compiled" version of the simplified module,
	  to speed up further use.
	- When you have enough modules, run lint on all of them together,
	  or use them when linting new modules.  You are extending the
	  facility that checks the usage of the libc functions.
	- I am sure you will want to run lint on all the originals together
	  eventually, if only once.

Need an example? Skip this if I was clear enough:

% lint file1.c
% vi file1.c	# make stub1.c
% lint stub1.c
% lint -C1 stub1.c	# make llib-l1.ln
% lint file2.c
% lint file2.c llib-l1.ln	# equivalent to lint file1.c file2.c
or
% lint llib-l1.ln llib-l2.ln ...	# lint all stubs together.

  Hope I helped.  I have no PL/1 -> C translator to offer, alas.
-- 
_______________________________________________
Any opinions expressed above have been grown organically and contain
no preservatives or artificial sweeteners.


** Tony Hansen (ihnp4!pegasus!hansen) says:

The standard lint on all UNIX systems takes multiple file arguments, as in:

	lint file1.c file2.c file3.c

After doing the intra-file checking on each file, it will do inter-file
checking.

The lints on System Vr2 and 4.2BSD are also capable of saving partial lint
runs for later use. On Vr2, "lint -c" produces a corresponding "file.ln"
file for each "file.c". Running lint on the .ln files later, possibly with
.c files, will cause the inter-file checking to be performed.

	lint -c file1.c
	lint -c file2.c
	lint -c file3.c
	lint file1.ln file2.ln file3.ln


** Doug Gwyn (rochester!seismo!BRL.ARPA!gwyn) said:

"Lint" does process several files at once and check inter-file
consistency.  "lint fooa.c foob.c fooc.c", for example.  Also,
you can make a "lint library" that contains interface declarations
(some versions of "lint" have more extensive support for this,
but all will support the simple approach using a trimmed-down
source file).  Then you can check individual modules against the
interface file without having to feed "lint" the entire batch of
C sources.  "lint fooa.c interface_specs.c", for example.


** And, lastly, ihnp4!shell!graffiti!peter said:

You can use grep, sed, and friends to copy the function headers into a file
and massage them so the format matches that of the lint library. Pardon me.
I just discovered some idiot with root permissions has clobbered /lib on this
machine by saving his mail into a file with the same name. For obvious
reasons I can't give you more info...



Thanks much to all who replied, and I did eventually persuade Lint to run
on my system and produce reasonable lint libraries. Lint is less than perfect,
but it can be quite a help. I hope the above accumulated wisdom makes its use
easier for you.

garry wiegand
garry%cadif-oak@cu-arpa.cs.cornell.edu