Bell 32V development
authorTom London <tbl@research.uucp>
Mon, 6 Nov 1978 04:31:16 +0000 (23:31 -0500)
committerTom London <tbl@research.uucp>
Mon, 6 Nov 1978 04:31:16 +0000 (23:31 -0500)
Work on file usr/src/cmd/lint/SHELL
Work on file usr/src/cmd/lint/lpass2.c
Work on file usr/src/cmd/lint/llib-port
Work on file usr/src/cmd/lint/lmanifest

Co-Authored-By: John Reiser <jfr@research.uucp>
Synthesized-from: 32v

usr/src/cmd/lint/SHELL [new file with mode: 0755]
usr/src/cmd/lint/llib-port [new file with mode: 0644]
usr/src/cmd/lint/lmanifest [new file with mode: 0644]
usr/src/cmd/lint/lpass2.c [new file with mode: 0644]

diff --git a/usr/src/cmd/lint/SHELL b/usr/src/cmd/lint/SHELL
new file mode 100755 (executable)
index 0000000..dbb6feb
--- /dev/null
@@ -0,0 +1,23 @@
+L=/usr/lib/lint T=/usr/tmp/lint.$$ PATH=/bin:/usr/bin O="-C -Dlint" X= P=unix
+LL=/usr/lib
+trap "rm -f $T; exit" 1 2 15
+for A in $*
+do
+       case $A in
+       -*n*)   P= ;;
+       -*p*)   P=port ;;
+       esac
+       case $A in
+       -l*)    (/lib/cpp $O $LL/llib$A | ${L}1 -v$X-L$A >>$T)2>&1 ;;
+       -[IDOU]*)       O="$O $A" ;;
+       -X)     LL=/usr/src/cmd/lint L=/usr/src/cmd/lint/lpass ;;
+       -*)     X="$X$A" ;;
+       *)      (/lib/cpp $O $A | ${L}1 $X-L$A >>$T)2>&1
+       esac
+       done
+case $P in
+       unix)   (/lib/cpp $O $LL/llib-lc | ${L}1 -v$X-L-lc >>$T)2>&1 ;;
+       port)   (/lib/cpp $O $LL/llib-port | ${L}1 -v$X-L-lc >>$T)2>&1 ;;
+       esac
+sort -u $T | ${L}2 $X
+rm -f $T
diff --git a/usr/src/cmd/lint/llib-port b/usr/src/cmd/lint/llib-port
new file mode 100644 (file)
index 0000000..c4773af
--- /dev/null
@@ -0,0 +1,44 @@
+       /* LINTLIBRARY */
+#include <stdio.h>
+       exit(s) {;}
+long   lseek(f, o, d) long o; { return(0); }
+char   *mktemp(p) char *p; { return(p);}
+int    (*signal(c, f))() int (*f)(); { return(f); }
+char   *strcat(a, b) char *a, *b; { ; }
+int    strcmp(a, b) char *a, *b; { return(1); }
+char   *strcpy(a, b) char *a, *b; { ; }
+int    strlen(s) char *s; { return(1); }
+long   tell(f) { return((long)0); }
+long   time(t) long *t; { return(0);}
+char   *calloc(n,s) unsigned n, s; { static char c[1]; return(c); }
+char   *malloc(n) unsigned n; {static char c; return(&c);}
+char   *realloc(p, n) char *p; unsigned n; { static char c; return(&c);}
+       free(p) char *p; {;}
+       fclose(f) FILE *f; {return(0);}
+       fflush(f) FILE *f; {return(0);}
+char   *fgets( s, l, f ) char *s; FILE *f; { return(s); }
+FILE   *fopen(s,m) char *s, *m; { return(stdin); }
+FILE   *freopen(s, m, f) char *s, *m; FILE *f; { return(stdin); }
+FILE   *fdopen(fd, m) char *m; { return(stdin);}
+       /* VARARGS */
+       fprintf( f, s ) FILE *f; char *s; {;}
+       fputs(s,f) char *s; FILE *f; {;}
+       fread( p, s, n, f ) char *p; FILE *f; {return(1);}
+       /* VARARGS */
+       fscanf( f, s ) FILE *f; char *s; {return(1);}
+int    fwrite( p, s, n, f ) char *p; FILE *f; {return(0);}
+       intss(){return(1); }
+       /* VARARGS */
+       printf( s ) char *s; {;}
+       rewind(f) FILE *f; {;}
+       /* VARARGS */
+       scanf( f ) char *f; {return(1); }
+       setbuf( f, b ) FILE *f; char *b; {;}
+       /* VARARGS */
+char   *sprintf( s, f ) char *s, *f; { return(s);}
+       /* VARARGS */
+       sscanf( s, f ) char *s, *f; { return(1); }
+       ungetc( c, f ) FILE *f; {  return(c); }
+       wdleng(){return(0); }
+struct _iobuf _iob[_NFILE];
+char   _ctype_[129];
diff --git a/usr/src/cmd/lint/lmanifest b/usr/src/cmd/lint/lmanifest
new file mode 100644 (file)
index 0000000..2a6ed88
--- /dev/null
@@ -0,0 +1,18 @@
+/*     the key:
+       LDI     defined and initialized: storage set aside
+       LIB     defined on a library
+       LDC     defined as a common region on UNIX
+       LDX     defined by an extern: if ! pflag, same as LDI
+       LRV     function returns a value
+       LUV     function used in a value context
+       LUE     function used in effects context
+       LUM     mentioned somewhere other than at the declaration
+       */
+# define LDI 01
+# define LIB 02
+# define LDC 04
+# define LDX 010
+# define LRV 020
+# define LUV 040
+# define LUE 0100
+# define LUM 0200
diff --git a/usr/src/cmd/lint/lpass2.c b/usr/src/cmd/lint/lpass2.c
new file mode 100644 (file)
index 0000000..5c20864
--- /dev/null
@@ -0,0 +1,367 @@
+# include "lmanifest"
+# include "manifest"
+
+# define USED 01
+# define VUSED 02
+# define EUSED 04
+# define RVAL 010
+# define VARARGS 0100
+
+typedef struct { TWORD aty; int extra; } atype;
+
+struct line {
+       char name[8];
+       int decflag;
+       atype type;
+       int nargs;
+       atype atyp[50];
+       int fline;
+       char file[100];
+       }
+
+       l1,
+       l2,
+       *pd,    /* pointer to line having definition */
+       *pc,    /* pointer to current line read */
+       *p3;    /* used for swapping pc and pd */
+
+int uses = USED;
+int hflag = 0;
+int pflag = 0;
+int xflag = 0;
+int uflag = 1;
+
+
+main( argc, argv ) char *argv[]; {
+
+       register char *p;
+
+       /* first argument is - options */
+
+       if( argc>=2 && argv[1][0] == '-' ){
+               for( p=argv[1]; *p; ++p ){
+                       switch( *p ){
+
+                       case 'h':
+                               hflag = 1;
+                               break;
+
+                       case 'p':
+                               pflag = 1;
+                               break;
+
+                       case 'x':
+                               xflag = 1;
+                               break;
+
+                       case 'u':
+                               uflag = 0;
+                               break;
+
+                               }
+                       }
+               }
+
+
+
+       pd = &l1;
+       pc = &l2;
+       pd->name[0] = '\0' ;
+       pd->fline = 0;
+       pd->file[0] = '\0';
+       pd->decflag = LDI;
+
+       /* main loop: read a line;
+               if same as last line, check compatibility
+               if not same as last line, becomes df.
+               */
+
+       for(;;){
+               lread();
+               if( steq(pc->name, pd->name) ) chkcompat();
+               else {
+                       lastone();
+                       setuse();
+                       p3=pc;
+                       pc = pd;
+                       pd = p3;
+                       }
+               }
+
+       }
+
+lread(){ /* read a line into pc */
+
+       register i, n;
+
+       getnam( pc->name );
+
+       pc->decflag = rdin10();
+       rdinty( &pc->type );
+       n = pc->nargs = rdin10();
+       if( n<0 ) n = -n;
+
+       for( i=0; i<n; ++i ){
+               rdinty( &pc->atyp[i] );
+               }
+
+       getnam( pc->file );
+       pc->fline = rdin10();
+
+       while( getchar() != '\n' ) ; /* VOID */
+       }
+
+rdin10(){
+       register val, c, s;
+
+       val = 0;
+       s = 1;
+
+       while( (c=getchar()) != '\t' ){
+               if( c <= 0 ) error( "unexpected EOF" );
+               else if( c == '-' ) {
+                       s = -1;
+                       continue;
+                       }
+               else if( c<'0' || c>'9' ) {
+                       error("rotten digit: %o\n", c );
+                       }
+               val = val*10 + c - '0';
+               }
+       return( val*s );
+       }
+
+rdinty( p ) atype *p; {
+       register val, c, s;
+
+       val = 0;
+       s = 1;
+
+       while( (c=getchar()) != '\t' && c!= '<' ){
+               if( c <= 0 ) error( "unexpected EOF" );
+               else if( c == '-' ) {
+                       s = -1;
+                       continue;
+                       }
+               else if( c<'0' || c>'7' ) {
+                       error("rotten digit: %o\n", c );
+                       }
+               val = (val<<3) + c - '0';
+               }
+       p->aty = val*s;
+       if( c == '<' ) p->extra = rdin10();
+       else p->extra = 0;
+       }
+
+getnam(p) char *p; {
+       register c;
+       while( (c=getchar()) != '\t' ){
+               if( c == '\n' ) error( "rotten name\n" );
+               if( c <= 0 ) cleanup();
+               *p++ = c;
+               }
+       *p = '\0';
+       }
+
+/* VARARGS */
+error( s, a ) char *s; {
+
+       fprintf( stderr, "pass 2 error: " );
+       fprintf( stderr, s, a );
+       fprintf( stderr, "\n" );
+       exit(1);
+       }
+
+steq(p,q) char *p,*q; { /* check that the p and q names are the same */
+
+
+       while( *p == *q ){
+               if( *p == 0 ) return(1);
+               ++p;
+               ++q;
+               }
+
+       return(0);
+       }
+
+chkcompat(){
+       /* are the types, etc. in pc and pd compatible */
+       register int i;
+
+       setuse();
+
+       /* argument check */
+
+       if( pd->decflag & (LDI|LIB|LUV|LUE) ){
+               if( pc->decflag & (LUV|LIB|LUE) ){
+                       if( pd->nargs != pc->nargs ){
+                               if( !(uses&VARARGS) ){
+                                       printf( "%.7s: variable # of args.", pd->name );
+                                       viceversa();
+                                       }
+                               if( pc->nargs > pd->nargs ) pc->nargs = pd->nargs;
+                               if( !(pd->decflag & (LDI|LIB) ) ) {
+                                       pd->nargs = pc->nargs;
+                                       uses |= VARARGS;
+                                       }
+                               }
+                       for( i=0; i<pc->nargs; ++i ){
+                               if( chktype(&pd->atyp[i], &pc->atyp[i]) ){
+                                       printf( "%.7s, arg. %d used inconsistently",
+                                               pd->name, i+1 );
+                                       viceversa();
+                                       }
+                               }
+                       }
+               }
+
+       if( (pd->decflag&(LDI|LIB|LUV)) && pc->decflag==LUV ){
+               if( chktype( &pc->type, &pd->type ) ){
+                       printf( "%.7s value used inconsistently", pd->name );
+                       viceversa();
+                       }
+               }
+
+       /* check for multiple declaration */
+
+       if( (pd->decflag&LDI) && (pc->decflag&(LDI|LIB)) ){
+               printf( "%.7s multiply declared", pd->name );
+               viceversa();
+               }
+
+       /* do a bit of checking of definitions and uses... */
+
+       if( (pd->decflag & (LDI|LIB|LDX|LDC)) && (pc->decflag & (LDX|LDC)) && pd->type.aty != pc->type.aty ){
+               printf( "%.7s value declared inconsistently", pd->name );
+               viceversa();
+               }
+
+       /* better not call functions which are declared to be structure or union returning */
+
+       if( (pd->decflag & (LDI|LIB|LDX|LDC)) && (pc->decflag & LUE) && pd->type.aty != pc->type.aty ){
+               /* only matters if the function returns union or structure */
+               TWORD ty;
+               ty = pd->type.aty;
+               if( ISFTN(ty) && ((ty = DECREF(ty))==STRTY || ty==UNIONTY ) ){
+                       printf( "%.7s function value type must be declared before use", pd->name );
+                       viceversa();
+                       }
+               }
+
+       if( pflag && pd->decflag==LDX && pc->decflag == LUM && !ISFTN(pd->type.aty) ){
+               /* make the external declaration go away */
+               /* in effect, it was used without being defined */
+
+               /* swap pc and pd */
+               p3 = pc;
+               pc = pd;
+               pd = p3;
+               }
+
+       }
+
+viceversa(){
+       /* print out file comparison */
+       printf( "       %s(%d)  ::  %s(%d)\n", pd->file, pd->fline, pc->file, pc->fline );
+       }
+
+       /* messages for defintion/use */
+char *
+mess[2][2] = {
+       "",
+       "%.7s used( %s(%d) ), but not defined\n",
+       "%.7s defined( %s(%d) ), but never used\n",
+       "%.7s declared( %s(%d) ), but never used or defined\n"
+       };
+
+lastone(){
+
+       /* called when pc and pd are at last different */
+       register nu, nd;
+
+       nu = nd = 0;
+
+       if( !(uses&USED) && pd->decflag != LIB ) {
+               if( !steq(pd->name,"main") )
+                       nu = 1;
+               }
+
+       if( !ISFTN(pd->type.aty) ){
+               switch( pd->decflag ){
+
+               case LIB:
+                       nu = nd = 0;  /* don't complain about uses on libraries */
+                       break;
+               case LDX:
+                       if( !xflag ) break;
+               case LUV:
+               case LUE:
+               case LUM:
+                       nd = 1;
+                       }
+               }
+
+       if( uflag && ( nu || nd ) ) printf( mess[nu][nd], pd->name, pd->file, pd->fline );
+
+       if( (uses&(RVAL+EUSED)) == (RVAL+EUSED) ){
+               printf( "%.7s returns value which is %s ignored\n", pd->name,
+                       uses&VUSED ? "sometimes" : "always" );
+               }
+
+       if( (uses&(RVAL+VUSED)) == (VUSED) && (pd->decflag&(LDI|LIB)) ){
+               printf( "%.7s value is used, but none returned\n", pd->name );
+               }
+
+       /* clean up pc, in preparation for the next thing */
+
+       uses = 0;
+       if( pc->nargs < 0 ){
+               pc->nargs = -pc->nargs;
+               uses = VARARGS;
+               }
+
+       }
+
+cleanup(){ /* call lastone and die gracefully */
+       lastone();
+       exit(0);
+       }
+
+setuse(){ /* check new type to ensure that it is used */
+
+       switch( pc->decflag ){
+
+       case LRV:
+               uses |= RVAL;
+               return;
+       case LUV:
+               uses |= VUSED+USED;
+               return;
+       case LUE:
+               uses |= EUSED+USED;
+               return;
+       case LUM:
+               uses |= USED;
+               return;
+
+               }
+       }
+
+chktype( pt1, pt2 ) register atype *pt1, *pt2; {
+
+       /* check the two type words to see if they are compatible */
+       /* for the moment, enums are turned into ints, and should be checked as such */
+       if( pt1->aty == ENUMTY ) pt1->aty =  INT;
+       if( pt2->aty == ENUMTY ) pt2->aty = INT;
+
+       if( pt2->extra ){ /* constant passed in */
+               if( pt1->aty == UNSIGNED && pt2->aty == INT ) return( 0 );
+               else if( pt1->aty == ULONG && pt2->aty == LONG ) return( 0 );
+               }
+       else if( pt1->extra ){ /* for symmetry */
+               if( pt2->aty == UNSIGNED && pt1->aty == INT ) return( 0 );
+               else if( pt2->aty == ULONG && pt1->aty == LONG ) return( 0 );
+               }
+
+       return( pt1->aty != pt2->aty );
+       }