|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include "efix.h" ! 3: ! 4: /* add casts to convert efl source into acceptable C */ ! 5: ! 6: #define INCLMAX 4 /* max include depth */ ! 7: #define INCLNAMX 128 /* max include pathname length */ ! 8: ! 9: FILE *fopen(), *infile; ! 10: ! 11: char emsg[64], linebuf[4096], type[257]; ! 12: char *adjnam, *eofmsg, *infname, *lastc = linebuf, ! 13: *nextc = linebuf, *progname, *tstart, **xargv; ! 14: char *linelist; ! 15: long lineno, linestart; ! 16: int adjval, eexit, inlevel, lineinc = 1, rc, untok, verbose; ! 17: struct Include { ! 18: FILE *infile; ! 19: char *infname; ! 20: long lineno, linestart; ! 21: } inclstak[INCLMAX+1]; ! 22: char inclname[INCLMAX][INCLNAMX]; ! 23: char **te_addr, *te_value; ! 24: ! 25: char *fgets(), *memset(), *strcpy(); ! 26: ! 27: next(eof) /* return next input character */ ! 28: /* eof == 0 ==> return Eof on end of file */ ! 29: /* eof == 1, 2 ==> quit on end of file */ ! 30: /* 1 ==> msg controlled by eofmsg; */ ! 31: /* 2 ==> complaint of unexpected eof (mid-token) */ ! 32: { ! 33: ! 34: if (nextc >= lastc) { ! 35: if (!fgets(linebuf, sizeof(linebuf), infile) ! 36: && !nextfile(1)) switch(eof) { ! 37: case 0: ! 38: return Eof; ! 39: case 1: ! 40: if (eofmsg) fprintf(stderr, ! 41: eofmsg, progname, infname); ! 42: exit(rc); ! 43: case 2: ! 44: squawk("unexpected end of file"); ! 45: exit(rc); ! 46: } ! 47: linestart += nextc - linebuf; ! 48: nextc = linebuf; ! 49: lastc = linebuf + strlen(linebuf); ! 50: lineno += lineinc; ! 51: lineinc = lastc[-1] == '\n'; ! 52: } ! 53: return *nextc++; ! 54: } ! 55: ! 56: #define unget(c) *--nextc = c ! 57: ! 58: where() /* report position of current token on stderr */ ! 59: { ! 60: int toff = --tstart - linebuf; ! 61: fprintf(stderr, "%s, line %ld [char %ld] of %s:\n\t", ! 62: progname, lineno, linestart + toff, infname); ! 63: return toff; ! 64: } ! 65: ! 66: scream(msg) ! 67: char *msg; ! 68: { ! 69: eexit = 1; ! 70: squawk(msg); ! 71: } ! 72: ! 73: squawk(msg) /* print error message */ ! 74: char *msg; ! 75: { ! 76: int toff = where(); ! 77: fprintf(stderr, "%s\ncontext: %.*s >>> %.*s <<< %s", msg, ! 78: toff, linebuf, nextc-tstart, tstart, nextc); ! 79: rc |= 1; ! 80: if (eexit) exit(rc); ! 81: } ! 82: ! 83: options(n) ! 84: { ! 85: static char *opts[] = { ! 86: "-L {put out # line comments}", ! 87: "-e {exit at first error}", ! 88: "-v {verbose}", ! 89: 0}; ! 90: char **o; ! 91: ! 92: fprintf(stderr, "usage: %s [-Lev] [file [file...]]\noptions:\n", ! 93: progname); ! 94: for(o = opts; *o; o++) fprintf(stderr, "\t%s\n", *o); ! 95: exit(n); ! 96: } ! 97: ! 98: nextfile(loop) /* start next file (implicitly cat input files) */ ! 99: { ! 100: char *s; ! 101: struct Include *I; ! 102: ! 103: while(inlevel > 0) { ! 104: fclose(infile); ! 105: I = inclstak + --inlevel; ! 106: if (!inlevel) ! 107: *te_addr = te_value; ! 108: infile = I->infile; ! 109: infname = I->infname; ! 110: lineno = I->lineno; ! 111: linestart = I->linestart; ! 112: lineinc = 0; ! 113: if (fgets(linebuf, sizeof(linebuf), infile)) { ! 114: nextc = linebuf; ! 115: return 1; ! 116: } ! 117: } ! 118: for(;;) { ! 119: if (!(s = *++xargv)) { ! 120: if (infname) return 0; ! 121: s = "-"; ! 122: --xargv; ! 123: } ! 124: if (*s == '-') switch(s[1]) { ! 125: case 0: ! 126: infile = stdin; ! 127: s = "/dev/stdin"; ! 128: break; ! 129: case 'L': ! 130: linelist = "\n#\tline %d, file \"%s\"\n"; ! 131: continue; ! 132: case 'e': ! 133: eexit = 1; ! 134: continue; ! 135: case 'v': ! 136: verbose = 1; ! 137: continue; ! 138: case '?': ! 139: options(0); ! 140: default: ! 141: fprintf(stderr, "\ninvalid option -%c\n", s[1]); ! 142: options(1); ! 143: } ! 144: else if (!(infile = fopen(s,"r"))) { ! 145: fprintf(stderr, "%s: can't open %s\n", progname, s); ! 146: exit(rc+2); ! 147: } ! 148: if (!loop || fgets(linebuf, sizeof(linebuf), infile)) break; ! 149: } ! 150: infname = s; ! 151: if (linelist) printf(linelist, 1, s); ! 152: linestart = 0; ! 153: nextc = linebuf; ! 154: return 1; ! 155: } ! 156: ! 157: void ! 158: inclopen(s) ! 159: char *s; ! 160: { ! 161: FILE *f; ! 162: struct Include *I; ! 163: char buf[INCLNAMX], *be = buf + sizeof(buf), *s1 = s; ! 164: ! 165: if (!(f = fopen(s,"r")) && *s != '/') { ! 166: s1 = buf; ! 167: adjoin(adjoin(buf,be,"/usr/include/"),be,s); ! 168: f = fopen(s1,"r"); ! 169: } ! 170: if (!f) { ! 171: fprintf(stderr, "%s: can't open \"%s\"\n", ! 172: progname, s1); ! 173: scream("include failure"); ! 174: } ! 175: I = inclstak + inlevel; ! 176: I->infile = infile; ! 177: I->infname = infname; ! 178: I->lineno = lineno + lineinc; ! 179: I->linestart = linestart + nextc - linebuf; ! 180: lineno = linestart = 0; ! 181: lineinc = 1; ! 182: infname = strcpy(inclname[inlevel++], s1); ! 183: infile = f; ! 184: } ! 185: ! 186: void ! 187: dumpwhite() /* kludge: dump #include white stuff */ ! 188: { ! 189: struct Tok *T1; ! 190: if (inlevel == 1) { ! 191: for(T1 = T->next; T1 != T; T1 = T1->next) ! 192: if (!T1->inlevel) { ! 193: T1->inlevel = 1; ! 194: printf("%s%s", T1->white, T1->tok); ! 195: } ! 196: printf("%s", T1->white); ! 197: } ! 198: } ! 199: ! 200: token(eof) /* return code for next token; T->tok := its print value */ ! 201: { ! 202: register c, ct; ! 203: register char *Type = type; ! 204: register char *t; ! 205: int c1, nlsquawk; ! 206: char *t1, *te; ! 207: struct Tok *T1; ! 208: ! 209: if (untok) { ! 210: c = untok; ! 211: untok = 0; ! 212: return c; ! 213: } ! 214: T = T1 = T->next; ! 215: if (!T1->inlevel) ! 216: printf("%s%s", T1->white, T1->tok); ! 217: t = T1->white; ! 218: te = t + sizeof(T1->white) - 1; ! 219: ! 220: /* kludge: allow restoration of te by nextfile() */ ! 221: te_addr = &te; ! 222: te_value = te; ! 223: ! 224: if (inlevel) ! 225: te = t; ! 226: top: ! 227: for(;;){ ! 228: for(;;) { ! 229: c = next(eof); ! 230: if (ct = Type[c]) break; ! 231: if (t < te) *t++ = c; ! 232: } ! 233: if (c == '/') { /* start of comment? */ ! 234: if (next(2) != '*') { --nextc; break; } ! 235: if (t < te) *t++ = '/'; ! 236: if (t < te) *t++ = '*'; ! 237: for(;;) { ! 238: do { ! 239: c = next(2); ! 240: if (t < te) *t++ = c; ! 241: } while(c != '*'); ! 242: do { ! 243: c = next(2); ! 244: if (t < te) *t++ = c; ! 245: if (c == '/') goto top; ! 246: } while(c == '*'); ! 247: } ! 248: } ! 249: else if (c == '#') { /* look for include "..." */ ! 250: if (t < te) *t++ = c; ! 251: do { ! 252: c = next(eof); ! 253: if (t < te) *t++ = c; ! 254: } while(!Type[c]); ! 255: if (c != 'i') goto eat_rest; ! 256: t1 = t; ! 257: do { ! 258: c = next(eof); ! 259: if (t < te) *t++ = c; ! 260: } while(Type[c] == SYMBOL); ! 261: if (strncmp(t1,"nclude",6)) ! 262: goto eat_rest; ! 263: ! 264: if (inlevel >= INCLMAX) ! 265: scream("includes nested too deeply"); ! 266: while(!Type[c]) { ! 267: c = next(eof); ! 268: if (t < te) *t++ = c; ! 269: } ! 270: switch(c) { ! 271: case '"': ! 272: c1 = c; ! 273: break; ! 274: case '<': ! 275: c1 = '>'; ! 276: break; ! 277: default: ! 278: goto eat_rest; ! 279: } ! 280: t1 = t; ! 281: do { ! 282: c = next(2); ! 283: if (t < te) *t++ = c; ! 284: } while(c > ' ' && c != c1); ! 285: if (t >= te) { ! 286: eat_rest: ! 287: while(c != '\n') { ! 288: c = next(2); ! 289: if (t < te) *t++ = c; ! 290: } ! 291: continue; ! 292: } ! 293: tstart = nextc; ! 294: if (t - t1 > INCLNAMX) ! 295: scream("oversize include name"); ! 296: *--t = 0; ! 297: /* open file, put stuff on include stack */ ! 298: inclopen(t1); ! 299: *t++ = c1; ! 300: while(nextc < lastc) { ! 301: if (t < te) *t++ = *nextc; ! 302: ++nextc; ! 303: } ! 304: *t = 0; ! 305: dumpwhite(); ! 306: te = t = T1->white; ! 307: nextc = lastc = linebuf; ! 308: } ! 309: else break; ! 310: } ! 311: *t = 0; ! 312: tstart = nextc; ! 313: t = T1->tok; ! 314: te = t + sizeof(T1->tok) - 1; ! 315: *t++ = c; ! 316: switch(ct) { ! 317: ! 318: case SYMBOL: ! 319: for(;; ++t) { ! 320: c = next(eof); ! 321: if (Type[c] != SYMBOL) { unget(c); break; } ! 322: if (t >= te) { ! 323: do c = next(eof); ! 324: while (Type[c] == SYMBOL); ! 325: unget(c); ! 326: squawk("truncating oversize symbol"); ! 327: break; ! 328: } ! 329: *t = c; ! 330: } ! 331: break; ! 332: ! 333: case OPERATOR /* ()[],;*#<>+/:^~|&!%={}?. */: ! 334: ct = c; ! 335: break; ! 336: ! 337: case STRING /* " */: ! 338: nlsquawk = 1; ! 339: for(;;) { ! 340: c = next(2); ! 341: if (t < te) *t++ = c; ! 342: switch(c) { ! 343: case '\\': ! 344: c = next(2); ! 345: if (t < te) *t++ = c; ! 346: continue; ! 347: case '\n': ! 348: if (nlsquawk) { ! 349: squawk("newline within string"); ! 350: nlsquawk = 0; ! 351: } ! 352: continue; ! 353: case '"': ! 354: goto break2; ! 355: } ! 356: } ! 357: break2: ! 358: if (t >= te) squawk("oversize string"); ! 359: break; ! 360: ! 361: case CHARCONST /* ' */: ! 362: do { ! 363: c = next(2); ! 364: if (t < te) *t++ = c; ! 365: if (c == '\\') { ! 366: c = next(2); ! 367: if (t < te) *t++ = c; ! 368: c = next(2); ! 369: if (t < te) *t++ = c; ! 370: } ! 371: if (c == '\n') { ! 372: squawk("newline in char constant"); ! 373: break; ! 374: } ! 375: } while(c != '\''); ! 376: *t = 0; ! 377: break; ! 378: ! 379: case ARROW /* - */: ! 380: c = next(2); ! 381: if (c == '>') { ! 382: if (t < te) *t++ = c; ! 383: } ! 384: else { ! 385: unget(c); ! 386: ct = '-'; ! 387: } ! 388: break; ! 389: ! 390: case FEND: ! 391: t = T1->tok; ! 392: } ! 393: *t = 0; ! 394: T1->inlevel = inlevel; ! 395: return T1->type = ct; ! 396: } ! 397: ! 398: main(argc,argv) ! 399: int argc; ! 400: char **argv; ! 401: { ! 402: int c; ! 403: char *s; ! 404: ! 405: progname = *argv; ! 406: xargv = argv; ! 407: ! 408: /* set up translate tables */ ! 409: ! 410: for(c = ' ' + 1; c < 0x7f; c++) type[c] = SYMBOL; ! 411: for(s = "()[],;*#<>+/:?^~|&!%={}?."; c = *s; s++) type[c] = OPERATOR; ! 412: type['"'] = STRING; ! 413: type['\''] = CHARCONST; ! 414: type['-'] = ARROW; ! 415: type[Eof] = FEND; ! 416: ! 417: if (!nextfile(0)) { ! 418: fprintf(stderr, "%s: no (nonempty) input\n"); ! 419: options(1); ! 420: } ! 421: ! 422: /* run */ ! 423: process(); ! 424: return rc; ! 425: } ! 426: ! 427: char * ! 428: adjoin(t,te,s) /* string concatenation with error-check and */ ! 429: /* pointer to null char at string's end returned */ ! 430: register char *t, *te, *s; ! 431: { ! 432: for(;; ++s, ++t) { ! 433: if (t >= te) { ! 434: sprintf(emsg, "%s = %d is too small", ! 435: adjnam, adjval); ! 436: squawk(emsg); ! 437: exit(rc); ! 438: } ! 439: if (!(*t = *s)) break; ! 440: } ! 441: return t; ! 442: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.