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