|
|
1.1 ! root 1: #include "e.h" ! 2: #include "y.tab.h" ! 3: #include <ctype.h> ! 4: #include <errno.h> ! 5: ! 6: Infile infile[10]; ! 7: Infile *curfile = infile; ! 8: ! 9: #define MAXSRC 50 ! 10: Src src[MAXSRC]; /* input source stack */ ! 11: Src *srcp = src; ! 12: ! 13: extern int getarg(char *); ! 14: extern void eprint(void); ! 15: ! 16: void pushsrc(int type, char *ptr) /* new input source */ ! 17: { ! 18: if (++srcp >= src + MAXSRC) ! 19: ERROR "inputs nested too deep" FATAL; ! 20: srcp->type = type; ! 21: srcp->sp = ptr; ! 22: if (dbg > 1) { ! 23: printf("\n%3d ", srcp - src); ! 24: switch (srcp->type) { ! 25: case File: ! 26: printf("push file %s\n", ((Infile *)ptr)->fname); ! 27: break; ! 28: case Macro: ! 29: printf("push macro <%s>\n", ptr); ! 30: break; ! 31: case Char: ! 32: printf("push char <%c>\n", *ptr); ! 33: break; ! 34: case String: ! 35: printf("push string <%s>\n", ptr); ! 36: break; ! 37: case Free: ! 38: printf("push free <%s>\n", ptr); ! 39: break; ! 40: default: ! 41: ERROR "pushed bad type %d\n", srcp->type FATAL; ! 42: } ! 43: } ! 44: } ! 45: ! 46: void popsrc(void) /* restore an old one */ ! 47: { ! 48: if (srcp <= src) ! 49: ERROR "too many inputs popped" FATAL; ! 50: if (dbg > 1) { ! 51: printf("%3d ", srcp - src); ! 52: switch (srcp->type) { ! 53: case File: ! 54: printf("pop file\n"); ! 55: break; ! 56: case Macro: ! 57: printf("pop macro\n"); ! 58: break; ! 59: case Char: ! 60: printf("pop char <%c>\n", *srcp->sp); ! 61: break; ! 62: case String: ! 63: printf("pop string\n"); ! 64: break; ! 65: case Free: ! 66: printf("pop free\n"); ! 67: break; ! 68: default: ! 69: ERROR "pop weird input %d\n", srcp->type FATAL; ! 70: } ! 71: } ! 72: srcp--; ! 73: } ! 74: ! 75: Arg args[10]; /* argument frames */ ! 76: Arg *argfp = args; /* frame pointer */ ! 77: int argcnt; /* number of arguments seen so far */ ! 78: ! 79: void dodef(tbl *stp) /* collect args and switch input to defn */ ! 80: { ! 81: int i, len; ! 82: char *p; ! 83: Arg *ap; ! 84: ! 85: ap = argfp+1; ! 86: if (ap >= args+10) ! 87: ERROR "more than arguments\n" FATAL; ! 88: argcnt = 0; ! 89: if (input() != '(') ! 90: ERROR "disaster in dodef\n"FATAL; ! 91: if (ap->argval == 0) ! 92: ap->argval = malloc(1000); ! 93: for (p = ap->argval; (len = getarg(p)) != -1; p += len) { ! 94: ap->argstk[argcnt++] = p; ! 95: if (input() == ')') ! 96: break; ! 97: } ! 98: for (i = argcnt; i < MAXARGS; i++) ! 99: ap->argstk[i] = ""; ! 100: if (dbg) ! 101: for (i = 0; i < argcnt; i++) ! 102: printf("arg %d.%d = <%s>\n", ap-args, i+1, ap->argstk[i]); ! 103: argfp = ap; ! 104: pushsrc(Macro, stp->cval); ! 105: } ! 106: ! 107: getarg(char *p) /* pick up single argument, store in p, return length */ ! 108: { ! 109: int n, c, npar; ! 110: ! 111: n = npar = 0; ! 112: for ( ;; ) { ! 113: c = input(); ! 114: if (c == EOF) ! 115: ERROR "end of file in getarg!\n" FATAL; ! 116: if (npar == 0 && (c == ',' || c == ')')) ! 117: break; ! 118: if (c == '"') /* copy quoted stuff intact */ ! 119: do { ! 120: *p++ = c; ! 121: n++; ! 122: } while ((c = input()) != '"' && c != EOF); ! 123: else if (c == '(') ! 124: npar++; ! 125: else if (c == ')') ! 126: npar--; ! 127: n++; ! 128: *p++ = c; ! 129: } ! 130: *p = 0; ! 131: unput(c); ! 132: return(n + 1); ! 133: } ! 134: ! 135: #define PBSIZE 2000 ! 136: char pbuf[PBSIZE]; /* pushback buffer */ ! 137: char *pb = pbuf-1; /* next pushed back character */ ! 138: ! 139: char ebuf[200]; /* collect input here for error reporting */ ! 140: char *ep = ebuf; ! 141: ! 142: input(void) ! 143: { ! 144: register int c; ! 145: ! 146: loop: ! 147: switch (srcp->type) { ! 148: case File: ! 149: c = getc(curfile->fin); ! 150: if (c == EOF) { ! 151: if (curfile == infile) ! 152: break; ! 153: if (curfile->fin != stdin) { ! 154: fclose(curfile->fin); ! 155: free(curfile->fname); /* assumes allocated */ ! 156: } ! 157: curfile--; ! 158: printf(".lf %d %s\n", curfile->lineno, curfile->fname); ! 159: popsrc(); ! 160: goto loop; ! 161: } ! 162: if (c == '\n') ! 163: curfile->lineno++; ! 164: break; ! 165: case Char: ! 166: if (pb >= pbuf) { ! 167: c = *pb--; ! 168: popsrc(); ! 169: break; ! 170: } else { /* can't happen? */ ! 171: popsrc(); ! 172: goto loop; ! 173: } ! 174: case String: ! 175: c = *srcp->sp++; ! 176: if (c == '\0') { ! 177: popsrc(); ! 178: goto loop; ! 179: } else { ! 180: if (*srcp->sp == '\0') /* empty, so pop */ ! 181: popsrc(); ! 182: break; ! 183: } ! 184: case Macro: ! 185: c = *srcp->sp++; ! 186: if (c == '\0') { ! 187: if (--argfp < args) ! 188: ERROR "argfp underflow" FATAL; ! 189: popsrc(); ! 190: goto loop; ! 191: } else if (c == '$' && isdigit(*srcp->sp)) { ! 192: int n = 0; ! 193: while (isdigit(*srcp->sp)) ! 194: n = 10 * n + *srcp->sp++ - '0'; ! 195: if (n > 0 && n <= MAXARGS) ! 196: pushsrc(String, argfp->argstk[n-1]); ! 197: goto loop; ! 198: } ! 199: break; ! 200: case Free: /* free string */ ! 201: free(srcp->sp); ! 202: popsrc(); ! 203: goto loop; ! 204: } ! 205: if (ep >= ebuf + sizeof ebuf) ! 206: ep = ebuf; ! 207: *ep++ = c; ! 208: return c; ! 209: } ! 210: ! 211: ! 212: unput(int c) ! 213: { ! 214: if (++pb >= pbuf + sizeof pbuf) ! 215: ERROR "pushback overflow\n"FATAL; ! 216: if (--ep < ebuf) ! 217: ep = ebuf + sizeof(ebuf) - 1; ! 218: *pb = c; ! 219: pushsrc(Char, pb); ! 220: return c; ! 221: } ! 222: ! 223: void pbstr(char *s) ! 224: { ! 225: pushsrc(String, s); ! 226: } ! 227: ! 228: void error(int die, char *s) ! 229: { ! 230: extern char *cmdname; ! 231: ! 232: if (synerr) ! 233: return; ! 234: fprintf(stderr, "%s: ", cmdname); ! 235: fprintf(stderr, s); ! 236: if (errno > 0) ! 237: perror("???"); ! 238: if (curfile->fin) ! 239: fprintf(stderr, " near line %d, file %s", ! 240: curfile->lineno, curfile->fname); ! 241: fprintf(stderr, "\n"); ! 242: eprint(); ! 243: synerr = 1; ! 244: errno = 0; ! 245: if (die) { ! 246: if (dbg) ! 247: abort(); ! 248: else ! 249: exit(1); ! 250: } ! 251: } ! 252: ! 253: void yyerror(char *s) ! 254: { ! 255: error(0, s); /* temporary */ ! 256: } ! 257: ! 258: char errbuf[200]; ! 259: ! 260: void eprint(void) /* try to print context around error */ ! 261: { ! 262: char *p, *q; ! 263: ! 264: if (ep == ebuf) ! 265: return; /* no context */ ! 266: p = ep - 1; ! 267: if (p > ebuf && *p == '\n') ! 268: p--; ! 269: for ( ; p >= ebuf && *p != '\n'; p--) ! 270: ; ! 271: while (*p == '\n') ! 272: p++; ! 273: fprintf(stderr, " context is\n\t"); ! 274: for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--) ! 275: ; ! 276: while (p < q) ! 277: putc(*p++, stderr); ! 278: fprintf(stderr, " >>> "); ! 279: while (p < ep) ! 280: putc(*p++, stderr); ! 281: fprintf(stderr, " <<< "); ! 282: while (pb >= pbuf) ! 283: putc(*pb--, stderr); ! 284: if (curfile->fin) ! 285: fgets(ebuf, sizeof ebuf, curfile->fin); ! 286: fprintf(stderr, "%s", ebuf); ! 287: pbstr("\n.EN\n"); /* safety first */ ! 288: ep = ebuf; ! 289: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.