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

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

unix.superglobalmegacorp.com

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