From 8f3f849bbc87ea8cd8ac8afbf7c1caf91e117abf Mon Sep 17 00:00:00 2001 From: Tom London Date: Sun, 5 Nov 1978 23:31:16 -0500 Subject: [PATCH] Bell 32V development 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 Synthesized-from: 32v --- usr/src/cmd/lint/SHELL | 23 +++ usr/src/cmd/lint/llib-port | 44 +++++ usr/src/cmd/lint/lmanifest | 18 ++ usr/src/cmd/lint/lpass2.c | 367 +++++++++++++++++++++++++++++++++++++ 4 files changed, 452 insertions(+) create mode 100755 usr/src/cmd/lint/SHELL create mode 100644 usr/src/cmd/lint/llib-port create mode 100644 usr/src/cmd/lint/lmanifest create mode 100644 usr/src/cmd/lint/lpass2.c diff --git a/usr/src/cmd/lint/SHELL b/usr/src/cmd/lint/SHELL new file mode 100755 index 0000000000..dbb6febe57 --- /dev/null +++ b/usr/src/cmd/lint/SHELL @@ -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 index 0000000000..c4773af05b --- /dev/null +++ b/usr/src/cmd/lint/llib-port @@ -0,0 +1,44 @@ + /* LINTLIBRARY */ +#include + 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 index 0000000000..2a6ed882a4 --- /dev/null +++ b/usr/src/cmd/lint/lmanifest @@ -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 index 0000000000..5c2086470d --- /dev/null +++ b/usr/src/cmd/lint/lpass2.c @@ -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; iatyp[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; inargs; ++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 ); + } -- 2.20.1