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