|
|
1.1 ! root 1: /*#ident "@(#)cpp:common/cpp.c 1.44" */ ! 2: ! 3: ! 4: #ifdef FLEXNAMES ! 5: # define NCPS 128 ! 6: #else ! 7: # define NCPS 8 ! 8: #endif ! 9: int ncps = NCPS; /* default name length */ ! 10: ! 11: # include <stdio.h> ! 12: # include <ctype.h> ! 13: # include <libc.h> ! 14: # include <sys/types.h> /* needed by stat.h */ ! 15: # include <sys/stat.h> /* needed by option -M */ ! 16: /* C command - C preprocessor */ ! 17: ! 18: /* ! 19: * See if necessary defines are given ! 20: */ ! 21: #if !defined( PD_MACH ) || !defined( PD_SYS ) ! 22: # include "*** Must define PD_MACH and PD_SYS ***" ! 23: #endif ! 24: /* ! 25: * These defines are used to enter new machines and/or systems ! 26: * to the two lists. To create a new instance of cpp in a cross ! 27: * compilation environment, set PD_MY_MACH=\"your-new-machine\" ! 28: * and/or PD_MY_SYS=\"your-new-os\" and set PD_MACH=MAX_PD_MACH ! 29: * and PD_SYS=MAX_PD_SYS. ! 30: */ ! 31: #ifndef PD_MY_MACH ! 32: # define PD_MY_MACH 0 ! 33: #endif ! 34: #ifndef PD_MY_SYS ! 35: # define PD_MY_SYS 0 ! 36: #endif ! 37: ! 38: #define STATIC ! 39: ! 40: #define STDIN 0 ! 41: #define STDOUT 1 ! 42: #define STDERR 2 ! 43: ! 44: #define CLASSCODE 27 /* exit status if #class seen */ ! 45: ! 46: #define READ "r" ! 47: #define WRITE "w" ! 48: #define SALT '#' ! 49: ! 50: #ifndef BUFSIZ ! 51: # define BUFSIZ 512 ! 52: #endif ! 53: ! 54: char *pbeg, *pbuf, *pend; ! 55: char *outp, *inp; ! 56: char *newp; ! 57: char cinit; ! 58: ! 59: #ifdef CXREF ! 60: char *xcopy(); ! 61: FILE *outfp; ! 62: static int ready = 0; ! 63: int xline; ! 64: #endif ! 65: ! 66: /* some code depends on whether characters are sign or zero extended */ ! 67: /* #if '\377' < 0 not used here, old cpp doesn't understand */ ! 68: #if pdp11 | vax ! 69: # define COFF 128 ! 70: #else ! 71: # define COFF 0 ! 72: #endif ! 73: ! 74: # if gcos ! 75: # define ALFSIZ 512 /* alphabet size */ ! 76: # else ! 77: # define ALFSIZ 256 /* alphabet size */ ! 78: # endif ! 79: char macbit[ ALFSIZ + 11 ]; ! 80: char toktyp[ ALFSIZ ]; ! 81: #define BLANK 1 ! 82: #define IDENT 2 ! 83: #define NUMBR 3 ! 84: ! 85: /* a superimposed code is used to reduce the number of calls to the ! 86: /* symbol table lookup routine. (if the kth character of an identifier ! 87: /* is 'a' and there are no macro names whose kth character is 'a' ! 88: /* then the identifier cannot be a macro name, hence there is no need ! 89: /* to look in the symbol table.) 'scw1' enables the test based on ! 90: /* single characters and their position in the identifier. 'scw2' ! 91: /* enables the test based on adjacent pairs of characters and their ! 92: /* position in the identifier. scw1 typically costs 1 indexed fetch, ! 93: /* an AND, and a jump per character of identifier, until the identifier ! 94: /* is known as a non-macro name or until the end of the identifier. ! 95: /* scw1 is inexpensive. scw2 typically costs 4 indexed fetches, ! 96: /* an add, an AND, and a jump per character of identifier, but it is also ! 97: /* slightly more effective at reducing symbol table searches. ! 98: /* scw2 usually costs too much because the symbol table search is ! 99: /* usually short; but if symbol table search should become expensive, ! 100: /* the code is here. ! 101: /* using both scw1 and scw2 is of dubious value. ! 102: */ ! 103: #define scw1 1 ! 104: #define scw2 0 ! 105: ! 106: #if scw2 ! 107: char t21[ ALFSIZ ], t22[ ALFSIZ ], t23[ ALFSIZ + NCPS ]; ! 108: #endif ! 109: ! 110: #if scw1 ! 111: # define b0 1 ! 112: # define b1 2 ! 113: # define b2 4 ! 114: # define b3 8 ! 115: # define b4 16 ! 116: # define b5 32 ! 117: # define b6 64 ! 118: # define b7 128 ! 119: #endif ! 120: ! 121: #define IB 1 ! 122: #define SB 2 ! 123: #define NB 4 ! 124: #define CB 8 ! 125: #define QB 16 ! 126: #define WB 32 ! 127: char fastab[ ALFSIZ ]; ! 128: char slotab[ ALFSIZ ]; ! 129: char *ptrtab; ! 130: #define isslo ( ptrtab == ( slotab + COFF ) ) ! 131: #define isid(a) ( ( fastab + COFF )[a] & IB ) ! 132: #define isspc(a) ( ptrtab[a] & SB ) ! 133: #define isnum(a) ( ( fastab + COFF )[a] & NB ) ! 134: #define iscom(a) ( ( fastab + COFF )[a] & CB ) ! 135: #define isquo(a) ( ( fastab + COFF )[a] & QB ) ! 136: #define iswarn(a) ( ( fastab + COFF )[a] & WB ) ! 137: ! 138: #define eob(a) ( ( a ) >= pend ) ! 139: #define bob(a) ( pbeg >= ( a ) ) ! 140: ! 141: char buffer[ NCPS + BUFSIZ + BUFSIZ + NCPS ]; ! 142: ! 143: # define MAXNEST 12 /* max number of nested #include's */ ! 144: # define MAXFRE 14 /* max buffers of macro pushback */ ! 145: ! 146: #ifdef pdp11 ! 147: # define SBSIZE 24000 ! 148: #else ! 149: /* The idea here is to define the buffer to have a certain size ! 150: ** (the literal number) plus enough room for slop and taking side buffers ! 151: ** out to hold processing interrupted by #include's. The cost of side ! 152: ** buffers is particularly noticable on an Amdahl, where BUFSIZ is 4096. ! 153: */ ! 154: # define SBSIZE (21000 + (MAXFRE+1)*BUFSIZ) ! 155: #endif ! 156: ! 157: char sbf[ SBSIZE ]; ! 158: char *savch = sbf; ! 159: ! 160: # define DROP '\376' /* special character not legal ASCII or EBCDIC */ ! 161: # define WARN DROP ! 162: # define SAME 0 ! 163: # define MAXINC 100 /* max number of directories for -I options */ ! 164: # define MAXFRM 31 /* max number of formals/actuals to a macro */ ! 165: ! 166: static char warnc = WARN; ! 167: ! 168: int mactop, fretop; ! 169: char *instack[ MAXFRE ], *bufstack[ MAXFRE ], *endbuf[ MAXFRE ]; ! 170: ! 171: int plvl; /* parenthesis level during scan for macro actuals */ ! 172: int maclin; /* line number of macro call requiring actuals */ ! 173: char *macfil; /* file name of macro call requiring actuals */ ! 174: char *macnam; /* name of macro requiring actuals */ ! 175: int maclvl; /* # calls since last decrease in nesting level */ ! 176: char *macforw; /* pointer which must be exceeded to decrease nesting level */ ! 177: int macdam; /* offset to macforw due to buffer shifting */ ! 178: ! 179: #if tgp ! 180: int tgpscan; /* flag for dump(); */ ! 181: #endif ! 182: ! 183: STATIC int inctop[ MAXNEST ]; ! 184: STATIC char *fnames[ MAXNEST ]; ! 185: STATIC char *fdates[ MAXNEST ]; /* for -M option */ ! 186: STATIC char *dirnams[ MAXNEST ]; /* actual directory of #include files */ ! 187: STATIC FILE *fins[ MAXNEST ]; ! 188: STATIC int lineno[ MAXNEST ]; ! 189: ! 190: STATIC char *dirs[ MAXINC ]; /* -I and <> directories */ ! 191: STATIC char *dfltdir = (char *) 0; /* user-supplied default (like /usr/include) */ ! 192: char *copy(), *subst(), *trmdir(), *strchr(); ! 193: char *chkend(), *getfdate(), *findfdate(); ! 194: struct symtab *stsym(); ! 195: STATIC FILE *fin = stdin; ! 196: STATIC FILE *fout = stdout; ! 197: STATIC int nd = 1; ! 198: STATIC int pflag; /* don't put out lines "# 12 foo.c" */ ! 199: STATIC int mflag; ! 200: STATIC int passcom; /* don't delete comments */ ! 201: STATIC int incomm; /* set while in comment so that EOF can be detected */ ! 202: STATIC int rflag; /* allow macro recursion */ ! 203: STATIC int print_incs; /* set to print out included filenames */ ! 204: STATIC int ifno; ! 205: # define NPREDEF 20 ! 206: STATIC char *prespc[ NPREDEF ]; ! 207: STATIC char **predef = prespc; ! 208: STATIC char *punspc[ NPREDEF ]; ! 209: STATIC char **prund = punspc; ! 210: STATIC int exfail; ! 211: struct symtab ! 212: { ! 213: char *name; ! 214: char *value; ! 215: } *lastsym, *lookup(), *slookup(); ! 216: ! 217: # if gcos ! 218: # include <setjmp.h> ! 219: static jmp_buf env; ! 220: # define main mainpp ! 221: # undef exit ! 222: # define exit(S) longjmp(env, 1) ! 223: # define symsiz 500 ! 224: # define LINEFORM "# %d %s\n" ! 225: # define ERRFORM "*%c* %s, line " ! 226: # else ! 227: # define symsiz 2000 ! 228: # define LINEFORM "# %d \"%s%s\"\n" ! 229: # define ERRFORM "*%c* \"%s%s\", line " ! 230: # endif ! 231: STATIC struct symtab stab[ symsiz ]; ! 232: ! 233: STATIC struct symtab *defloc; ! 234: STATIC struct symtab *udfloc; ! 235: STATIC struct symtab *incloc; ! 236: STATIC struct symtab *ifloc; ! 237: STATIC struct symtab *elsloc; ! 238: STATIC struct symtab *eifloc; ! 239: STATIC struct symtab *elifloc; ! 240: STATIC struct symtab *ifdloc; ! 241: STATIC struct symtab *ifnloc; ! 242: STATIC struct symtab *ysysloc; ! 243: STATIC struct symtab *varloc; ! 244: STATIC struct symtab *lneloc; ! 245: STATIC struct symtab *ulnloc; ! 246: STATIC struct symtab *uflloc; ! 247: STATIC struct symtab *clsloc; ! 248: STATIC struct symtab *idtloc; ! 249: STATIC struct symtab *pragmaloc; ! 250: STATIC int trulvl; ! 251: STATIC int flslvl; ! 252: #define MAX_DEPTH 500 /* max of trulvl + flslvl */ ! 253: #define SEEN_ELSE 0x1 ! 254: #define TRUE_ELIF 0x2 ! 255: STATIC char ifelstk[MAX_DEPTH]; ! 256: ! 257: /* ! 258: * To facilitate the handling of different cpp's and cross cpp's, ! 259: * the sets of mutually exclusive predefined are placed into lists. ! 260: * The value used from these lists are set when building from the ! 261: * command line. ! 262: */ ! 263: #define MAX_PD_MACH 13 /* set so it is where PD_MY_MACH is at */ ! 264: #define D_tss 0 /*define table indexes */ ! 265: #define D_os 1 ! 266: #define D_mert 2 ! 267: #define D_RT 3 ! 268: #define D_RES 4 ! 269: #define D_interdata 5 ! 270: #define D_pdp11 6 ! 271: #define D_vax 7 ! 272: #define D_u370 8 ! 273: #define D_u3b 9 ! 274: #define D_u3b5 10 ! 275: #define D_u3b2 11 ! 276: #define D_u3b20d 12 ! 277: #define D_newmach MAX_PD_MACH ! 278: #define D_nomach MAX_PD_MACH ! 279: ! 280: char *pdef_mach[MAX_PD_MACH+2] = /* choose using PD_MACH */ ! 281: { ! 282: /* ! 283: * The following are ``machines'' for historical reasons only. ! 284: */ ! 285: "tss", "os", "mert", ! 286: "RT", "RES", ! 287: /* These are the currently supported machines */ ! 288: "interdata", "pdp11", "vax", ! 289: "u370", "u3b", "u3b5", ! 290: "u3b2", "u3b20d", ! 291: PD_MY_MACH, /* for adding "own" machine */ ! 292: 0 ! 293: }; ! 294: ! 295: #define MAX_PD_SYS 4 /* set so that it is where PD_MY_SYS is at */ ! 296: #define D_unix 0 ! 297: #define D_gcos 1 ! 298: #define D_ibm 2 ! 299: #define D_DMERT 3 ! 300: #define D_newsys MAX_PD_SYS ! 301: #define D_nosys MAX_PD_SYS ! 302: ! 303: char *pdef_sys[MAX_PD_SYS+2] = /* choose using PD_SYS */ ! 304: { ! 305: "unix", ! 306: "gcos", ! 307: "ibm", ! 308: "DMERT", ! 309: PD_MY_SYS, /* for adding "own" system */ ! 310: 0 ! 311: }; ! 312: #if PD_MACH < 0 || PD_MACH > MAX_PD_MACH ! 313: # include "*** PD_MACH set illegally ***" ! 314: #endif ! 315: #if PD_SYS < 0 || PD_SYS > MAX_PD_SYS ! 316: # include "*** PD_SYS set illegally ***" ! 317: #endif ! 318: ! 319: ! 320: ! 321: sayline() ! 322: { ! 323: if ( pflag == 0 ) ! 324: fprintf( fout, LINEFORM, lineno[ifno], fnames[ifno] ,fdates[ifno] ); ! 325: } ! 326: ! 327: /* data structure guide ! 328: /* ! 329: /* most of the scanning takes place in the buffer: ! 330: /* ! 331: /* (low address) (high address) ! 332: /* pbeg pbuf pend ! 333: /* | <-- BUFSIZ chars --> | <-- BUFSIZ chars --> | ! 334: /* _______________________________________________________________________ ! 335: /* |_______________________________________________________________________| ! 336: /* | | | ! 337: /* |<-- waiting -->| |<-- waiting --> ! 338: /* | to be |<-- current -->| to be ! 339: /* | written | token | scanned ! 340: /* | | | ! 341: /* outp inp p ! 342: /* ! 343: /* *outp first char not yet written to output file ! 344: /* *inp first char of current token ! 345: /* *p first char not yet scanned ! 346: /* ! 347: /* macro expansion: write from *outp to *inp (chars waiting to be written), ! 348: /* ignore from *inp to *p (chars of the macro call), place generated ! 349: /* characters in front of *p (in reverse order), update pointers, ! 350: /* resume scanning. ! 351: /* ! 352: /* symbol table pointers point to just beyond the end of macro definitions; ! 353: /* the first preceding character is the number of formal parameters. ! 354: /* the appearance of a formal in the body of a definition is marked by ! 355: /* 2 chars: the char WARN, and a char containing the parameter number. ! 356: /* the first char of a definition is preceded by a zero character. ! 357: /* ! 358: /* when macro expansion attempts to back up over the beginning of the ! 359: /* buffer, some characters preceding *pend are saved in a side buffer, ! 360: /* the address of the side buffer is put on 'instack', and the rest ! 361: /* of the main buffer is moved to the right. the end of the saved buffer ! 362: /* is kept in 'endbuf' since there may be nulls in the saved buffer. ! 363: /* ! 364: /* similar action is taken when an 'include' statement is processed, ! 365: /* except that the main buffer must be completely emptied. the array ! 366: /* element 'inctop[ifno]' records the last side buffer saved when ! 367: /* file 'ifno' was included. these buffers remain dormant while ! 368: /* the file is being read, and are reactivated at end-of-file. ! 369: /* ! 370: /* instack[0 : mactop] holds the addresses of all pending side buffers. ! 371: /* instack[inctop[ifno]+1 : mactop-1] holds the addresses of the side ! 372: /* buffers which are "live"; the side buffers instack[0 : inctop[ifno]] ! 373: /* are dormant, waiting for end-of-file on the current file. ! 374: /* ! 375: /* space for side buffers is obtained from 'savch' and is never returned. ! 376: /* bufstack[0:fretop-1] holds addresses of side buffers which ! 377: /* are available for use. ! 378: */ ! 379: ! 380: dump() ! 381: { ! 382: /* write part of buffer which lies between outp and inp . ! 383: /* this should be a direct call to 'write', but the system slows ! 384: /* to a crawl if it has to do an unaligned copy. thus we buffer. ! 385: /*? this silly loop is 15% of the total time, thus even the 'putc' ! 386: /*? macro is too slow. ! 387: */ ! 388: register char *p1; ! 389: register FILE *f; ! 390: #if tgp ! 391: register char *p2; ! 392: #endif ! 393: ! 394: if ( ( p1 = outp ) == inp || flslvl != 0 ) ! 395: return; ! 396: #if tgp ! 397: # define MAXOUT 80 ! 398: if ( !tgpscan ) /* scan again to insure <= MAXOUT ! 399: { /* chars between linefeeds */ ! 400: register char c, *pblank; ! 401: char savc, stopc, brk; ! 402: ! 403: tgpscan = 1; ! 404: brk = stopc = pblank = 0; ! 405: p2 = inp; ! 406: savc = *p2; ! 407: *p2 = '\0'; ! 408: while ( c = *p1++ ) ! 409: { ! 410: if ( c == '\\' ) ! 411: c = *p1++; ! 412: if ( stopc == c ) ! 413: stopc = 0; ! 414: else if ( c == '"' || c == '\'' ) ! 415: stopc = c; ! 416: if ( p1 - outp > MAXOUT && pblank != 0 ) ! 417: { ! 418: *pblank++ = '\n'; ! 419: inp = pblank; ! 420: dump(); ! 421: brk = 1; ! 422: pblank = 0; ! 423: } ! 424: if ( c == ' ' && stopc == 0 ) ! 425: pblank = p1 - 1; ! 426: } ! 427: if ( brk ) ! 428: sayline(); ! 429: *p2 = savc; ! 430: inp = p2; ! 431: p1 = outp; ! 432: tgpscan = 0; ! 433: } ! 434: #endif ! 435: f = fout; ! 436: # if gcos ! 437: /* filter out "$ program c" card if first line of input */ ! 438: /* gmatch is a simple pattern matcher in the GCOS Standard Library */ ! 439: { ! 440: static int gmfirst = 0; ! 441: ! 442: if ( !gmfirst ) ! 443: { ! 444: ++gmfirst; ! 445: if ( gmatch( p1, "^$*program[ \t]*c*") ) ! 446: p1 = strchr( p1, '\n' ); ! 447: } ! 448: } ! 449: # endif ! 450: while (p1 < inp) ! 451: putc(*p1++, f); ! 452: outp = p1; ! 453: } ! 454: ! 455: char * ! 456: refill( p ) ! 457: register char *p; ! 458: { ! 459: /* dump buffer. save chars from inp to p. read into buffer at pbuf, ! 460: /* contiguous with p. update pointers, return new p. ! 461: */ ! 462: register char *np, *op; ! 463: register int ninbuf; ! 464: ! 465: dump(); ! 466: /* slide current token to left of pbuf */ ! 467: ninbuf = p - inp; ! 468: np = pbuf - ninbuf; ! 469: if ( bob( np + 1 ) ) ! 470: { ! 471: pperror( "token too long" ); ! 472: np = pbeg; ! 473: p = inp + BUFSIZ; ! 474: } ! 475: macdam += np - inp; ! 476: memcpy(np, inp, ninbuf); ! 477: p = np + ninbuf; /* usually pbuf - ninbuf */ ! 478: outp = inp = np; ! 479: for ( ;; ) ! 480: { ! 481: /* retrieve hunk of pushed-back macro text */ ! 482: if ( mactop > inctop[ifno] ) ! 483: { ! 484: op = instack[ --mactop ]; ! 485: memcpy(pbuf, op, endbuf[mactop] - op); ! 486: pend = pbuf + (endbuf[mactop] - op) - 1; ! 487: /* make buffer space avail for 'include' processing */ ! 488: if ( fretop < MAXFRE ) ! 489: bufstack[fretop++] = instack[mactop]; ! 490: return( p ); ! 491: } ! 492: else /* get more text from file(s) */ ! 493: { ! 494: maclvl = 0; ! 495: #if NOTDEF ! 496: if ( 0 < ( ninbuf = fread( pbuf, sizeof( char ), BUFSIZ, fin ) ) ) ! 497: { ! 498: #else ! 499: /* ! 500: * very much faster, but don't remove stdio completely for now ! 501: * in vague search for compatibility ! 502: */ ! 503: if ((ninbuf = read(fileno(fin), pbuf, BUFSIZ)) > 0) { ! 504: #endif ! 505: pend = pbuf + ninbuf; ! 506: *pend = '\0'; ! 507: return( p ); ! 508: } ! 509: /* end of #include file */ ! 510: if ( ifno == 0 ) /* end of input */ ! 511: { ! 512: if ( plvl != 0 ) ! 513: { ! 514: int n = plvl, tlin = lineno[ifno]; ! 515: char *tfil = fnames[ifno]; ! 516: ! 517: lineno[ifno] = maclin; ! 518: fnames[ifno] = macfil; ! 519: pperror( "%s: unterminated macro call", ! 520: macnam ); ! 521: lineno[ifno] = tlin; ! 522: fnames[ifno] = tfil; ! 523: np = p; ! 524: /*shut off unterminated quoted string*/ ! 525: *np++ = '\n'; ! 526: /* supply missing parens */ ! 527: while ( --n >= 0 ) ! 528: *np++ = ')'; ! 529: pend = np; ! 530: *np = '\0'; ! 531: if ( plvl < 0 ) ! 532: plvl = 0; ! 533: return( p ); ! 534: } ! 535: if ( incomm ) { ! 536: pperror( "Unexpected EOF in comment" ); ! 537: /* undo flslvl bump when comment started */ ! 538: if (flslvl) --flslvl; ! 539: } ! 540: if ( trulvl +flslvl > 0 ) ! 541: pperror( "Unexpected EOF within #if, #ifdef or #ifndef" ); ! 542: inp = p; ! 543: dump(); ! 544: if ( fout && ferror( fout ) ) ! 545: pperror( "Problems with writing output file; probably out of temp space" ); ! 546: exit( exfail ? ( exfail == ! 547: CLASSCODE ? CLASSCODE : 2 ) : 0 ); ! 548: } ! 549: fclose( fin ); ! 550: fin = fins[--ifno]; ! 551: dirs[0] = dirnams[ifno]; ! 552: sayline(); ! 553: #ifdef CXREF ! 554: fprintf(outfp, "\"%s\"\n", fnames[ifno]); ! 555: #endif ! 556: } ! 557: } ! 558: } ! 559: ! 560: #define BEG 0 ! 561: #define LF 1 ! 562: ! 563: char * ! 564: cotoken( p ) ! 565: register char *p; ! 566: { ! 567: register int c, i; ! 568: char quoc; ! 569: static int state = BEG; ! 570: static int speakup = 0; ! 571: ! 572: if ( state != BEG ) ! 573: goto prevlf; ! 574: for ( ;; ) ! 575: { ! 576: again: ! 577: while ( !isspc( c = *p++ ) ) ! 578: ; ! 579: inp = p - 1; ! 580: switch ( c ) ! 581: { ! 582: case 0: ! 583: if ( eob( --p ) ) ! 584: { ! 585: p = refill( p ); ! 586: goto again; ! 587: } ! 588: else ! 589: ++p; /* ignore null byte */ ! 590: break; ! 591: case '|': ! 592: case '&': ! 593: for ( ;; ) /* sloscan only */ ! 594: { ! 595: if ( *p++ == *inp ) ! 596: break; ! 597: if ( eob( --p ) ) ! 598: p = refill( p ); ! 599: else ! 600: break; ! 601: } ! 602: break; ! 603: case '=': ! 604: case '!': ! 605: for ( ;; ) /* sloscan only */ ! 606: { ! 607: if ( *p++ == '=' ) ! 608: break; ! 609: if ( eob( --p ) ) ! 610: p = refill( p ); ! 611: else ! 612: break; ! 613: } ! 614: break; ! 615: case '<': ! 616: case '>': ! 617: for ( ;; ) /* sloscan only */ ! 618: { ! 619: if ( *p++ == '=' || p[-2] == p[-1] ) ! 620: break; ! 621: if ( eob( --p ) ) ! 622: p = refill( p ); ! 623: else ! 624: break; ! 625: } ! 626: break; ! 627: case '\\': ! 628: for ( ;; ) ! 629: { ! 630: if ( *p++ == '\n' ) ! 631: { ! 632: ++lineno[ifno]; ! 633: break; ! 634: } ! 635: if ( eob( --p ) ) ! 636: p = refill( p ); ! 637: else ! 638: { ! 639: ++p; ! 640: break; ! 641: } ! 642: } ! 643: break; ! 644: case '/': ! 645: for ( ;; ) ! 646: { ! 647: if ( *p++ == '*' ) /* comment */ ! 648: { ! 649: incomm = 1; ! 650: if ( !passcom ) ! 651: { ! 652: inp = p - 2; ! 653: dump(); ! 654: ++flslvl; ! 655: } ! 656: for ( ;; ) ! 657: { ! 658: while ( !iscom( *p++ ) ) ! 659: ; ! 660: if ( p[-1] == '*' ) ! 661: for ( ;; ) ! 662: { ! 663: if ( *p++ == '/' ) ! 664: goto endcom; ! 665: if ( eob( --p ) ) ! 666: { ! 667: if ( !passcom ) ! 668: { ! 669: inp = p; ! 670: p = refill( p ); ! 671: } ! 672: /* split long comment */ ! 673: else if ( ( p - inp ) >= BUFSIZ ) ! 674: { ! 675: *p++ = '*'; ! 676: *p++ = '/'; ! 677: inp = p; ! 678: p = refill( p ); ! 679: outp = inp = p -= 2; ! 680: *p++ = '/'; ! 681: *p++ = '*'; ! 682: } ! 683: else ! 684: p = refill( p ); ! 685: } ! 686: else ! 687: break; ! 688: } ! 689: else if ( p[-1] == '\n' ) ! 690: { ! 691: ++lineno[ifno]; ! 692: if ( !passcom && flslvl <= 1 ) ! 693: putc( '\n', fout ); ! 694: } ! 695: else if ( eob( --p ) ) ! 696: { ! 697: if ( !passcom ) ! 698: { ! 699: inp = p; ! 700: p = refill( p ); ! 701: } ! 702: /* split long comment */ ! 703: else if ( ( p - inp ) >= BUFSIZ ) ! 704: { ! 705: *p++ = '*'; ! 706: *p++ = '/'; ! 707: inp = p; ! 708: p = refill( p ); ! 709: outp = inp = p -= 2; ! 710: *p++ = '/'; ! 711: *p++ = '*'; ! 712: } ! 713: else ! 714: p = refill( p ); ! 715: } ! 716: else ! 717: ++p; /* ignore null byte */ ! 718: } ! 719: endcom: ! 720: incomm = 0; ! 721: if ( !passcom ) ! 722: { ! 723: outp = inp = p; ! 724: --flslvl; ! 725: goto again; ! 726: } ! 727: break; ! 728: } ! 729: if ( eob( --p ) ) ! 730: p = refill( p ); ! 731: else ! 732: break; ! 733: } ! 734: break; ! 735: # if gcos ! 736: case '`': ! 737: # endif ! 738: case '"': ! 739: case '\'': ! 740: quoc = p[-1]; ! 741: for ( ;; ) ! 742: { ! 743: while ( !isquo( *p++ ) ) ! 744: ; ! 745: if ( p[-1] == quoc ) ! 746: break; ! 747: if ( p[-1] == '\n' ) /* bare \n terminates quotation */ ! 748: { ! 749: --p; ! 750: break; ! 751: } ! 752: if ( p[-1] == '\\' ) ! 753: for ( ;; ) ! 754: { ! 755: if ( *p++ == '\n' ) /* escaped \n ignored */ ! 756: { ! 757: ++lineno[ifno]; ! 758: break; ! 759: } ! 760: if ( eob( --p ) ) ! 761: p = refill( p ); ! 762: else ! 763: { ! 764: ++p; ! 765: break; ! 766: } ! 767: } ! 768: else if ( eob( --p ) ) ! 769: p = refill( p ); ! 770: else ! 771: ++p; /* it was a different quote character */ ! 772: } ! 773: break; ! 774: case WARN: ! 775: { ! 776: int ii; ! 777: ! 778: dump(); ! 779: speakup = 0; ! 780: for ( ii = sizeof(int) / sizeof(char); --ii >= 0; ) ! 781: { ! 782: if ( eob( p ) ) ! 783: p = refill( p ); ! 784: speakup |= ( *p++ & 0xFF ) << ( ii * 8 ); ! 785: } ! 786: inp = outp = p; ! 787: break; ! 788: } ! 789: case '\n': ! 790: ++lineno[ifno]; ! 791: if ( isslo ) ! 792: { ! 793: state=LF; ! 794: return( p ); ! 795: } ! 796: prevlf: ! 797: if ( speakup ) ! 798: { ! 799: inp = p; ! 800: dump(); ! 801: lineno[ifno] = speakup + 1; ! 802: sayline(); ! 803: speakup = 0; ! 804: } ! 805: state = BEG; ! 806: for ( ;; ) ! 807: { ! 808: /* ! 809: * ignore formfeeds and vertical tabs ! 810: * which may be just before the SALT ! 811: */ ! 812: #if NOTDEF ! 813: if ( *p == '\f' || *p == '\v' ) ! 814: { ! 815: register char *s = p; ! 816: ! 817: while ( *++s == '\f' || *s == '\v' ) ! 818: ; ! 819: if ( *s == SALT ) ! 820: { ! 821: /* ! 822: * get the SALT to the front! ! 823: */ ! 824: *s = *p; ! 825: *p = SALT; ! 826: } ! 827: } ! 828: #endif ! 829: if ( *p++ == SALT ) ! 830: return( p ); ! 831: if ( eob( inp = --p ) ) ! 832: p = refill( p ); ! 833: else ! 834: goto again; ! 835: } ! 836: case '0': case '1': case '2': case '3': case '4': ! 837: case '5': case '6': case '7': case '8': case '9': ! 838: for ( ;; ) ! 839: { ! 840: while ( isnum( *p++ ) ) ! 841: ; ! 842: if ( eob( --p ) ) ! 843: p = refill( p ); ! 844: else ! 845: break; ! 846: } ! 847: break; ! 848: case 'A': case 'B': case 'C': case 'D': case 'E': ! 849: case 'F': case 'G': case 'H': case 'I': case 'J': ! 850: case 'K': case 'L': case 'M': case 'N': case 'O': ! 851: case 'P': case 'Q': case 'R': case 'S': case 'T': ! 852: case 'U': case 'V': case 'W': case 'X': case 'Y': ! 853: case 'Z': case '_': ! 854: case 'a': case 'b': case 'c': case 'd': case 'e': ! 855: case 'f': case 'g': case 'h': case 'i': case 'j': ! 856: case 'k': case 'l': case 'm': case 'n': case 'o': ! 857: case 'p': case 'q': case 'r': case 's': case 't': ! 858: case 'u': case 'v': case 'w': case 'x': case 'y': ! 859: case 'z': ! 860: #if scw1 ! 861: # define tmac1( c, bit ) if ( !xmac1( c, bit, & ) ) \ ! 862: goto nomac ! 863: # define xmac1( c, bit, op ) ( ( macbit + COFF )[c] op ( bit ) ) ! 864: #else ! 865: # define tmac1( c, bit ) ! 866: # define xmac1( c, bit, op ) ! 867: #endif ! 868: ! 869: #if scw2 ! 870: # define tmac2( c0, c1, cpos ) if ( !xmac2( c0, c1, cpos, & ) ) \ ! 871: goto nomac ! 872: # define xmac2( c0, c1, cpos, op ) \ ! 873: ( ( macbit + COFF )[ ( t21 + COFF )[c0] + \ ! 874: ( t22 + COFF )[c1]] op ( t23 + COFF + cpos )[c0] ) ! 875: #else ! 876: # define tmac2( c0, c1, cpos ) ! 877: # define xmac2( c0, c1, cpos, op ) ! 878: #endif ! 879: ! 880: if ( flslvl ) ! 881: goto nomac; ! 882: for ( ;; ) ! 883: { ! 884: c = p[-1]; ! 885: tmac1( c, b0 ); ! 886: i = *p++; ! 887: if ( !isid( i ) ) ! 888: goto endid; ! 889: tmac1( i, b1 ); ! 890: tmac2( c, i, 0 ); ! 891: c = *p++; ! 892: if ( !isid( c ) ) ! 893: goto endid; ! 894: tmac1( c, b2 ); ! 895: tmac2( i, c, 1 ); ! 896: i = *p++; ! 897: if ( !isid( i ) ) ! 898: goto endid; ! 899: tmac1( i, b3 ); ! 900: tmac2( c, i, 2 ); ! 901: c = *p++; ! 902: if ( !isid( c ) ) ! 903: goto endid; ! 904: tmac1( c, b4 ); ! 905: tmac2( i, c, 3 ); ! 906: i = *p++; ! 907: if ( !isid( i ) ) ! 908: goto endid; ! 909: tmac1( i, b5 ); ! 910: tmac2( c, i, 4 ); ! 911: c = *p++; ! 912: if ( !isid( c ) ) ! 913: goto endid; ! 914: tmac1( c, b6 ); ! 915: tmac2( i, c, 5 ); ! 916: i = *p++; ! 917: if ( !isid( i ) ) ! 918: goto endid; ! 919: tmac1( i, b7 ); ! 920: tmac2( c, i, 6 ); ! 921: tmac2( i, 0, 7 ); ! 922: while ( isid( *p++ ) ) ! 923: ; ! 924: if ( eob( --p ) ) ! 925: { ! 926: refill( p ); ! 927: p = inp + 1; ! 928: continue; ! 929: } ! 930: goto lokid; ! 931: endid: ! 932: if ( eob( --p ) ) ! 933: { ! 934: refill( p ); ! 935: p = inp + 1; ! 936: continue; ! 937: } ! 938: tmac2( p[-1], 0, -1 + ( p - inp ) ); ! 939: lokid: ! 940: slookup( inp, p, 0 ); ! 941: if ( newp ) ! 942: { ! 943: p = newp; ! 944: goto again; ! 945: } ! 946: else ! 947: break; ! 948: nomac: ! 949: while ( isid( *p++ ) ) ! 950: ; ! 951: if ( eob( --p ) ) ! 952: { ! 953: p = refill( p ); ! 954: goto nomac; ! 955: } ! 956: else ! 957: break; ! 958: } ! 959: break; ! 960: } /* end of switch */ ! 961: ! 962: if ( isslo ) ! 963: return( p ); ! 964: } /* end of infinite loop */ ! 965: } ! 966: ! 967: char * ! 968: skipbl( p ) /* get next non-blank token */ ! 969: register char *p; ! 970: { ! 971: do ! 972: { ! 973: outp = inp = p; ! 974: p = cotoken( p ); ! 975: } ! 976: while ( ( toktyp + COFF )[*inp] == BLANK ); ! 977: return( p ); ! 978: } ! 979: ! 980: char * ! 981: unfill( p ) ! 982: register char *p; ! 983: { ! 984: /* take <= BUFSIZ chars from right end of buffer and put ! 985: /* them on instack. slide rest of buffer to the right, ! 986: /* update pointers, return new p. ! 987: */ ! 988: register char *np, *op; ! 989: register int d; ! 990: ! 991: if ( mactop >= MAXFRE ) ! 992: { ! 993: pperror( "%s: too much pushback", macnam ); ! 994: p = inp = pend; /* begin flushing pushback */ ! 995: dump(); ! 996: while ( mactop > inctop[ifno] ) ! 997: { ! 998: (void) refill( p ); ! 999: p = inp = pend; ! 1000: dump(); ! 1001: } ! 1002: } ! 1003: if ( fretop > 0 ) ! 1004: np = bufstack[--fretop]; ! 1005: else ! 1006: { ! 1007: np = savch; ! 1008: savch += BUFSIZ; ! 1009: if ( savch >= sbf + SBSIZE ) ! 1010: { ! 1011: pperror( "no space" ); ! 1012: exit( exfail ? ( exfail == CLASSCODE ? CLASSCODE : 2 ) ! 1013: : 0 ); ! 1014: } ! 1015: *savch++ = '\0'; ! 1016: } ! 1017: instack[mactop] = np; ! 1018: op = pend - BUFSIZ; ! 1019: if ( op < p ) ! 1020: op = p; ! 1021: memcpy(np, op, pend - op); ! 1022: np += pend - op; ! 1023: *np++ = 0; ! 1024: endbuf[mactop++] = np; /* mark end of saved text */ ! 1025: np = pbuf + BUFSIZ; ! 1026: op = pend - BUFSIZ; ! 1027: pend = np; ! 1028: if ( op < p ) ! 1029: op = p; ! 1030: while ( outp < op ) /* slide over new */ ! 1031: *--np = *--op; ! 1032: if ( bob( np ) ) ! 1033: pperror( "token too long" ); ! 1034: d = np - outp; ! 1035: outp += d; ! 1036: inp += d; ! 1037: macdam += d; ! 1038: return( p + d ); ! 1039: } ! 1040: ! 1041: char * ! 1042: doincl( p ) ! 1043: register char *p; ! 1044: { ! 1045: int filok, inctype; ! 1046: register char *cp; ! 1047: char **dirp, *nfil; ! 1048: char filname[BUFSIZ]; ! 1049: ! 1050: p = skipbl( p ); ! 1051: cp = filname; ! 1052: if ( *inp++ == '<' ) /* special <> syntax */ ! 1053: { ! 1054: inctype = 1; ! 1055: ++flslvl; /* prevent macro expansion */ ! 1056: for ( ;; ) ! 1057: { ! 1058: outp = inp = p; ! 1059: p = cotoken( p ); ! 1060: if ( *inp == '\n' ) ! 1061: { ! 1062: --p; ! 1063: *cp = '\0'; ! 1064: break; ! 1065: } ! 1066: if ( *inp == '>' ) ! 1067: { ! 1068: *cp = '\0'; ! 1069: break; ! 1070: } ! 1071: # ifdef gimpel ! 1072: if ( *inp == '.' && !intss() ) ! 1073: *inp = '#'; ! 1074: # endif ! 1075: while ( inp < p ) ! 1076: *cp++ = *inp++; ! 1077: } ! 1078: --flslvl; /* reenable macro expansion */ ! 1079: } ! 1080: else if ( inp[-1] == '"' ) /* regular "" syntax */ ! 1081: { ! 1082: inctype = 0; ! 1083: # ifdef gimpel ! 1084: while ( inp < p ) ! 1085: { ! 1086: if ( *inp == '.' && !intss() ) ! 1087: *inp = '#'; ! 1088: *cp++ = *inp++; ! 1089: } ! 1090: # else ! 1091: while ( inp < p ) ! 1092: *cp++ = *inp++; ! 1093: # endif ! 1094: if ( *--cp == '"' ) ! 1095: *cp = '\0'; ! 1096: } ! 1097: else ! 1098: { ! 1099: int ppwarn(), pperror(); ! 1100: /* This is a warning if we're skipping, error if not. */ ! 1101: (*(flslvl ? ppwarn : pperror))( "bad include syntax", 0 ); ! 1102: inctype = 2; ! 1103: } ! 1104: /* flush current file to \n , then write \n */ ! 1105: ! 1106: p = chkend( p, 1 ); ! 1107: ! 1108: outp = inp = p; ! 1109: ! 1110: dump(); ! 1111: if ( inctype == 2 || flslvl != 0 ) ! 1112: return( p ); ! 1113: /* look for included file */ ! 1114: if ( ifno + 1 >= MAXNEST ) ! 1115: { ! 1116: pperror( "Unreasonable include nesting", 0 ); ! 1117: return( p ); ! 1118: } ! 1119: if ( ( nfil = savch ) > sbf + SBSIZE - BUFSIZ ) ! 1120: { ! 1121: pperror( "no space" ); ! 1122: exit( exfail ? ( exfail == CLASSCODE ? CLASSCODE : 2 ) : 0 ); ! 1123: } ! 1124: ! 1125: /* check for #include "/usr/include/..." */ ! 1126: if (strncmp(filname, "/usr/include/", 13) == 0) ! 1127: ppwarn("#include of /usr/include/... may be non-portable"); ! 1128: ! 1129: filok = 0; ! 1130: for ( dirp = dirs + inctype; *dirp; ++dirp ) ! 1131: { ! 1132: if ( ! 1133: # if gcos ! 1134: strchr( filname, '/' ) ! 1135: # else ! 1136: filname[0] == '/' ! 1137: # endif ! 1138: || **dirp == '\0' ) ! 1139: { ! 1140: strcpy( nfil, filname ); ! 1141: } ! 1142: else ! 1143: { ! 1144: strcpy( nfil, *dirp ); ! 1145: # if unix || gcos || DMERT ! 1146: strcat( nfil, "/" ); ! 1147: # endif ! 1148: #ifdef ibm ! 1149: # ifndef gimpel ! 1150: strcat( nfil, "." ); ! 1151: # endif ! 1152: #endif ! 1153: strcat( nfil, filname ); ! 1154: } ! 1155: if ( NULL != ( fins[ifno + 1] = fopen( nfil, READ ) ) ) ! 1156: { ! 1157: filok = 1; ! 1158: fin = fins[++ifno]; ! 1159: if ( print_incs ) ! 1160: fprintf( stderr, "%s\n", nfil ); ! 1161: break; ! 1162: } ! 1163: } ! 1164: if ( filok == 0 ) ! 1165: pperror( "Can't find include file %s", filname ); ! 1166: else ! 1167: { ! 1168: lineno[ifno] = 1; ! 1169: fnames[ifno] = cp = nfil; ! 1170: while ( *cp++) ! 1171: ; ! 1172: savch = cp; ! 1173: fdates[ifno] = getfdate( fin ); ! 1174: dirnams[ifno] = dirs[0] = trmdir( copy( nfil ) ); ! 1175: sayline(); ! 1176: #ifdef CXREF ! 1177: fprintf(outfp, "\"%s\"\n", fnames[ifno]); ! 1178: #endif ! 1179: /* save current contents of buffer */ ! 1180: while ( !eob( p ) ) ! 1181: p = unfill( p ); ! 1182: inctop[ifno] = mactop; ! 1183: } ! 1184: return( p ); ! 1185: } ! 1186: ! 1187: equfrm( a, p1, p2 ) ! 1188: register char *a, *p1, *p2; ! 1189: { ! 1190: register char c; ! 1191: int flag; ! 1192: ! 1193: c = *p2; ! 1194: *p2 = '\0'; ! 1195: flag = strcmp( a, p1 ); ! 1196: *p2 = c; ! 1197: return( flag == SAME ); ! 1198: } ! 1199: ! 1200: char * ! 1201: dodef( p ) /* process '#define' */ ! 1202: char *p; ! 1203: { ! 1204: register char *pin, *psav, *cf; ! 1205: char **pf, **qf; ! 1206: int b, c, params; ! 1207: int ex_blank; /* used to ignore extra blanks in token-string */ ! 1208: int sav_passcom = passcom; /* saved passcom, used to reset it */ ! 1209: struct symtab *np; ! 1210: char *oldval, *oldsavch; ! 1211: char *formal[MAXFRM]; /* formal[n] is name of nth formal */ ! 1212: char formtxt[BUFSIZ]; /* space for formal names */ ! 1213: ! 1214: if ( savch > sbf + SBSIZE - BUFSIZ ) ! 1215: { ! 1216: pperror( "too much defining" ); ! 1217: return( p ); ! 1218: } ! 1219: oldsavch = savch; /* to reclaim space if redefinition */ ! 1220: ++flslvl; /* prevent macro expansion during 'define' */ ! 1221: p = skipbl( p ); ! 1222: pin = inp; ! 1223: if ( ( toktyp + COFF )[*pin] != IDENT ) ! 1224: { ! 1225: if (*pin == '\n') --lineno[ifno]; ! 1226: ppwarn( "illegal/missing macro name" ); ! 1227: if (*pin == '\n') ++lineno[ifno]; ! 1228: while ( *inp != '\n' ) ! 1229: p = skipbl( p ); ! 1230: --flslvl; /* restore expansion */ ! 1231: return( p ); ! 1232: } ! 1233: np = slookup( pin, p, 1 ); ! 1234: if ( oldval = np->value ) /* was previously defined */ ! 1235: savch = oldsavch; ! 1236: #ifdef CXREF ! 1237: def(np->name, lineno[ifno]); ! 1238: #endif ! 1239: b = 1; ! 1240: cf = pin; ! 1241: while ( cf < p ) /* update macbit */ ! 1242: { ! 1243: c = *cf++; ! 1244: xmac1( c, b, |= ); ! 1245: b = ( b + b ) & 0xFF; ! 1246: if ( cf != p ) ! 1247: xmac2( c, *cf, -1 + ( cf - pin ), |= ); ! 1248: else ! 1249: xmac2( c, 0, -1 + ( cf - pin ), |= ); ! 1250: } ! 1251: params = 0; ! 1252: outp = inp = p; ! 1253: p = cotoken( p ); ! 1254: pin = inp; ! 1255: if ( *pin == '(' ) /* with parameters; identify the formals */ ! 1256: { ! 1257: #ifdef CXREF ! 1258: newf(np->name, lineno[ifno]); ! 1259: #endif ! 1260: cf = formtxt; ! 1261: pf = formal; ! 1262: for ( ;; ) ! 1263: { ! 1264: p = skipbl( p ); ! 1265: pin = inp; ! 1266: if ( *pin == '\n' ) ! 1267: { ! 1268: --lineno[ifno]; ! 1269: --p; ! 1270: pperror( "%s: missing )", np->name ); ! 1271: break; ! 1272: } ! 1273: if ( *pin == ')' ) ! 1274: break; ! 1275: if ( *pin == ',' ) ! 1276: continue; ! 1277: if ( ( toktyp + COFF )[*pin] != IDENT ) ! 1278: { ! 1279: c = *p; ! 1280: *p = '\0'; ! 1281: pperror( "bad formal: %s", pin ); ! 1282: *p = c; ! 1283: } ! 1284: else if ( pf >= &formal[MAXFRM] ) ! 1285: { ! 1286: c = *p; ! 1287: *p = '\0'; ! 1288: pperror( "too many formals: %s", pin ); ! 1289: *p = c; ! 1290: } ! 1291: else ! 1292: { ! 1293: *pf++ = cf; ! 1294: while ( pin < p ) ! 1295: *cf++ = *pin++; ! 1296: *cf++ = '\0'; ! 1297: ++params; ! 1298: #ifdef CXREF ! 1299: def(*(pf-1), lineno[ifno]); ! 1300: #endif ! 1301: } ! 1302: } ! 1303: if ( params == 0 ) /* #define foo() ... */ ! 1304: --params; ! 1305: } ! 1306: else if ( *pin == '\n' ) ! 1307: { ! 1308: --lineno[ifno]; ! 1309: --p; ! 1310: } ! 1311: else ! 1312: p = inp; /* back up to scan non-blank next token */ ! 1313: /* ! 1314: * remember beginning of macro body, so that we can ! 1315: * warn if a redefinition is different from old value. ! 1316: */ ! 1317: oldsavch = psav = savch; ! 1318: passcom = 1; /* make cotoken() return comments as tokens */ ! 1319: ex_blank = 1; /* must have some delimiter - might as well be blank */ ! 1320: for ( ;; ) /* accumulate definition until linefeed */ ! 1321: { ! 1322: outp = inp = p; ! 1323: p = cotoken( p ); ! 1324: pin = inp; ! 1325: if ( *pin == '\\' && pin[1] == '\n' ) /* ignore escaped lf */ ! 1326: { ! 1327: if ( !ex_blank ) /* replace it with a blank */ ! 1328: { ! 1329: *psav++ = ' '; ! 1330: ex_blank = 1; ! 1331: } ! 1332: putc( '\n', fout ); ! 1333: continue; ! 1334: } ! 1335: if ( *pin == '\n' ) ! 1336: break; ! 1337: if ( ( toktyp + COFF )[*pin] == BLANK ) /* skip extra blanks */ ! 1338: { ! 1339: if ( ex_blank ) ! 1340: continue; ! 1341: *pin = ' '; /* force it to be a "real" blank */ ! 1342: ex_blank = 1; ! 1343: } ! 1344: else ! 1345: ex_blank = 0; ! 1346: if ( *pin == '/' && pin[1] == '*' ) /* skip comment */ ! 1347: { /* except for \n's */ ! 1348: while ( pin < p ) ! 1349: if ( *pin++ == '\n' ) ! 1350: putc( '\n', fout ); ! 1351: continue; ! 1352: } ! 1353: if ( params ) /* mark the appearance of formals in the definiton */ ! 1354: { ! 1355: if ( ( toktyp + COFF )[*pin] == IDENT ) ! 1356: { ! 1357: for ( qf = pf; --qf >= formal; ) ! 1358: { ! 1359: if ( equfrm( *qf, pin, p ) ) ! 1360: { ! 1361: #ifdef CXREF ! 1362: #ifndef NO_MACRO_FORMAL ! 1363: ref(*qf, lineno[ifno]); ! 1364: #endif ! 1365: #endif ! 1366: *psav++ = qf - formal + 1; ! 1367: *psav++ = WARN; ! 1368: pin = p; ! 1369: break; ! 1370: } ! 1371: } ! 1372: } ! 1373: /* inside quotation marks, too */ ! 1374: else if ( *pin == '"' || *pin == '\'' ! 1375: # if gcos ! 1376: || *pin == '`' ! 1377: # endif ! 1378: ) ! 1379: { ! 1380: char quoc = *pin; ! 1381: ! 1382: for ( *psav++ = *pin++; pin < p && *pin != quoc; ) ! 1383: { ! 1384: while ( pin < p && !isid( *pin ) ) ! 1385: { ! 1386: if ( *pin == '\n' ! 1387: && pin[-1] == '\\' ) ! 1388: { ! 1389: putc( '\n', fout ); ! 1390: psav--; /* no \ */ ! 1391: pin++; /* no \n */ ! 1392: } ! 1393: else ! 1394: *psav++ = *pin++; ! 1395: } ! 1396: cf = pin; ! 1397: while ( cf < p && isid( *cf ) ) ! 1398: ++cf; ! 1399: for ( qf = pf; --qf >= formal; ) ! 1400: { ! 1401: if ( equfrm( *qf, pin, cf ) ) ! 1402: { ! 1403: *psav++ = qf - formal + 1; ! 1404: *psav++ = WARN; ! 1405: pin = cf; ! 1406: break; ! 1407: } ! 1408: } ! 1409: while ( pin < cf ) ! 1410: *psav++ = *pin++; ! 1411: } ! 1412: } ! 1413: } ! 1414: while ( pin < p ) ! 1415: if ( *pin == '\n' && pin[-1] == '\\' ) ! 1416: { ! 1417: putc( '\n', fout ); ! 1418: psav--; /* no \ */ ! 1419: pin++; /* no \n */ ! 1420: } ! 1421: else ! 1422: *psav++ = *pin++; ! 1423: } ! 1424: passcom = sav_passcom; /* restore to "real" value */ ! 1425: if ( psav[-1] == ' ' ) /* if token-string ended with a blank */ ! 1426: psav--; /* then it is unnecessary - throw away */ ! 1427: *psav++ = params; ! 1428: *psav++ = '\0'; ! 1429: if ( ( cf = oldval ) != NULL ) /* redefinition */ ! 1430: { ! 1431: --cf; /* skip no. of params, which may be zero */ ! 1432: while ( *--cf ) /* go back to the beginning */ ! 1433: ; ! 1434: if ( 0 != strcmp( ++cf, oldsavch ) ) /* redefinition different from old */ ! 1435: { ! 1436: --lineno[ifno]; ! 1437: ppwarn( "%s redefined", np->name ); ! 1438: ++lineno[ifno]; ! 1439: np->value = psav - 1; ! 1440: } ! 1441: else ! 1442: psav = oldsavch; /* identical redef.; reclaim space */ ! 1443: } ! 1444: else ! 1445: np->value = psav - 1; ! 1446: --flslvl; ! 1447: inp = pin; ! 1448: savch = psav; ! 1449: return( p ); ! 1450: } ! 1451: ! 1452: #define fasscan() ptrtab = fastab + COFF ! 1453: #define sloscan() ptrtab = slotab + COFF ! 1454: /* this macro manages the lookup of a macro name and produces ! 1455: ** a warning if the name is missing ! 1456: */ ! 1457: #define LOOKUP(skipblank, flag) \ ! 1458: ++flslvl; if (skipblank) p = skipbl(p); \ ! 1459: if ( ( toktyp + COFF )[*inp] != IDENT ) \ ! 1460: { \ ! 1461: if (*inp == '\n') --lineno[ifno];\ ! 1462: ppwarn( "illegal/missing macro name" ); \ ! 1463: if (*inp == '\n') ++lineno[ifno];\ ! 1464: while ( *inp != '\n' ) \ ! 1465: p = skipbl( p ); \ ! 1466: --flslvl; \ ! 1467: continue; \ ! 1468: } \ ! 1469: np = slookup(inp,p,flag); --flslvl ! 1470: ! 1471: control( p ) /* find and handle preprocessor control lines */ ! 1472: register char *p; ! 1473: { ! 1474: register struct symtab *np; ! 1475: ! 1476: for ( ;; ) ! 1477: { ! 1478: fasscan(); ! 1479: p = cotoken( p ); ! 1480: if ( *inp == '\n' ) ! 1481: ++inp; ! 1482: dump(); ! 1483: sloscan(); ! 1484: p = skipbl( p ); ! 1485: *--inp = SALT; ! 1486: outp = inp; ! 1487: ++flslvl; ! 1488: np = slookup( inp, p, 0 ); ! 1489: --flslvl; ! 1490: if ( np == defloc ) /* define */ ! 1491: { ! 1492: if ( flslvl == 0 ) ! 1493: { ! 1494: p = dodef( p ); ! 1495: continue; ! 1496: } ! 1497: } ! 1498: else if ( np == incloc ) /* include */ ! 1499: { ! 1500: p = doincl( p ); ! 1501: continue; ! 1502: } ! 1503: else if ( np == ifnloc ) /* ifndef */ ! 1504: { ! 1505: LOOKUP(1/*skipbl*/, 0/*flag*/); /* sets "np" */ ! 1506: if ( flslvl == 0 && np->value == 0 ) ! 1507: ++trulvl; ! 1508: else ! 1509: ++flslvl; ! 1510: if ( trulvl + flslvl >= MAX_DEPTH ) ! 1511: pperror( "#if,ifdef,ifndef nesting too deep" ); ! 1512: else ! 1513: ifelstk[trulvl + flslvl] = ! 1514: flslvl ? 0 : TRUE_ELIF; ! 1515: #ifdef CXREF ! 1516: ref(xcopy(inp, p), lineno[ifno]); ! 1517: #endif ! 1518: p = chkend( p, 1 ); ! 1519: } ! 1520: else if ( np == ifdloc ) /* ifdef */ ! 1521: { ! 1522: LOOKUP(1/*skipbl*/, 0/*flag*/); /* sets "np" */ ! 1523: if ( flslvl == 0 && np->value != 0 ) ! 1524: ++trulvl; ! 1525: else ! 1526: ++flslvl; ! 1527: if ( trulvl + flslvl >= MAX_DEPTH ) ! 1528: pperror( "#if,ifdef,ifndef nesting too deep" ); ! 1529: else ! 1530: ifelstk[trulvl + flslvl] = ! 1531: flslvl ? 0 : TRUE_ELIF; ! 1532: #ifdef CXREF ! 1533: ref(xcopy(inp, p), lineno[ifno]); ! 1534: #endif ! 1535: p = chkend( p, 1 ); ! 1536: } ! 1537: else if ( np == eifloc ) /* endif */ ! 1538: { ! 1539: if ( flslvl ) ! 1540: { ! 1541: if ( --flslvl == 0 ) ! 1542: sayline(); ! 1543: } ! 1544: else if ( trulvl ) ! 1545: --trulvl; ! 1546: else ! 1547: pperror( "If-less endif", 0 ); ! 1548: p = chkend( p, 2 ); /* research mod; summit uses 1 */ ! 1549: } ! 1550: else if ( np == elifloc ) /* elif */ ! 1551: { ! 1552: if ( ifelstk[trulvl + flslvl] & SEEN_ELSE ) ! 1553: pperror( "#elif following #else", 0 ); ! 1554: if ( flslvl ) ! 1555: { ! 1556: if ( --flslvl != 0 ) ! 1557: ++flslvl; ! 1558: else ! 1559: { ! 1560: newp = p; ! 1561: #ifdef CXREF ! 1562: xline = lineno[ifno]; ! 1563: #endif ! 1564: if ( ifelstk[trulvl + flslvl + 1] == 0 ! 1565: && yyparse() ) ! 1566: { ! 1567: ++trulvl; ! 1568: ifelstk[trulvl + flslvl] = ! 1569: TRUE_ELIF; ! 1570: sayline(); ! 1571: } ! 1572: else ! 1573: ++flslvl; ! 1574: p = newp; ! 1575: } ! 1576: } ! 1577: else if ( trulvl ) ! 1578: { ! 1579: ++flslvl; ! 1580: --trulvl; ! 1581: } ! 1582: else ! 1583: pperror( "If-less elif", 0 ); ! 1584: } ! 1585: else if ( np == elsloc ) /* else */ ! 1586: { ! 1587: if ( ifelstk[trulvl + flslvl] & SEEN_ELSE ) ! 1588: pperror( "too many #else's", 0 ); ! 1589: if ( flslvl ) ! 1590: { ! 1591: if ( --flslvl != 0 ) ! 1592: ++flslvl; ! 1593: else if ( ifelstk[trulvl + flslvl + 1] == 0 ) ! 1594: { ! 1595: ++trulvl; ! 1596: sayline(); ! 1597: } ! 1598: else ! 1599: ++flslvl; ! 1600: } ! 1601: else if ( trulvl ) ! 1602: { ! 1603: ++flslvl; ! 1604: --trulvl; ! 1605: } ! 1606: else ! 1607: pperror( "If-less else", 0 ); ! 1608: ifelstk[trulvl + flslvl] |= SEEN_ELSE; ! 1609: p = chkend( p, 1 ); ! 1610: } ! 1611: else if ( np == udfloc ) /* undefine */ ! 1612: { ! 1613: if ( flslvl == 0 ) ! 1614: { ! 1615: LOOKUP(1/*skipbl*/, DROP); /* sets "np" */ ! 1616: p = chkend( p, 1 ); ! 1617: } ! 1618: else ! 1619: p = chkend( p, 2 ); ! 1620: #ifdef CXREF ! 1621: ref(xcopy(inp, p), lineno[ifno]); ! 1622: #endif ! 1623: } ! 1624: else if ( np == ifloc ) /* if */ ! 1625: { ! 1626: #if tgp ! 1627: pperror( " IF not implemented, true assumed", 0 ); ! 1628: if ( flslvl == 0 ) ! 1629: ++trulvl; ! 1630: else ! 1631: ++flslvl; ! 1632: #else ! 1633: newp = p; ! 1634: #ifdef CXREF ! 1635: xline = lineno[ifno]; ! 1636: #endif ! 1637: if ( flslvl == 0 && yyparse() ) ! 1638: ++trulvl; ! 1639: else ! 1640: ++flslvl; ! 1641: p = newp; ! 1642: if ( trulvl + flslvl >= MAX_DEPTH ) ! 1643: pperror( "#if,ifdef,ifndef nesting too deep" ); ! 1644: else ! 1645: ifelstk[trulvl + flslvl] = ! 1646: flslvl ? 0 : TRUE_ELIF; ! 1647: #endif ! 1648: } ! 1649: else if ( np == lneloc ) /* line */ ! 1650: { ! 1651: if ( flslvl == 0 && pflag == 0 ) ! 1652: { ! 1653: register char *s; ! 1654: register int ln; ! 1655: ! 1656: outp = inp = p; ! 1657: do_line: ! 1658: *--outp = '#'; ! 1659: /* ! 1660: * make sure that the whole ! 1661: * directive has been read ! 1662: */ ! 1663: s = p; ! 1664: while ( *s && *s != '\n' ) ! 1665: s++; ! 1666: if ( eob( s ) ) ! 1667: p = refill( s ); ! 1668: /* ! 1669: * eat the line number ! 1670: */ ! 1671: s = inp; ! 1672: while ( ( toktyp + COFF )[*s] == BLANK ) ! 1673: s++; ! 1674: ln = 0; ! 1675: while ( isdigit( *s ) ) ! 1676: ln = ln * 10 + *s++ - '0'; ! 1677: if ( ln ) ! 1678: lineno[ifno] = ln - 1; ! 1679: else ! 1680: pperror( "bad number for #line" ); ! 1681: /* ! 1682: * eat the optional "filename" ! 1683: */ ! 1684: while ( ( toktyp + COFF )[*s] == BLANK ) ! 1685: s++; ! 1686: if ( *s != '\n' ) ! 1687: { ! 1688: if ( *s != '"' ) ! 1689: pperror( "bad file for #line" ); ! 1690: else ! 1691: { ! 1692: register char *t = savch; ! 1693: ! 1694: for ( ;; ) ! 1695: { ! 1696: if ( *++s == '"' ) ! 1697: break; ! 1698: else if ( *s == '\n' || ! 1699: *s == '\0' ) ! 1700: { ! 1701: pperror( "bad file for #line" ); ! 1702: break; ! 1703: } ! 1704: *t++ = *s; ! 1705: } ! 1706: *t++ = '\0'; ! 1707: if ( strcmp( savch, fnames[ifno] ) ) ! 1708: { ! 1709: fnames[ifno] = savch; ! 1710: fdates[ifno] = findfdate( &fnames[ifno] ); ! 1711: savch = t; ! 1712: } ! 1713: } ! 1714: } ! 1715: /* ! 1716: * push it all along to be eventually printed ! 1717: */ ! 1718: while ( *inp != '\n' ) ! 1719: p = cotoken( p ); ! 1720: continue; ! 1721: } ! 1722: } ! 1723: else if ( np == clsloc ) /* class */ ! 1724: exfail = CLASSCODE; /* return value */ ! 1725: else if ( np == idtloc ) /* ident */ ! 1726: { ! 1727: if ( pflag == 0 ) ! 1728: while ( *inp != '\n' ) /* just pass it along */ ! 1729: p = cotoken( p ); ! 1730: } ! 1731: #ifdef PRAGMA ! 1732: else if ( np == pragmaloc ) { /* pragma */ ! 1733: while ( *inp != '\n' ) /* pass it all along */ ! 1734: p = cotoken( p ); ! 1735: } ! 1736: #endif ! 1737: else if ( *++inp == '\n' ) /* allows blank line after # */ ! 1738: outp = inp; ! 1739: else if ( isdigit( *inp ) ) /* pass thru line directives */ ! 1740: { ! 1741: outp = p = inp; ! 1742: goto do_line; ! 1743: } ! 1744: else ! 1745: pperror( "undefined control", 0 ); ! 1746: /* flush to lf */ ! 1747: ++flslvl; ! 1748: while ( *inp != '\n' ) ! 1749: { ! 1750: outp = inp = p; ! 1751: p = cotoken( p ); ! 1752: } ! 1753: --flslvl; ! 1754: } ! 1755: } ! 1756: ! 1757: struct symtab * ! 1758: stsym( s ) ! 1759: register char *s; ! 1760: { ! 1761: char buf[BUFSIZ]; ! 1762: register char *p; ! 1763: ! 1764: /* make definition look exactly like end of #define line */ ! 1765: /* copy to avoid running off end of world when param list is at end */ ! 1766: p = buf; ! 1767: while ( *p++ = *s++ ) ! 1768: ; ! 1769: p = buf; ! 1770: while ( isid( *p++ ) ) /* skip first identifier */ ! 1771: ; ! 1772: if ( *--p == '=' ) ! 1773: { ! 1774: *p++ = ' '; ! 1775: while ( *p++ ) ! 1776: ; ! 1777: } ! 1778: else ! 1779: { ! 1780: s = " 1"; ! 1781: while ( *p++ = *s++ ) ! 1782: ; ! 1783: } ! 1784: pend = p; ! 1785: *--p = '\n'; ! 1786: sloscan(); ! 1787: dodef( buf ); ! 1788: return( lastsym ); ! 1789: } ! 1790: ! 1791: struct symtab * ! 1792: ppsym( s ) /* kludge */ ! 1793: char *s; ! 1794: { ! 1795: register struct symtab *sp; ! 1796: ! 1797: cinit = SALT; ! 1798: *savch++ = SALT; ! 1799: sp = stsym( s ); ! 1800: --sp->name; ! 1801: cinit = 0; ! 1802: return( sp ); ! 1803: } ! 1804: ! 1805: ! 1806: int yy_errflag; /* TRUE when pperror called by yyerror() */ ! 1807: ! 1808: /* VARARGS1 */ ! 1809: pperror( s, x, y ) ! 1810: char *s; ! 1811: { ! 1812: if ( fnames[ifno][0] ) ! 1813: # if gcos ! 1814: fprintf( stderr, ERRFORM, exfail >= 0 ? 'F' : 'W',fnames[ifno]); ! 1815: # else ! 1816: fprintf( stderr, "%s: ", fnames[ifno] ); ! 1817: # endif ! 1818: fprintf( stderr, "%d: ", lineno[ifno] ); ! 1819: fprintf( stderr, s, x, y ); ! 1820: if ( yy_errflag ) ! 1821: fprintf( stderr, " (in preprocessor if)\n" ); ! 1822: else ! 1823: fprintf( stderr, "\n" ); ! 1824: if ( exfail < CLASSCODE - 1 ) ! 1825: ++exfail; ! 1826: } ! 1827: ! 1828: yyerror( s, a, b ) ! 1829: char *s; ! 1830: { ! 1831: yy_errflag = 1; ! 1832: pperror( s, a, b ); ! 1833: yy_errflag = 0; ! 1834: } ! 1835: ! 1836: ppwarn( s, x ) ! 1837: char *s; ! 1838: { ! 1839: int fail = exfail; ! 1840: ! 1841: exfail = -1; ! 1842: pperror( s, x ); ! 1843: exfail = fail; ! 1844: } ! 1845: ! 1846: struct symtab * ! 1847: lookup( namep, enterf ) ! 1848: char *namep; ! 1849: { ! 1850: register char *np, *snp; ! 1851: register int c, i; ! 1852: int around; ! 1853: register struct symtab *sp; ! 1854: ! 1855: /* namep had better not be too long (currently, <=ncps chars) */ ! 1856: np = namep; ! 1857: around = 0; ! 1858: i = cinit; ! 1859: while ( c = *np++ ) ! 1860: i += i + c; ! 1861: c = i; /* c=i for register usage on pdp11 */ ! 1862: c %= symsiz; ! 1863: if ( c < 0 ) ! 1864: c += symsiz; ! 1865: sp = &stab[c]; ! 1866: while ( snp = sp->name ) ! 1867: { ! 1868: np = namep; ! 1869: while ( *snp++ == *np ) ! 1870: if ( *np++ == '\0' ) ! 1871: { ! 1872: if ( enterf == DROP ) ! 1873: { ! 1874: sp->name[0] = DROP; ! 1875: sp->value = 0; ! 1876: } ! 1877: return( lastsym = sp ); ! 1878: } ! 1879: if ( --sp < &stab[0] ) ! 1880: if ( around ) ! 1881: { ! 1882: pperror( "too many defines", 0 ); ! 1883: exit( exfail ? ( exfail == ! 1884: CLASSCODE ? CLASSCODE : 2 ) : 0 ); ! 1885: } ! 1886: else ! 1887: { ! 1888: ++around; ! 1889: sp = &stab[symsiz - 1]; ! 1890: } ! 1891: } ! 1892: if ( enterf == 1 ) ! 1893: sp->name = namep; ! 1894: return( lastsym = sp ); ! 1895: } ! 1896: ! 1897: struct symtab * ! 1898: slookup( p1, p2, enterf ) ! 1899: register char *p1, *p2; ! 1900: int enterf; ! 1901: { ! 1902: register char *p3; ! 1903: char c2, c3; ! 1904: struct symtab *np; ! 1905: ! 1906: c2 = *p2; /* mark end of token */ ! 1907: *p2 ='\0'; ! 1908: if ( ( p2 - p1 ) > ncps ) ! 1909: p3 = p1 + ncps; ! 1910: else ! 1911: p3 = p2; ! 1912: c3 = *p3; /* truncate to ncps chars or less */ ! 1913: *p3 ='\0'; ! 1914: if ( enterf == 1 ) ! 1915: p1 = copy( p1 ); ! 1916: np = lookup( p1, enterf ); ! 1917: *p3 = c3; ! 1918: *p2 = c2; ! 1919: if ( np->value != 0 && flslvl == 0 ) ! 1920: newp = subst( p2, np ); ! 1921: else ! 1922: newp = 0; ! 1923: return( np ); ! 1924: } ! 1925: ! 1926: char * ! 1927: subst( p, sp ) ! 1928: register char *p; ! 1929: struct symtab *sp; ! 1930: { ! 1931: static char match[] = "%s: argument mismatch"; ! 1932: register char *ca, *vp; ! 1933: int params; ! 1934: char *actual[MAXFRM]; /* actual[n] is text of nth actual */ ! 1935: char acttxt[BUFSIZ]; /* space for actuals */ ! 1936: ! 1937: if ( 0 == ( vp = sp->value ) ) ! 1938: return( p ); ! 1939: if ( ( p - macforw ) <= macdam ) ! 1940: { ! 1941: if ( ++maclvl > symsiz && !rflag ) ! 1942: { ! 1943: pperror( "%s: macro recursion", sp->name ); ! 1944: return( p ); ! 1945: } ! 1946: } ! 1947: else ! 1948: maclvl = 0; /* level decreased */ ! 1949: macforw = p; /* new target for decrease in level */ ! 1950: macdam = 0; ! 1951: macnam = sp->name; ! 1952: #ifdef CXREF ! 1953: ref(macnam, lineno[ifno]); ! 1954: #endif ! 1955: dump(); ! 1956: if ( sp == ulnloc ) ! 1957: { ! 1958: vp = acttxt; ! 1959: *vp++ = '\0'; ! 1960: sprintf( vp, "%d", lineno[ifno] ); ! 1961: while ( *vp++ ) ! 1962: ; ! 1963: } ! 1964: else if ( sp == uflloc ) ! 1965: { ! 1966: vp = acttxt; ! 1967: *vp++ = '\0'; ! 1968: sprintf( vp, "\"%s\"", fnames[ifno] ); ! 1969: while ( *vp++ ) ! 1970: ; ! 1971: } ! 1972: if ( 0 != ( params = *--vp & 0xFF ) ) /*definition calls for params */ ! 1973: { ! 1974: register char **pa; ! 1975: int dparams; /* parameters in definition */ ! 1976: ! 1977: ca = acttxt; ! 1978: pa = actual; ! 1979: if ( params == 0xFF ) /* #define foo() ... */ ! 1980: params = 0; ! 1981: dparams = params; ! 1982: sloscan(); ! 1983: ++flslvl; /* no expansion during search for actuals */ ! 1984: plvl = -1; ! 1985: maclin = lineno[ifno]; ! 1986: macfil = fnames[ifno]; ! 1987: do ! 1988: { ! 1989: p = skipbl( p ); ! 1990: } ! 1991: while ( *inp == '\n' ); /* skip \n too */ ! 1992: if ( *inp == '(' ) ! 1993: { ! 1994: for ( plvl = 1; plvl != 0; ) ! 1995: { ! 1996: *ca++ = '\0'; ! 1997: for ( ;; ) ! 1998: { ! 1999: outp = inp = p; ! 2000: p = cotoken( p ); ! 2001: if ( *inp == '(' ) ! 2002: ++plvl; ! 2003: if ( *inp == ')' && --plvl == 0 ) ! 2004: { ! 2005: if ( ca > acttxt+1 ) ! 2006: --params; ! 2007: break; ! 2008: } ! 2009: if ( plvl == 1 && *inp == ',' ) ! 2010: { ! 2011: --params; ! 2012: break; ! 2013: } ! 2014: while ( inp < p ) ! 2015: { ! 2016: /* ! 2017: * toss newlines in arguments ! 2018: * to macros - keep problems ! 2019: * to a minimum. ! 2020: * if a backslash is just ! 2021: * before the newline, assume ! 2022: * it is in a string and ! 2023: * leave it in. ! 2024: */ ! 2025: if ( *inp == '\n' ! 2026: && inp[-1] != '\\' ) ! 2027: { ! 2028: *inp = ' '; ! 2029: } ! 2030: *ca++ = *inp++; ! 2031: } ! 2032: if ( ca > &acttxt[BUFSIZ] ) ! 2033: pperror( "%s: actuals too long", sp->name ); ! 2034: } ! 2035: if ( pa >= &actual[MAXFRM] ) ! 2036: ppwarn( match, sp->name ); ! 2037: else ! 2038: *pa++ = ca; ! 2039: } ! 2040: } ! 2041: else { /* should have seen (, because def ! 2042: ** had args ! 2043: */ ! 2044: ppwarn( match, sp->name ); ! 2045: p = inp; /* back up to current token */ ! 2046: } ! 2047: if ( maclin != lineno[ifno] ) /* embedded linefeeds in macro call */ ! 2048: { ! 2049: int i, j = lineno[ifno]; ! 2050: ! 2051: for ( i = sizeof( int ) / sizeof( char ); --i >= 0; ) ! 2052: { ! 2053: if ( bob( p ) ) ! 2054: { ! 2055: outp = inp = p; ! 2056: p = unfill( p ); ! 2057: } ! 2058: *--p = j; ! 2059: j >>= 8; ! 2060: } ! 2061: if ( bob( p ) ) ! 2062: { ! 2063: outp = inp = p; ! 2064: p = unfill( p ); ! 2065: } ! 2066: *--p = warnc; ! 2067: } ! 2068: /* def with one arg and use with zero args is special ok case */ ! 2069: if ( params < 0 || (params > 0 && dparams != 1) ) ! 2070: ppwarn( match, sp->name ); ! 2071: while ( --params >= 0 ) ! 2072: *pa++ = "" + 1; /* null string for missing actuals */ ! 2073: --flslvl; ! 2074: fasscan(); ! 2075: } ! 2076: for ( ;; ) /* push definition onto front of input stack */ ! 2077: { ! 2078: while ( !iswarn( *--vp ) ) ! 2079: { ! 2080: if ( bob( p ) ) ! 2081: { ! 2082: outp = inp = p; ! 2083: p = unfill( p ); ! 2084: } ! 2085: *--p = *vp; ! 2086: } ! 2087: if ( *vp == warnc ) /* insert actual param */ ! 2088: { ! 2089: ca = actual[*--vp - 1]; ! 2090: while ( *--ca ) ! 2091: { ! 2092: if ( bob( p ) ) ! 2093: { ! 2094: outp = inp = p; ! 2095: p = unfill( p ); ! 2096: } ! 2097: *--p = *ca; ! 2098: } ! 2099: } ! 2100: else ! 2101: break; ! 2102: } ! 2103: outp = inp = p; ! 2104: return( p ); ! 2105: } ! 2106: ! 2107: ! 2108: ! 2109: ! 2110: char * ! 2111: trmdir( s ) ! 2112: register char *s; ! 2113: { ! 2114: register char *p = s; ! 2115: ! 2116: while ( *p++ ) ! 2117: ; ! 2118: --p; ! 2119: while ( p > s && *--p != '/' ) ! 2120: ; ! 2121: # if unix || DMERT ! 2122: if ( p == s ) ! 2123: *p++ = '.'; ! 2124: # endif ! 2125: *p = '\0'; ! 2126: return( s ); ! 2127: } ! 2128: ! 2129: STATIC char * ! 2130: copy( s ) ! 2131: register char *s; ! 2132: { ! 2133: register char *old; ! 2134: ! 2135: old = savch; ! 2136: while ( *savch++ = *s++ ) ! 2137: ; ! 2138: return( old ); ! 2139: } ! 2140: ! 2141: yywrap() ! 2142: { ! 2143: return( 1 ); ! 2144: } ! 2145: ! 2146: main( argc, argv ) ! 2147: char *argv[]; ! 2148: { ! 2149: register int i, c; ! 2150: register char *p; ! 2151: char *tf, **cp2; ! 2152: int forclass = 0; /* 1 if C-with-classes selected */ ! 2153: ! 2154: # if gcos ! 2155: if ( setjmp( env ) ) ! 2156: return( exfail ? ( exfail == CLASSCODE ? CLASSCODE : 2 ) : 0 ); ! 2157: # endif ! 2158: p = "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; ! 2159: i = 0; ! 2160: while ( c = *p++ ) ! 2161: { ! 2162: ( fastab + COFF )[c] |= IB | NB | SB; ! 2163: ( toktyp + COFF )[c] = IDENT; ! 2164: #if scw2 ! 2165: /* 53 == 63-10; digits rarely appear in identifiers, ! 2166: /* and can never be the first char of an identifier. ! 2167: /* 11 == 53*53/sizeof(macbit) . ! 2168: */ ! 2169: ++i; ! 2170: ( t21 + COFF )[c] = ( 53 * i ) / 11; ! 2171: ( t22 + COFF )[c] = i % 11; ! 2172: #endif ! 2173: } ! 2174: p = "0123456789."; ! 2175: while ( c = *p++ ) ! 2176: { ! 2177: ( fastab + COFF )[c] |= NB | SB; ! 2178: ( toktyp + COFF )[c] = NUMBR; ! 2179: } ! 2180: # if gcos ! 2181: p = "\n\"'`/\\"; ! 2182: # else ! 2183: p = "\n\"'/\\"; ! 2184: # endif ! 2185: while ( c = *p++ ) ! 2186: ( fastab + COFF )[c] |= SB; ! 2187: # if gcos ! 2188: p = "\n\"'`\\"; ! 2189: # else ! 2190: p = "\n\"'\\"; ! 2191: # endif ! 2192: while ( c = *p++ ) ! 2193: ( fastab + COFF )[c] |= QB; ! 2194: p = "*\n"; ! 2195: while ( c = *p++ ) ! 2196: ( fastab + COFF)[c] |= CB; ! 2197: ( fastab + COFF )[warnc] |= WB | SB; ! 2198: ( fastab + COFF )['\0'] |= CB | QB | SB | WB; ! 2199: for ( i = ALFSIZ; --i >= 0; ) ! 2200: slotab[i] = fastab[i] | SB; ! 2201: p = " \t\v\f\r"; /* note no \n; */ ! 2202: while ( c = *p++ ) ! 2203: ( toktyp + COFF )[c] = BLANK; ! 2204: #if scw2 ! 2205: for ( ( t23 + COFF )[i = ALFSIZ + 7 - COFF] = 1; --i >= -COFF; ) ! 2206: if ( ( ( t23 + COFF )[i] = ( t23 + COFF + 1 )[i] << 1 ) == 0 ) ! 2207: ( t23 + COFF )[i] = 1; ! 2208: #endif ! 2209: ! 2210: # if unix || DMERT ! 2211: fnames[ifno = 0] = ""; ! 2212: fdates[ifno = 0] = ""; ! 2213: dirnams[0] = dirs[0] = "."; ! 2214: # endif ! 2215: # if ibm ! 2216: fnames[ifno = 0] = ""; ! 2217: fdates[ifno = 0] = ""; ! 2218: # endif ! 2219: # if gcos ! 2220: if ( inquire( stdin, _TTY ) ) ! 2221: freopen( "*src", "rt", stdin ); ! 2222: # endif ! 2223: # if gimpel || gcos ! 2224: fnames[ifno = 0] = (char *) inquire( stdin, _FILENAME ); ! 2225: dirnams[0] = dirs[0] = trmdir( copy( fnames[0] ) ); ! 2226: # endif ! 2227: for ( i = 1; i < argc; i++ ) ! 2228: { ! 2229: switch ( argv[i][0] ) ! 2230: { ! 2231: case '-': ! 2232: # if gcos ! 2233: /* case-independent on GCOS */ ! 2234: switch ( toupper( argv[i][1] ) ) ! 2235: # else ! 2236: switch( argv[i][1] ) ! 2237: # endif ! 2238: { ! 2239: case 'M': /* research: filename+moddate*/ ! 2240: mflag++; ! 2241: continue; ! 2242: case 'P': ! 2243: pflag++; ! 2244: case 'E': ! 2245: continue; ! 2246: case 'R': ! 2247: ++rflag; ! 2248: continue; ! 2249: case 'C': ! 2250: passcom++; ! 2251: continue; ! 2252: #ifdef CXREF ! 2253: case 'F': ! 2254: if ((outfp = fopen(argv[++i],"w")) == NULL) ! 2255: { ! 2256: fprintf(stderr, "Can't open %s\n", ! 2257: argv[i]); ! 2258: exit(1); ! 2259: } ! 2260: continue; ! 2261: #endif ! 2262: case 'D': ! 2263: if ( predef > prespc + NPREDEF ) ! 2264: { ! 2265: pperror( "too many -D options, ignoring %s", argv[i] ); ! 2266: continue; ! 2267: } ! 2268: /* ignore plain "-D" (no argument) */ ! 2269: if ( *( argv[i] + 2 ) ) ! 2270: *predef++ = argv[i] + 2; ! 2271: continue; ! 2272: case 'U': ! 2273: if ( prund > punspc + NPREDEF ) ! 2274: { ! 2275: pperror( "too many -U options, ignoring %s", argv[i] ); ! 2276: continue; ! 2277: } ! 2278: *prund++ = argv[i] + 2; ! 2279: continue; ! 2280: case 'I': ! 2281: if ( nd > MAXINC - 4 ) ! 2282: pperror( "excessive -I file (%s) ignored", argv[i] ); ! 2283: else ! 2284: dirs[nd++] = argv[i] + 2; ! 2285: continue; ! 2286: case 'Y': ! 2287: dfltdir = argv[i] + 2; ! 2288: continue; ! 2289: case '\0': ! 2290: continue; ! 2291: case 'T': ! 2292: ncps = 8; /* backward name compatabilty */ ! 2293: continue; ! 2294: case 'H': /* print included filenames */ ! 2295: print_incs++; ! 2296: continue; ! 2297: case 'W': /* enable C with classes */ ! 2298: forclass = 1; ! 2299: continue; ! 2300: default: ! 2301: pperror( "unknown flag %s", argv[i] ); ! 2302: continue; ! 2303: } ! 2304: default: ! 2305: if ( fin == stdin ) ! 2306: { ! 2307: if ( NULL == ( fin = fopen( argv[i], READ ) ) ) ! 2308: { ! 2309: pperror( "No source file %s", argv[i] ); ! 2310: exit(2); ! 2311: } ! 2312: fnames[ifno] = copy( argv[i] ); ! 2313: fdates[ifno] = getfdate( fin ); ! 2314: #ifdef CXREF ! 2315: fprintf(outfp,"\"%s\"\n", fnames[ifno]); ! 2316: #endif ! 2317: dirs[0] = dirnams[ifno] = trmdir( argv[i] ); ! 2318: # ifndef gcos ! 2319: /* too dangerous to have file name in same syntactic position ! 2320: be input or output file depending on file redirections, ! 2321: so force output to stdout, willy-nilly ! 2322: [i don't see what the problem is. jfr] ! 2323: */ ! 2324: } ! 2325: else if ( fout == stdout ) ! 2326: { ! 2327: static char _sobuf[BUFSIZ]; ! 2328: ! 2329: if ( NULL == ( fout = fopen( argv[i], WRITE ) ) ) ! 2330: { ! 2331: pperror( "Can't create %s", argv[i] ); ! 2332: exit(2); ! 2333: } ! 2334: else ! 2335: { ! 2336: fclose( stdout ); ! 2337: setbuf( fout, _sobuf ); ! 2338: } ! 2339: # endif ! 2340: } ! 2341: else ! 2342: pperror( "extraneous name %s", argv[i] ); ! 2343: } ! 2344: } ! 2345: ! 2346: fins[ifno] = fin; ! 2347: exfail = 0; ! 2348: /* after user -I files here are the standard include libraries */ ! 2349: /* use user-supplied default first */ ! 2350: if (dfltdir != (char *) 0) ! 2351: dirs[nd++] = dfltdir; ! 2352: else { ! 2353: # if unix || DMERT ! 2354: # if defined(SGSINC) || defined(DMERT) ! 2355: if ( strlen( SGSINC ) != 0 ) ! 2356: dirs[nd++] = SGSINC; /* For cross cpp's */ ! 2357: # endif ! 2358: # ifdef USRINC ! 2359: if ( strlen( USRINC ) != 0 ) ! 2360: dirs[nd++] = USRINC; /* usually /usr/include */ ! 2361: # endif ! 2362: # if !defined( SGSINC ) && !defined( USRINC ) ! 2363: dirs[nd++] = "/usr/include"; ! 2364: # endif ! 2365: # endif ! 2366: # if gcos ! 2367: dirs[nd++] = "cc/include"; ! 2368: # endif ! 2369: # if ibm ! 2370: # ifndef gimpel ! 2371: dirs[nd++] = "BTL$CLIB"; ! 2372: # endif ! 2373: # endif ! 2374: # ifdef gimpel ! 2375: dirs[nd++] = intss() ? "SYS3.C." : ""; ! 2376: # endif ! 2377: # ifdef compool ! 2378: dirs[nd++] = "/compool"; ! 2379: # endif ! 2380: } ! 2381: dirs[nd++] = 0; ! 2382: defloc = ppsym( "define" ); ! 2383: udfloc = ppsym( "undef" ); ! 2384: incloc = ppsym( "include" ); ! 2385: elsloc = ppsym( "else" ); ! 2386: eifloc = ppsym( "endif" ); ! 2387: elifloc = ppsym( "elif" ); ! 2388: ifdloc = ppsym( "ifdef" ); ! 2389: ifnloc = ppsym( "ifndef" ); ! 2390: ifloc = ppsym( "if" ); ! 2391: lneloc = ppsym( "line" ); ! 2392: if (forclass) /* only when C with classes enabled */ ! 2393: clsloc = ppsym( "class" ); ! 2394: idtloc = ppsym( "ident" ); ! 2395: #ifdef PRAGMA ! 2396: pragmaloc = ppsym( "pragma" ); ! 2397: #endif ! 2398: for ( i = sizeof( macbit ) / sizeof( macbit[0] ); --i >= 0; ) ! 2399: macbit[i] = 0; ! 2400: ! 2401: if ( pdef_mach[PD_MACH] ) ! 2402: ysysloc = stsym( pdef_mach[PD_MACH] ); ! 2403: if ( pdef_sys[PD_SYS] ) ! 2404: varloc = stsym( pdef_sys[PD_SYS] ); ! 2405: ! 2406: tf = fnames[ifno]; /* do the -D and -U options now */ ! 2407: fnames[ifno] = "command line"; ! 2408: lineno[ifno] = 1; ! 2409: cp2 = prespc; ! 2410: while ( cp2 < predef ) ! 2411: stsym( *cp2++ ); ! 2412: cp2 = punspc; ! 2413: while ( cp2 < prund ) ! 2414: { ! 2415: if ( p = strchr( *cp2, '=' ) ) ! 2416: *p = '\0'; ! 2417: /* ! 2418: * Truncate to ncps characters if needed. ! 2419: */ ! 2420: if ( strlen( *cp2 ) > ncps ) ! 2421: (*cp2)[ncps] = '\0'; ! 2422: lookup( *cp2++, DROP ); ! 2423: } ! 2424: ! 2425: ulnloc = stsym( "__LINE__" ); ! 2426: uflloc = stsym( "__FILE__" ); ! 2427: fnames[ifno] = tf; ! 2428: pbeg = buffer + ncps; ! 2429: pbuf = pbeg + BUFSIZ; ! 2430: pend = pbuf + BUFSIZ; ! 2431: ! 2432: trulvl = 0; ! 2433: flslvl = 0; ! 2434: lineno[0] = 1; ! 2435: sayline(); ! 2436: outp = inp = pend; ! 2437: #ifdef CXREF ! 2438: ready = 1; ! 2439: #endif ! 2440: control( pend ); ! 2441: if ( fout && ferror( fout ) ) ! 2442: pperror( "Problems with output file; probably out of temp space" ); ! 2443: exit( exfail ? ( exfail == CLASSCODE ? CLASSCODE : 2 ) : 0 ); ! 2444: } ! 2445: ! 2446: #ifdef CXREF ! 2447: ref( name, line ) ! 2448: char *name; ! 2449: int line; ! 2450: { ! 2451: #ifdef FLEXNAMES ! 2452: fprintf(outfp, "R%s\t%05d\n", name, line); ! 2453: #else ! 2454: fprintf(outfp, "R%.8s\t%05d\n", name, line); ! 2455: #endif ! 2456: } ! 2457: ! 2458: def( name, line ) ! 2459: char *name; ! 2460: int line; ! 2461: { ! 2462: if (ready) ! 2463: #ifdef FLEXNAMES ! 2464: fprintf(outfp, "D%s\t%05d\n", name, line); ! 2465: #else ! 2466: fprintf(outfp, "D%.8s\t%05d\n", name, line); ! 2467: #endif ! 2468: } ! 2469: ! 2470: newf( name, line ) ! 2471: char *name; ! 2472: int line; ! 2473: { ! 2474: #ifdef FLEXNAMES ! 2475: fprintf(outfp, "F%s\t%05d\n", name, line); ! 2476: #else ! 2477: fprintf(outfp, "F%.8s\t%05d\n", name, line); ! 2478: #endif ! 2479: } ! 2480: ! 2481: char * ! 2482: xcopy( ptr1, ptr2 ) ! 2483: register char *ptr1, *ptr2; ! 2484: { ! 2485: static char name[NCPS]; ! 2486: char *saveptr, ch; ! 2487: register char *ptr3 = name; ! 2488: ! 2489: /* locate end of name; save character there */ ! 2490: if ((ptr2 - ptr1) > ncps) ! 2491: { ! 2492: saveptr = ptr1 + ncps; ! 2493: ch = *saveptr; ! 2494: *saveptr = '\0'; ! 2495: } ! 2496: else { ! 2497: ch = *ptr2; ! 2498: *ptr2 = '\0'; ! 2499: saveptr = ptr2; ! 2500: } ! 2501: while (*ptr3++ = *ptr1++) ; /* copy name */ ! 2502: *saveptr = ch; /* replace character */ ! 2503: return( name ); ! 2504: } ! 2505: #endif ! 2506: ! 2507: /* Scan over the end of a directive, making sure there's no ! 2508: ** residual junk. ! 2509: ** ! 2510: ** This code is a little messier than you might expect. To avoid bumping ! 2511: ** the line number when we hit the newline, print the message the first time ! 2512: ** we find we've got too many tokens. ! 2513: */ ! 2514: ! 2515: char * ! 2516: chkend( p, ntoken ) ! 2517: char * p; ! 2518: int ntoken; /* number of tokens at which to warn */ ! 2519: { ! 2520: int extratokens = 0; ! 2521: int save_passcom = passcom; ! 2522: ! 2523: passcom = 0; /* ignore comments in this context */ ! 2524: ++flslvl; /* don't expand anything */ ! 2525: ! 2526: /* if at newline, force rescan to do end-of-line stuff */ ! 2527: if (*inp == '\n') ! 2528: p = inp; ! 2529: ! 2530: for (;;) { ! 2531: p = skipbl(p); /* get next token */ ! 2532: if (*inp == '\n') ! 2533: break; /* reached end */ ! 2534: if(++extratokens == ntoken) /* hit number of extras; flag here */ ! 2535: ppwarn("extra tokens (ignored) after directive"); ! 2536: } ! 2537: ! 2538: /* restore comment flag */ ! 2539: passcom = save_passcom; ! 2540: --flslvl; /* back to previous expansion level */ ! 2541: ! 2542: return( p ); ! 2543: } ! 2544: ! 2545: char * ! 2546: getfdate( fin ) ! 2547: FILE *fin; ! 2548: { ! 2549: char date[ 10 ]; ! 2550: struct stat sb; ! 2551: if ( !mflag ) ! 2552: return ""; ! 2553: fstat( fileno( fin ), &sb ); ! 2554: sprintf( date, "@%ld", sb.st_mtime ); ! 2555: return copy( date ); ! 2556: } ! 2557: ! 2558: char * ! 2559: findfdate( fname ) ! 2560: char *fname; ! 2561: { ! 2562: register char *s; ! 2563: for ( s = fname; *s; s++ ) ! 2564: if ( *s == '@' ) { ! 2565: *s++ = 0; ! 2566: break; ! 2567: } ! 2568: return s; ! 2569: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.