Annotation of researchv10no/cmd/grap/non-ansi/input.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include <ctype.h>
                      3: #include <errno.h>
                      4: #include "grap.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:                ERROR "inputs nested too deep" FATAL;
                     20:        srcp->type = type;
                     21:        srcp->sp = ptr;
                     22:        if (dbg) {
                     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 Thru:
                     35:                        printf("push thru\n");
                     36:                        break;
                     37:                case String:
                     38:                        printf("push string <%s>\n", ptr);
                     39:                        break;
                     40:                case Free:
                     41:                        printf("push free <%s>\n", ptr);
                     42:                        break;
                     43:                default:
                     44:                        ERROR "pushed bad type %d", srcp->type FATAL;
                     45:                }
                     46:        }
                     47: }
                     48: 
                     49: popsrc()       /* restore an old one */
                     50: {
                     51:        if (srcp <= src)
                     52:                ERROR "too many inputs popped" FATAL;
                     53:        if (dbg) {
                     54:                printf("%3d ", srcp - src);
                     55:                switch (srcp->type) {
                     56:                case File:
                     57:                        printf("pop file\n");
                     58:                        break;
                     59:                case Macro:
                     60:                        printf("pop macro\n");
                     61:                        break;
                     62:                case Char:
                     63:                        printf("pop char <%c>\n", *srcp->sp);
                     64:                        break;
                     65:                case Thru:
                     66:                        printf("pop thru\n");
                     67:                        break;
                     68:                case String:
                     69:                        printf("pop string\n");
                     70:                        break;
                     71:                case Free:
                     72:                        printf("pop free\n");
                     73:                        break;
                     74:                default:
                     75:                        ERROR "pop weird input %d", srcp->type FATAL;
                     76:                }
                     77:        }
                     78:        srcp--;
                     79: }
                     80: 
                     81: definition(s)  /* collect definition for s and install */
                     82:        char *s;        /* definitions picked up lexically */
                     83: {
                     84:        char *p;
                     85:        Obj *stp;
                     86: 
                     87:        p = delimstr("definition");
                     88:        stp = lookup(s, 0);
                     89:        if (stp != NULL) {      /* it's there before */
                     90:                if (stp->type != DEFNAME) {
                     91:                        ERROR "%s used as variable and definition", s WARNING;
                     92:                        return;
                     93:                }
                     94:                free(stp->val);
                     95:        } else {
                     96:                stp = lookup(s, 1);
                     97:                stp->type = DEFNAME;
                     98:        }
                     99:        stp->val = p;
                    100:        dprintf("installing %s as `%s'\n", s, p);
                    101: }
                    102: 
                    103: char *delimstr(s)      /* get body of X ... X */
                    104:        char *s;                /* message if too big */
                    105: {
                    106:        int c, delim, rdelim, n, deep;
                    107:        static char *buf = NULL;
                    108:        static int nbuf = 0;
                    109:        char *p;
                    110: 
                    111:        if (buf == NULL)
                    112:                buf = grow(buf, "buf", nbuf += 1000, sizeof(buf[0]));
                    113:        while ((delim = input()) == ' ' || delim == '\t' || delim == '\n')
                    114:                ;
                    115:        rdelim = baldelim(delim, "{}");         /* could be "(){}[]`'" */
                    116:        deep = 1;
                    117:        for (p = buf; ; ) {
                    118:                c = input();
                    119:                if (c == rdelim)
                    120:                        if (--deep == 0)
                    121:                                break;
                    122:                if (c == delim)
                    123:                        deep++;
                    124:                if (p >= buf + nbuf) {
                    125:                        n = p - buf;
                    126:                        buf = grow(buf, "buf", nbuf += 1000, sizeof(buf[0]));
                    127:                        p = buf + n;
                    128:                }
                    129:                if (c == EOF)
                    130:                        ERROR "end of file in %s %c %.20s... %c", s, delim, buf, delim FATAL;
                    131:                *p++ = c;
                    132:        }
                    133:        *p = '\0';
                    134:        dprintf("delimstr %s %c <%s> %c\n", s, delim, buf, delim);
                    135:        return tostring(buf);
                    136: }
                    137: 
                    138: baldelim(c, s) /* replace c by balancing entry in s */
                    139:        int c;
                    140:        char *s;
                    141: {
                    142:        for ( ; *s; s += 2)
                    143:                if (*s == c)
                    144:                        return s[1];
                    145:        return c;
                    146: }
                    147: 
                    148: Arg    args[10];       /* argument frames */
                    149: Arg    *argfp = args;  /* frame pointer */
                    150: int    argcnt;         /* number of arguments seen so far */
                    151: 
                    152: dodef(stp)     /* collect args and switch input to defn */
                    153:        Obj *stp;
                    154: {
                    155:        int i, len;
                    156:        char *p;
                    157:        Arg *ap;
                    158: 
                    159:        ap = argfp+1;
                    160:        if (ap >= args+10)
                    161:                ERROR "arguments too deep" FATAL;
                    162:        argcnt = 0;
                    163:        if (input() != '(')
                    164:                ERROR "disaster in dodef" FATAL;
                    165:        if (ap->argval == 0)
                    166:                ap->argval = malloc(1000);
                    167:        for (p = ap->argval; (len = getarg(p)) != -1; p += len) {
                    168:                ap->argstk[argcnt++] = p;
                    169:                if (input() == ')')
                    170:                        break;
                    171:        }
                    172:        for (i = argcnt; i < MAXARGS; i++)
                    173:                ap->argstk[i] = "";
                    174:        if (dbg)
                    175:                for (i = 0; i < argcnt; i++)
                    176:                        printf("arg %d.%d = <%s>\n", ap-args, i+1, ap->argstk[i]);
                    177:        argfp = ap;
                    178:        pushsrc(Macro, stp->val);
                    179: }
                    180: 
                    181: getarg(p)      /* pick up single argument, store in p, return length */
                    182:        char *p;
                    183: {
                    184:        int n, c, npar;
                    185: 
                    186:        n = npar = 0;
                    187:        for ( ;; ) {
                    188:                c = input();
                    189:                if (c == EOF)
                    190:                        ERROR "end of file in getarg!" FATAL;
                    191:                if (npar == 0 && (c == ',' || c == ')'))
                    192:                        break;
                    193:                if (c == '"')   /* copy quoted stuff intact */
                    194:                        do {
                    195:                                *p++ = c;
                    196:                                n++;
                    197:                        } while ((c = input()) != '"' && c != EOF);
                    198:                else if (c == '(')
                    199:                        npar++;
                    200:                else if (c == ')')
                    201:                        npar--;
                    202:                n++;
                    203:                *p++ = c;
                    204:        }
                    205:        *p = 0;
                    206:        unput(c);
                    207:        return(n + 1);
                    208: }
                    209: 
                    210: #define        PBSIZE  2000
                    211: char   pbuf[PBSIZE];           /* pushback buffer */
                    212: char   *pb     = pbuf-1;       /* next pushed back character */
                    213: 
                    214: char   ebuf[200];              /* collect input here for error reporting */
                    215: char   *ep     = ebuf;
                    216: 
                    217: int    begin   = 0;
                    218: extern int     thru;
                    219: extern Obj     *thrudef;
                    220: extern char    *untilstr;
                    221: 
                    222: input()
                    223: {
                    224:        register int c;
                    225: 
                    226:        if (thru && begin) {
                    227:                do_thru();
                    228:                begin = 0;
                    229:        }
                    230:        c = nextchar();
                    231:        dprintf(" <%c>", c);
                    232:        if (ep >= ebuf + sizeof ebuf)
                    233:                ep = ebuf;
                    234:        return *ep++ = c;
                    235: }
                    236: 
                    237: nextchar()
                    238: {
                    239:        register int c;
                    240: 
                    241:   loop:
                    242:        switch (srcp->type) {
                    243:        case Free:      /* free string */
                    244:                free(srcp->sp);
                    245:                popsrc();
                    246:                goto loop;
                    247:        case Thru:      /* end of pushed back line */
                    248:                begin = 1;
                    249:                popsrc();
                    250:                c = '\n';
                    251:                break;
                    252:        case Char:
                    253:                if (pb >= pbuf) {
                    254:                        c = *pb--;
                    255:                        popsrc();
                    256:                        break;
                    257:                } else {        /* can't happen? */
                    258:                        popsrc();
                    259:                        goto loop;
                    260:                }
                    261:        case String:
                    262:                c = *srcp->sp++;
                    263:                if (c == '\0') {
                    264:                        popsrc();
                    265:                        goto loop;
                    266:                } else {
                    267:                        if (*srcp->sp == '\0')  /* empty, so pop */
                    268:                                popsrc();
                    269:                        break;
                    270:                }
                    271:        case Macro:
                    272:                c = *srcp->sp++;
                    273:                if (c == '\0') {
                    274:                        if (--argfp < args)
                    275:                                ERROR "argfp underflow" FATAL;
                    276:                        popsrc();
                    277:                        goto loop;
                    278:                } else if (c == '$' && isdigit(*srcp->sp)) {
                    279:                        int n = 0;
                    280:                        while (isdigit(*srcp->sp))
                    281:                                n = 10 * n + *srcp->sp++ - '0';
                    282:                        if (n > 0 && n <= MAXARGS)
                    283:                                pushsrc(String, argfp->argstk[n-1]);
                    284:                        goto loop;
                    285:                }
                    286:                break;
                    287:        case File:
                    288:                c = getc(curfile->fin);
                    289:                if (c == EOF) {
                    290:                        if (curfile == infile)
                    291:                                ERROR "end of file inside .G1/.G2" FATAL;
                    292:                        if (curfile->fin != stdin) {
                    293:                                fclose(curfile->fin);
                    294:                                free(curfile->fname);   /* assumes allocated */
                    295:                        }
                    296:                        curfile--;
                    297:                        printf(".lf %d %s\n", curfile->lineno, curfile->fname);
                    298:                        popsrc();
                    299:                        thru = 0;       /* chicken out */
                    300:                        thrudef = 0;
                    301:                        if (untilstr) {
                    302:                                free(untilstr);
                    303:                                untilstr = 0;
                    304:                        }
                    305:                        goto loop;
                    306:                }
                    307:                if (c == '\n')
                    308:                        curfile->lineno++;
                    309:                break;
                    310:        }
                    311:        return c;
                    312: }
                    313: 
                    314: do_thru()      /* read one line, make into a macro expansion */
                    315: {
                    316:        int c, i;
                    317:        char *p;
                    318:        Arg *ap;
                    319: 
                    320:        ap = argfp+1;
                    321:        if (ap >= args+10)
                    322:                ERROR "arguments too deep" FATAL;
                    323:        if (ap->argval == NULL)
                    324:                ap->argval = malloc(1000);
                    325:        p = ap->argval;
                    326:        argcnt = 0;
                    327:        c = nextchar();
                    328:        if (thru == 0) {        /* end of file was seen, so thru is done */
                    329:                unput(c);
                    330:                return;
                    331:        }
                    332:        for ( ; c != '\n' && c != EOF; ) {
                    333:                if (c == ' ' || c == '\t') {
                    334:                        c = nextchar();
                    335:                        continue;
                    336:                }
                    337:                if (argcnt >= MAXARGS)
                    338:                        ERROR "too many fields on input line" FATAL;
                    339:                ap->argstk[argcnt++] = p;
                    340:                if (c == '"') {
                    341:                        do {
                    342:                                *p++ = c;
                    343:                                if ((c = nextchar()) == '\\') {
                    344:                                        *p++ = c;
                    345:                                        *p++ = nextchar();
                    346:                                        c = nextchar();
                    347:                                }
                    348:                        } while (c != '"' && c != '\n' && c != EOF);
                    349:                        *p++ = '"';
                    350:                        if (c == '"')
                    351:                                c = nextchar();
                    352:                } else {
                    353:                        do {
                    354:                                *p++ = c;
                    355:                        } while ((c = nextchar())!=' ' && c!='\t' && c!='\n' && c!=',' && c!=EOF);
                    356:                        if (c == ',')
                    357:                                c = nextchar();
                    358:                }
                    359:                *p++ = '\0';
                    360:        }
                    361:        if (c == EOF)
                    362:                ERROR "unexpected end of file in do_thru" FATAL;
                    363:        if (argcnt == 0) {      /* ignore blank line */
                    364:                pushsrc(Thru, (char *) 0);
                    365:                return;
                    366:        }
                    367:        for (i = argcnt; i < MAXARGS; i++)
                    368:                ap->argstk[i] = "";
                    369:        if (dbg)
                    370:                for (i = 0; i < argcnt; i++)
                    371:                        printf("arg %d.%d = <%s>\n", ap-args, i+1, ap->argstk[i]);
                    372:        if (strcmp(ap->argstk[0], ".G2") == 0) {
                    373:                thru = 0;
                    374:                thrudef = 0;
                    375:                pushsrc(String, "\n.G2\n");
                    376:                return;
                    377:        }
                    378:        if (untilstr && strcmp(ap->argstk[0], untilstr) == 0) {
                    379:                thru = 0;
                    380:                thrudef = 0;
                    381:                free(untilstr);
                    382:                untilstr = 0;
                    383:                return;
                    384:        }
                    385:        pushsrc(Thru, (char *) 0);
                    386:        dprintf("do_thru pushing back <%s>\n", thrudef->val);
                    387:        argfp = ap;
                    388:        pushsrc(Macro, thrudef->val);
                    389: }
                    390: 
                    391: unput(c)
                    392: {
                    393:        if (++pb >= pbuf + sizeof pbuf)
                    394:                ERROR "pushback overflow" FATAL;
                    395:        if (--ep < ebuf)
                    396:                ep = ebuf + sizeof(ebuf) - 1;
                    397:        *pb = c;
                    398:        pushsrc(Char, pb);
                    399:        return c;
                    400: }
                    401: 
                    402: pbstr(s)
                    403:        char *s;
                    404: {
                    405:        pushsrc(String, s);
                    406: }
                    407: 
                    408: double errcheck(x, s)
                    409:        double x;
                    410:        char *s;
                    411: {
                    412:        extern int errno;
                    413: 
                    414:        if (errno == EDOM) {
                    415:                errno = 0;
                    416:                ERROR "%s argument out of domain", s WARNING;
                    417:        } else if (errno == ERANGE) {
                    418:                errno = 0;
                    419:                ERROR "%s result out of range", s WARNING;
                    420:        }
                    421:        return x;
                    422: }
                    423: 
                    424: char   errbuf[200];
                    425: 
                    426: yyerror(s)
                    427:        char *s;
                    428: {
                    429:        extern char *cmdname, *sys_errlist[];
                    430:        extern int errno, sys_nerr;
                    431: 
                    432:        if (synerr)
                    433:                return;
                    434:        fflush(stdout);
                    435:        fprintf(stderr, "%s: %s", cmdname, s);
                    436:        if (errno > 0 && errno < sys_nerr)
                    437:                fprintf(stderr, " (%s)", sys_errlist[errno]);
                    438:        fprintf(stderr, " near line %d, file %s\n",
                    439:                curfile->lineno, curfile->fname);
                    440:        eprint();
                    441:        synerr = 1;
                    442:        errno = 0;
                    443: }
                    444: 
                    445: eprint()       /* try to print context around error */
                    446: {
                    447:        char *p, *q;
                    448: 
                    449:        p = ep - 1;
                    450:        if (p > ebuf && *p == '\n')
                    451:                p--;
                    452:        for ( ; p >= ebuf && *p != '\n'; p--)
                    453:                ;
                    454:        while (*p == '\n')
                    455:                p++;
                    456:        fprintf(stderr, " context is\n\t");
                    457:        for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--)
                    458:                ;
                    459:        while (p < q)
                    460:                putc(*p++, stderr);
                    461:        fprintf(stderr, " >>> ");
                    462:        while (p < ep)
                    463:                putc(*p++, stderr);
                    464:        fprintf(stderr, " <<< ");
                    465:        while (pb >= pbuf)
                    466:                putc(*pb--, stderr);
                    467:        fgets(ebuf, sizeof ebuf, curfile->fin);
                    468:        fprintf(stderr, "%s", ebuf);
                    469:        pbstr("\n.G2\n");       /* safety first */
                    470:        ep = ebuf;
                    471: }
                    472: 
                    473: yywrap() {;}
                    474: 
                    475: char   *newfile = 0;           /* filename for file copy */
                    476: char   *untilstr = 0;          /* string that terminates a thru */
                    477: int    thru    = 0;            /* 1 if copying thru macro */
                    478: Obj    *thrudef = 0;           /* macro being used */
                    479: 
                    480: copyfile(s)    /* remember file to start reading from */
                    481:        char *s;
                    482: {
                    483:        newfile = s;
                    484: }
                    485: 
                    486: copydef(p)     /* remember macro Obj */
                    487:        Obj *p;
                    488: {
                    489:        thrudef = p;
                    490: }
                    491: 
                    492: Obj *copythru(s)       /* collect the macro name or body for thru */
                    493:        char *s;
                    494: {
                    495:        Obj *p;
                    496:        char *q, *addnewline();
                    497: 
                    498:        p = lookup(s, 0);
                    499:        if (p != NULL) {
                    500:                if (p->type == DEFNAME) {
                    501:                        p->val = addnewline(p->val);
                    502:                        return p;
                    503:                } else
                    504:                        ERROR "%s used as define and name", s FATAL;
                    505:        }
                    506:        /* have to collect the definition */
                    507:        pbstr(s);       /* first char is the delimiter */
                    508:        q = delimstr("thru body");
                    509:        p = lookup("nameless", 1);
                    510:        if (p != NULL)
                    511:                if (p->val)
                    512:                        free(p->val);
                    513:        p->type = DEFNAME;
                    514:        p->val = q;
                    515:        p->val = addnewline(p->val);
                    516:        dprintf("installing nameless as `%s'\n", p->val);
                    517:        return p;
                    518: }
                    519: 
                    520: char *addnewline(p)    /* add newline to end of p */
                    521:        char *p;
                    522: {
                    523:        int n;
                    524:        extern char *realloc();
                    525: 
                    526:        n = strlen(p);
                    527:        if (p[n-1] != '\n') {
                    528:                p = realloc(p, n+2);
                    529:                p[n] = '\n';
                    530:                p[n+1] = '\0';
                    531:        }
                    532:        return p;
                    533: }
                    534: 
                    535: copyuntil(s)   /* string that terminates a thru */
                    536:        char *s;
                    537: {
                    538:        untilstr = s;
                    539: }
                    540: 
                    541: copy() /* begin input from file, etc. */
                    542: {
                    543:        FILE *fin;
                    544: 
                    545:        if (newfile) {
                    546:                if ((fin = fopen(newfile, "r")) == NULL)
                    547:                        ERROR "can't open file %s", newfile FATAL;
                    548:                curfile++;
                    549:                curfile->fin = fin;
                    550:                curfile->fname = tostring(newfile);
                    551:                curfile->lineno = 0;
                    552:                printf(".lf 1 %s\n", curfile->fname);
                    553:                pushsrc(File, curfile->fname);
                    554:                newfile = 0;
                    555:        }
                    556:        if (thrudef) {
                    557:                thru = 1;
                    558:                begin = 1;      /* wrong place */
                    559:        }
                    560: }
                    561: 
                    562: char   shellbuf[1000], *shellp;
                    563: 
                    564: shell_init()   /* set up to interpret a shell command */
                    565: {
                    566:        fprintf(tfd, "# shell cmd...\n");
                    567:        sprintf(shellbuf, "sh -c '");
                    568:        shellp = shellbuf + strlen(shellbuf);
                    569: }
                    570: 
                    571: shell_text(s)  /* add string to command being collected */
                    572:        char *s;
                    573: {
                    574:        /* fprintf(tfd, "#add <%s> to <%s>\n", s, shellbuf); */
                    575:        while (*s) {
                    576:                if (*s == '\'') {       /* protect interior quotes */
                    577:                        *shellp++ = '\'';
                    578:                        *shellp++ = '\\';
                    579:                        *shellp++ = '\'';
                    580:                }
                    581:                *shellp++ = *s++;
                    582:        }
                    583: }
                    584: 
                    585: shell_exec()   /* do it */
                    586: {
                    587:        /* fprintf(tfd, "# run <%s>\n", shellbuf); */
                    588:        *shellp++ = '\'';
                    589:        *shellp = '\0';
                    590:        system(shellbuf);
                    591: }

unix.superglobalmegacorp.com

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