# 2.11BSD#431 - /usr/src/lib/cpp/cpp.c

##### Functions

    control           X
    copy              X
    cotoken           X
    dodef             X
    doincl            X
    dump              X
    equfrm            X
    lookup            X
    main              X
    pperror           X
    ppsym             X
    ppwarn            X
    refill            X
    savestring        X
    sayline           X
    skipbl            X
    slookup           X
    strdex            X
    stsym             X
    subst             X
    trmdir            X
    unfill            X
    yyerror           X
    yywrap            X

##### Variables

    buffer            X
    bufstack          X
    cinit             X
    defloc            X
    dirnams           X
    dirs              X
    eifloc            X
    elsloc            X
    endbuf            X
    exfail            X
    fastab            X
    fin               X
    fins              X
    flslvl            X
    fnames            X
    fretop            X
    ifdloc            X
    ifloc             X
    ifnloc            X
    ifno              X
    incloc            X
    inctop            X
    infile            X
    inp               X
    instack           X
    lastsym           X
    lineno            X
    lneloc            X
    macbit            X
    macdam            X
    macfil            X
    macforw           X
    maclin            X
    maclvl            X
    macnam            X
    mactop            X
    mflag             X
    nd                X
    newp              X
    outp              X
    passcom           X
    pbeg              X
    pbuf              X
    pend              X
    pflag             X
    plvl              X
    predef            X
    prespc            X
    prund             X
    ptrtab            X
    punspc            X
    rflag             X
    savch             X
    sbf               X
    sbff              X
    slotab            X
    stab              X
    t21               X
    t22               X
    t23               X
    tgpscan           X
    toktyp            X
    trulvl            X
    udfloc            X
    uflloc            X
    ulnloc            X
    varloc            X
    ysysloc           X

##### Macros

    ALFSIZ            X
    BACK              X
    BEG               X
    BLANK             X
    BUFSIZ            X
    CB                X
    COFF              X
    CONT              X
    DROP              X
    IB                X
    IDENT             X
    LF                X
    MAXFRE            X
    MAXFRM            X
    MAXINC            X
    MAXOUT            X
    NB                X
    NCPS              X
    NPREDEF           X
    NUMBR             X
    QB                X
    READ              X
    SALT              X
    SAME              X
    SB                X
    SBSIZE            X
    START             X
    STATIC            X
    STDERR            X
    STDIN             X
    STDOUT            X
    WARN              X
    WB                X
    WRITE             X
    b0                X
    b1                X
    b2                X
    b3                X
    b4                X
    b5                X
    b6                X
    b7                X
    bob               X
    close             X
    cputc             X
    eob               X
    exit              X
    fasscan           X
    iscom             X
    isid              X
    isnum             X
    isquo             X
    isslo             X
    isspc             X
    iswarn            X
    main              X
    open              X
    sbf               X
    scw1              X
    scw2              X
    sloscan           X
    symsiz            X
    tmac1             X
    tmac2             X
    xmac1             X
    xmac2             X

##### struct's

    symtab            X

       1: /* static char sccsid[] = "@(#)cpp.c	1.8.2 1996/7/11"; */
       2:
       3: #ifdef FLEXNAMES
       4: #define NCPS    128
       5: #else
       6: #define NCPS    8
       7: #endif
       8:
       9: # include "stdio.h"
      10: # include "ctype.h"
      11: /* C command
      12: /* written by John F. Reiser
      13: /* July/August 1978
      14: */
      15:
      16: #define STATIC
      17:
      18: #define STDIN 0
      19: #define STDOUT 1
      20: #define STDERR 2
      21: #define READ 0
      22: #define WRITE 1
      23: #define SALT '#'
      24: #ifndef BUFSIZ
      25: #define BUFSIZ 512
      26: #endif
      27:
      28: char *pbeg,*pbuf,*pend;
      29: char *outp,*inp;
      30: char *newp;
      31: char cinit;
      32:
      33: /* some code depends on whether characters are sign or zero extended */
      34: /*	#if '\377' < 0		not used here, old cpp doesn't understand */
      35: #if pdp11 | vax | mc68000
      36: #define COFF 128
      37: #else
      38: #define COFF 0
      39: #endif
      40:
      41: # if gcos
      42: #define ALFSIZ 512  /* alphabet size */
      43: # else
      44: #define ALFSIZ 256  /* alphabet size */
      45: # endif
      46: char macbit[ALFSIZ+11];
      47: char toktyp[ALFSIZ];
      48: #define BLANK 1
      49: #define IDENT 2
      50: #define NUMBR 3
      51:
      52: /* a superimposed code is used to reduce the number of calls to the
      53: /* symbol table lookup routine.  (if the kth character of an identifier
      54: /* is 'a' and there are no macro names whose kth character is 'a'
      55: /* then the identifier cannot be a macro name, hence there is no need
      56: /* to look in the symbol table.)  'scw1' enables the test based on
      57: /* single characters and their position in the identifier.  'scw2'
      58: /* enables the test based on adjacent pairs of characters and their
      59: /* position in the identifier.  scw1 typically costs 1 indexed fetch,
      60: /* an AND, and a jump per character of identifier, until the identifier
      61: /* is known as a non-macro name or until the end of the identifier.
      62: /* scw1 is inexpensive.  scw2 typically costs 4 indexed fetches,
      63: /* an add, an AND, and a jump per character of identifier, but it is also
      64: /* slightly more effective at reducing symbol table searches.
      65: /* scw2 usually costs too much because the symbol table search is
      66: /* usually short; but if symbol table search should become expensive,
      67: /* the code is here.
      68: /* using both scw1 and scw2 is of dubious value.
      69: */
      70: #define scw1 1
      71: #define scw2 0
      72:
      73: #if scw2
      74: char t21[ALFSIZ],t22[ALFSIZ],t23[ALFSIZ+NCPS];
      75: #endif
      76:
      77: #if scw1
      78: #define b0 1
      79: #define b1 2
      80: #define b2 4
      81: #define b3 8
      82: #define b4 16
      83: #define b5 32
      84: #define b6 64
      85: #define b7 128
      86: #endif
      87:
      88: #define IB 1
      89: #define SB 2
      90: #define NB 4
      91: #define CB 8
      92: #define QB 16
      93: #define WB 32
      94: char fastab[ALFSIZ];
      95: char slotab[ALFSIZ];
      96: char *ptrtab;
      97: #define isslo (ptrtab==(slotab+COFF))
      98: #define isid(a)  ((fastab+COFF)[a]&IB)
      99: #define isspc(a) (ptrtab[a]&SB)
     100: #define isnum(a) ((fastab+COFF)[a]&NB)
     101: #define iscom(a) ((fastab+COFF)[a]&CB)
     102: #define isquo(a) ((fastab+COFF)[a]&QB)
     103: #define iswarn(a) ((fastab+COFF)[a]&WB)
     104:
     105: #define eob(a) ((a)>=pend)
     106: #define bob(a) (pbeg>=(a))
     107:
     108: # define cputc(a,b) if(!flslvl) putc(a,b)
     109:
     110: char buffer[NCPS+BUFSIZ+BUFSIZ+NCPS];
     111:
     112: #ifdef pdp11
     113: # define SBSIZE ((unsigned)0114130) /* PDP compiler doesn't like 39024 */
     114: short   sbff[SBSIZE/2];
     115: # define sbf ((char *)sbff)
     116: #else !pdp11
     117: # define SBSIZE 60000       /* std = 12000, wnj aug 1979 */
     118: char    sbf[SBSIZE];
     119: #endif pdp11
     120: char    *savch  = sbf;
     121:
     122: # define DROP 0xFE  /* special character not legal ASCII or EBCDIC */
     123: # define WARN DROP
     124: # define SAME 0
     125: # define MAXINC 10
     126: # define MAXFRE 14  /* max buffers of macro pushback */
     127: # define MAXFRM 31  /* max number of formals/actuals to a macro */
     128:
     129: static char warnc = WARN;
     130:
     131: int mactop,fretop;
     132: char *instack[MAXFRE],*bufstack[MAXFRE],*endbuf[MAXFRE];
     133:
     134: int plvl;   /* parenthesis level during scan for macro actuals */
     135: int maclin; /* line number of macro call requiring actuals */
     136: char *macfil;   /* file name of macro call requiring actuals */
     137: char *macnam;   /* name of macro requiring actuals */
     138: int maclvl; /* # calls since last decrease in nesting level */
     139: char *macforw;  /* pointer which must be exceeded to decrease nesting level */
     140: int macdam; /* offset to macforw due to buffer shifting */
     141:
     142: #if tgp
     143: int tgpscan;    /* flag for dump(); */
     144: #endif
     145:
     146: STATIC  int inctop[MAXINC];
     147: STATIC  char    *fnames[MAXINC];
     148: STATIC  char    *dirnams[MAXINC];   /* actual directory of #include files */
     149: STATIC  int fins[MAXINC];
     150: STATIC  int lineno[MAXINC];
     151:
     152: STATIC  char    *dirs[10];  /* -I and <> directories */
     153: char *strdex(), *copy(), *subst(), *trmdir();
     154: struct symtab *stsym();
     155: STATIC  int fin = STDIN;
     156: STATIC  FILE    *fout   = stdout;
     157: STATIC  int nd  = 1;
     158: STATIC  int pflag;  /* don't put out lines "# 12 foo.c" */
     159: int passcom;    /* don't delete comments */
     160: STATIC  int rflag;  /* allow macro recursion */
     161: STATIC  int mflag;  /* generate makefile dependencies */
     162: STATIC  char *infile;   /* name of .o file to build dependencies from */
     163: STATIC  FILE *mout; /* file to place dependencies on */
     164: #define START 1
     165: #define CONT  2
     166: #define BACK  3
     167: STATIC  int ifno;
     168: # define NPREDEF 30
     169: STATIC  char *prespc[NPREDEF];
     170: STATIC  char **predef = prespc;
     171: STATIC  char *punspc[NPREDEF];
     172: STATIC  char **prund = punspc;
     173: STATIC  int exfail;
     174: struct symtab {
     175:     char    *name;
     176:     char    *value;
     177: } *lastsym, *lookup(), *slookup();
     178:
     179: # if gcos
     180: #include <setjmp.h>
     181: static jmp_buf env;
     182: # define main   mainpp
     183: # undef exit
     184: # define exit(S)    longjmp(env, 1)
     185: # define open(S,D)  fileno(fopen(S, "r"))
     186: # define close(F)   fclose(_f[F])
     187: extern FILE *_f[];
     188: # define symsiz 500
     189: # else
     190: # define symsiz 2000        /* std = 500, wnj aug 1979 */
     191: # endif
     192: STATIC  struct symtab stab[symsiz];
     193:
     194: STATIC  struct symtab *defloc;
     195: STATIC  struct symtab *udfloc;
     196: STATIC  struct symtab *incloc;
     197: STATIC  struct symtab *ifloc;
     198: STATIC  struct symtab *elsloc;
     199: STATIC  struct symtab *eifloc;
     200: STATIC  struct symtab *ifdloc;
     201: STATIC  struct symtab *ifnloc;
     202: STATIC  struct symtab *ysysloc;
     203: STATIC  struct symtab *varloc;
     204: STATIC  struct symtab *lneloc;
     205: STATIC  struct symtab *ulnloc;
     206: STATIC  struct symtab *uflloc;
     207: STATIC  int trulvl;
     208: STATIC  int flslvl;
     209:
     210: sayline(where)
     211:     int where;
     212: {
     213:     if (mflag && where==START) fprintf(mout, "%s: %s\n", infile, fnames[ifno]);
     214:     if (pflag==0) fprintf(fout,"# %d \"%s\"\n", lineno[ifno], fnames[ifno]);
     215: }
     216:
     217: /* data structure guide
     218: /*
     219: /* most of the scanning takes place in the buffer:
     220: /*
     221: /*  (low address)                                             (high address)
     222: /*  pbeg                           pbuf                                 pend
     223: /*  |      <-- BUFSIZ chars -->      |         <-- BUFSIZ chars -->        |
     224: /*  _______________________________________________________________________
     225: /* |_______________________________________________________________________|
     226: /*          |               |               |
     227: /*          |<-- waiting -->|               |<-- waiting -->
     228: /*          |    to be      |<-- current -->|    to be
     229: /*          |    written    |    token      |    scanned
     230: /*          |               |               |
     231: /*          outp            inp             p
     232: /*
     233: /*  *outp   first char not yet written to output file
     234: /*  *inp    first char of current token
     235: /*  *p      first char not yet scanned
     236: /*
     237: /* macro expansion: write from *outp to *inp (chars waiting to be written),
     238: /* ignore from *inp to *p (chars of the macro call), place generated
     239: /* characters in front of *p (in reverse order), update pointers,
     240: /* resume scanning.
     241: /*
     242: /* symbol table pointers point to just beyond the end of macro definitions;
     243: /* the first preceding character is the number of formal parameters.
     244: /* the appearance of a formal in the body of a definition is marked by
     245: /* 2 chars: the char WARN, and a char containing the parameter number.
     246: /* the first char of a definition is preceded by a zero character.
     247: /*
     248: /* when macro expansion attempts to back up over the beginning of the
     249: /* buffer, some characters preceding *pend are saved in a side buffer,
     250: /* the address of the side buffer is put on 'instack', and the rest
     251: /* of the main buffer is moved to the right.  the end of the saved buffer
     252: /* is kept in 'endbuf' since there may be nulls in the saved buffer.
     253: /*
     254: /* similar action is taken when an 'include' statement is processed,
     255: /* except that the main buffer must be completely emptied.  the array
     256: /* element 'inctop[ifno]' records the last side buffer saved when
     257: /* file 'ifno' was included.  these buffers remain dormant while
     258: /* the file is being read, and are reactivated at end-of-file.
     259: /*
     260: /* instack[0 : mactop] holds the addresses of all pending side buffers.
     261: /* instack[inctop[ifno]+1 : mactop-1] holds the addresses of the side
     262: /* buffers which are "live"; the side buffers instack[0 : inctop[ifno]]
     263: /* are dormant, waiting for end-of-file on the current file.
     264: /*
     265: /* space for side buffers is obtained from 'savch' and is never returned.
     266: /* bufstack[0:fretop-1] holds addresses of side buffers which
     267: /* are available for use.
     268: */
     269:
     270: dump() {
     271: /* write part of buffer which lies between  outp  and  inp .
     272: /* this should be a direct call to 'write', but the system slows to a crawl
     273: /* if it has to do an unaligned copy.  thus we buffer.  this silly loop
     274: /* is 15% of the total time, thus even the 'putc' macro is too slow.
     275: */
     276:     register char *p1,*p2; register FILE *f;
     277:     if ((p1=outp)==inp || flslvl!=0) return;
     278: #if tgp
     279: #define MAXOUT 80
     280:     if (!tgpscan) {/* scan again to insure <= MAXOUT chars between linefeeds */
     281:         register char c,*pblank; char savc,stopc,brk;
     282:         tgpscan=1; brk=stopc=pblank=0; p2=inp; savc= *p2; *p2='\0';
     283:         while (c= *p1++) {
     284:             if (c=='\\') c= *p1++;
     285:             if (stopc==c) stopc=0;
     286:             else if (c=='"' || c=='\'') stopc=c;
     287:             if (p1-outp>MAXOUT && pblank!=0) {
     288:                 *pblank++='\n'; inp=pblank; dump(); brk=1; pblank=0;
     289:             }
     290:             if (c==' ' && stopc==0) pblank=p1-1;
     291:         }
     292:         if (brk) sayline(CONT);
     293:         *p2=savc; inp=p2; p1=outp; tgpscan=0;
     294:     }
     295: #endif
     296:     f=fout;
     297: # if gcos
     298: /* filter out "$ program c" card if first line of input */
     299: /* gmatch is a simple pattern matcher in the GCOS Standard Library */
     300: {   static int gmfirst = 0;
     301:     if (!gmfirst) {
     302:         ++gmfirst;
     303:         if (gmatch(p1, "^$*program[ \t]*c*"))
     304:             p1 = strdex(p1, '\n');
     305:     }
     306: }
     307: # endif
     308:     while (p1<inp) putc(*p1++,f);
     309:     outp=p1;
     310: }
     311:
     312: char *
     313: refill(p) register char *p; {
     314: /* dump buffer.  save chars from inp to p.  read into buffer at pbuf,
     315: /* contiguous with p.  update pointers, return new p.
     316: */
     317:     register char *np,*op; register int ninbuf;
     318:     dump(); np=pbuf-(p-inp); op=inp;
     319:     if (bob(np+1)) {pperror("token too long"); np=pbeg; p=inp+BUFSIZ;}
     320:     macdam += np-inp; outp=inp=np;
     321:     while (op<p) *np++= *op++;
     322:     p=np;
     323:     for (;;) {
     324:         if (mactop>inctop[ifno]) {/* retrieve hunk of pushed-back macro text */
     325:             op=instack[--mactop]; np=pbuf;
     326:             do {while (*np++= *op++);} while (op<endbuf[mactop]); pend=np-1;
     327:             /* make buffer space avail for 'include' processing */
     328:             if (fretop<MAXFRE) bufstack[fretop++]=instack[mactop];
     329:             return(p);
     330:         } else {/* get more text from file(s) */
     331:             maclvl=0;
     332:             if (0<(ninbuf=read(fin,pbuf,BUFSIZ))) {
     333:                 pend=pbuf+ninbuf; *pend='\0';
     334:                 return(p);
     335:             }
     336:             /* end of #include file */
     337:             if (ifno==0) {/* end of input */
     338:                 if (plvl!=0) {
     339:                     int n=plvl,tlin=lineno[ifno]; char *tfil=fnames[ifno];
     340:                     lineno[ifno]=maclin; fnames[ifno]=macfil;
     341:                     pperror("%s: unterminated macro call",macnam);
     342:                     lineno[ifno]=tlin; fnames[ifno]=tfil;
     343:                     np=p; *np++='\n';   /* shut off unterminated quoted string */
     344:                     while (--n>=0) *np++=')';   /* supply missing parens */
     345:                     pend=np; *np='\0'; if (plvl<0) plvl=0;
     346:                     return(p);
     347:                 }
     348:                 if (trulvl || flslvl)
     349:                     pperror("missing endif");
     350:                 inp=p; dump(); exit(exfail);
     351:             }
     352:             close(fin); fin=fins[--ifno]; dirs[0]=dirnams[ifno]; sayline(BACK);
     353:         }
     354:     }
     355: }
     356:
     357: #define BEG 0
     358: #define LF 1
     359:
     360: char *
     361: cotoken(p) register char *p; {
     362:     register int c,i; char quoc;
     363:     static int state = BEG;
     364:
     365:     if (state!=BEG) goto prevlf;
     366: for (;;) {
     367: again:
     368:     while (!isspc(*p++));
     369:     switch (*(inp=p-1)) {
     370:     case 0: {
     371:         if (eob(--p)) {p=refill(p); goto again;}
     372:         else ++p; /* ignore null byte */
     373:     } break;
     374:     case '|': case '&': for (;;) {/* sloscan only */
     375:         if (*p++== *inp) break;
     376:         if (eob(--p)) p=refill(p);
     377:         else break;
     378:     } break;
     379:     case '=': case '!': for (;;) {/* sloscan only */
     380:         if (*p++=='=') break;
     381:         if (eob(--p)) p=refill(p);
     382:         else break;
     383:     } break;
     384:     case '<': case '>': for (;;) {/* sloscan only */
     385:         if (*p++=='=' || p[-2]==p[-1]) break;
     386:         if (eob(--p)) p=refill(p);
     387:         else break;
     388:     } break;
     389:     case '\\': for (;;) {
     390:         if (*p++=='\n') {++lineno[ifno]; break;}
     391:         if (eob(--p)) p=refill(p);
     392:         else {++p; break;}
     393:     } break;
     394:     case '/': for (;;) {
     395:         if (*p++=='*') {/* comment */
     396:             if (!passcom) {inp=p-2; dump(); ++flslvl;}
     397:             for (;;) {
     398:                 while (!iscom(*p++));
     399:                 if (p[-1]=='*') for (;;) {
     400:                     if (*p++=='/') goto endcom;
     401:                     if (eob(--p)) {
     402:                         if (!passcom) {inp=p; p=refill(p);}
     403:                         else if ((p-inp)>=BUFSIZ) {/* split long comment */
     404:                             inp=p; p=refill(p); /* last char written is '*' */
     405:                             cputc('/',fout);    /* terminate first part */
     406:                             /* and fake start of 2nd */
     407:                             outp=inp=p-=3; *p++='/'; *p++='*'; *p++='*';
     408:                         } else p=refill(p);
     409:                     } else break;
     410:                 } else if (p[-1]=='\n') {
     411:                     ++lineno[ifno]; if (!passcom) putc('\n',fout);
     412:                 } else if (eob(--p)) {
     413:                     if (!passcom) {inp=p; p=refill(p);}
     414:                     else if ((p-inp)>=BUFSIZ) {/* split long comment */
     415:                         inp=p; p=refill(p);
     416:                         cputc('*',fout); cputc('/',fout);
     417:                         outp=inp=p-=2; *p++='/'; *p++='*';
     418:                     } else p=refill(p);
     419:                 } else ++p; /* ignore null byte */
     420:             }
     421:         endcom:
     422:             if (!passcom) {outp=inp=p; --flslvl; goto again;}
     423:             break;
     424:         }
     425:         if (eob(--p)) p=refill(p);
     426:         else break;
     427:     } break;
     428: # if gcos
     429:     case '`':
     430: # endif
     431:     case '"': case '\'': {
     432:         quoc=p[-1];
     433:         for (;;) {
     434:             while (!isquo(*p++));
     435:             if (p[-1]==quoc) break;
     436:             if (p[-1]=='\n') {--p; break;} /* bare \n terminates quotation */
     437:             if (p[-1]=='\\') for (;;) {
     438:                 if (*p++=='\n') {++lineno[ifno]; break;} /* escaped \n ignored */
     439:                 if (eob(--p)) p=refill(p);
     440:                 else {++p; break;}
     441:             } else if (eob(--p)) p=refill(p);
     442:             else ++p;   /* it was a different quote character */
     443:         }
     444:     } break;
     445:     case '\n': {
     446:         ++lineno[ifno]; if (isslo) {state=LF; return(p);}
     447: prevlf:
     448:         state=BEG;
     449:         for (;;) {
     450:             if (*p++=='#') return(p);
     451:             if (eob(inp= --p)) p=refill(p);
     452:             else goto again;
     453:         }
     454:     } break;
     455:     case '0': case '1': case '2': case '3': case '4':
     456:     case '5': case '6': case '7': case '8': case '9':
     457:     for (;;) {
     458:         while (isnum(*p++));
     459:         if (eob(--p)) p=refill(p);
     460:         else break;
     461:     } break;
     462:     case 'A': case 'B': case 'C': case 'D': case 'E':
     463:     case 'F': case 'G': case 'H': case 'I': case 'J':
     464:     case 'K': case 'L': case 'M': case 'N': case 'O':
     465:     case 'P': case 'Q': case 'R': case 'S': case 'T':
     466:     case 'U': case 'V': case 'W': case 'X': case 'Y':
     467:     case 'Z': case '_':
     468:     case 'a': case 'b': case 'c': case 'd': case 'e':
     469:     case 'f': case 'g': case 'h': case 'i': case 'j':
     470:     case 'k': case 'l': case 'm': case 'n': case 'o':
     471:     case 'p': case 'q': case 'r': case 's': case 't':
     472:     case 'u': case 'v': case 'w': case 'x': case 'y':
     473:     case 'z':
     474: #if scw1
     475: #define tmac1(c,bit) if (!xmac1(c,bit,&)) goto nomac
     476: #define xmac1(c,bit,op) ((macbit+COFF)[c] op (bit))
     477: #else
     478: #define tmac1(c,bit)
     479: #define xmac1(c,bit,op)
     480: #endif
     481:
     482: #if scw2
     483: #define tmac2(c0,c1,cpos) if (!xmac2(c0,c1,cpos,&)) goto nomac
     484: #define xmac2(c0,c1,cpos,op)\
     485:     ((macbit+COFF)[(t21+COFF)[c0]+(t22+COFF)[c1]] op (t23+COFF+cpos)[c0])
     486: #else
     487: #define tmac2(c0,c1,cpos)
     488: #define xmac2(c0,c1,cpos,op)
     489: #endif
     490:
     491:     if (flslvl) goto nomac;
     492:     for (;;) {
     493:         c= p[-1];                          tmac1(c,b0);
     494:         i= *p++; if (!isid(i)) goto endid; tmac1(i,b1); tmac2(c,i,0);
     495:         c= *p++; if (!isid(c)) goto endid; tmac1(c,b2); tmac2(i,c,1);
     496:         i= *p++; if (!isid(i)) goto endid; tmac1(i,b3); tmac2(c,i,2);
     497:         c= *p++; if (!isid(c)) goto endid; tmac1(c,b4); tmac2(i,c,3);
     498:         i= *p++; if (!isid(i)) goto endid; tmac1(i,b5); tmac2(c,i,4);
     499:         c= *p++; if (!isid(c)) goto endid; tmac1(c,b6); tmac2(i,c,5);
     500:         i= *p++; if (!isid(i)) goto endid; tmac1(i,b7); tmac2(c,i,6);
     501:                                                         tmac2(i,0,7);
     502:         while (isid(*p++));
     503:         if (eob(--p)) {refill(p); p=inp+1; continue;}
     504:         goto lokid;
     505:     endid:
     506:         if (eob(--p)) {refill(p); p=inp+1; continue;}
     507:         tmac2(p[-1],0,-1+(p-inp));
     508:     lokid:
     509:         slookup(inp,p,0); if (newp) {p=newp; goto again;}
     510:         else break;
     511:     nomac:
     512:         while (isid(*p++));
     513:         if (eob(--p)) {p=refill(p); goto nomac;}
     514:         else break;
     515:     } break;
     516:     } /* end of switch */
     517:
     518:     if (isslo) return(p);
     519: } /* end of infinite loop */
     520: }
     521:
     522: char *
     523: skipbl(p) register char *p; {/* get next non-blank token */
     524:     do {outp=inp=p; p=cotoken(p);} while ((toktyp+COFF)[*inp]==BLANK);
     525:     return(p);
     526: }
     527:
     528: char *
     529: unfill(p) register char *p; {
     530: /* take <= BUFSIZ chars from right end of buffer and put them on instack .
     531: /* slide rest of buffer to the right, update pointers, return new p.
     532: */
     533:     register char *np,*op; register int d;
     534:     if (mactop>=MAXFRE) {
     535:         pperror("%s: too much pushback",macnam);
     536:         p=inp=pend; dump(); /* begin flushing pushback */
     537:         while (mactop>inctop[ifno]) {p=refill(p); p=inp=pend; dump();}
     538:     }
     539:     if (fretop>0) np=bufstack[--fretop];
     540:     else {
     541:         np=savch; savch+=BUFSIZ;
     542:         if (savch>=sbf+SBSIZE) {pperror("no space"); exit(exfail);}
     543:         *savch++='\0';
     544:     }
     545:     instack[mactop]=np; op=pend-BUFSIZ; if (op<p) op=p;
     546:     for (;;) {while (*np++= *op++); if (eob(op)) break;} /* out with old */
     547:     endbuf[mactop++]=np;    /* mark end of saved text */
     548:     np=pbuf+BUFSIZ; op=pend-BUFSIZ; pend=np; if (op<p) op=p;
     549:     while (outp<op) *--np= *--op; /* slide over new */
     550:     if (bob(np)) pperror("token too long");
     551:     d=np-outp; outp+=d; inp+=d; macdam+=d; return(p+d);
     552: }
     553:
     554: char *
     555: doincl(p) register char *p; {
     556:     int filok,inctype;
     557:     register char *cp; char **dirp,*nfil; char filname[BUFSIZ];
     558:
     559:     p=skipbl(p); cp=filname;
     560:     if (*inp++=='<') {/* special <> syntax */
     561:         inctype=1;
     562:         ++flslvl;   /* prevent macro expansion */
     563:         for (;;) {
     564:             outp=inp=p; p=cotoken(p);
     565:             if (*inp=='\n') {--p; *cp='\0'; break;}
     566:             if (*inp=='>') {      *cp='\0'; break;}
     567: # ifdef gimpel
     568:             if (*inp=='.' && !intss()) *inp='#';
     569: # endif
     570:             while (inp<p) *cp++= *inp++;
     571:         }
     572:         --flslvl;   /* reenable macro expansion */
     573:     } else if (inp[-1]=='"') {/* regular "" syntax */
     574:         inctype=0;
     575: # ifdef gimpel
     576:         while (inp<p) {if (*inp=='.' && !intss()) *inp='#'; *cp++= *inp++;}
     577: # else
     578:         while (inp<p) *cp++= *inp++;
     579: # endif
     580:         if (*--cp=='"') *cp='\0';
     581:     } else {pperror("bad include syntax",0); inctype=2;}
     582:     /* flush current file to \n , then write \n */
     583:     ++flslvl; do {outp=inp=p; p=cotoken(p);} while (*inp!='\n'); --flslvl;
     584:     inp=p; dump(); if (inctype==2) return(p);
     585:     /* look for included file */
     586:     if (ifno+1 >=MAXINC) {
     587:         pperror("Unreasonable include nesting",0); return(p);
     588:     }
     589:     if((nfil=savch)>sbf+SBSIZE-BUFSIZ) {pperror("no space"); exit(exfail);}
     590:     filok=0;
     591:     for (dirp=dirs+inctype; *dirp; ++dirp) {
     592:         if (
     593: # if gcos
     594:             strdex(filname, '/')
     595: # else
     596:             filname[0]=='/'
     597: # endif
     598:                 || **dirp=='\0') strcpy(nfil,filname);
     599:         else {
     600:             strcpy(nfil,*dirp);
     601: # if unix || gcos
     602:             strcat(nfil,"/");
     603: # endif
     604: #ifdef ibm
     605: #ifndef gimpel
     606:             strcat(nfil,".");
     607: #endif
     608: #endif
     609:             strcat(nfil,filname);
     610:         }
     611:         if (0<(fins[ifno+1]=open(nfil,READ))) {
     612:             filok=1; fin=fins[++ifno]; break;
     613:         }
     614:     }
     615:     if (filok==0) pperror("Can't find include file %s",filname);
     616:     else {
     617:         lineno[ifno]=1; fnames[ifno]=cp=nfil; while (*cp++); savch=cp;
     618:         dirnams[ifno]=dirs[0]=trmdir(copy(nfil));
     619:         sayline(START);
     620:         /* save current contents of buffer */
     621:         while (!eob(p)) p=unfill(p);
     622:         inctop[ifno]=mactop;
     623:     }
     624:     return(p);
     625: }
     626:
     627: equfrm(a,p1,p2) register char *a,*p1,*p2; {
     628:     register char c; int flag;
     629:     c= *p2; *p2='\0';
     630:     flag=strcmp(a,p1); *p2=c; return(flag==SAME);
     631: }
     632:
     633: char *
     634: dodef(p) char *p; {/* process '#define' */
     635:     register char *pin,*psav,*cf;
     636:     char **pf,**qf; int b,c,params; struct symtab *np;
     637:     char *oldval,*oldsavch;
     638:     char *formal[MAXFRM]; /* formal[n] is name of nth formal */
     639:     char formtxt[BUFSIZ]; /* space for formal names */
     640:     int spasscom = passcom;
     641:     passcom = 0;        /* strip comments from defines to save space */
     642:
     643:     if (savch>sbf+SBSIZE-BUFSIZ) {pperror("too much defining"); return(p);}
     644:     oldsavch=savch; /* to reclaim space if redefinition */
     645:     ++flslvl; /* prevent macro expansion during 'define' */
     646:     p=skipbl(p); pin=inp;
     647:     if ((toktyp+COFF)[*pin]!=IDENT) {
     648:         ppwarn("illegal macro name"); while (*inp!='\n') p=skipbl(p); return(p);
     649:     }
     650:     np=slookup(pin,p,1);
     651:     if (oldval=np->value) savch=oldsavch;   /* was previously defined */
     652:     b=1; cf=pin;
     653:     while (cf<p) {/* update macbit */
     654:         c= *cf++; xmac1(c,b,|=); b=(b+b)&0xFF;
     655:         if (cf!=p) xmac2(c,*cf,-1+(cf-pin),|=);
     656:         else xmac2(c,0,-1+(cf-pin),|=);
     657:     }
     658:     params=0; outp=inp=p; p=cotoken(p); pin=inp;
     659:     if (*pin=='(') {/* with parameters; identify the formals */
     660:         cf=formtxt; pf=formal;
     661:         for (;;) {
     662:             p=skipbl(p); pin=inp;
     663:             if (*pin=='\n') {
     664:                 --lineno[ifno]; --p; pperror("%s: missing )",np->name); break;
     665:             }
     666:             if (*pin==')') break;
     667:             if (*pin==',') continue;
     668:             if ((toktyp+COFF)[*pin]!=IDENT) {
     669:                 c= *p; *p='\0'; pperror("bad formal: %s",pin); *p=c;
     670:             } else if (pf>= &formal[MAXFRM]) {
     671:                 c= *p; *p='\0'; pperror("too many formals: %s",pin); *p=c;
     672:             } else {
     673:                 *pf++=cf; while (pin<p) *cf++= *pin++; *cf++='\0'; ++params;
     674:             }
     675:         }
     676:         if (params==0) --params; /* #define foo() ... */
     677:     } else if (*pin=='\n') {--lineno[ifno]; --p;}
     678:     /* remember beginning of macro body, so that we can
     679: 	/* warn if a redefinition is different from old value.
     680: 	*/
     681:     oldsavch=psav=savch;
     682:     for (;;) {/* accumulate definition until linefeed */
     683:         outp=inp=p; p=cotoken(p); pin=inp;
     684:         if (*pin=='\\' && pin[1]=='\n') {putc('\n',fout); continue;}    /* ignore escaped lf */
     685:         if (*pin=='\n') break;
     686:         if (params) {/* mark the appearance of formals in the definiton */
     687:             if ((toktyp+COFF)[*pin]==IDENT) {
     688:                 for (qf=pf; --qf>=formal; ) {
     689:                     if (equfrm(*qf,pin,p)) {
     690:                         *psav++=qf-formal+1; *psav++=WARN; pin=p; break;
     691:                     }
     692:                 }
     693:             } else if (*pin=='"' || *pin=='\''
     694: # if gcos
     695:                     || *pin=='`'
     696: # endif
     697:                         ) {/* inside quotation marks, too */
     698:                 char quoc= *pin;
     699:                 for (*psav++= *pin++; pin<p && *pin!=quoc; ) {
     700:                     while (pin<p && !isid(*pin)) *psav++= *pin++;
     701:                     cf=pin; while (cf<p && isid(*cf)) ++cf;
     702:                     for (qf=pf; --qf>=formal; ) {
     703:                         if (equfrm(*qf,pin,cf)) {
     704:                             *psav++=qf-formal+1; *psav++=WARN; pin=cf; break;
     705:                         }
     706:                     }
     707:                     while (pin<cf) *psav++= *pin++;
     708:                 }
     709:             }
     710:         }
     711:         while (pin<p) *psav++= *pin++;
     712:     }
     713:     *psav++=params; *psav++='\0';
     714:     if ((cf=oldval)!=NULL) {/* redefinition */
     715:         --cf;   /* skip no. of params, which may be zero */
     716:         while (*--cf);  /* go back to the beginning */
     717:         if (0!=strcmp(++cf,oldsavch)) {/* redefinition different from old */
     718:             --lineno[ifno]; ppwarn("%s redefined",np->name); ++lineno[ifno];
     719:             np->value=psav-1;
     720:         } else psav=oldsavch; /* identical redef.; reclaim space */
     721:     } else np->value=psav-1;
     722:     --flslvl; inp=pin; savch=psav; passcom = spasscom; return(p);
     723: }
     724:
     725: #define fasscan() ptrtab=fastab+COFF
     726: #define sloscan() ptrtab=slotab+COFF
     727:
     728: char *
     729: control(p) register char *p; {/* find and handle preprocessor control lines */
     730:     register struct symtab *np;
     731: for (;;) {
     732:     fasscan(); p=cotoken(p); if (*inp=='\n') ++inp; dump();
     733:     sloscan(); p=skipbl(p);
     734:     *--inp=SALT; outp=inp; ++flslvl; np=slookup(inp,p,0); --flslvl;
     735:     if (np==defloc) {/* define */
     736:         if (flslvl==0) {p=dodef(p); continue;}
     737:     } else if (np==incloc) {/* include */
     738:         if (flslvl==0) {p=doincl(p); continue;}
     739:     } else if (np==ifnloc) {/* ifndef */
     740:         ++flslvl; p=skipbl(p); np=slookup(inp,p,0); --flslvl;
     741:         if (flslvl==0 && np->value==0) ++trulvl;
     742:         else ++flslvl;
     743:     } else if (np==ifdloc) {/* ifdef */
     744:         ++flslvl; p=skipbl(p); np=slookup(inp,p,0); --flslvl;
     745:         if (flslvl==0 && np->value!=0) ++trulvl;
     746:         else ++flslvl;
     747:     } else if (np==eifloc) {/* endif */
     748:         if (flslvl) {if (--flslvl==0) sayline(CONT);}
     749:         else if (trulvl) --trulvl;
     750:         else pperror("If-less endif",0);
     751:     } else if (np==elsloc) {/* else */
     752:         if (flslvl) {
     753:             if (--flslvl!=0) ++flslvl;
     754:             else {++trulvl; sayline(CONT);}
     755:         }
     756:         else if (trulvl) {++flslvl; --trulvl;}
     757:         else pperror("If-less else",0);
     758:     } else if (np==udfloc) {/* undefine */
     759:         if (flslvl==0) {
     760:             ++flslvl; p=skipbl(p); slookup(inp,p,DROP); --flslvl;
     761:         }
     762:     } else if (np==ifloc) {/* if */
     763: #if tgp
     764:         pperror(" IF not implemented, true assumed", 0);
     765:         if (flslvl==0) ++trulvl; else ++flslvl;
     766: #else
     767:         newp=p;
     768:         if (flslvl==0 && yyparse()) ++trulvl; else ++flslvl;
     769:         p=newp;
     770: #endif
     771:     } else if (np==lneloc) {/* line */
     772:         if (flslvl==0 && pflag==0) {
     773:             char *cp, *cp2, *savestring();
     774:             outp=inp=p; *--outp='#'; while (*inp!='\n') p=cotoken(p);
     775:             cp = outp + 1;
     776:             while (isspace(*cp) && cp < inp)
     777:                 cp++;
     778:             while (isdigit(*cp) && cp < inp)
     779:                 cp++;
     780:             while (*cp != '"' && cp < inp)
     781:                 cp++;
     782:             if (cp < inp) {
     783:                 cp++;
     784:                 cp2 = cp;
     785:                 while (*cp2 != '"' && cp2 < inp)
     786:                     cp2++;
     787:                 fnames[ifno] = savestring(cp, cp2);
     788:             }
     789:             continue;
     790:         }
     791:     } else if (*++inp=='\n') outp=inp;  /* allows blank line after # */
     792:     else pperror("undefined control",0);
     793:     /* flush to lf */
     794:     ++flslvl; while (*inp!='\n') {outp=inp=p; p=cotoken(p);} --flslvl;
     795: }
     796: }
     797:
     798: char *
     799: savestring(start, finish)
     800:     register char *start, *finish;
     801: {
     802:     char *retbuf;
     803:     register char *cp;
     804:
     805:     retbuf = (char *) calloc(finish - start + 1, sizeof (char));
     806:     cp = retbuf;
     807:     while (start < finish)
     808:         *cp++ = *start++;
     809:     *cp = 0;
     810:     return(retbuf);
     811: }
     812:
     813: struct symtab *
     814: stsym(s) register char *s; {
     815:     char buf[BUFSIZ]; register char *p;
     816:
     817:     /* make definition look exactly like end of #define line */
     818:     /* copy to avoid running off end of world when param list is at end */
     819:     p=buf; while (*p++= *s++);
     820:     p=buf; while (isid(*p++)); /* skip first identifier */
     821:     if (*--p=='=') {*p++=' '; while (*p++);}
     822:     else {s=" 1"; while (*p++= *s++);}
     823:     pend=p; *--p='\n';
     824:     sloscan(); dodef(buf); return(lastsym);
     825: }
     826:
     827: struct symtab *
     828: ppsym(s) char *s; {/* kluge */
     829:     register struct symtab *sp;
     830:     cinit=SALT; *savch++=SALT; sp=stsym(s); --sp->name; cinit=0; return(sp);
     831: }
     832:
     833: /* VARARGS1 */
     834: pperror(s,x,y) char *s; {
     835:     if (fnames[ifno][0]) fprintf(stderr,
     836: # if gcos
     837:             "*%c*   \"%s\", line ", exfail >= 0 ? 'F' : 'W',
     838: # else
     839:             "%s: ",
     840: # endif
     841:                  fnames[ifno]);
     842:     fprintf(stderr, "%d: ",lineno[ifno]);
     843:     fprintf(stderr, s, x, y);
     844:     fprintf(stderr,"\n");
     845:     ++exfail;
     846: }
     847:
     848: yyerror(s,a,b) char *s; {
     849:     pperror(s,a,b);
     850: }
     851:
     852: ppwarn(s,x) char *s; {
     853:     int fail = exfail;
     854:     exfail = -1;
     855:     pperror(s,x);
     856:     exfail = fail;
     857: }
     858:
     859: struct symtab *
     860: lookup(namep, enterf)
     861: char *namep;
     862: {
     863:     register char *np, *snp;
     864:     register int c, i; int around;
     865:     register struct symtab *sp;
     866:
     867:     /* namep had better not be too long (currently, <=NCPS chars) */
     868:     np=namep; around=0; i=cinit;
     869:     while (c= *np++) i += i+c; c=i; /* c=i for register usage on pdp11 */
     870:     c %= symsiz; if (c<0) c += symsiz;
     871:     sp = &stab[c];
     872:     while (snp=sp->name) {
     873:         np = namep;
     874:         while (*snp++ == *np) if (*np++ == '\0') {
     875:                 if (enterf==DROP) {sp->name[0]= DROP; sp->value=0;}
     876:                 return(lastsym=sp);
     877:             }
     878:         if (--sp < &stab[0])
     879:             if (around) {pperror("too many defines", 0); exit(exfail);}
     880:             else {++around; sp = &stab[symsiz-1];}
     881:     }
     882:     if (enterf==1) sp->name=namep;
     883:     return(lastsym=sp);
     884: }
     885:
     886: struct symtab *
     887: slookup(p1,p2,enterf) register char *p1,*p2; int enterf;{
     888:     register char *p3; char c2,c3; struct symtab *np;
     889:              c2= *p2; *p2='\0'; /* mark end of token */
     890:     if ((p2-p1)>NCPS) p3=p1+NCPS; else p3=p2;
     891:              c3= *p3; *p3='\0'; /* truncate to NCPS chars or less */
     892:     if (enterf==1) p1=copy(p1);
     893:     np=lookup(p1,enterf); *p3=c3; *p2=c2;
     894:     if (np->value!=0 && flslvl==0) newp=subst(p2,np);
     895:     else newp=0;
     896:     return(np);
     897: }
     898:
     899: char *
     900: subst(p,sp) register char *p; struct symtab *sp; {
     901:     static char match[]="%s: argument mismatch";
     902:     register char *ca,*vp; int params;
     903:     char *actual[MAXFRM]; /* actual[n] is text of nth actual   */
     904:     char actused[MAXFRM]; /* for newline processing in actuals */
     905:     char acttxt[BUFSIZ];  /* space for actuals */
     906:     int  nlines = 0;
     907:
     908:     if (0==(vp=sp->value)) return(p);
     909:     if ((p-macforw)<=macdam) {
     910:         if (++maclvl>symsiz && !rflag) {
     911:             pperror("%s: macro recursion",sp->name); return(p);
     912:         }
     913:     } else maclvl=0;    /* level decreased */
     914:     macforw=p; macdam=0;    /* new target for decrease in level */
     915:     macnam=sp->name;
     916:     dump();
     917:     if (sp==ulnloc) {
     918:         vp=acttxt; *vp++='\0';
     919:         sprintf(vp,"%d",lineno[ifno]); while (*vp++);
     920:     } else if (sp==uflloc) {
     921:         vp=acttxt; *vp++='\0';
     922:         sprintf(vp,"\"%s\"",fnames[ifno]); while (*vp++);
     923:     }
     924:     if (0!=(params= *--vp&0xFF)) {/* definition calls for params */
     925:         register char **pa;
     926:         ca=acttxt; pa=actual;
     927:         if (params==0xFF) params=1; /* #define foo() ... */
     928:         sloscan(); ++flslvl; /* no expansion during search for actuals */
     929:         plvl= -1;
     930:         do p=skipbl(p); while (*inp=='\n'); /* skip \n too */
     931:         if (*inp=='(') {
     932:             maclin=lineno[ifno]; macfil=fnames[ifno];
     933:             for (plvl=1; plvl!=0; ) {
     934:                 *ca++='\0';
     935:                 for (;;) {
     936:                     outp=inp=p; p=cotoken(p);
     937:                     if (*inp=='(') ++plvl;
     938:                     if (*inp==')' && --plvl==0) {--params; break;}
     939:                     if (plvl==1 && *inp==',') {--params; break;}
     940:                     while (inp<p) *ca++= *inp++;
     941:                     if (ca> &acttxt[BUFSIZ])
     942:                         pperror("%s: actuals too long",sp->name);
     943:                 }
     944:                 if (pa>= &actual[MAXFRM]) ppwarn(match,sp->name);
     945:                 else { actused[pa-actual]=0; *pa++=ca; }
     946:             }
     947:             nlines = lineno[ifno] - maclin;
     948:             lineno[ifno] = maclin; /* don't count newlines here */
     949:         }
     950:         if (params!=0) ppwarn(match,sp->name);
     951:         while (--params>=0) *pa++=""+1; /* null string for missing actuals */
     952:         --flslvl; fasscan();
     953:     }
     954:     for (;;) {/* push definition onto front of input stack */
     955:         while (!iswarn(*--vp)) {
     956:             if (bob(p)) {outp=inp=p; p=unfill(p);}
     957:             *--p= *vp;
     958:         }
     959:         if (*vp==warnc) {/* insert actual param */
     960:             ca=actual[*--vp-1];
     961:             while (*--ca) {
     962:                 if (bob(p)) {outp=inp=p; p=unfill(p);}
     963:                 /* Actuals with newlines confuse line numbering */
     964:                 if (*ca == '\n' && actused[*vp-1])
     965:                     if (*(ca-1) == '\\') ca--;
     966:                     else *--p = ' ';
     967:                 else { *--p= *ca; if (*ca == '\n') nlines--; }
     968:             }
     969:             actused[*vp-1] = 1;
     970:         } else {
     971:             if (nlines > 0 )
     972:                 while (nlines-- > 0)
     973:                     *--p = '\n';
     974:             break;
     975:         }
     976:     }
     977:     outp=inp=p;
     978:     return(p);
     979: }
     980:
     981:
     982:
     983:
     984: char *
     985: trmdir(s) register char *s; {
     986:     register char *p = s;
     987:     while (*p++); --p; while (p>s && *--p!='/');
     988: # if unix
     989:     if (p==s) *p++='.';
     990: # endif
     991:     *p='\0';
     992:     return(s);
     993: }
     994:
     995: STATIC char *
     996: copy(s) register char *s; {
     997:     register char *old;
     998:
     999:     old = savch; while (*savch++ = *s++);
    1000:     return(old);
    1001: }
    1002:
    1003: char *
    1004: strdex(s,c) char *s,c; {
    1005:     while (*s) if (*s++==c) return(--s);
    1006:     return(0);
    1007: }
    1008:
    1009: yywrap(){ return(1); }
    1010:
    1011: main(argc,argv)
    1012:     char *argv[];
    1013: {
    1014:     register int i,c;
    1015:     register char *p;
    1016:     char *tf,**cp2, obuf[BUFSIZ];
    1017:
    1018: # if gcos
    1019:     if (setjmp(env)) return (exfail);
    1020: # endif
    1021:     p="_$ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    1022:         i=0;
    1023:         while (c= *p++) {
    1024:             (fastab+COFF)[c] |= IB|NB|SB; (toktyp+COFF)[c]=IDENT;
    1025: #if scw2
    1026:             /* 53 == 63-10; digits rarely appear in identifiers,
    1027: 			/* and can never be the first char of an identifier.
    1028: 			/* 11 == 53*53/sizeof(macbit) .
    1029: 			*/
    1030:             ++i; (t21+COFF)[c]=(53*i)/11; (t22+COFF)[c]=i%11;
    1031: #endif
    1032:         }
    1033:     p="0123456789.";
    1034:         while (c= *p++) {(fastab+COFF)[c] |= NB|SB; (toktyp+COFF)[c]=NUMBR;}
    1035: # if gcos
    1036:     p="\n\"'`/\\";
    1037: # else
    1038:     p="\n\"'/\\";
    1039: # endif
    1040:         while (c= *p++) (fastab+COFF)[c] |= SB;
    1041: # if gcos
    1042:     p="\n\"'`\\";
    1043: # else
    1044:     p="\n\"'\\";
    1045: # endif
    1046:         while (c= *p++) (fastab+COFF)[c] |= QB;
    1047:     p="*\n"; while (c= *p++) (fastab+COFF)[c] |= CB;
    1048:     (fastab+COFF)[warnc] |= WB;
    1049:     (fastab+COFF)['\0'] |= CB|QB|SB|WB;
    1050:     for (i=ALFSIZ; --i>=0; ) slotab[i]=fastab[i]|SB;
    1051:     p=" \t\013\f\r";    /* note no \n;	\v not legal for vertical tab? */
    1052:         while (c= *p++) (toktyp+COFF)[c]=BLANK;
    1053: #if scw2
    1054:     for ((t23+COFF)[i=ALFSIZ+7-COFF]=1; --i>=-COFF; )
    1055:         if (((t23+COFF)[i]=(t23+COFF+1)[i]<<1)==0) (t23+COFF)[i]=1;
    1056: #endif
    1057:
    1058: # if unix
    1059:     fnames[ifno=0] = ""; dirnams[0]=dirs[0]=".";
    1060: # endif
    1061: # if ibm
    1062:     fnames[ifno=0] = "";
    1063: # endif
    1064: # if gcos
    1065:     if (inquire(stdin, _TTY)) freopen("*src", "rt", stdin);
    1066: # endif
    1067: # if gimpel || gcos
    1068:     fnames[ifno=0] = (char *)inquire(stdin, _FILENAME);
    1069:     dirnams[0] = dirs[0] = trmdir(copy(fnames[0]));
    1070: # endif
    1071:     for(i=1; i<argc; i++)
    1072:         {
    1073:         switch(argv[i][0])
    1074:             {
    1075:             case '-':
    1076: # if gcos
    1077:             switch(toupper(argv[i][1])) { /* case-independent on GCOS */
    1078: # else
    1079:             switch(argv[i][1]) {
    1080: # endif
    1081:                 case 'M': mflag++;
    1082:                 case 'P': pflag++;
    1083:                 case 'E': continue;
    1084:                 case 'R': ++rflag; continue;
    1085:                 case 'C': passcom++; continue;
    1086:                 case 'D':
    1087:                     if (predef>prespc+NPREDEF) {
    1088:                         pperror("too many -D options, ignoring %s",argv[i]);
    1089:                         continue;
    1090:                     }
    1091:                     /* ignore plain "-D" (no argument) */
    1092:                     if (*(argv[i]+2)) *predef++ = argv[i]+2;
    1093:                     continue;
    1094:                 case 'U':
    1095:                     if (prund>punspc+NPREDEF) {
    1096:                         pperror("too many -U options, ignoring %s",argv[i]);
    1097:                         continue;
    1098:                     }
    1099:                     *prund++ = argv[i]+2;
    1100:                     continue;
    1101:                 case 'I':
    1102:                     if (nd>8) pperror("excessive -I file (%s) ignored",argv[i]);
    1103:                     else dirs[nd++] = argv[i]+2;
    1104:                     continue;
    1105:                 case '\0': continue;
    1106:                 default:
    1107:                     pperror("unknown flag %s", argv[i]);
    1108:                     continue;
    1109:                 }
    1110:             default:
    1111:                 if (fin==STDIN) {
    1112:                     if (0>(fin=open(argv[i], READ))) {
    1113:                         pperror("No source file %s",argv[i]); exit(8);
    1114:                     }
    1115:                     fnames[ifno]=copy(argv[i]);
    1116:                     infile=copy(argv[i]);
    1117:                     dirs[0]=dirnams[ifno]=trmdir(argv[i]);
    1118: # ifndef gcos
    1119: /* too dangerous to have file name in same syntactic position
    1120:    be input or output file depending on file redirections,
    1121:    so force output to stdout, willy-nilly
    1122: 	[i don't see what the problem is.  jfr]
    1123: */
    1124:                 } else if (fout==stdout) {
    1125:                     if (NULL==(fout=fopen(argv[i], "w"))) {
    1126:                         pperror("Can't create %s", argv[i]); exit(8);
    1127:                     } else fclose(stdout);
    1128: # endif
    1129:                 } else pperror("extraneous name %s", argv[i]);
    1130:             }
    1131:         }
    1132:
    1133:     if (mflag) {
    1134:         if (infile==(char *)0) {
    1135:             fprintf(stderr,
    1136:                 "no input file specified with -M flag\n");
    1137:             exit(8);
    1138:         }
    1139:         tf=(char *)rindex(infile, '.');
    1140:         if (tf==0) {
    1141:             fprintf(stderr, "missing component name on %s\n",
    1142:                 infile);
    1143:             exit(8);
    1144:         }
    1145:         tf[1]='o';
    1146:         tf=(char *)rindex(infile, '/');
    1147:         if (tf!=(char *)0)
    1148:             infile = tf + 1;
    1149:         mout=fout;
    1150:         setbuf(mout, (char *)NULL);
    1151:         if (NULL==(fout=fopen("/dev/null", "w"))) {
    1152:             pperror("Can't open /dev/null");
    1153:             exit(8);
    1154:         }
    1155:     }
    1156:     setbuf(fout, obuf);
    1157:     fins[ifno]=fin;
    1158:     exfail = 0;
    1159:         /* after user -I files here are the standard include libraries */
    1160: # if unix
    1161:     dirs[nd++] = "/usr/include";
    1162: # endif
    1163: # if gcos
    1164:     dirs[nd++] = "cc/include";
    1165: # endif
    1166: # if ibm
    1167: # ifndef gimpel
    1168:     dirs[nd++] = "BTL$CLIB";
    1169: # endif
    1170: # endif
    1171: # ifdef gimpel
    1172:     dirs[nd++] = intss() ?  "SYS3.C." : "" ;
    1173: # endif
    1174:     /* dirs[nd++] = "/compool"; */
    1175:     dirs[nd++] = 0;
    1176:     defloc=ppsym("define");
    1177:     udfloc=ppsym("undef");
    1178:     incloc=ppsym("include");
    1179:     elsloc=ppsym("else");
    1180:     eifloc=ppsym("endif");
    1181:     ifdloc=ppsym("ifdef");
    1182:     ifnloc=ppsym("ifndef");
    1183:     ifloc=ppsym("if");
    1184:     lneloc=ppsym("line");
    1185:     for (i=sizeof(macbit)/sizeof(macbit[0]); --i>=0; ) macbit[i]=0;
    1186: # if unix
    1187:     ysysloc=stsym("unix");
    1188: # endif
    1189: # if gcos
    1190:     ysysloc=stsym ("gcos");
    1191: # endif
    1192: # if ibm
    1193:     ysysloc=stsym ("ibm");
    1194: # endif
    1195: # if pdp11
    1196:     varloc=stsym("pdp11");
    1197: # endif
    1198: # if vax
    1199:     varloc=stsym("vax");
    1200: # endif
    1201: # if interdata
    1202:     varloc=stsym ("interdata");
    1203: # endif
    1204: # if tss
    1205:     varloc=stsym ("tss");
    1206: # endif
    1207: # if os
    1208:     varloc=stsym ("os");
    1209: # endif
    1210: # if mert
    1211:     varloc=stsym ("mert");
    1212: # endif
    1213: # if mc68000
    1214:     varloc=stsym("mc68000");
    1215: # endif
    1216: # if sun
    1217:     varloc=stsym("sun");
    1218: # endif
    1219: # if BSD2_11
    1220:     varloc=stsym("BSD2_11");
    1221: # endif
    1222: # if BSD2_10
    1223:     varloc=stsym("BSD2_10");
    1224: # endif
    1225: # if BSD2_9
    1226:     varloc=stsym("BSD2_9");
    1227: # endif
    1228:     ulnloc=stsym ("__LINE__");
    1229:     uflloc=stsym ("__FILE__");
    1230:
    1231:     tf=fnames[ifno]; fnames[ifno]="command line"; lineno[ifno]=1;
    1232:     cp2=prespc;
    1233:     while (cp2<predef) stsym(*cp2++);
    1234:     cp2=punspc;
    1235:     while (cp2<prund) {
    1236:         if (p=strdex(*cp2, '=')) *p++='\0';
    1237:         lookup(*cp2++, DROP);
    1238:     }
    1239:     fnames[ifno]=tf;
    1240:     pbeg=buffer+NCPS; pbuf=pbeg+BUFSIZ; pend=pbuf+BUFSIZ;
    1241:
    1242:     trulvl = 0; flslvl = 0;
    1243:     lineno[0] = 1; sayline(START);
    1244:     outp=inp=pend;
    1245:     control(pend);
    1246:     return (exfail);
    1247: }

#### Defined functions

control defined in line 728; used 1 times

- in line 1245

copy defined in line 995; used 6 times

- in line 153, 618, 892, 1069, 1115-1116(2)

cotoken defined in line 360; used 9 times

- in line 524, 564, 583, 658, 683, 732, 774, 794, 936

dodef defined in line 633; used 2 times

- in line 736, 824

doincl defined in line 554; used 1 times

- in line 738

dump defined in line 270; used 9 times

- in line 288, 318, 350, 396, 536-537(2), 584, 732, 916

equfrm defined in line 627; used 2 times

- in line 689, 703

lookup defined in line 859; used 5 times

- in line 177, 893, 1237
- in /usr/src/lib/cpp/yylex.c line 24, 46

main defined in line 1011; never used
pperror defined in line 834; used 33 times

- in line 319, 341, 349, 535, 542, 550, 581, 587-589(2), 615, 643, 664-671(3), 750, 757, 764, 792, 849, 855, 879, 911, 942, 1088, 1096, 1102-1107(2), 1113, 1126-1129(2), 1152
- in /usr/src/lib/cpp/yylex.c line 61, 86

ppsym defined in line 827; used 9 times

- in line 1176-1184(9)

ppwarn defined in line 852; used 4 times

- in line 648, 718, 944, 950

refill defined in line 312; used 20 times

- in line 371-391(5), 402-418(6), 425, 439-441(2), 451, 459, 503-506(2), 513, 537

savestring defined in line 798; used 2 times

- in line 773, 787

sayline defined in line 210; used 6 times

- in line 292, 352, 619, 748, 754, 1243

skipbl defined in line 522; used 11 times

- in line 559, 646-648(2), 662, 733, 740-744(2), 760, 930
- in /usr/src/lib/cpp/yylex.c line 19, 30

slookup defined in line 886; used 7 times

- in line 177, 509, 650, 734, 740-744(2), 760

strdex defined in line 1003; used 4 times

- in line 153, 304, 594, 1236

stsym defined in line 813; used 19 times

- in line 154, 830, 1187-1233(17)

subst defined in line 899; used 2 times

- in line 153, 894

trmdir defined in line 984; used 4 times

- in line 153, 618, 1069, 1117

unfill defined in line 528; used 3 times

- in line 621, 956, 962

yyerror defined in line 848; never used
yywrap defined in line 1009; never used

#### Defined variables

buffer defined in line 110; used 1 times

- in line 1240

bufstack defined in line 132; used 2 times

- in line 328, 539

cinit defined in line 31; used 3 times

- in line 830(2), 868

defloc defined in line 194; used 2 times

- in line 735, 1176

dirnams defined in line 148; used 5 times

- in line 352, 618, 1059, 1069, 1117

dirs defined in line 152; used 12 times

- in line 352, 591, 618, 1059, 1069, 1103, 1117, 1161-1175(5)

eifloc defined in line 199; used 2 times

- in line 747, 1180

elsloc defined in line 198; used 2 times

- in line 751, 1179

endbuf defined in line 132; used 2 times

- in line 326, 547

env defined in line 181; used 2 times

- in line 184, 1019

exfail defined in line 173; used 12 times

- in line 350, 542, 589, 837, 845, 853-856(3), 879, 1019, 1158, 1246

fastab defined in line 94; used 14 times

- in line 98-103(5), 725, 1024, 1034, 1040, 1046-1050(5)

fin defined in line 155; used 7 times

- in line 332, 352(2), 612, 1111-1112(2), 1157

fins defined in line 149; used 4 times

- in line 352, 611-612(2), 1157

flslvl defined in line 208; used 44 times

- in line 108, 277, 348, 396, 422, 491, 562, 572, 583(2), 645, 722, 734-772(26), 794(2), 894, 928, 952, 1242

fnames defined in line 147; used 19 times

- in line 213-214(2), 339-342(3), 617, 787, 835, 841, 922, 932, 1059-1062(2), 1068-1069(2), 1115, 1231(2), 1239

fretop defined in line 131; used 4 times

- in line 328(2), 539(2)

ifdloc defined in line 200; used 2 times

- in line 743, 1181

ifloc defined in line 197; used 2 times

- in line 762, 1183

ifnloc defined in line 201; used 2 times

- in line 739, 1182

ifno defined in line 167; used 49 times

- in line 213-214(3), 324, 337-342(7), 352(2), 390, 411, 438, 446, 537, 586, 611-622(6), 664, 677, 718(2), 787, 835, 841-842(2), 919-922(2), 932(2), 947-948(2), 1059-1062(2), 1068, 1115-1117(2), 1157, 1231(3), 1239

incloc defined in line 196; used 2 times

- in line 737, 1178

inctop defined in line 146; used 3 times

- in line 324, 537, 622

infile defined in line 162; used 7 times

- in line 213, 1116, 1134-1148(5)

inp defined in line 29; used 90 times

- in line 277-282(2), 288-293(2), 308, 318-320(5), 350, 369, 375, 396, 402-407(4), 413-422(5), 451, 503-509(4), 524(2), 536-537(2), 551, 560-584(18), 646-648(2), 658-662(3), 683(2), 722, 732-734(5), 740-744(2), 760, 774-785(7), 791-794(4), 930-940(8), 956, 962, 977, 1244

instack defined in line 132; used 3 times

- in line 325-328(2), 545

lastsym defined in line 177; used 3 times

- in line 824, 876, 883

lineno defined in line 150; used 20 times

- in line 214, 339-342(3), 390, 411, 438, 446, 617, 664, 677, 718(2), 842, 919, 932, 947-948(2), 1231, 1243

lneloc defined in line 204; used 2 times

- in line 771, 1184

macbit defined in line 46; used 5 times

- in line 476, 485, 1185(3)

macdam defined in line 140; used 4 times

- in line 320, 551, 909-914(2)

macfil defined in line 136; used 2 times

- in line 340, 932

macforw defined in line 139; used 2 times

- in line 909-914(2)

maclin defined in line 135; used 4 times

- in line 340, 932, 947-948(2)

maclvl defined in line 138; used 3 times

- in line 331, 910-913(2)

macnam defined in line 137; used 3 times

- in line 341, 535, 915

mactop defined in line 131; used 9 times

- in line 324-328(4), 534-537(2), 545-547(2), 622

mflag defined in line 161; used 3 times

- in line 213, 1081, 1133

nd defined in line 157; used 7 times

- in line 1102-1103(2), 1161-1175(5)

newp defined in line 30; used 6 times

- in line 509(2), 767-769(2), 894-895(2)

outp defined in line 29; used 27 times

- in line 277, 287, 293, 309, 320, 407, 417-422(2), 524, 549-551(3), 564, 583, 658, 683, 734, 774-775(3), 791-794(2), 936, 956, 962, 977, 1244

passcom defined in line 159; used 9 times

- in line 396, 402, 411-413(2), 422, 640-641(2), 722, 1085

pbeg defined in line 28; used 4 times

- in line 106, 319, 1240(2)

pbuf defined in line 28; used 7 times

- in line 318, 325, 332-333(2), 548, 1240(2)

pend defined in line 28; used 14 times

- in line 105, 326, 333(2), 345, 536-537(2), 545-548(3), 823, 1240-1245(3)

pflag defined in line 158; used 3 times

- in line 214, 772, 1082

plvl defined in line 134; used 10 times

- in line 338-339(2), 345(2), 929-939(6)

predef defined in line 170; used 3 times

- in line 1087-1092(2), 1233

prespc defined in line 169; used 3 times

- in line 170, 1087, 1232

prund defined in line 172; used 3 times

- in line 1095-1099(2), 1235

ptrtab defined in line 96; used 4 times

- in line 97-99(2), 725-726(2)

punspc defined in line 171; used 3 times

- in line 172, 1095, 1234

rflag defined in line 160; used 2 times

- in line 910, 1084

savch defined in line 120; used 14 times

- in line 541-543(4), 589, 617, 643-644(2), 651, 681, 722, 830, 999(2)

sbf defined in line 118; never used
sbff defined in line 114; used 1 times

- in line 115

slotab defined in line 95; used 3 times

- in line 97, 726, 1050

stab defined in line 192; used 3 times

- in line 871, 878-880(2)

t21 defined in line 74; used 2 times

- in line 485, 1030

t22 defined in line 74; used 2 times

- in line 485, 1030

t23 defined in line 74; used 5 times

- in line 485, 1054-1055(4)

tgpscan defined in line 143; used 3 times

- in line 280-282(2), 293

toktyp defined in line 47; used 7 times

- in line 524, 647, 668, 687, 1024, 1034, 1052

trulvl defined in line 207; used 11 times

- in line 348, 741-756(7), 765-768(2), 1242

udfloc defined in line 195; used 2 times

- in line 758, 1177

uflloc defined in line 206; used 2 times

- in line 920, 1229

ulnloc defined in line 205; used 2 times

- in line 917, 1228

varloc defined in line 203; used 11 times

- in line 1196-1226(11)

warnc defined in line 129; used 2 times

- in line 959, 1048

ysysloc defined in line 202; used 3 times

- in line 1187-1193(3)

#### Defined struct's

symtab defined in line 174; used 49 times

- in line 154, 192-206(28), 636(2), 730(2), 813(2), 827-829(4), 859(2), 865(2), 886-888(4), 900(2)

#### Defined macros

ALFSIZ defined in line 44; used 9 times

- in line 46-47(2), 74(3), 94-95(2), 1050-1054(2)

BACK defined in line 166; used 1 times

- in line 352

BEG defined in line 357; used 3 times

- in line 363-365(2), 448

BLANK defined in line 48; used 2 times

- in line 524, 1052

BUFSIZ defined in line 25; used 21 times

- in line 24, 110(2), 319, 332, 403, 414, 541-548(4), 557, 589, 639-643(2), 815, 905, 941, 1016, 1240(2)

CB defined in line 91; used 3 times

- in line 101, 1047-1049(2)

COFF defined in line 38; used 35 times

- in line 97-103(6), 476, 485(4), 524, 647, 668, 687, 725-726(2), 1024(2), 1030-1034(4), 1040, 1046-1055(11)

CONT defined in line 165; used 3 times

- in line 292, 748, 754

DROP defined in line 122; used 5 times

- in line 123, 760, 875(2), 1237

IB defined in line 88; used 2 times

- in line 98, 1024

IDENT defined in line 49; used 4 times

- in line 647, 668, 687, 1024

LF defined in line 358; used 1 times

- in line 446

MAXFRE defined in line 126; used 5 times

- in line 132(3), 328, 534

MAXFRM defined in line 127; used 5 times

- in line 638, 670, 903-904(2), 944

MAXINC defined in line 125; used 6 times

- in line 146-150(5), 586

MAXOUT defined in line 279; used 1 times

- in line 287

NB defined in line 90; used 3 times

- in line 100, 1024, 1034

NCPS defined in line 6; used 6 times

- in line 74, 110(2), 890(2), 1240

NPREDEF defined in line 168; used 4 times

- in line 169-171(2), 1087, 1095

NUMBR defined in line 50; used 1 times

- in line 1034

QB defined in line 92; used 3 times

- in line 102, 1046-1049(2)

READ defined in line 21; used 2 times

- in line 611, 1112

SALT defined in line 23; used 3 times

- in line 734, 830(2)

SAME defined in line 124; used 1 times

- in line 630

SB defined in line 89; used 6 times

- in line 99, 1024, 1034, 1040, 1049-1050(2)

SBSIZE defined in line 117; used 5 times

- in line 114-118(2), 542, 589, 643

START defined in line 164; used 3 times

- in line 213, 619, 1243

STATIC defined in line 16; used 37 times

- in line 146-173(20), 192-208(16), 995

STDERR defined in line 20; never used
STDIN defined in line 18; used 2 times

- in line 155, 1111

STDOUT defined in line 19; never used
WARN defined in line 123; used 3 times

- in line 129, 690, 704

WB defined in line 93; used 3 times

- in line 103, 1048-1049(2)

WRITE defined in line 22; never used
b0 defined in line 78; used 1 times

- in line 493

b1 defined in line 79; used 1 times

- in line 494

b2 defined in line 80; used 1 times

- in line 495

b3 defined in line 81; used 1 times

- in line 496

b4 defined in line 82; used 1 times

- in line 497

b5 defined in line 83; used 1 times

- in line 498

b6 defined in line 84; used 1 times

- in line 499

b7 defined in line 85; used 1 times

- in line 500

bob defined in line 106; used 4 times

- in line 319, 550, 956, 962

close defined in line 186; used 1 times

- in line 352

cputc defined in line 108; used 3 times

- in line 405, 416(2)

eob defined in line 105; used 17 times

- in line 371-391(5), 401, 412, 425, 439-441(2), 451, 459, 503-506(2), 513, 546, 621

exit defined in line 184; used 10 times

- in line 183, 350, 542, 589, 879, 1113, 1126, 1137, 1143, 1153

fasscan defined in line 725; used 2 times

- in line 732, 952

iscom defined in line 101; used 1 times

- in line 398

isid defined in line 98; used 12 times

- in line 494-502(8), 512, 700-701(2), 820

isnum defined in line 100; used 1 times

- in line 458

isquo defined in line 102; used 1 times

- in line 434

isslo defined in line 97; used 2 times

- in line 446, 518

isspc defined in line 99; used 1 times

- in line 368

iswarn defined in line 103; used 1 times

- in line 955

main defined in line 182; never used
open defined in line 185; used 2 times

- in line 611, 1112

sbf defined in line 115; used 4 times

- in line 120, 542, 589, 643

scw1 defined in line 70; used 2 times

- in line 77, 474

scw2 defined in line 71; used 4 times

- in line 73, 482, 1025, 1053

sloscan defined in line 726; used 3 times

- in line 733, 824, 928

symsiz defined in line 190; used 5 times

- in line 192, 870(2), 880, 910

tmac1 defined in line 478; used 8 times

- in line 493-500(8)

tmac2 defined in line 487; used 9 times

- in line 494-501(8), 507

xmac1 defined in line 479; used 2 times

- in line 475, 654

xmac2 defined in line 488; used 3 times

- in line 483, 655-656(2)

Last modified: 1996-07-12 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 3214 |