Annotation of researchv9/cmd/eqn/input.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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