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