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