📄 lpass2.c
字号:
/************************************************************************ * * * Copyright (c) 1988 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * Change history * * 001 Jon Reeves, 1988-July-07 * Increased FSZ from 500 to 5000. */#ifndef lintstatic char sccsid[] = "@(#)lpass2.c 4.1 ULTRIX 7/3/90";#endif lint# include "manifest"# include "lmanifest"# define USED 01# define VUSED 02# define EUSED 04# define RVAL 010# define VARARGS 0100# define NSZ 2048# define TYSZ 3500# define FSZ 5000# define NTY 50typedef struct sty STYPE;struct sty { ATYPE t; STYPE *next; };typedef struct sym {#ifndef FLEXNAMES char name[LCHNM];#else char *name;#endif short nargs; int decflag; int fline; STYPE symty; int fno; int use; } STAB;STAB stab[NSZ];STAB *find();STYPE tary[TYSZ];STYPE *tget();#ifndef FLEXNAMESchar fnm[FSZ][LFNM];#elsechar *fnm[FSZ];#endif#ifdef FLEXNAMESchar *getstr();#endifint tfree; /* used to allocate types */int ffree; /* used to save filenames */struct ty atyp[NTY]; /* r is where all the input ends up */union rec r;int hflag = 0;int pflag = 0;int xflag = 0;int uflag = 1;int ddddd = 0;int zflag = 0;int Pflag = 0;int cfno; /* current file number */main( argc, argv ) char *argv[]; { register char *p; /* first argument is intermediate file */ /* second argument is - options */ for( ; argc>2 && argv[argc-1][0] == '-' ; --argc ){ for( p=argv[argc-1]; *p; ++p ){ switch( *p ){ case 'h': hflag = 1; break; case 'p': pflag = 1; break; case 'x': xflag = 1; break; case 'X': ddddd = 1; break; case 'u': uflag = 0; break; case 'z': zflag = 1; break; case 'P': Pflag = 1; break; } } } if( argc < 2 || !freopen( argv[1], "r", stdin ) ){ error( "cannot open intermediate file" ); exit( 1 ); } if( Pflag ){ pfile(); return( 0 ); } mloop( LDI|LIB|LST ); rewind( stdin ); mloop( LDC|LDX ); rewind( stdin ); mloop( LRV|LUV|LUE|LUM ); cleanup(); return(0); }mloop( m ){ /* do the main loop */ register STAB *q; while( lread(m) ){ q = find(); if( q->decflag ) chkcompat(q); else setuse(q); } }lread(m){ /* read a line into r.l */ register n; for(;;) { if( fread( (char *)&r, sizeof(r), 1, stdin ) <= 0 ) return(0); if( r.l.decflag & LFN ){ /* new filename */#ifdef FLEXNAMES r.f.fn = getstr();#endif if( Pflag ) return( 1 ); setfno( r.f.fn ); continue; }#ifdef FLEXNAMES r.l.name = getstr();#endif n = r.l.nargs; if( n<0 ) n = -n; if( n>=NTY ) error( "more than %d args?", n ); fread( (char *)atyp, sizeof(ATYPE), n, stdin ); if( ( r.l.decflag & m ) ) return( 1 ); } }setfno( s ) char *s; { /* look up current file names */ /* first, strip backwards to the beginning or to the first / */ int i; /* now look up s */ for( i=0; i<ffree; ++i ){#ifndef FLEXNAMES if( !strncmp( s, fnm[i], LFNM ) )#else if (fnm[i] == s)#endif { cfno = i; return; } } /* make a new entry */ if( ffree >= FSZ ) error( "more than %d files", FSZ );#ifndef FLEXNAMES strncpy( fnm[ffree], s, LFNM );#else fnm[ffree] = s;#endif cfno = ffree++; }/* VARARGS */error( s, a ) char *s; {#ifndef FLEXNAMES fprintf( stderr, "pass 2 error:(file %.*s) ", LFNM, fnm[cfno] );#else fprintf( stderr, "pass 2 error:(file %s) ", fnm[cfno] );#endif fprintf( stderr, s, a ); fprintf( stderr, "\n" ); exit(1); }STAB *find(){ register h=0;#ifndef FLEXNAMES h = hashstr(r.l.name, LCHNM) % NSZ;#else h = (int)r.l.name % NSZ;#endif { register STAB *p, *q; for( p=q= &stab[h]; q->decflag; ){#ifndef FLEXNAMES if( !strncmp( r.l.name, q->name, LCHNM))#else if (r.l.name == q->name)#endif if( ((q->decflag|r.l.decflag)&LST)==0 || q->fno==cfno ) return(q); if( ++q >= &stab[NSZ] ) q = stab; if( q == p ) error( "too many names defined" ); }#ifndef FLEXNAMES strncpy( q->name, r.l.name, LCHNM );#else q->name = r.l.name;#endif return( q ); } }STYPE *tget(){ if( tfree >= TYSZ ){ error( "too many types needed" ); } return( &tary[tfree++] ); }chkcompat(q) STAB *q; { /* are the types, etc. in r.l and q compatible */ register int i; STYPE *qq; setuse(q); /* argument check */ if( q->decflag & (LDI|LIB|LUV|LUE|LST) ){ if( r.l.decflag & (LUV|LIB|LUE) ){ if( q->nargs != r.l.nargs ){ if( !(q->use&VARARGS) ){#ifndef FLEXNAMES printf( "%.8s: variable # of args.", q->name );#else printf( "%s: variable # of args.", q->name );#endif viceversa(q); } if( r.l.nargs > q->nargs ) r.l.nargs = q->nargs; if( !(q->decflag & (LDI|LIB|LST) ) ) { q->nargs = r.l.nargs; q->use |= VARARGS; } } for( i=0,qq=q->symty.next; i<r.l.nargs; ++i,qq=qq->next){ if( chktype( &qq->t, &atyp[i] ) ){#ifndef FLEXNAMES printf( "%.8s, arg. %d used inconsistently",#else printf( "%s, arg. %d used inconsistently",#endif q->name, i+1 ); viceversa(q); } } } } if( (q->decflag&(LDI|LIB|LUV|LST)) && r.l.decflag==LUV ){ if( chktype( &r.l.type, &q->symty.t ) ){#ifndef FLEXNAMES printf( "%.8s value used inconsistently", q->name );#else printf( "%s value used inconsistently", q->name );#endif viceversa(q); } } /* check for multiple declaration */ if( (q->decflag&(LDI|LST)) && (r.l.decflag&(LDI|LIB|LST)) ){#ifndef FLEXNAMES printf( "%.8s multiply declared", q->name );#else printf( "%s multiply declared", q->name );#endif viceversa(q); } /* do a bit of checking of definitions and uses... */ if( (q->decflag & (LDI|LIB|LDX|LDC|LUM|LST)) && (r.l.decflag & (LDX|LDC|LUM)) && q->symty.t.aty != r.l.type.aty ){#ifndef FLEXNAMES printf( "%.8s value declared inconsistently", q->name );#else printf( "%s value declared inconsistently", q->name );#endif viceversa(q); } /* better not call functions which are declared to be structure or union returning */ if( (q->decflag & (LDI|LIB|LDX|LDC|LST)) && (r.l.decflag & LUE) && q->symty.t.aty != r.l.type.aty ){ /* only matters if the function returns union or structure */ TWORD ty; ty = q->symty.t.aty; if( ISFTN(ty) && ((ty = DECREF(ty))==STRTY || ty==UNIONTY ) ){#ifndef FLEXNAMES printf( "%.8s function value type must be declared before use", q->name );#else printf( "%s function value type must be declared before use", q->name );#endif viceversa(q); } } if( pflag && q->decflag==LDX && r.l.decflag == LUM && !ISFTN(q->symty.t.aty) ){ /* make the external declaration go away */ /* in effect, it was used without being defined */ } }viceversa(q) STAB *q; { /* print out file comparison */#ifndef FLEXNAMES printf( " %.*s(%d) :: %.*s(%d)\n", LFNM, fnm[q->fno], q->fline, LFNM, fnm[cfno], r.l.fline );#else printf( " %s(%d) :: %s(%d)\n", fnm[q->fno], q->fline, fnm[cfno], r.l.fline );#endif } /* messages for defintion/use */char *mess[2][2] ={ "",#ifndef FLEXNAMES "%.8s used( %.*s(%d) ), but not defined\n", "%.8s defined( %.*s(%d) ), but never used\n", "%.8s declared( %.*s(%d) ), but never used or defined\n"#else "%s used( %s(%d) ), but not defined\n", "%s defined( %s(%d) ), but never used\n", "%s declared( %s(%d) ), but never used or defined\n"#endif };lastone(q) STAB *q; { register nu, nd, uses; if( ddddd ) pst(q); nu = nd = 0; uses = q->use; if( !(uses&USED) && q->decflag != LIB ) {#ifndef FLEXNAMES if( strncmp(q->name,"main",7) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -