Annotation of researchv9/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 <ctype.h>
                      9: #include <signal.h>
                     10: #include <sys/types.h>
                     11: #include <sys/stat.h>
                     12: #include <setjmp.h>
                     13: 
                     14: #include "tdef.h"
                     15: #include "ext.h"
                     16: 
                     17: #ifdef NROFF
                     18: #include "tw.h"
                     19: #endif
                     20: 
                     21: jmp_buf sjbuf;
                     22: extern char    *sprintf();
                     23: static char *sprintn();
                     24: static printn();
                     25: filep  ipl[NSO];
                     26: long   offl[NSO];
                     27: long   ioff;
                     28: char   cfname[NSO+1][NS] = {  "<standard input>" };    /*file name stack*/
                     29: int    cfline[NSO];            /*input line count stack*/
                     30: char   *progname;      /* program name (troff) */
                     31: 
                     32: main(argc, argv)
                     33: int    argc;
                     34: char   **argv;
                     35: {
                     36:        register char   *p;
                     37:        register j;
                     38:        register tchar i;
                     39:        extern catch(), kcatch();
                     40:        char    **oargv, *getenv();
                     41: 
                     42:        progname = argv[0];
                     43:        signal(SIGHUP, catch);
                     44:        if (signal(SIGINT, catch) == SIG_IGN) {
                     45:                signal(SIGHUP, SIG_IGN);
                     46:                signal(SIGINT, SIG_IGN);
                     47:                signal(SIGQUIT, SIG_IGN);
                     48:        }
                     49:        signal(SIGPIPE, catch);
                     50:        signal(SIGTERM, kcatch);
                     51:        oargv = argv;
                     52:        mrehash();
                     53:        nrehash();
                     54:        init0();
                     55: 
                     56: #ifdef NROFF
                     57:        if ((p = getenv("NROFFTERM")) != 0)
                     58:                strcpy(devname, p);
                     59: #else
                     60:        if ((p = getenv("TYPESETTER")) != 0)
                     61:                strcpy(devname, p);
                     62: #endif
                     63: 
                     64:        while (--argc > 0 && (++argv)[0][0] == '-')
                     65:                switch (argv[0][1]) {
                     66: 
                     67:                case 'F':       /* switch font tables from default */
                     68:                        if (argv[0][2] != '\0') {
                     69:                                strcpy(termtab, &argv[0][2]);
                     70:                                strcpy(fontdir, &argv[0][2]);
                     71:                        } else {
                     72:                                argv++; argc--;
                     73:                                strcpy(termtab, argv[0]);
                     74:                                strcpy(fontdir, argv[0]);
                     75:                        }
                     76:                        continue;
                     77:                case 0:
                     78:                        goto start;
                     79:                case 'i':
                     80:                        stdi++;
                     81:                        continue;
                     82:                case 'q':
                     83: #ifdef NROFF
                     84:                        quiet++;
                     85:                        save_tty();
                     86: #else
                     87:                        errprint("-q option ignored in troff");
                     88: #endif NROFF
                     89:                        continue;
                     90:                case 'n':
                     91:                        npn = ctoi(&argv[0][2]);
                     92:                        continue;
                     93:                case 'u':       /* set emboldening amount */
                     94:                        bdtab[3] = ctoi(&argv[0][2]);
                     95:                        if (bdtab[3] < 0 || bdtab[3] > 50)
                     96:                                bdtab[3] = 0;
                     97:                        continue;
                     98:                case 's':
                     99:                        if (!(stop = ctoi(&argv[0][2])))
                    100:                                stop++;
                    101:                        continue;
                    102:                case 'r':
                    103:                        eibuf = sprintf(ibuf+strlen(ibuf), ".nr %c %s\n",
                    104:                                argv[0][2], &argv[0][3]);
                    105:                        continue;
                    106:                case 'c':
                    107:                case 'm':
                    108:                        if (mflg++ >= NMF) {
                    109:                                errprint("Too many macro packages: %s", argv[0]);
                    110:                                continue;
                    111:                        }
                    112:                        strcpy (mfiles[nmfi], nextf);
                    113:                        strcat (mfiles[nmfi++], &argv[0][2]);
                    114:                        continue;
                    115:                case 'o':
                    116:                        getpn(&argv[0][2]);
                    117:                        continue;
                    118:                case 'T':
                    119:                        strcpy(devname, &argv[0][2]);
                    120:                        dotT++;
                    121:                        continue;
                    122: #ifdef NROFF
                    123:                case 'h':
                    124:                        hflg++;
                    125:                        continue;
                    126:                case 'z':
                    127:                        no_out++;
                    128:                        continue;
                    129:                case 'e':
                    130:                        eqflg++;
                    131:                        continue;
                    132: #endif
                    133: #ifndef NROFF
                    134:                case 'z':
                    135:                        no_out++;
                    136:                case 'a':
                    137:                        ascii = 1;
                    138:                        nofeed++;
                    139:                        continue;
                    140:                case 'f':
                    141:                        nofeed++;
                    142:                        continue;
                    143: #endif
                    144:                default:
                    145:                        errprint("unknown option %s", argv[0]);
                    146:                        done(02);
                    147:                }
                    148: 
                    149: start:
                    150:        init1(oargv[0][0]);
                    151:        argp = argv;
                    152:        rargc = argc;
                    153:        nmfi = 0;
                    154:        init2();
                    155:        setjmp(sjbuf);
                    156: loop:
                    157:        copyf = lgf = nb = nflush = nlflg = 0;
                    158:        if (ip && rbf0(ip) == 0 && ejf && frame->pframe <= ejl) {
                    159:                nflush++;
                    160:                trap = 0;
                    161:                eject((struct s *)0);
                    162:                goto loop;
                    163:        }
                    164:        i = getch();
                    165:        if (pendt)
                    166:                goto Lt;
                    167:        if ((j = cbits(i)) == XPAR) {
                    168:                copyf++;
                    169:                tflg++;
                    170:                while (cbits(i) != '\n')
                    171:                        pchar(i = getch());
                    172:                tflg = 0;
                    173:                copyf--;
                    174:                goto loop;
                    175:        }
                    176:        if (j == cc || j == c2) {
                    177:                if (j == c2)
                    178:                        nb++;
                    179:                copyf++;
                    180:                while ((j = cbits(i = getch())) == ' ' || j == '\t')
                    181:                        ;
                    182:                ch = i;
                    183:                copyf--;
                    184:                control(getrq(), 1);
                    185:                flushi();
                    186:                goto loop;
                    187:        }
                    188: Lt:
                    189:        ch = i;
                    190:        text();
                    191:        if (nlflg)
                    192:                numtab[HP].val = 0;
                    193:        goto loop;
                    194: }
                    195: 
                    196: 
                    197: catch()
                    198: {
                    199:        done3(01);
                    200: }
                    201: 
                    202: 
                    203: kcatch()
                    204: {
                    205:        signal(SIGTERM, SIG_IGN);
                    206:        done3(01);
                    207: }
                    208: 
                    209: 
                    210: init0()
                    211: {
                    212:        eibuf = ibufp = ibuf;
                    213:        ibuf[0] = 0;
                    214:        numtab[NL].val = -1;
                    215: }
                    216: 
                    217: 
                    218: init1(a)
                    219: char   a;
                    220: {
                    221:        register char   *p;
                    222:        char    *mktemp();
                    223:        register i;
                    224: 
                    225:        p = mktemp("/usr/tmp/trtmpXXXXX");
                    226:        if (a == 'a')
                    227:                p = &p[9];
                    228:        if ((close(creat(p, 0600))) < 0) {
                    229:                errprint("cannot create temp file.");
                    230:                exit(-1);
                    231:        }
                    232:        ibf = open(p, 2);
                    233:        unlkp = p;
                    234:        for (i = NTRTAB; --i; )
                    235:                trtab[i] = i;
                    236:        trtab[UNPAD] = ' ';
                    237: }
                    238: 
                    239: 
                    240: init2()
                    241: {
                    242:        register i;
                    243:        extern char     *setbrk();
                    244: 
                    245:        ttyod = 2;
                    246:        iflg = 0;
                    247:        obufp = obuf;
                    248:        ptinit();
                    249:        mchbits();
                    250:        cvtime();
                    251:        numtab[PID].val = getpid();
                    252:        olinep = oline;
                    253:        ioff = 0;
                    254:        numtab[HP].val = init = 0;
                    255:        numtab[NL].val = -1;
                    256:        nfo = 0;
                    257:        ifile = 0;
                    258:        copyf = raw = 0;
                    259:        eibuf = sprintf(ibuf+strlen(ibuf), ".ds .T %s\n", devname);
                    260:        numtab[CD].val = -1;    /* compensation */
                    261:        cpushback(ibuf);
                    262:        ibufp = ibuf;
                    263:        nx = mflg;
                    264:        frame = stk = (struct s *)setbrk(DELTA);
                    265:        dip = &d[0];
                    266:        nxf = frame + 1;
                    267: #ifdef INCORE
                    268:        for (i = 0; i < NEV; i++) {
                    269:                extern tchar corebuf[];
                    270:                envcopy((struct env *) &corebuf[i * sizeof(env)/sizeof(tchar)], &env);
                    271:        }
                    272: #else
                    273:        for (i = NEV; i--; )
                    274:                write(ibf, (char *) & env, sizeof(env));
                    275: #endif
                    276: }
                    277: 
                    278: #include <time.h>
                    279: 
                    280: cvtime()
                    281: {
                    282:        long    tt;
                    283:        struct tm *ltime, *localtime();
                    284: 
                    285:        time(&tt);
                    286:        ltime = localtime(&tt);
                    287:        numtab[YR].val = ltime->tm_year;
                    288:        numtab[MO].val = ltime->tm_mon + 1;     /* troff uses 1..12 */
                    289:        numtab[DY].val = ltime->tm_mday;
                    290:        numtab[DW].val = ltime->tm_wday + 1;    /* troff uses 1..7 */
                    291: 
                    292: /*     register i;
                    293: /*     static int ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
                    294: /*     tt -= 3600 * ZONE;      /* 5hrs for EST */
                    295: /*     numtab[DY].val = (tt / 86400L) + 1;
                    296: /*     numtab[DW].val = (numtab[DY].val + 3) % 7 + 1;
                    297: /*     for (numtab[YR].val = 70; ; numtab[YR].val++) {
                    298: /*             if ((numtab[YR].val) % 4)
                    299: /*                     ms[1] = 28;
                    300: /*             else 
                    301: /*                     ms[1] = 29;
                    302: /*             for (i = 0; i < 12; ) {
                    303: /*                     if (numtab[DY].val <= ms[i]) {
                    304: /*                             numtab[MO].val = i + 1;
                    305: /*                             return;
                    306: /*                     }
                    307: /*                     numtab[DY].val -= ms[i++];
                    308: /*             }
                    309: /*     }
                    310: */
                    311: }
                    312: 
                    313: 
                    314: ctoi(s)
                    315:        register char *s;
                    316: {
                    317:        register n;
                    318: 
                    319:        while (*s == ' ')
                    320:                s++;
                    321:        n = 0;
                    322:        while (isdigit(*s))
                    323:                n = 10 * n + *s++ - '0';
                    324:        return n;
                    325: }
                    326: 
                    327: 
                    328: errprint(s, s1, s2, s3, s4, s5)        /* error message printer */
                    329:        char *s, *s1, *s2, *s3, *s4, *s5;
                    330: {
                    331:        fdprintf(stderr, "%s: ", progname);
                    332:        fdprintf(stderr, s, s1, s2, s3, s4, s5);
                    333:        if (numtab[CD].val > 0)
                    334:                fdprintf(stderr, "; line %d, file %s", numtab[CD].val, cfname[ifi]);
                    335:        fdprintf(stderr, "\n");
                    336:        stackdump();
                    337: }
                    338: 
                    339: 
                    340: /*
                    341:  * Scaled down version of C Library printf.
                    342:  * Only %s %u %d (==%u) %o %c %x %D are recognized.
                    343:  */
                    344: #define        putchar(n)      (*pfbp++ = (n)) /* NO CHECKING! */
                    345: 
                    346: static char    pfbuf[NTM];
                    347: static char    *pfbp = pfbuf;
                    348: int    stderr   = 2;   /* NOT stdio value */
                    349: 
                    350: /* VARARGS2 */
                    351: fdprintf(fd, fmt, x1)
                    352: int    fd;
                    353: register char  *fmt;
                    354: {
                    355:        register c;
                    356:        register char *adx;
                    357:        char    *s;
                    358:        register i;
                    359: 
                    360:        pfbp = pfbuf;
                    361:        adx = (char*)&x1;
                    362: loop:
                    363:        while ((c = *fmt++) != '%') {
                    364:                if (c == '\0') {
                    365:                        if (fd == stderr)
                    366:                                write(stderr, pfbuf, (int)(pfbp - pfbuf));
                    367:                        else {
                    368:                                *pfbp = 0;
                    369:                                pfbp = pfbuf;
                    370:                                while (*pfbp) {
                    371:                                        *obufp++ = *pfbp++;
                    372:                                        if (obufp >= &obuf[OBUFSZ])
                    373:                                                flusho();
                    374:                                }
                    375:                        }
                    376:                        return;
                    377:                }
                    378:                putchar(c);
                    379:        }
                    380:        c = *fmt++;
                    381:        if (c == 'd') {
                    382:                i = *(int*)adx;
                    383:                if (i < 0) {
                    384:                        putchar('-');
                    385:                        i = -i;
                    386:                }
                    387:                printn((long)i, 10);
                    388:                adx += sizeof(int);
                    389:        } else if (c == 'u' || c == 'o' || c == 'x') {
                    390:                i = *(int*)adx;
                    391:                printn((long)i, c == 'o' ? 8 : (c == 'x' ? 16 : 10));
                    392:                adx += sizeof(int);
                    393:        }
                    394:        else if (c == 'c') {
                    395:                c = *(int*)adx & 0377;
                    396:                if (c > 0177 || (c < 040 && c != '\n' && c != '\t'))
                    397:                        putchar('\\');
                    398:                putchar(c & 0177);
                    399:                adx += sizeof(int);
                    400:        } else if (c == 's') {
                    401:                s = *(char**)adx;
                    402:                while (c = *s++)
                    403:                        putchar(c);
                    404:                adx += sizeof(char**);
                    405:        } else if (c == 'D') {
                    406:                printn(*(long*)adx, 10);
                    407:                adx += sizeof(long);
                    408:        } else if (c == 'O') {
                    409:                printn(*(long*)adx, 8);
                    410:                adx += sizeof(long);
                    411:        }
                    412:        goto loop;
                    413: }
                    414: 
                    415: 
                    416: /*
                    417:  * Print an unsigned integer in base b.
                    418:  */
                    419: static printn(n, b)
                    420: register long  n;
                    421: register b;
                    422: {
                    423:        char s[20];
                    424:        register char *p;
                    425:        register c;
                    426: 
                    427:        if (n < b) {
                    428:                if(n >= 0) {
                    429:                        putchar("0123456789ABCDEF"[n]);
                    430:                        return;
                    431:                }
                    432:                putchar('-');
                    433:                n = -n;
                    434:        }
                    435:        p = s+20;
                    436:        *--p = 0;
                    437:        for(;;) {
                    438:                *--p = "0123456789ABCDEF"[n % b];
                    439:                if(!(n /= b))
                    440:                        break;
                    441:        }
                    442:        while(c = *p++)
                    443:                putchar(c);
                    444: }
                    445: 
                    446: /* scaled down version of library sprintf */
                    447: /* same limits as fdprintf */
                    448: /* returns pointer to \0 that ends the string */
                    449: 
                    450: /* VARARGS2 */
                    451: char *sprintf(str, fmt, x1)
                    452: char   *str;
                    453: char   *fmt;
                    454: {
                    455:        register c;
                    456:        register char *adx;
                    457:        char    *s;
                    458:        register i;
                    459: 
                    460:        adx = (char*)&x1;
                    461: loop:
                    462:        while ((c = *fmt++) != '%') {
                    463:                if (c == '\0') {
                    464:                        *str = 0;
                    465:                        return str;
                    466:                }
                    467:                *str++ = c;
                    468:        }
                    469:        c = *fmt++;
                    470:        if (c == 'd') {
                    471:                i = *(int*)adx;
                    472:                if (i < 0) {
                    473:                        *str++ = '-';
                    474:                        i = -i;
                    475:                }
                    476:                str = sprintn(str, (long)i, 10);
                    477:                adx += sizeof(int);
                    478:        } else if (c == 'u' || c == 'o' || c == 'x') {
                    479:                i = *(int*)adx;
                    480:                str = sprintn(str, (long)i, c == 'o' ? 8 : (c == 'x' ? 16 : 10));
                    481:                adx += sizeof(int);
                    482:        }
                    483:        else if (c == 'c') {
                    484:                c = *(int*)adx & 0377;
                    485:                if (c > 0177 || c < 040)
                    486:                        *str++ = '\\';
                    487:                *str++ = c & 0177;
                    488:                adx += sizeof(int);
                    489:        } else if (c == 's') {
                    490:                s = *(char**)adx;
                    491:                while (c = *s++)
                    492:                        *str++ = c;
                    493:                adx += sizeof(char**);
                    494:        } else if (c == 'D') {
                    495:                str = sprintn(str, *(long*)adx, 10);
                    496:                adx += sizeof(long);
                    497:        } else if (c == 'O') {
                    498:                str = sprintn(str, *(long*)adx, 8);
                    499:                adx += sizeof(long);
                    500:        }
                    501:        goto loop;
                    502: }
                    503: 
                    504: /*
                    505:  * Print an unsigned integer in base b.
                    506:  */
                    507: static char *sprintn(s, n, b)
                    508:        register char *s;
                    509:        register long n;
                    510: {
                    511:        register long   a;
                    512: 
                    513:        if (n < 0) {    /* shouldn't happen */
                    514:                *s++ = '-';
                    515:                n = -n;
                    516:        }
                    517:        if (a = n / b)
                    518:                s = sprintn(s, a, b);
                    519:        *s++ = "0123456789ABCDEF"[(int)(n%b)];
                    520:        return s;
                    521: }
                    522: 
                    523: 
                    524: control(a, b)
                    525: register int   a, b;
                    526: {
                    527:        register int    j;
                    528: 
                    529:        if (a == 0 || (j = findmn(a)) == -1)
                    530:                return(0);
                    531:        if (contab[j].f == 0) {
                    532:                nxf->nargs = 0;
                    533:                if (b)
                    534:                        collect();
                    535:                flushi();
                    536:                return pushi(contab[j].mx, a);
                    537:        } else if (b)
                    538:                return((*contab[j].f)(0));
                    539:        else
                    540:                return(0);
                    541: }
                    542: 
                    543: 
                    544: getrq()
                    545: {
                    546:        register i, j;
                    547: 
                    548:        if (((i = getach()) == 0) || ((j = getach()) == 0))
                    549:                goto rtn;
                    550:        i = PAIR(i, j);
                    551: rtn:
                    552:        return(i);
                    553: }
                    554: 
                    555: /*
                    556:  * table encodes some special characters, to speed up tests
                    557:  * in getchar, viz FLSS, RPT, f, \b, \n, fc, tabch, ldrch
                    558:  */
                    559: 
                    560: char
                    561: gchtab[] = {
                    562:        000,004,000,000,010,000,000,000, /* fc, ldr */
                    563:        001,002,001,000,001,000,000,000, /* \b, tab, nl, RPT */
                    564:        000,000,000,000,000,000,000,000,
                    565:        000,001,000,000,000,000,000,000, /* FLSS */
                    566:        000,000,000,000,000,000,000,000,
                    567:        000,000,000,000,000,000,000,000,
                    568:        000,000,000,000,000,000,000,000,
                    569:        000,000,000,000,000,000,000,000,
                    570:        000,000,000,000,000,000,000,000,
                    571:        000,000,000,000,000,000,000,000,
                    572:        000,000,000,000,000,000,000,000,
                    573:        000,000,000,000,000,000,000,000,
                    574:        000,000,000,000,000,000,001,000, /* f */
                    575:        000,000,000,000,000,000,000,000,
                    576:        000,000,000,000,000,000,000,000,
                    577:        000,000,000,000,000,000,000,000,
                    578: };
                    579: 
                    580: tchar
                    581: getch()
                    582: {
                    583:        register int    k;
                    584:        register tchar i, j;
                    585:        tchar setht(), setslant();
                    586: 
                    587: g0:
                    588:        if(ch) {
                    589:                i = ch;
                    590:                if (cbits(i) == '\n')
                    591:                        nlflg++;
                    592:                ch = 0;
                    593:                return(i);
                    594:        }
                    595: 
                    596:        if (nlflg)
                    597:                return('\n');
                    598:        i = getch0();
                    599:        if (ismot(i))
                    600:                return(i);
                    601:        k = cbits(i);
                    602:        if (k != ESC) {
                    603:                if (k >= sizeof(gchtab)/sizeof(gchtab[0]) || gchtab[k] == 0)
                    604:                        return(i);
                    605:                if (k == '\n') {
                    606:                        if (cbits(i) == '\n') {
                    607:                                nlflg++;
                    608:                                if (ip == 0)
                    609:                                        numtab[CD].val++; /* line number */
                    610:                        }
                    611:                        return(k);
                    612:                }
                    613:                if (k == FLSS) {
                    614:                        copyf++; 
                    615:                        raw++;
                    616:                        i = getch0();
                    617:                        if (!fi)
                    618:                                flss = i;
                    619:                        copyf--; 
                    620:                        raw--;
                    621:                        goto g0;
                    622:                }
                    623:                if (k == RPT) {
                    624:                        setrpt();
                    625:                        goto g0;
                    626:                }
                    627:                if (!copyf) {
                    628:                        if (k == 'f' && lg && !lgf) {
                    629:                                i = getlg(i);
                    630:                                return(i);
                    631:                        }
                    632:                        if (k == fc || k == tabch || k == ldrch) {
                    633:                                if ((i = setfield(k)) == 0)
                    634:                                        goto g0; 
                    635:                                else 
                    636:                                        return(i);
                    637:                        }
                    638:                        if (k == '\b') {
                    639:                                i = makem(-width(' ' | chbits));
                    640:                                return(i);
                    641:                        }
                    642:                }
                    643:                return(i);
                    644:        }
                    645:        k = cbits(j = getch0());
                    646:        if (ismot(j))
                    647:                return(j);
                    648:        switch (k) {
                    649: 
                    650:        case '\n':      /* concealed newline */
                    651:                goto g0;
                    652:        case 'n':       /* number register */
                    653:                setn();
                    654:                goto g0;
                    655:        case '*':       /* string indicator */
                    656:                setstr();
                    657:                goto g0;
                    658:        case '$':       /* argument indicator */
                    659:                seta();
                    660:                goto g0;
                    661:        case '{':       /* LEFT */
                    662:                i = LEFT;
                    663:                goto gx;
                    664:        case '}':       /* RIGHT */
                    665:                i = RIGHT;
                    666:                goto gx;
                    667:        case '"':       /* comment */
                    668:                while (cbits(i = getch0()) != '\n')
                    669:                        ;
                    670:                nlflg++;
                    671:                if (ip == 0)
                    672:                        numtab[CD].val++;
                    673:                return(i);
                    674:        case ESC:       /* double backslash */
                    675:                i = eschar;
                    676:                goto gx;
                    677:        case 'e':       /* printable version of current eschar */
                    678:                i = PRESC;
                    679:                goto gx;
                    680:        case ' ':       /* unpaddable space */
                    681:                i = UNPAD;
                    682:                goto gx;
                    683:        case '\'':      /* \(aa */
                    684:                i = ACUTE;
                    685:                goto gx;
                    686:        case '`':       /* \(ga */
                    687:                i = GRAVE;
                    688:                goto gx;
                    689:        case '_':       /* \(ul */
                    690:                i = UNDERLINE;
                    691:                goto gx;
                    692:        case '-':       /* current font minus */
                    693:                i = MINUS;
                    694:                goto gx;
                    695:        case '&':       /* filler */
                    696:                i = FILLER;
                    697:                goto gx;
                    698:        case 'c':       /* to be continued */
                    699:                i = CONT;
                    700:                goto gx;
                    701:        case '!':       /* transparent indicator */
                    702:                i = XPAR;
                    703:                goto gx;
                    704:        case 't':       /* tab */
                    705:                i = '\t';
                    706:                return(i);
                    707:        case 'a':       /* leader (SOH) */
                    708: /* old:                *pbp++ = LEADER; goto g0; */
                    709:                i = LEADER;
                    710:                return i;
                    711:        case '%':       /* ohc */
                    712:                i = OHC;
                    713:                return(i);
                    714:        case 'g':       /* return format of a number register */
                    715:                setaf();
                    716:                goto g0;
                    717:        case '.':       /* . */
                    718:                i = '.';
                    719: gx:
                    720:                setsfbits(i, sfbits(j));
                    721:                return(i);
                    722:        }
                    723:        if (copyf) {
                    724:                *pbp++ = j;
                    725:                return(eschar);
                    726:        }
                    727:        switch (k) {
                    728: 
                    729:        case 'p':       /* spread */
                    730:                spread++;
                    731:                goto g0;
                    732:        case '(':       /* special char name \(xx */
                    733:        case 'C':       /*              \C'...' */
                    734:                if ((i = setch(k)) == 0)
                    735:                        goto g0;
                    736:                return(i);
                    737:        case 'N':       /* absolute character number */
                    738:                if ((i = setabs()) == 0)
                    739:                        goto g0;
                    740:                return i;
                    741:        case 's':       /* size indicator */
                    742:                setps();
                    743:                goto g0;
                    744:        case 'H':       /* character height */
                    745:                return(setht());
                    746:        case 'S':       /* slant */
                    747:                return(setslant());
                    748:        case 'f':       /* font indicator */
                    749:                setfont(0);
                    750:                goto g0;
                    751:        case 'w':       /* width function */
                    752:                setwd();
                    753:                goto g0;
                    754:        case 'v':       /* vert mot */
                    755:                if (i = vmot())
                    756:                        return(i);
                    757:                goto g0;
                    758:        case 'h':       /* horiz mot */
                    759:                if (i = hmot())
                    760:                        return(i);
                    761:                goto g0;
                    762:        case 'z':       /* zero with char */
                    763:                return(setz());
                    764:        case 'l':       /* hor line */
                    765:                setline();
                    766:                goto g0;
                    767:        case 'L':       /* vert line */
                    768:                setvline();
                    769:                goto g0;
                    770:        case 'D':       /* drawing function */
                    771:                setdraw();
                    772:                goto g0;
                    773:        case 'X':       /* \X'...' for copy through */
                    774:                setxon();
                    775:                goto g0;
                    776:        case 'b':       /* bracket */
                    777:                setbra();
                    778:                goto g0;
                    779:        case 'o':       /* overstrike */
                    780:                setov();
                    781:                goto g0;
                    782:        case 'k':       /* mark hor place */
                    783:                if ((k = findr(getsn())) != -1) {
                    784:                        numtab[k].val = numtab[HP].val;
                    785:                }
                    786:                goto g0;
                    787:        case '0':       /* number space */
                    788:                return(makem(width('0' | chbits)));
                    789: #ifdef NROFF
                    790:        case '|':
                    791:        case '^':
                    792:                goto g0;
                    793: #else
                    794:        case '|':       /* narrow space */
                    795:                return(makem((int)(EM)/6));
                    796:        case '^':       /* half narrow space */
                    797:                return(makem((int)(EM)/12));
                    798: #endif
                    799:        case 'x':       /* extra line space */
                    800:                if (i = xlss())
                    801:                        return(i);
                    802:                goto g0;
                    803:        case 'u':       /* half em up */
                    804:        case 'r':       /* full em up */
                    805:        case 'd':       /* half em down */
                    806:                return(sethl(k));
                    807:        default:
                    808:                return(j);
                    809:        }
                    810:        /* NOTREACHED */
                    811: }
                    812: 
                    813: setxon()       /* \X'...' for copy through */
                    814: {
                    815:        tchar xbuf[NC];
                    816:        register tchar *i;
                    817:        tchar c;
                    818:        int delim, k;
                    819: 
                    820:        if (ismot(c = getch()))
                    821:                return;
                    822:        delim = cbits(c);
                    823:        i = xbuf;
                    824:        *i++ = XON | chbits;
                    825:        while ((k = cbits(c = getch())) != delim && k != '\n' && i < xbuf+NC-1) {
                    826:                if (k == ' ')
                    827:                        setcbits(c, UNPAD);
                    828:                *i++ = c | ZBIT;
                    829:        }
                    830:        *i++ = XOFF | chbits;
                    831:        *i = 0;
                    832:        pushback(xbuf);
                    833: }
                    834: 
                    835: 
                    836: char   ifilt[32] = {
                    837:        0, 001, 002, 003, 0, 005, 006, 007, 010, 011, 012};
                    838: 
                    839: tchar
                    840: getch0()
                    841: {
                    842:        register int    j;
                    843:        register tchar i;
                    844: 
                    845: again:
                    846:        if (pbp > lastpbp)
                    847:                i = *--pbp;
                    848:        else if (ip) {
                    849: #ifdef INCORE
                    850:                extern tchar corebuf[];
                    851:                i = corebuf[ip];
                    852:                if (i == 0)
                    853:                        i = rbf();
                    854:                else {
                    855:                        if ((++ip & (BLK - 1)) == 0) {
                    856:                                --ip;
                    857:                                (void)rbf();
                    858:                        }
                    859:                }
                    860: #else
                    861:                i = rbf();
                    862: #endif
                    863:        } else {
                    864:                if (donef || ndone)
                    865:                        done(0);
                    866:                if (nx || ibufp >= eibuf) {
                    867:                        if (nfo==0) {
                    868: g0:
                    869:                                if (nextfile()) {
                    870:                                        if (ip)
                    871:                                                goto again;
                    872:                                        if (ibufp < eibuf)
                    873:                                                goto g2;
                    874:                                }
                    875:                        }
                    876:                        nx = 0;
                    877:                        if ((j = read(ifile, ibuf, IBUFSZ)) <= 0)
                    878:                                goto g0;
                    879:                        ibufp = ibuf;
                    880:                        eibuf = ibuf + j;
                    881:                        if (ip)
                    882:                                goto again;
                    883:                }
                    884: g2:
                    885:                i = *ibufp++ & 0177;
                    886:                ioff++;
                    887:                if (i >= 040 && i < 0177)
                    888:                        goto g4;
                    889:                if (i != 0177) 
                    890:                        i = ifilt[i];
                    891:        }
                    892:        if (cbits(i) == IMP && !raw)
                    893:                goto again;
                    894:        if ((i == 0 || i == 0177) && !init && !raw) {
                    895:                goto again;
                    896:        }
                    897: g4:
                    898:        if (ismot(i))
                    899:                return i;
                    900:        if (copyf == 0 && sfbits(i) == 0)
                    901:                i |= chbits;
                    902:        if (cbits(i) == eschar && !raw)
                    903:                setcbits(i, ESC);
                    904:        return(i);
                    905: }
                    906: 
                    907: pushback(b)
                    908: register tchar *b;
                    909: {
                    910:        register tchar *ob = b;
                    911: 
                    912:        while (*b++)
                    913:                ;
                    914:        b--;
                    915:        while (b > ob && pbp < &pbbuf[NC-3])
                    916:                *pbp++ = *--b;
                    917:        if (pbp >= &pbbuf[NC-3]) {
                    918:                errprint("pushback overflow");
                    919:                done(2);
                    920:        }
                    921: }
                    922: 
                    923: cpushback(b)
                    924: register char *b;
                    925: {
                    926:        register char *ob = b;
                    927: 
                    928:        while (*b++)
                    929:                ;
                    930:        b--;
                    931:        while (b > ob && pbp < &pbbuf[NC-3])
                    932:                *pbp++ = *--b;
                    933:        if (pbp >= &pbbuf[NC-3]) {
                    934:                errprint("cpushback overflow");
                    935:                done(2);
                    936:        }
                    937: }
                    938: 
                    939: nextfile()
                    940: {
                    941:        register char   *p;
                    942: 
                    943: n0:
                    944:        if (ifile)
                    945:                close(ifile);
                    946:        if (nx  ||  nmfi < mflg) {
                    947:                p = mfiles[nmfi++];
                    948:                if (*p != 0)
                    949:                        goto n1;
                    950:        }
                    951:        if (ifi > 0) {
                    952:                if (popf())
                    953:                        goto n0; /* popf error */
                    954:                return(1); /* popf ok */
                    955:        }
                    956:        if (rargc-- <= 0) {
                    957:                if ((nfo -= mflg) && !stdi)
                    958:                        done(0);
                    959:                nfo++;
                    960:                numtab[CD].val = ifile = stdi = mflg = 0;
                    961:                strcpy(cfname[ifi], "<standard input>");
                    962:                ioff = 0;
                    963:                return(0);
                    964:        }
                    965:        p = (argp++)[0];
                    966: n1:
                    967:        numtab[CD].val = 0;
                    968:        if (p[0] == '-' && p[1] == 0) {
                    969:                ifile = 0;
                    970:                strcpy(cfname[ifi], "<standard input>");
                    971:        } else if ((ifile = open(p, 0)) < 0) {
                    972:                errprint("cannot open file %s", p);
                    973:                nfo -= mflg;
                    974:                done(02);
                    975:        } else
                    976:                strcpy(cfname[ifi],p);
                    977:        nfo++;
                    978:        ioff = 0;
                    979:        return(0);
                    980: }
                    981: 
                    982: 
                    983: popf()
                    984: {
                    985:        register i;
                    986:        register char   *p, *q;
                    987: 
                    988:        ioff = offl[--ifi];
                    989:        numtab[CD].val = cfline[ifi];           /*restore line counter*/
                    990:        ip = ipl[ifi];
                    991:        if ((ifile = ifl[ifi]) == 0) {
                    992:                p = xbuf;
                    993:                q = ibuf;
                    994:                ibufp = xbufp;
                    995:                eibuf = xeibuf;
                    996:                while (q < eibuf)
                    997:                        *q++ = *p++;
                    998:                return(0);
                    999:        }
                   1000:        if (lseek(ifile, (long)(ioff & ~(IBUFSZ-1)), 0) == (long) -1
                   1001:           || (i = read(ifile, ibuf, IBUFSZ)) < 0)
                   1002:                return(1);
                   1003:        eibuf = ibuf + i;
                   1004:        ibufp = ibuf;
                   1005: /*
                   1006:        if (ttyname(ifile) == 0)
                   1007: */
                   1008:                if ((ibufp = ibuf + (int)(ioff & (IBUFSZ - 1))) > eibuf)
                   1009:                        return(1);
                   1010:        return(0);
                   1011: }
                   1012: 
                   1013: 
                   1014: flushi()
                   1015: {
                   1016:        if (nflush)
                   1017:                return;
                   1018:        ch = 0;
                   1019:        copyf++;
                   1020:        while (!nlflg) {
                   1021:                if (donef && (frame == stk))
                   1022:                        break;
                   1023:                getch();
                   1024:        }
                   1025:        copyf--;
                   1026: }
                   1027: 
                   1028: 
                   1029: getach()
                   1030: {
                   1031:        register tchar i;
                   1032:        register j;
                   1033: 
                   1034:        lgf++;
                   1035:        j = cbits(i = getch());
                   1036:        /* this test ought to be more general and more careful */
                   1037:        if (ismot(i) || j == ' ' || j == '\n' || j == RIGHT || j & 0200) {
                   1038:                ch = i;
                   1039:                j = 0;
                   1040:        }
                   1041:        lgf--;
                   1042:        return(j & 0177);
                   1043: }
                   1044: 
                   1045: 
                   1046: casenx()
                   1047: {
                   1048:        lgf++;
                   1049:        skip();
                   1050:        getname();
                   1051:        nx++;
                   1052:        if (nmfi > 0)
                   1053:                nmfi--;
                   1054:        strcpy(mfiles[nmfi], nextf);
                   1055:        nextfile();
                   1056:        nlflg++;
                   1057:        ip = 0;
                   1058:        pendt = 0;
                   1059:        frame = stk;
                   1060:        nxf = frame + 1;
                   1061: }
                   1062: 
                   1063: 
                   1064: getname()
                   1065: {
                   1066:        register int    j, k;
                   1067:        tchar i;
                   1068: 
                   1069:        lgf++;
                   1070:        for (k = 0; k < (NS - 1); k++) {
                   1071:                if (((j = cbits(i = getch())) <= ' ') || (j > 0176))
                   1072:                        break;
                   1073:                nextf[k] = j;
                   1074:        }
                   1075:        nextf[k] = 0;
                   1076:        ch = i;
                   1077:        lgf--;
                   1078:        return(nextf[0]);
                   1079: }
                   1080: 
                   1081: 
                   1082: caseso()
                   1083: {
                   1084:        register i;
                   1085:        register char   *p, *q;
                   1086: 
                   1087:        lgf++;
                   1088:        nextf[0] = 0;
                   1089:        if (skip() || !getname() || ((i = open(nextf, 0)) < 0) || (ifi >= NSO)) {
                   1090:                errprint("can't open file %s", nextf);
                   1091:                done(02);
                   1092:        }
                   1093:        strcpy(cfname[ifi+1], nextf);
                   1094:        cfline[ifi] = numtab[CD].val;           /*hold line counter*/
                   1095:        numtab[CD].val = 0;
                   1096:        flushi();
                   1097:        ifl[ifi] = ifile;
                   1098:        ifile = i;
                   1099:        offl[ifi] = ioff;
                   1100:        ioff = 0;
                   1101:        ipl[ifi] = ip;
                   1102:        ip = 0;
                   1103:        nx++;
                   1104:        nflush++;
                   1105:        if (!ifl[ifi++]) {
                   1106:                p = ibuf;
                   1107:                q = xbuf;
                   1108:                xbufp = ibufp;
                   1109:                xeibuf = eibuf;
                   1110:                while (p < eibuf)
                   1111:                        *q++ = *p++;
                   1112:        }
                   1113: }
                   1114: 
                   1115: caself()       /* set line number and file */
                   1116: {
                   1117:        int n;
                   1118: 
                   1119:        if (skip())
                   1120:                return;
                   1121:        n = atoi();
                   1122:        cfline[ifi] = numtab[CD].val = n - 2;
                   1123:        if (skip())
                   1124:                return;
                   1125:        if (getname())
                   1126:                strcpy(cfname[ifi], nextf);
                   1127: }
                   1128: 
                   1129: 
                   1130: casecf()
                   1131: {      /* copy file without change */
                   1132: #ifndef NROFF
                   1133:        int     fd, n;
                   1134:        char    buf[512];
                   1135:        extern int hpos, esc, po;
                   1136: 
                   1137:        lgf++;
                   1138:        nextf[0] = 0;
                   1139:        if (skip() || !getname() || (fd = open(nextf, 0)) < 0) {
                   1140:                errprint("can't open file %s", nextf);
                   1141:                done(02);
                   1142:        }
                   1143:        lgf--;
                   1144:        /* make it into a clean state, be sure that everything is out */
                   1145:        tbreak();
                   1146:        hpos = po;
                   1147:        esc = 0;
                   1148:        ptesc();        /* to left margin */
                   1149:        esc = un;
                   1150:        ptesc();
                   1151:        ptlead();
                   1152:        ptps();
                   1153:        ptfont();
                   1154:        flusho();
                   1155:        while ((n = read(fd, buf, sizeof buf)) > 0)
                   1156:                write(ptid, buf, n);
                   1157:        close(fd);
                   1158:        ptps();
                   1159:        ptfont();
                   1160: #endif
                   1161: }
                   1162: 
                   1163: 
                   1164: casesy()       /* call system */
                   1165: {
                   1166:        char    sybuf[NTM];
                   1167:        int     i;
                   1168: 
                   1169:        lgf++;
                   1170:        copyf++;
                   1171:        skip();
                   1172:        for (i = 0; i < NTM - 2; i++)
                   1173:                if ((sybuf[i] = getch()) == '\n' || sybuf[i] == RIGHT)
                   1174:                        break;
                   1175:        sybuf[i] = 0;
                   1176:        system(sybuf);
                   1177:        copyf--;
                   1178:        lgf--;
                   1179: }
                   1180: 
                   1181: 
                   1182: getpn(a)
                   1183:        register char *a;
                   1184: {
                   1185:        register int n, neg;
                   1186: 
                   1187:        if (*a == 0)
                   1188:                return;
                   1189:        neg = 0;
                   1190:        for ( ; *a; a++)
                   1191:                switch (*a) {
                   1192:                case '+':
                   1193:                case ',':
                   1194:                        continue;
                   1195:                case '-':
                   1196:                        neg = 1;
                   1197:                        continue;
                   1198:                default:
                   1199:                        n = 0;
                   1200:                        if (isdigit(*a)) {
                   1201:                                do
                   1202:                                        n = 10 * n + *a++ - '0';
                   1203:                                while (isdigit(*a));
                   1204:                                a--;
                   1205:                        } else
                   1206:                                n = 9999;
                   1207:                        *pnp++ = neg ? -n : n;
                   1208:                        neg = 0;
                   1209:                        if (pnp >= &pnlist[NPN-2]) {
                   1210:                                errprint("too many page numbers");
                   1211:                                done3(-3);
                   1212:                        }
                   1213:                }
                   1214:        if (neg)
                   1215:                *pnp++ = -9999;
                   1216:        *pnp = -32767;
                   1217:        print = 0;
                   1218:        pnp = pnlist;
                   1219:        if (*pnp != -32767)
                   1220:                chkpn();
                   1221: }
                   1222: 
                   1223: 
                   1224: setrpt()
                   1225: {
                   1226:        tchar i, j;
                   1227: 
                   1228:        copyf++;
                   1229:        raw++;
                   1230:        i = getch0();
                   1231:        copyf--;
                   1232:        raw--;
                   1233:        if (i < 0 || cbits(j = getch0()) == RPT)
                   1234:                return;
                   1235:        i &= BYTEMASK;
                   1236:        while (i>0 && pbp < &pbbuf[NC-3]) {
                   1237:                i--;
                   1238:                *pbp++ = j;
                   1239:        }
                   1240: }

unix.superglobalmegacorp.com

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