ifline() { while(1) { inline(); if(eof) return; if(match("#ifdef")) { ++iflevel; if(skiplevel) continue; blanks(); symname(msname, NO); /*19*/ if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0)==0) /*19*/ skiplevel=iflevel; continue; } if(match("#ifndef")) { ++iflevel; if(skiplevel) continue; symname(msname, NO); /*19*/ if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0)) /*19*/ skiplevel=iflevel; continue; } if(match("#else")) { if(iflevel) { if(skiplevel==iflevel) skiplevel=0; else if(skiplevel==0) skiplevel=iflevel; } else noiferr(); continue; } if(match("#endif")) { if(iflevel) { if(skiplevel==iflevel) skiplevel=0; --iflevel; } else noiferr(); continue; } if(skiplevel) continue; if(listfp) { if(listfp==output) cout(';', output); sout(line, listfp); } if(ch==0) continue; break; } } keepch(c) char c; { if(pptr=LINEMAX) error("line too long"); keepch(0); line=pline; bump(0); } noiferr() { error("no matching #if..."); errflag=0; } addmac() { int k; if(symname(msname, NO)==0) { illname(); kill(); return; } k=0; if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0)==0) { if(cptr2=cptr) while(*cptr2++ = msname[k++]); else { error("macro name table full"); return; } } putint(macptr, cptr+NAMESIZE, 2); while(white()) gch(); while(putmac(gch())); if(macptr>=MACMAX) { error("macro string queue full"); abort(ERRCODE); } } putmac(c) char c; { macq[macptr]=c; if(macptr= end) cptr=buf; if(cptr == cptr2) return (cptr=0); } return 0; } hash(sname) char *sname; { int i, c; i=0; while(c = *sname++) i=(i<<1)+c; return i; } setstage(before, start) int *before, *start; { if((*before=stagenext)==0) stagenext=stage; *start=stagenext; } clearstage(before, start) char *before, *start; { *stagenext=0; if(stagenext=before) return; if(start) { #ifdef OPTIMIZE peephole(start); #else /* OPTIMIZE */ sout(start, output); #endif /* OPTIMIZE */ } } outdec(number) int number; { int k,zs; char c, *q, *r; /*09*/ zs = 0; k=10000; if (number<0) { number=(-number); outbyte('-'); } while (k>=1) { q=0; r=number; /*09*/ while(r >= k) {++q; r -=k;} /*09*/ c = q + '0'; /*09*/ if ((c!='0')|(k==1)|(zs)) { zs=1; outbyte(c); } number = r; /*09*/ k=k/10; } } ol(ptr) char ptr[]; { ot(ptr); nl(); } ot(ptr) char ptr[]; { outstr(ptr); } outstr(ptr) char ptr[]; { poll(1); /* allow program interruption */ /* must work with symbol table names terminated by length */ while(*ptr >= ' ') outbyte(*ptr++); } outbyte(c) char c; { if(stagenext) { if(stagenext==stagelast) { error("staging buffer overflow"); return 0; } else *stagenext++ = c; } else cout(c,output); return c; } cout(c, fd) char c; int fd; { if(fputc(c, fd)==EOF) xout(); } sout(string, fd) char *string; int fd; { if(fputs(string, fd)==EOF) xout(); } lout(line, fd) char *line; int fd; { sout(line, fd); cout('\n', fd); } xout() { fputs("output error\n", stderr); abort(ERRCODE); } nl() { outbyte('\n'); } col() { #ifdef COL outbyte(':'); #endif /* COL */ } error(msg) char msg[]; { if(errflag) return; else errflag=1; lout(line, stderr); errout(msg, stderr); if(alarm) fputc(7, stderr); /* ** while reading from stderr is not strictly legal, ** stderr will always be assigned to the user's terminal ** (CON: on CP/M systems [should be /dev/tty on Unix]). */ if(pause) while(fgetc(stderr)!='\n'); if(listfp>0) errout(msg, listfp); } errout(msg, fp) char msg[]; int fp; { int k; k=line+2; while(k++ <= lptr) cout(' ', fp); lout("/\\", fp); sout("**** ", fp); lout(msg, fp); } streq(str1,str2) char str1[],str2[]; { /* check for string equality over whole string */ int k; k=0; while (str2[k]) { if ((str1[k])!=(str2[k])) return 0; ++k; } return k; } astreq(str1,str2,len) char str1[],str2[];int len; { /* check for string equality over first 'len' characters */ int k; k=0; while (k ' ') op[opsize++] = *list++; op[opsize]=0; if(opsize=streq(lptr, op)) if((*(lptr+opsize) != '=')& (*(lptr+opsize) != *(lptr+opsize-1))) return 1; if(*list) { ++list; ++opindex; } else return 0; } } blanks() { while(1) { while(ch) { if(white()) gch(); else return; } if(line==mline) return; preprocess(); if(eof) break; } }