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