Annotation of researchv10no/cmd/troff/n1.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * n1.c
                      3:  *
                      4:  *     consume options, initialization, main loop,
                      5:  *     input routines, escape function calling
                      6:  */
                      7: 
                      8: #include "tdef.h"
                      9: #include "fns.h"
                     10: #include "ext.h"
                     11: 
                     12: #include <setjmp.h>
                     13: #include <time.h>
                     14: 
                     15: char   *Version        = "Dec 1, 1992";
                     16: 
                     17: int    TROFF   = 1;    /* assume we started in troff... */
                     18: 
                     19: jmp_buf sjbuf;
                     20: Offset ipl[NSO];
                     21: 
                     22: static FILE    *ifile  = stdin;
                     23: static FILE    *ifl[NSO];      /* open input file pointers */
                     24: char   cfname[NSO+1][NS] = {  "stdin" };       /* file name stack */
                     25: int    cfline[NSO];            /* input line count stack */
                     26: char   *progname;              /* program name (troff or nroff) */
                     27: 
                     28: int    trace = 0;      /* tracing flag */
                     29: #define TRMAC 01               /* trace macros */
                     30: #define TRREQ 02               /* trace requests */
                     31: 
                     32: main(int argc, char *argv[])
                     33: {
                     34:        char *p;
                     35:        int j;
                     36:        Tchar i;
                     37:        int eileenct;           /* count to test for "Eileen's loop" */
                     38:        char buf[100];
                     39: 
                     40:        progname = argv[0];
                     41:        if ((p = strrchr(progname, '/')) == NULL)
                     42:                p = progname;
                     43:        else
                     44:                p++;
                     45:        if (strcmp(p, "nroff") == 0)
                     46:                TROFF = 0;
                     47:        if ((p = getenv("TYPESETTER")) != 0)
                     48:                strcpy(devname, p);
                     49:        mrehash();
                     50:        nrehash();
                     51:        numtab[NL].val = -1;
                     52: 
                     53:        while (--argc > 0 && (++argv)[0][0] == '-')
                     54:                switch (argv[0][1]) {
                     55: 
                     56:                case 'N':       /* ought to be used first... */
                     57:                        TROFF = 0;
                     58:                        break;
                     59:                case 'd':
                     60:                        fprintf(stderr, "troff/nroff version %s\n", Version);
                     61:                        break;
                     62:                case 'F':       /* switch font tables from default */
                     63:                        if (argv[0][2] != '\0') {
                     64:                                strcpy(termtab, &argv[0][2]);
                     65:                                strcpy(fontdir, &argv[0][2]);
                     66:                        } else {
                     67:                                argv++; argc--;
                     68:                                strcpy(termtab, argv[0]);
                     69:                                strcpy(fontdir, argv[0]);
                     70:                        }
                     71:                        break;
                     72:                case 0:
                     73:                        goto start;
                     74:                case 'i':
                     75:                        stdi++;
                     76:                        break;
                     77:                case 'n':
                     78:                        npn = atoi(&argv[0][2]);
                     79:                        break;
                     80:                case 'u':       /* set emboldening amount */
                     81:                        bdtab[3] = atoi(&argv[0][2]);
                     82:                        if (bdtab[3] < 0 || bdtab[3] > 50)
                     83:                                bdtab[3] = 0;
                     84:                        break;
                     85:                case 's':
                     86:                        if (!(stop = atoi(&argv[0][2])))
                     87:                                stop++;
                     88:                        break;
                     89:                case 'r':
                     90:                        sprintf(buf + strlen(buf), ".nr %c %s\n",
                     91:                                argv[0][2], &argv[0][3]);
                     92:                        cpushback(buf);
                     93:                        /* dotnr(&argv[0][2], &argv[0][3]); */
                     94:                        break;
                     95:                case 'm':
                     96:                        if (mflg++ >= NMF) {
                     97:                                ERROR "Too many macro packages: %s", argv[0] WARN;
                     98:                                break;
                     99:                        }
                    100:                        strcpy(mfiles[nmfi], nextf);
                    101:                        strcat(mfiles[nmfi++], &argv[0][2]);
                    102:                        break;
                    103:                case 'o':
                    104:                        getpn(&argv[0][2]);
                    105:                        break;
                    106:                case 'T':
                    107:                        strcpy(devname, &argv[0][2]);
                    108:                        dotT++;
                    109:                        break;
                    110:                case 'a':
                    111:                        ascii = 1;
                    112:                        break;
                    113:                case 'h':
                    114:                        hflg++;
                    115:                        break;
                    116:                case 'e':
                    117:                        eqflg++;
                    118:                        break;
                    119:                case 'q':
                    120:                        quiet++;
                    121:                        save_tty();
                    122:                        break;
                    123:                default:
                    124:                        ERROR "unknown option %s", argv[0] WARN;
                    125:                        done(02);
                    126:                }
                    127: 
                    128: start:
                    129:        argp = argv;
                    130:        rargc = argc;
                    131:        nmfi = 0;
                    132:        init2();
                    133:        setjmp(sjbuf);
                    134:        eileenct = 0;           /*reset count for "Eileen's loop"*/
                    135:                                /* this is a really sick bit of code */
                    136:                                /* but i've never been able to figure out */
                    137:                                /* how to fix it. */
                    138: loop:
                    139:        copyf = lgf = nb = nflush = nlflg = 0;
                    140:        if (ip && rbf0(ip) == 0 && ejf && frame->pframe <= ejl) {
                    141:                nflush++;
                    142:                trap = 0;
                    143:                eject((Stack *)0);
                    144:                if (eileenct > 20) {
                    145:                        ERROR "job looping; check abuse of macros" WARN;
                    146:                        ejf = 0;        /* try to break Eileen's loop */
                    147:                        eileenct = 0;
                    148:                } else
                    149:                        eileenct++;
                    150:                goto loop;
                    151:        }
                    152:        eileenct = 0;           /*reset count for "Eileen's loop"*/
                    153:        i = getch();
                    154:        if (pendt)
                    155:                goto Lt;
                    156:        if ((j = cbits(i)) == XPAR) {
                    157:                copyf++;
                    158:                tflg++;
                    159:                while (cbits(i) != '\n')
                    160:                        pchar(i = getch());
                    161:                tflg = 0;
                    162:                copyf--;
                    163:                goto loop;
                    164:        }
                    165:        if (j == cc || j == c2) {
                    166:                if (j == c2)
                    167:                        nb++;
                    168:                copyf++;
                    169:                while ((j = cbits(i = getch())) == ' ' || j == '\t')
                    170:                        ;
                    171:                ch = i;
                    172:                copyf--;
                    173:                control(getrq(), 1);
                    174:                flushi();
                    175:                goto loop;
                    176:        }
                    177: Lt:
                    178:        ch = i;
                    179:        text();
                    180:        if (nlflg)
                    181:                numtab[HP].val = 0;
                    182:        goto loop;
                    183: }
                    184: 
                    185: 
                    186: 
                    187: void init2(void)
                    188: {
                    189:        int i;
                    190:        char buf[100];
                    191: 
                    192:        for (i = NTRTAB; --i; )
                    193:                trtab[i] = i;
                    194:        trtab[UNPAD] = ' ';
                    195:        iflg = 0;
                    196:        obufp = obuf;
                    197:        if (TROFF)
                    198:                t_ptinit();
                    199:        else
                    200:                n_ptinit();
                    201:        mchbits();
                    202:        cvtime();
                    203:        numtab[PID].val = getpid();
                    204:        olinep = oline;
                    205:        numtab[HP].val = init = 0;
                    206:        numtab[NL].val = -1;
                    207:        nfo = 0;
                    208:        copyf = raw = 0;
                    209:        sprintf(buf, ".ds .T %s\n", devname);
                    210:        cpushback(buf);
                    211:        numtab[CD].val = -1;    /* compensation */
                    212:        nx = mflg;
                    213:        frame = stk = (Stack *)setbrk(STACKSIZE);
                    214:        dip = &d[0];
                    215:        nxf = frame + 1;
                    216:        for (i = 1; i < NEV; i++)       /* propagate the environment */
                    217:                envcopy(&env[i], &env[0]);
                    218:        blockinit();
                    219: }
                    220: 
                    221: void cvtime(void)
                    222: {
                    223:        long tt;
                    224:        struct tm *ltime;
                    225: 
                    226:        time(&tt);
                    227:        ltime = localtime(&tt);
                    228:        numtab[YR].val = ltime->tm_year;
                    229:        numtab[MO].val = ltime->tm_mon + 1;     /* troff uses 1..12 */
                    230:        numtab[DY].val = ltime->tm_mday;
                    231:        numtab[DW].val = ltime->tm_wday + 1;    /* troff uses 1..7 */
                    232: }
                    233: 
                    234: 
                    235: 
                    236: char   errbuf[200];
                    237: 
                    238: void errprint(void)    /* error message printer */
                    239: {
                    240:        fprintf(stderr, "%s: ", progname);
                    241:        fputs(errbuf, stderr);
                    242:        if (numtab[CD].val > 0)
                    243:                fprintf(stderr, "; line %d, file %s", numtab[CD].val, cfname[ifi]);
                    244:        fputs("\n", stderr);
                    245:        stackdump();
                    246: }
                    247: 
                    248: 
                    249: int control(int a, int b)
                    250: {
                    251:        int j;
                    252: 
                    253:        if (a == 0 || (j = findmn(a)) == -1)
                    254:                return(0);
                    255:        if (contab[j].f == 0) {
                    256:                if (trace & TRMAC)
                    257:                        fprintf(stderr, "invoke macro %s\n", unpair(a));
                    258:                nxf->nargs = 0;
                    259:                if (b)
                    260:                        collect();
                    261:                flushi();
                    262:                return pushi(contab[j].mx, a);  /* BUG??? all that matters is 0/!0 */
                    263:        }
                    264:        if (b) {
                    265:                if (trace & TRREQ)
                    266:                        fprintf(stderr, "invoke request %s\n", unpair(a));
                    267:                 (*contab[j].f)();
                    268:        }
                    269:        return(0);
                    270: }
                    271: 
                    272: void casept(void)
                    273: {
                    274:        skip();
                    275:        noscale++;
                    276:        trace = atoi0();
                    277:        noscale = 0;
                    278: }
                    279:                
                    280: 
                    281: int getrq(void)
                    282: {
                    283:        int i, j;
                    284: 
                    285:        if ((i = getach()) == 0 || (j = getach()) == 0)
                    286:                goto rtn;
                    287:        i = PAIR(i, j);
                    288: rtn:
                    289:        return(i);
                    290: }
                    291: 
                    292: /*
                    293:  * table encodes some special characters, to speed up tests
                    294:  * in getch, viz FLSS, RPT, f, \b, \n, fc, tabch, ldrch
                    295:  */
                    296: 
                    297: char gchtab[NCHARS] = {
                    298:        000,004,000,000,010,000,000,000, /* fc, ldr */
                    299:        001,002,001,000,001,000,000,000, /* \b, tab, nl, RPT */
                    300:        000,000,000,000,000,000,000,000,
                    301:        000,001,000,001,000,000,000,000, /* FLSS, ESC */
                    302:        000,000,000,000,000,000,000,000,
                    303:        000,000,000,000,000,000,000,000,
                    304:        000,000,000,000,000,000,000,000,
                    305:        000,000,000,000,000,000,000,000,
                    306:        000,000,000,000,000,000,000,000,
                    307:        000,000,000,000,000,000,000,000,
                    308:        000,000,000,000,000,000,000,000,
                    309:        000,000,000,000,000,000,000,000,
                    310:        000,000,000,000,000,000,001,000, /* f */
                    311:        000,000,000,000,000,000,000,000,
                    312:        000,000,000,000,000,000,000,000,
                    313:        000,000,000,000,000,000,000,000,
                    314: };
                    315: 
                    316: int realcbits(Tchar c) /* return character bits, or MOTCH if motion */
                    317: {
                    318:        if (ismot(c))
                    319:                return MOTCH;
                    320:        else
                    321:                return c & 0xFFFF;
                    322: }
                    323: 
                    324: Tchar getch(void)
                    325: {
                    326:        int k;
                    327:        Tchar i, j;
                    328: 
                    329: g0:
                    330:        if (ch) {
                    331:                i = ch;
                    332:                if (cbits(i) == '\n')
                    333:                        nlflg++;
                    334:                ch = 0;
                    335:                return(i);
                    336:        }
                    337: 
                    338:        if (nlflg)
                    339:                return('\n');
                    340:        i = getch0();
                    341:        if (ismot(i))
                    342:                return(i);
                    343:        k = cbits(i);
                    344:        if (k >= sizeof(gchtab)/sizeof(gchtab[0]) || gchtab[k] == 0)    /* nothing special */
                    345:                return(i);
                    346:        if (k != ESC) {
                    347:                if (k == '\n') {
                    348:                        nlflg++;
                    349:                        if (ip == 0)
                    350:                                numtab[CD].val++; /* line number */
                    351:                        return(k);
                    352:                }
                    353:                if (k == FLSS) {
                    354:                        copyf++; 
                    355:                        raw++;
                    356:                        i = getch0();
                    357:                        if (!fi)
                    358:                                flss = i;
                    359:                        copyf--; 
                    360:                        raw--;
                    361:                        goto g0;
                    362:                }
                    363:                if (k == RPT) {
                    364:                        setrpt();
                    365:                        goto g0;
                    366:                }
                    367:                if (!copyf) {
                    368:                        if (k == 'f' && lg && !lgf) {
                    369:                                i = getlg(i);
                    370:                                return(i);
                    371:                        }
                    372:                        if (k == fc || k == tabch || k == ldrch) {
                    373:                                if ((i = setfield(k)) == 0)
                    374:                                        goto g0; 
                    375:                                else 
                    376:                                        return(i);
                    377:                        }
                    378:                        if (k == '\b') {
                    379:                                i = makem(-width(' ' | chbits));
                    380:                                return(i);
                    381:                        }
                    382:                }
                    383:                return(i);
                    384:        }
                    385: 
                    386:        k = cbits(j = getch0());
                    387:        if (ismot(j))
                    388:                return(j);
                    389: 
                    390:        switch (k) {
                    391:        case 'n':       /* number register */
                    392:                setn();
                    393:                goto g0;
                    394:        case '$':       /* argument indicator */
                    395:                seta();
                    396:                goto g0;
                    397:        case '*':       /* string indicator */
                    398:                setstr();
                    399:                goto g0;
                    400:        case '{':       /* LEFT */
                    401:                i = LEFT;
                    402:                goto gx;
                    403:        case '}':       /* RIGHT */
                    404:                i = RIGHT;
                    405:                goto gx;
                    406:        case '"':       /* comment */
                    407:                while (cbits(i = getch0()) != '\n')
                    408:                        ;
                    409:                nlflg++;
                    410:                if (ip == 0)
                    411:                        numtab[CD].val++;
                    412:                return(i);
                    413: 
                    414: /* experiment: put it here instead of copy mode */
                    415:        case '(':       /* special char name \(xx */
                    416:        case 'C':       /*              \C'...' */
                    417:                if ((i = setch(k)) == 0)
                    418:                        goto g0;
                    419:                goto gx;
                    420: 
                    421:        case ESC:       /* double backslash */
                    422:                i = eschar;
                    423:                goto gx;
                    424:        case 'e':       /* printable version of current eschar */
                    425:                i = PRESC;
                    426:                goto gx;
                    427:        case '\n':      /* concealed newline */
                    428:                goto g0;
                    429:        case ' ':       /* unpaddable space */
                    430:                i = UNPAD;
                    431:                goto gx;
                    432:        case '\'':      /* \(aa */
                    433:                i = ACUTE;
                    434:                goto gx;
                    435:        case '`':       /* \(ga */
                    436:                i = GRAVE;
                    437:                goto gx;
                    438:        case '_':       /* \(ul */
                    439:                i = UNDERLINE;
                    440:                goto gx;
                    441:        case '-':       /* current font minus */
                    442:                i = MINUS;
                    443:                goto gx;
                    444:        case '&':       /* filler */
                    445:                i = FILLER;
                    446:                goto gx;
                    447:        case 'c':       /* to be continued */
                    448:                i = CONT;
                    449:                goto gx;
                    450:        case '!':       /* transparent indicator */
                    451:                i = XPAR;
                    452:                goto gx;
                    453:        case 't':       /* tab */
                    454:                i = '\t';
                    455:                return(i);
                    456:        case 'a':       /* leader (SOH) */
                    457: /* old:                *pbp++ = LEADER; goto g0; */
                    458:                i = LEADER;
                    459:                return i;
                    460:        case '%':       /* ohc */
                    461:                i = OHC;
                    462:                return(i);
                    463:        case 'g':       /* return format of a number register */
                    464:                setaf();        /* should this really be in copy mode??? */
                    465:                goto g0;
                    466:        case '.':       /* . */
                    467:                i = '.';
                    468: gx:
                    469:                setsfbits(i, sfbits(j));
                    470:                return(i);
                    471:        }
                    472:        if (copyf) {
                    473:                *pbp++ = j;
                    474:                return(eschar);
                    475:        }
                    476:        switch (k) {
                    477: 
                    478:        case 'f':       /* font indicator */
                    479:                setfont(0);
                    480:                goto g0;
                    481:        case 's':       /* size indicator */
                    482:                setps();
                    483:                goto g0;
                    484:        case 'v':       /* vert mot */
                    485:                if (i = vmot()) {
                    486:                        return(i);
                    487:                }
                    488:                goto g0;
                    489:        case 'h':       /* horiz mot */
                    490:                if (i = hmot())
                    491:                        return(i);
                    492:                goto g0;
                    493:        case '|':       /* narrow space */
                    494:                if (NROFF)
                    495:                        goto g0;
                    496:                return(makem((int)(EM)/6));
                    497:        case '^':       /* half narrow space */
                    498:                if (NROFF)
                    499:                        goto g0;
                    500:                return(makem((int)(EM)/12));
                    501:        case 'w':       /* width function */
                    502:                setwd();
                    503:                goto g0;
                    504:        case 'p':       /* spread */
                    505:                spread++;
                    506:                goto g0;
                    507:        case 'N':       /* absolute character number */
                    508:                if ((i = setabs()) == 0)
                    509:                        goto g0;
                    510:                return i;
                    511:        case 'H':       /* character height */
                    512:                return(setht());
                    513:        case 'S':       /* slant */
                    514:                return(setslant());
                    515:        case 'z':       /* zero with char */
                    516:                return(setz());
                    517:        case 'l':       /* hor line */
                    518:                setline();
                    519:                goto g0;
                    520:        case 'L':       /* vert line */
                    521:                setvline();
                    522:                goto g0;
                    523:        case 'D':       /* drawing function */
                    524:                setdraw();
                    525:                goto g0;
                    526:        case 'X':       /* \X'...' for copy through */
                    527:                setxon();
                    528:                goto g0;
                    529:        case 'b':       /* bracket */
                    530:                setbra();
                    531:                goto g0;
                    532:        case 'o':       /* overstrike */
                    533:                setov();
                    534:                goto g0;
                    535:        case 'k':       /* mark hor place */
                    536:                if ((k = findr(getsn())) != -1) {
                    537:                        numtab[k].val = numtab[HP].val;
                    538:                }
                    539:                goto g0;
                    540:        case '0':       /* number space */
                    541:                return(makem(width('0' | chbits)));
                    542:        case 'x':       /* extra line space */
                    543:                if (i = xlss())
                    544:                        return(i);
                    545:                goto g0;
                    546:        case 'u':       /* half em up */
                    547:        case 'r':       /* full em up */
                    548:        case 'd':       /* half em down */
                    549:                return(sethl(k));
                    550:        default:
                    551:                return(j);
                    552:        }
                    553:        /* NOTREACHED */
                    554: }
                    555: 
                    556: void setxon(void)      /* \X'...' for copy through */
                    557: {
                    558:        Tchar xbuf[NC];
                    559:        Tchar *i;
                    560:        Tchar c;
                    561:        int delim, k;
                    562: 
                    563:        if (ismot(c = getch()))
                    564:                return;
                    565:        delim = cbits(c);
                    566:        i = xbuf;
                    567:        *i++ = XON | chbits;
                    568:        while ((k = cbits(c = getch())) != delim && k != '\n' && i < xbuf+NC-1) {
                    569:                if (k == ' ')
                    570:                        setcbits(c, WORDSP);
                    571:                *i++ = c | ZBIT;
                    572:        }
                    573:        *i++ = XOFF | chbits;
                    574:        *i = 0;
                    575:        pushback(xbuf);
                    576: }
                    577: 
                    578: 
                    579: char   ifilt[32] = { 0, 001, 002, 003, 0, 005, 006, 007, 010, 011, 012 };
                    580: 
                    581: Tchar getch0(void)
                    582: {
                    583:        int j;
                    584:        Tchar i;
                    585: 
                    586: again:
                    587:        if (pbp > lastpbp)
                    588:                i = *--pbp;
                    589:        else if (ip) {
                    590:                /* i = rbf(); */
                    591:                i = rbf0(ip);
                    592:                if (i == 0)
                    593:                        i = rbf();
                    594:                else {
                    595:                        ++ip;
                    596:                        if (pastend(ip)) {
                    597:                                --ip;
                    598:                                rbf();
                    599:                        }
                    600:                }
                    601:        } else {
                    602:                if (donef || ndone)
                    603:                        done(0);
                    604:                if (nx || 1) {  /* BUG: was ibufp >= eibuf, so EOF test is wrong */
                    605:                        if (nfo < 0)
                    606:                                ERROR "in getch0, nfo = %d", nfo WARN;
                    607:                        if (nfo == 0) {
                    608: g0:
                    609:                                if (nextfile()) {
                    610:                                        if (ip)
                    611:                                                goto again;
                    612:                                }
                    613:                        }
                    614:                        nx = 0;
                    615:                        if ((i = getc(ifile)) == EOF)
                    616:                                goto g0;
                    617:                        if (ip)
                    618:                                goto again;
                    619:                }
                    620: g2:
                    621:                if (i >= 040)                   /* zapped: && i < 0177 */
                    622:                        goto g4;
                    623:                i = ifilt[i];
                    624:        }
                    625:        if (cbits(i) == IMP && !raw)
                    626:                goto again;
                    627:        if (i == 0 && !init && !raw) {          /* zapped:  || i == 0177 */
                    628:                goto again;
                    629:        }
                    630: g4:
                    631:        if (ismot(i))
                    632:                return i;
                    633:        if (copyf == 0 && sfbits(i) == 0)
                    634:                i |= chbits;
                    635:        if (cbits(i) == eschar && !raw)
                    636:                setcbits(i, ESC);
                    637:        return(i);
                    638: }
                    639: 
                    640: void pushback(Tchar *b)
                    641: {
                    642:        Tchar *ob = b;
                    643: 
                    644:        while (*b++)
                    645:                ;
                    646:        b--;
                    647:        while (b > ob && pbp < &pbbuf[NC-3])
                    648:                *pbp++ = *--b;
                    649:        if (pbp >= &pbbuf[NC-3]) {
                    650:                ERROR "pushback overflow" WARN;
                    651:                done(2);
                    652:        }
                    653: }
                    654: 
                    655: void cpushback(char *b)
                    656: {
                    657:        char *ob = b;
                    658: 
                    659:        while (*b++)
                    660:                ;
                    661:        b--;
                    662:        while (b > ob && pbp < &pbbuf[NC-3])
                    663:                *pbp++ = *--b;
                    664:        if (pbp >= &pbbuf[NC-3]) {
                    665:                ERROR "cpushback overflow" WARN;
                    666:                done(2);
                    667:        }
                    668: }
                    669: 
                    670: int nextfile(void)
                    671: {
                    672:        char *p;
                    673: 
                    674: n0:
                    675:        if (ifile != stdin)
                    676:                fclose(ifile);
                    677:        if (ifi > 0 && !nx) {
                    678:                if (popf())
                    679:                        goto n0; /* popf error */
                    680:                return(1);       /* popf ok */
                    681:        }
                    682:        if (nx || nmfi < mflg) {
                    683:                p = mfiles[nmfi++];
                    684:                if (*p != 0)
                    685:                        goto n1;
                    686:        }
                    687:        if (rargc-- <= 0) {
                    688:                if ((nfo -= mflg) && !stdi) {
                    689:                        done(0);
                    690: }
                    691:                nfo++;
                    692:                numtab[CD].val = stdi = mflg = 0;
                    693:                ifile = stdin;
                    694:                strcpy(cfname[ifi], "stdin");
                    695:                return(0);
                    696:        }
                    697:        p = (argp++)[0];
                    698: n1:
                    699:        numtab[CD].val = 0;
                    700:        if (p[0] == '-' && p[1] == 0) {
                    701:                ifile = stdin;
                    702:                strcpy(cfname[ifi], "stdin");
                    703:        } else if ((ifile = fopen(p, "r")) == NULL) {
                    704:                ERROR "cannot open file %s", p WARN;
                    705:                nfo -= mflg;
                    706:                done(02);
                    707:        } else
                    708:                strcpy(cfname[ifi],p);
                    709:        nfo++;
                    710:        return(0);
                    711: }
                    712: 
                    713: 
                    714: popf(void)
                    715: {
                    716:        --ifi;
                    717:        if (ifi < 0) {
                    718:                ERROR "popf went negative" WARN;
                    719:                return 1;
                    720:        }
                    721:        numtab[CD].val = cfline[ifi];   /* restore line counter */
                    722:        ip = ipl[ifi];                  /* input pointer */
                    723:        ifile = ifl[ifi];               /* input FILE * */
                    724:        return(0);
                    725: }
                    726: 
                    727: 
                    728: void flushi(void)
                    729: {
                    730:        if (nflush)
                    731:                return;
                    732:        ch = 0;
                    733:        copyf++;
                    734:        while (!nlflg) {
                    735:                if (donef && frame == stk)
                    736:                        break;
                    737:                getch();
                    738:        }
                    739:        copyf--;
                    740: }
                    741: 
                    742: 
                    743: getach(void)   /* return ascii/alphabetic character */
                    744: {
                    745:        Tchar i;
                    746:        int j;
                    747: 
                    748:        lgf++;
                    749:        j = cbits(i = getch());
                    750:        if (ismot(i) || !isgraph(j)) {
                    751:                ch = i;
                    752:                j = 0;
                    753:        }
                    754:        lgf--;
                    755:        return j;
                    756: }
                    757: 
                    758: 
                    759: void casenx(void)
                    760: {
                    761:        lgf++;
                    762:        skip();
                    763:        getname();
                    764:        nx++;
                    765:        if (nmfi > 0)
                    766:                nmfi--;
                    767:        strcpy(mfiles[nmfi], nextf);
                    768:        nextfile();
                    769:        nlflg++;
                    770:        ip = 0;
                    771:        pendt = 0;
                    772:        frame = stk;
                    773:        nxf = frame + 1;
                    774: }
                    775: 
                    776: 
                    777: getname(void)
                    778: {
                    779:        int j, k;
                    780:        Tchar i;
                    781: 
                    782:        lgf++;
                    783:        for (k = 0; k < NS - 1; k++) {
                    784:                j = getach();
                    785:                if (!j)
                    786:                        break;
                    787:                nextf[k] = j;
                    788:        }
                    789:        nextf[k] = 0;
                    790:        lgf--;
                    791:        return(nextf[0]);
                    792: }
                    793: 
                    794: 
                    795: void caseso(void)
                    796: {
                    797:        FILE *fp;
                    798:        char *p, *q;
                    799: 
                    800:        lgf++;
                    801:        nextf[0] = 0;
                    802:        if (skip() || !getname() || (fp = fopen(nextf, "r")) == NULL || ifi >= NSO) {
                    803:                ERROR "can't open file %s", nextf WARN;
                    804:                done(02);
                    805:        }
                    806:        strcpy(cfname[ifi+1], nextf);
                    807:        cfline[ifi] = numtab[CD].val;           /*hold line counter*/
                    808:        numtab[CD].val = 0;
                    809:        flushi();
                    810:        ifl[ifi] = ifile;
                    811:        ifile = fp;
                    812:        ipl[ifi] = ip;
                    813:        ip = 0;
                    814:        nx++;
                    815:        nflush++;
                    816:        ifi++;
                    817: }
                    818: 
                    819: void caself(void)      /* set line number and file */
                    820: {
                    821:        int n;
                    822: 
                    823:        if (skip())
                    824:                return;
                    825:        n = atoi0();
                    826:        cfline[ifi] = numtab[CD].val = n - 2;
                    827:        if (skip())
                    828:                return;
                    829:        if (getname())
                    830:                strcpy(cfname[ifi], nextf);
                    831: }
                    832: 
                    833: 
                    834: void casecf(void)
                    835: {      /* copy file without change */
                    836:        int     fd, n;
                    837:        char    buf[1024];
                    838:        extern int hpos, esc, po;
                    839: 
                    840:        /* this may not make much sense in nroff... */
                    841: 
                    842:        lgf++;
                    843:        nextf[0] = 0;
                    844:        if (skip() || !getname() || (fd = open(nextf, 0)) < 0) {
                    845:                ERROR "can't open file %s", nextf WARN;
                    846:                done(02);
                    847:        }
                    848:        lgf--;
                    849: 
                    850:        /* make it into a clean state, be sure that everything is out */
                    851:        tbreak();
                    852:        hpos = po;
                    853:        esc = 0;
                    854:        ptesc();        /* to left margin */
                    855:        esc = un;
                    856:        ptesc();
                    857:        ptlead();
                    858:        ptps();
                    859:        ptfont();
                    860:        flusho();
                    861:        while ((n = read(fd, buf, sizeof buf)) > 0)
                    862:                fwrite(buf, n, 1, ptid);
                    863:        close(fd);
                    864:        ptps();
                    865:        ptfont();
                    866: }
                    867: 
                    868: void getline(char *s, int n)   /* get rest of input line into s */
                    869: {
                    870:        int i;
                    871: 
                    872:        lgf++;
                    873:        copyf++;
                    874:        skip();
                    875:        for (i = 0; i < n-1; i++)
                    876:                if ((s[i] = cbits(getch())) == '\n' || s[i] == RIGHT)
                    877:                        break;
                    878:        s[i] = 0;
                    879:        copyf--;
                    880:        lgf--;
                    881: }
                    882: 
                    883: void casesy(void)      /* call system */
                    884: {
                    885:        char sybuf[NTM];
                    886: 
                    887:        getline(sybuf, NTM);
                    888:        system(sybuf);
                    889: }
                    890: 
                    891: 
                    892: void getpn(char *a)
                    893: {
                    894:        int n, neg;
                    895: 
                    896:        if (*a == 0)
                    897:                return;
                    898:        neg = 0;
                    899:        for ( ; *a; a++)
                    900:                switch (*a) {
                    901:                case '+':
                    902:                case ',':
                    903:                        continue;
                    904:                case '-':
                    905:                        neg = 1;
                    906:                        continue;
                    907:                default:
                    908:                        n = 0;
                    909:                        if (isdigit(*a)) {
                    910:                                do
                    911:                                        n = 10 * n + *a++ - '0';
                    912:                                while (isdigit(*a));
                    913:                                a--;
                    914:                        } else
                    915:                                n = 9999;
                    916:                        *pnp++ = neg ? -n : n;
                    917:                        neg = 0;
                    918:                        if (pnp >= &pnlist[NPN-2]) {
                    919:                                ERROR "too many page numbers" WARN;
                    920:                                done3(-3);
                    921:                        }
                    922:                }
                    923:        if (neg)
                    924:                *pnp++ = -9999;
                    925:        *pnp = -INT_MAX;
                    926:        print = 0;
                    927:        pnp = pnlist;
                    928:        if (*pnp != -INT_MAX)
                    929:                chkpn();
                    930: }
                    931: 
                    932: 
                    933: void setrpt(void)
                    934: {
                    935:        Tchar i, j;
                    936: 
                    937:        copyf++;
                    938:        raw++;
                    939:        i = getch0();
                    940:        copyf--;
                    941:        raw--;
                    942:        if ((long) i < 0 || cbits(j = getch0()) == RPT)
                    943:                return;
                    944:        while (i > 0 && pbp < &pbbuf[NC-3]) {
                    945:                i--;
                    946:                *pbp++ = j;
                    947:        }
                    948: }

unix.superglobalmegacorp.com

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