Annotation of researchv10no/cmd/efl/efixsrc/main.c, revision 1.1.1.1

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:        }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.