📄 lpass2.c
字号:
/* "%.8s returns value which is sometimes ignored\n" */ /* "%s returns value which is sometimes ignored\n" */ buffer( 11, q ); else /* "%.8s returns value which is always ignored\n" */ /* "%s returns value which is always ignored\n" */ buffer( 10, q ); } if( (uses&(RVAL+VUSED)) == (VUSED) && (q->decflag&(LDI|LDS|LIB)) ) /* "%.8s value is used, but none returned\n" */ /* "%s value is used, but none returned\n" */ buffer( 9, q );}/* cleanup - call lastone and die gracefully */cleanup(){ SYMTAB *q; for( q=stab; q < &stab[NSZ]; ++q ) if( q->decflag ) lastone(q);}/* setuse - check new type to ensure that it is used */setuse(q) SYMTAB *q;{ if( !q->decflag ){ /* new one */ q->decflag = r.l.decflag; q->symty.t = r.l.type; if( r.l.nargs < 0 ){ q->nargs = -r.l.nargs - 1; q->use = VARARGS; } else { q->nargs = r.l.nargs; q->use = 0; } q->fline = r.l.fline; q->fno = cfno; q->mno = cmno; if( q->nargs ){ int i; STYPE *qq; for( i=0,qq= &q->symty; i<q->nargs; ++i,qq=qq->next ){ qq->next = tget(); qq->next->t = atyp[i]; } } } switch( r.l.decflag ){ case LRV: q->use |= RVAL; return; case LUV: q->use |= VUSED+USED; return; case LUE: q->use |= EUSED+USED; return; /* 01/04/80 */ case LUV | LUE: case LUM: q->use |= USED; return; } /* 04/06/80 */ if ( (q->decflag & LDX) && (r.l.decflag & LDC) ) q->decflag = LDC;}/* chktype - check the two type words to see if they are compatible */chktype( pt1, pt2 ) register ATYPE *pt1, *pt2; { register TWORD t,t2; t = ctype(pt1->aty); t2= ctype(pt2->aty); switch(BTYPE(t)){ case ENUMTY: case STRTY: case UNIONTY: case MOETY: if( t != t2){ /* * if qflag: permit const 0 and (void *) as actual * parameters when formal parameter has pointer * type. */ if (qflag && ISPTR(t)) { if (t2==INT && pt2->extra && pt2->extra1==0 ) { /* formal is ptr, actual is const 0 */ return 0; } if (TVOIDPTR(t2)) { /* formal is ptr, actual is (void*) */ return 0; } } return 1; }else if( pt1->extra1 != pt2->extra1 ) return 1; /* if -z then don't worry about undefined structures, as long as the names match */ if( zflag && (pt1->extra == 0 || pt2->extra == 0) ) return 0; return pt1->extra != pt2->extra; default: break; } if( pt2->extra ){ /* constant passed in */ /* * integer constant acceptable as unsigned. * long constant acceptable as unsigned long. * zero acceptable as pointer if qflag. */ if( t == UNSIGNED && t2 == INT ) return( 0 ); else if( t == ULONG && t2 == LONG ) return( 0 ); else if (ISPTR(t) && (pt2->extra1==0) ) return(!qflag); } else if( pt1->extra ){ /* for symmetry */ if( t2 == UNSIGNED && t == INT ) return( 0 ); else if( t2 == ULONG && t == LONG ) return( 0 ); } if (qflag) { /* * (void*) is compatible with any other pointer type */ if (ISPTR(t) && TVOIDPTR(t2) || ISPTR(t2) && TVOIDPTR(t)) { return ( 0 ); } } return( t != t2 );}/* snarffed from lint.c */TWORDctype( type ){ /* map types which are not defined on the local machine */ /* this is appropriate for sunrise/68000 mapping, since "we know" * that long == int */ if (qflag){ switch( BTYPE(type) ){ case ENUMTY: /* no such thing */ MODTYPE(type,UNSIGNED); break; case LONG: /* don't waste my time */ MODTYPE(type,INT); break; case ULONG: /* don't waste my time */ MODTYPE(type,UNSIGNED); break; } } return( type );}# ifdef DEBUG/* diagnostic output tools * the following programs are used to print out internal information * for diagnostic purposes * Current options: * -Xi * turns on printing of intermediate file on entry to lint2 * (input information) * -Xo * turns on printing of lint symbol table on last pass of lint2 * (output information) */struct tb { int m; char * nm };static struct tb dfs[] = { LDI, "LDI", LIB, "LIB", LDC, "LDC", LDX, "LDX", LRV, "LRV", LUV, "LUV", LUE, "LUE", LUM, "LUM", LDS, "LDS", 0, "" };static struct tb us[] = { USED, "USED", VUSED, "VUSED", EUSED, "EUSED", RVAL, "RVAL", VARARGS, "VARARGS", 0, 0,};/* ptb - print a value from the table */ptb( v, tp ) struct tb *tp; { int flag = 0; for( ; tp->m; ++tp ) if( v&tp->m ){ if( flag++ ) putchar( '|' ); printf( "%s", tp->nm ); }}/* pif - print intermediate file * prints file written out by first pass of lint * printing turned on by the debug option -Xi */pif(){ printf("\n\tintermediate file printout:\n"); printf("\t===========================\n"); while( 0 < fread( (char *)&r, sizeof(r), 1, stdin) ) { if ( r.l.decflag & LFN ) { r.f.fn = getstr(); printf( "\nFILE NAME: %-15s\n", r.f.fn ); } else { r.l.name = getstr(); printf( "\t%-8s (", r.l.name ); ptb(r.l.decflag, dfs); printf(")\t line= %d", r.l.fline); if ( ISFTN(r.l.type.aty) ) printf("\tnargs= %d", r.l.nargs); else printf("\t\t\t"); printf("\t type= "); tprint(r.l.type.aty); printf("\n"); if ( r.l.nargs ) { int n = 0; if ( r.l.nargs < 0 ) r.l.nargs= -r.l.nargs - 1; fread( (char *)atyp, sizeof(ATYPE), r.l.nargs, stdin); while ( ++n <= r.l.nargs ) { printf("\t\t arg(%d)= ",n); tprint(atyp[n-1].aty); printf("\n"); } } } } /*while*/ rewind( stdin );} /*end pif*//* pst - print lint symbol table * prints symbol table created from intermediate file * printing turned on by the debug option -Xo */pst(){ int count = 0; SYMTAB *q; printf("\n\tsymbol table printout:\n"); printf("\t======================\n"); for( q=stab; q < &stab[NSZ]; ++q) { if( q->decflag ) { count++; printf( "\t%8s (", q->name ); ptb(q->decflag, dfs); printf(")\t line= %d", q->fline); if ( ISFTN(q->symty.t.aty) ) printf("\tnargs= %d", q->nargs); else printf("\t\t\t"); printf("\t type= "); tprint(q->symty.t.aty); printf("\t use= "); ptb(q->use, us); printf("\n"); if ( q->nargs ) { int n = 1; STYPE *qq; for( qq=q->symty.next; n <= q->nargs; qq=qq->next) { printf("\t\t arg(%d)= ",n++); tprint(qq->t.aty); printf("\n"); } } } /*end if(q->decflag)*/ } /*end for*/ printf("\n%d symbol table entries\n",count);}/* tprint - print a nice description of a type * borrowed from PCC */tprint( t ) TWORD t; { static char * tnames[] = { "void", "farg", "char", "short", "int", "long", "float", "double", "strty", "unionty", "enumty", "moety", "uchar", "ushort", "unsigned", "ulong", "?", "?" }; for(;; t = DECREF(t) ){ if( ISPTR(t) ) printf( "PTR " ); else if( ISFTN(t) ) printf( "FTN " ); else if( ISARY(t) ) printf( "ARY " ); else if((unsigned)t > ULONG) { printf( "t=0x%x ", t ); return; } else { printf( "%s", tnames[t] ); return; } }}# elsepif(){ printf("intermediate file dump not available\n"); }pst(){ printf("symbol table dump not available\n"); }# endif#include <ctype.h>char *getstr() /* read arb. len. name string from input & return ptr to it */{ char buf[BUFSIZ]; register char *cp = buf; register int c; while ( ( c = getchar() ) != EOF ) { *cp++ = c; if ( c == '\0' || !isascii( c ) ) break; } if ( feof( stdin ) ) { sprintf( buf, "Premature end of file %s", ifilename ? ifilename : "<stdin>" ); lerror( buf, CCLOSE | FATAL | ERRMSG ); } else if ( ferror( stdin ) ) { sprintf( buf, "Read error on %s", ifilename ? ifilename : "<stdin>" ); lerror( buf, CCLOSE | FATAL | ERRMSG ); } else if ( c != '\0' ) { sprintf( buf, "Name string format error in intermediate file %s", ifilename ? ifilename : "<stdin>" ); lerror( buf, CCLOSE | FATAL | ERRMSG ); } return ( hash( buf ) );}#define NSAVETAB 4096char *savetab;int saveleft;char *savestr( cp ) /* copy string into permanent string storage */ register char *cp;{ register int len; len = strlen( cp ) + 1; if ( len > saveleft ) { saveleft = NSAVETAB; if ( len > saveleft ) saveleft = len; savetab = (char *) malloc( (unsigned) saveleft ); if ( savetab == 0 ) lerror( "Ran out of memory [savestr()]", CCLOSE | FATAL | ERRMSG ); } (void) strncpy( savetab, cp, len ); cp = savetab; savetab += len; saveleft -= len; return ( cp );}/** The segmented hash tables*/#define MAXHASH 20#define HASHINC 1013struct ht{ char **ht_low; char **ht_high; int ht_used;};struct ht htab[MAXHASH]; /* non-filenames */char *hash( s ) /* hash and store name in permanent storage area */ char *s;{ register char **h; register int i; register char *cp; struct ht *htp; int sh; /* * Hash on all the characters. */ sh = hashstr(s) % HASHINC; cp = s; /* * Look through each table for name. If not found in the current * table, skip to the next one. */ for ( htp = htab; htp < &htab[MAXHASH]; htp++ ) { if ( htp->ht_low == 0 ) { register char **hp = (char **) calloc( sizeof (char **), HASHINC ); if ( hp == 0 ) lerror( "Ran out of memory [fhash()]", CCLOSE | FATAL | ERRMSG ); htp->ht_low = hp; htp->ht_high = hp + HASHINC; } h = htp->ht_low + sh; /* * Use quadratic re-hash */ i = 1; do { if ( *h == 0 ) { if ( htp->ht_used > ( HASHINC * 3 ) / 4 ) break; htp->ht_used++; *h = savestr( cp ); return ( *h ); } if ( **h == *cp && strcmp( *h, cp ) == 0 ) return ( *h ); h += i; i += 2; if ( h >= htp->ht_high ) h -= HASHINC; } while ( i < HASHINC ); } lerror( "Ran out of hash tables", CCLOSE | FATAL | ERRMSG ); /*NOTREACHED*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -