home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource4
/
210_01
/
kittylnt.c
< prev
next >
Wrap
Text File
|
1985-11-15
|
22KB
|
716 lines
/*lintoff*/
/* Saturday, July 12, 1986 3:41 PM */
/* */
/* KITTENSOFT */
/* */
/* Dan Schechter */
/* Route 1 Box 19 */
/* Amenia, North Dakota 58004 */
/* (701) 967-8371 */
/* */
/* Do what you like with this program. Please let me know if */
/* you find bugs. Exactly as is it compiles under Aztec C II */
/* for CP/M. I have no idea how portable it is because I do */
/* not know how compatible the Manx library functions are with */
/* those of other compilers. */
/* */
/* This is not intended to be a real LINT program. That would */
/* be far beyond my programming ability. This is just a sort */
/* of delimiter checker. I have used it only for a short time */
/* but I have found it useful. I hope you will also. */
/* */
/* Following are some general comments about this program: */
/*
When checking for proper line termination it returns <good> on
end-of-comment marker. This might not be the best choice as it could mask
an error on the same line (when a short comment is on the same line as
a line of code).
It expects if, for, and while loops to be terminated by closing parenthesis
(no semicolon) if and only if the loop declaration has no following statement.
Example 1: if (a==b)
x=y;
Example 2: if (a==b) x=y;
Both the above are correct and will not cause error messages.
Example 3: while(a[i++]!=0);
In the above, the programmer wants to increment i until a[i] is 0,
thus the semicolon is correct, but the lint program expects any kind of
loop to control a statement or block of statements, and so generates
the error message "Check line termination".
Sometimes, line labels will generate spurious error messages.
It will check printf(), fprintf(), sprintf and scanf() to see that the number
of parameters matches the number of <%> conversion characters. However it
does NOT check for type consistency, or anything about parameters
passed to functions. It will check to make sure that a for() loop has
exactly two semicolons inside the parentheses. A spurious error message
will be generated if a function name ends in "for" as the program thinks
it is a for() loop.
It will check for the balance of () parentheses, [] brackets, "" quote marks,
and {} braces. Spurious error messgaes may be generated if any of these are
used as text characters. Parentheses, braces, and quotes, but not brackets,
may be balanced on following lines if the LAST character on a line is a
backslash. Even white space following a backslash is not permitted. This is
consistent with Aztec C. This program will flag white space following the
last backslash on a line.
It will flag a line that appears to be a function declaration with a
semicolon. This may generate some spurious error messages.
It will flag nested or unbalanced comment markers.
It will not check for undeclared variables.
It does not recognize the comma that terminates lines in initializing
statements as permissable. Thus initializers will generate spurious error
messages. I suggest toggling lint off for these.
Most of the time it will find the syntax mistakes I make most often:
unbalanced parentheses, brackets, braces, and quotes; missing semicolons,
semicolons after function declarations, nested comments, parameters
left out of printf() statements, and too many or two few semicolons
inside for() statements.
Checking is toggled on and off with the words */
/*linton*/
/*lintoff*/ /*
which must appear starting at column 1, between comment markers,
without spaces. They may not be nested.
*/
/*linton*/
#include <stdio.h>
#define BELL 7
int errno;
main(n,arg)
int n;
char **arg;
{
int i,op=0,cp=0,ob=0,cb=0,os=0,cs=0,cmt=0,sq=0,quo=0,quot=0,l=0,conline=0;
char disab=0,q,string[300],fn[20],*fgets(),*r=1,cmtb=0;
FILE *fp;
/* If there is a file name on the command line it will use it. Otherwise */
/* it will ask for a file name */
if (n==2) strcpy(fn,arg[1]);
else getfn(fn);
o: if ((fp=fopen(fn,"r"))==0){
printf("Can't find %s errno=%d",fn,errno);
errno=0;
getfn(fn);
goto o;
}
while(r){
l++;
/* The following initializes string to all newline characters. Without this, */
/* under rare circumstances, the last line can get spurious error flags as */
/* the string winds up with part of the next-to-last line hanging on. */
for (i=0;i<255;i++) string[i]='\n';
/* The following gets one line of source code */
r=fgets(string,250,fp);
/* It ignores lines beginning with # because they usually require no */
/* special line termination: */
if (string[0]=='#') continue;
if ((i=strncmp(string,"/*lintoff*/",11))==0) {
disab=1;
/* conline keeps track of how many lines have been printed, so the */
/* program can pause for you to read the error messages. */
conline++;
printf("\
%s line: %d --> LINT TURNED OFF.\n\n",fn,l);
if (conline>9) pause(&conline);
}
if ((i=strncmp(string,"/*linton*/",10))==0) {
disab=0;
conline++;
printf("\
%s line: %d --> LINT TURNED BACK ON.\n\n",fn,l);
if (conline>9) pause(&conline);
}
if (disab) continue;
q=cktsp(string);
if (q=='b'){
conline++;
printf("\
%s line: %d --> White space after backslash:\n%s",fn,l,string);
q='r';
if (conline>9) pause(&conline);
}
diddle(string);
/* This is to skip blank lines: */
if (string[0]=='\n') continue;
q=endcheck(string);
if ( (q=='f') && ((op!=cp)||(ob!=cb)) ) {
conline++;
printf("\
%s line: %d --> New function declaration. --> %s\
Unbalanced parentheses<%d> or wavy brackets<%d> in the preceding function.\n",\
fn,l,string,(op-cp),(ob-cb));
if (conline>9) pause(&conline);
op=0;cp=0;ob=0;cb=0;os=0;cs=0;
}
if (q=='b'){
q=endexcpt(string);
if (q=='b'){
conline++;
printf("\
%s line: %d --> check line termination:\n%s",fn,l,string);
if (conline>9) pause(&conline);
}
q='r';
}
if (q=='g'){
q=loopwscn(string);
if (q=='b'){
conline++;
printf("\
%s line: %d --> check line termination:\n%s",fn,l,string);
if (conline>9) pause(&conline);
}
q='r';
}
/* These keep track of brackets: */
for (i=0;string[i]!='\n';i++){
if (string[i]=='(') op++;
if (string[i]==')') cp++;
if (string[i]=='{') ob++;
if (string[i]=='}') cb++;
if (string[i]=='[') os++;
if (string[i]==']') cs++;
/* This keeps track of comment markers: */
if (string[i]=='*'){
if (string[i-1]=='/') cmt++;
if (string[i+1]=='/') cmt--;
if ((cmt>1)||(cmt<0)) cmtb=1;
}
/* These keep track of apostrophes and quotes: */
if (string[i]=='\'') sq^=1;
if (string[i]=='\"') {
quo^=1;
quot++;
}
}
if (os!=cs) {
conline++;
printf("\
%s line: %d --> unbalanced square brackets:\n%s",fn,l,string);
if (conline>9) pause(&conline);
}
os=0;
cs=0;
if (op!=cp) {
q=querybks(string);
if (q=='b') {
conline++;
printf("\
%s line: %d --> unbalanced parentheses:\n%s",fn,l,string);