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