Annotation of researchv10no/cmd/troff/n1.c, revision 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.