|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <ctype.h> ! 3: #include "pic.h" ! 4: #include "y.tab.h" ! 5: ! 6: extern FILE *yyin; ! 7: extern int lineno; ! 8: extern char *filename; ! 9: extern int synerr; ! 10: ! 11: char *definition(s) /* collect definition for s and install */ ! 12: char *s; /* definitions picked up lexically */ ! 13: { ! 14: char buf[2000], *p, *tostring(); ! 15: int c, delim; ! 16: struct symtab *stp; ! 17: ! 18: while ((delim = input()) == ' ' || delim == '\t') ! 19: ; ! 20: for (p = buf; (c = input()) != delim; ) { ! 21: if (p >= buf + sizeof(buf)) { ! 22: yyerror("definition of %s is too long", s); ! 23: exit(1); ! 24: } ! 25: if (c == EOF) { ! 26: yyerror("end of file while defining %s", s); ! 27: exit(1); ! 28: } ! 29: *p++ = c; ! 30: } ! 31: *p = '\0'; ! 32: p = tostring(buf); ! 33: stp = lookup(s); ! 34: if (stp != NULL) { /* it's there before */ ! 35: if (stp->s_type != DEFNAME) { ! 36: yyerror("%s used as variable and definition\n", s); ! 37: return; ! 38: } ! 39: free(stp->s_val); ! 40: stp->s_val = (int) p; ! 41: } else { ! 42: makevar(tostring(s), DEFNAME, p); ! 43: } ! 44: dprintf("installing %s as `%s'\n", s, p); ! 45: sprintf(buf, ".md %s", s); ! 46: return(tostring(buf)); /* handled as TROFF */ ! 47: } ! 48: ! 49: char *argstk[10]; /* pointers to actual arguments in argval */ ! 50: char argval[1000]; /* arguments stored here end to end */ ! 51: char *argp; /* current position in argval */ ! 52: int argcnt; /* number of arguments seen so far */ ! 53: ! 54: char *defuse(s, p) /* used definition s, found at tbl p */ ! 55: char *s; ! 56: struct symtab *p; ! 57: { ! 58: int c; ! 59: char buf[100], buf1[1000], *bp; ! 60: ! 61: c = input(); ! 62: unput(c); ! 63: /* this only works for macros with no args */ ! 64: if (c == '(') /* it's name(...) */ ! 65: dodef(p); ! 66: else { /* no argument list */ ! 67: bp = buf1; ! 68: do { ! 69: *bp = input(); ! 70: } while (*bp++ != '\n'); /* collect rest of input line */ ! 71: *bp = 0; ! 72: sprintf(buf, ".e %s\n", s); ! 73: dprintf("pushing back `%s'\n", buf); ! 74: pbstr(buf); /* terminate use of defined name */ ! 75: dprintf("pushing back `%s'\n", buf1); ! 76: pbstr(buf1); ! 77: dprintf("pushing back `%s'\n", p->s_val); ! 78: pbstr(p->s_val); ! 79: unput('\n'); ! 80: } ! 81: sprintf(buf, ".u %s%s", s, buf1); ! 82: return(tostring(buf)); ! 83: } ! 84: ! 85: dodef(stp) /* collect args and push back defn for name in table slot n */ ! 86: struct symtab *stp; ! 87: { ! 88: int i, c, len; ! 89: char *p; ! 90: ! 91: argcnt = 0; ! 92: if (input() != '(') ! 93: yyerror("disaster in dodef\n"); ! 94: for (argp = argval; (len = getarg(argp)) != -1; argp += len) { ! 95: argstk[argcnt++] = argp; ! 96: if (input() == ')') ! 97: break; ! 98: } ! 99: for (i = argcnt; i < 10; i++) ! 100: argstk[i] = ""; ! 101: if (dbg) { ! 102: for (i = 0; i < argcnt; i++) ! 103: printf("arg %d = %s\n", i, argstk[i]); ! 104: } ! 105: ! 106: /* push them back */ ! 107: for (p = (char *) stp->s_val; *p; p++) ! 108: ; /* find the end */ ! 109: for (--p; p >= (char *) stp->s_val; p--) { ! 110: if (*(p-1) == '$') { ! 111: if (isdigit(*p)) { ! 112: pbstr(argstk[*p - '0' - 1]); ! 113: p--; ! 114: } ! 115: else ! 116: unput(*p); ! 117: } else { ! 118: unput(*p); ! 119: } ! 120: } ! 121: } ! 122: ! 123: getarg(p) /* pick up single argument, store in p, return length */ ! 124: char *p; ! 125: { ! 126: int n, c, npar; ! 127: ! 128: n = npar = 0; ! 129: for ( ;; ) { ! 130: c = input(); ! 131: if (c == EOF) ! 132: yyerror("end of file in getarg!\n"); ! 133: if (npar == 0 && (c == ',' || c == ')')) ! 134: break; ! 135: if (c == '"') /* copy quoted stuff intact */ ! 136: do { ! 137: *p++ = c; ! 138: n++; ! 139: } while ((c = input()) != '"' && c != EOF); ! 140: else if (c == '(') ! 141: npar++; ! 142: else if (c == ')') ! 143: npar--; ! 144: n++; ! 145: *p++ = c; ! 146: } ! 147: *p = 0; ! 148: unput(c); ! 149: return(n + 1); ! 150: } ! 151: ! 152: #define PBSIZE 2000 ! 153: char pbuf[PBSIZE]; /* pushback buffer */ ! 154: char *pb = pbuf-1; /* next pushed back character */ ! 155: ! 156: char ebuf[200]; /* collect input here for error reporting */ ! 157: char *ep = ebuf; ! 158: ! 159: input() ! 160: { ! 161: register int c; ! 162: ! 163: if (pb >= pbuf) { ! 164: c = *pb--; ! 165: } else { ! 166: c = getc(yyin); ! 167: if (c == '\n') ! 168: lineno++; ! 169: else if (c == EOF) { ! 170: yyerror("end of file inside .PS/.PE"); ! 171: exit(1); ! 172: } ! 173: } ! 174: if (ep >= ebuf + sizeof ebuf) ! 175: ep = ebuf; ! 176: return (*ep++ = c); ! 177: } ! 178: ! 179: unput(c) ! 180: { ! 181: if (++pb >= pbuf + sizeof pbuf) { ! 182: yyerror("pushback overflow\n"); ! 183: exit(1); ! 184: } ! 185: if (--ep < ebuf) ! 186: ep = ebuf + sizeof(ebuf) - 1; ! 187: return(*pb = c); ! 188: } ! 189: ! 190: pbstr(s) ! 191: char *s; ! 192: { ! 193: int n; ! 194: ! 195: n = strlen(s); ! 196: while (--n >= 0) ! 197: unput(s[n]); ! 198: } ! 199: ! 200: yyerror(s, s1, s2, s3, s4) ! 201: char *s, *s1, *s2, *s3, *s4; ! 202: { ! 203: if (synerr) ! 204: return; ! 205: fprintf(stderr, "pic: "); ! 206: fprintf(stderr, s, s1, s2, s3, s4); ! 207: fprintf(stderr, " near line %d, file %s\n", lineno, filename); ! 208: eprint(); ! 209: synerr = 1; ! 210: } ! 211: ! 212: eprint() /* try to print context around error */ ! 213: { ! 214: char *p, *q; ! 215: int c; ! 216: ! 217: p = ep - 1; ! 218: if (p > ebuf && *p == '\n') ! 219: p--; ! 220: for ( ; p >= ebuf && *p != '\n'; p--) ! 221: ; ! 222: while (*p == '\n') ! 223: p++; ! 224: fprintf(stderr, " context is\n\t"); ! 225: while (p < ep) ! 226: putc(*p++, stderr); ! 227: fprintf(stderr, " ^ "); ! 228: while (pb >= pbuf) ! 229: putc(*pb--, stderr); ! 230: fgets(ebuf, sizeof ebuf, yyin); ! 231: fprintf(stderr, "%s", ebuf); ! 232: pbstr(".PE\n"); /* safety first */ ! 233: ep = ebuf; ! 234: } ! 235: ! 236: yywrap() {;}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.