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