Annotation of researchv10no/cmd/troff/Old/n4.c, revision 1.1.1.1

1.1       root        1: #include       <ctype.h>
                      2: #include "tdef.h"
                      3: extern
                      4: #include "d.h"
                      5: extern
                      6: #include "v.h"
                      7: #ifdef NROFF
                      8: extern
                      9: #include "tw.h"
                     10: #endif
                     11: #include "s.h"
                     12: /*
                     13: troff4.c
                     14: 
                     15: number registers, conversion, arithmetic
                     16: */
                     17: 
                     18: #include <sgtty.h>
                     19: #include "ext.h"
                     20: 
                     21: int    regcnt = NNAMES;
                     22: int    falsef  = 0;    /* on if inside false branch of if */
                     23: 
                     24: setn()
                     25: {
                     26:        register i, j;
                     27:        tchar ii;
                     28:        int     f;
                     29: 
                     30:        f = nform = 0;
                     31:        if ((i = cbits(ii = getch())) == '+')
                     32:                f = 1;
                     33:        else if (i == '-')
                     34:                f = -1;
                     35:        else 
                     36:                ch = ii;
                     37:        if (falsef)
                     38:                f = 0;
                     39:        if ((i = getsn()) == 0)
                     40:                return;
                     41:        if ((i & 0177) == '.')
                     42:                switch (i >> BYTE) {
                     43:                case 's': 
                     44:                        i = pts;        
                     45:                        break;
                     46:                case 'v': 
                     47:                        i = lss;                
                     48:                        break;
                     49:                case 'f': 
                     50:                        i = font;       
                     51:                        break;
                     52:                case 'p': 
                     53:                        i = pl;         
                     54:                        break;
                     55:                case 't':  
                     56:                        i = findt1();   
                     57:                        break;
                     58:                case 'o': 
                     59:                        i = po;         
                     60:                        break;
                     61:                case 'l': 
                     62:                        i = ll;         
                     63:                        break;
                     64:                case 'i': 
                     65:                        i = in;         
                     66:                        break;
                     67:                case '$': 
                     68:                        i = frame->nargs;               
                     69:                        break;
                     70:                case 'A': 
                     71:                        i = ascii;              
                     72:                        break;
                     73:                case 'c': 
                     74:                        i = v.cd;               
                     75:                        break;
                     76:                case 'n': 
                     77:                        i = lastl;              
                     78:                        break;
                     79:                case 'a': 
                     80:                        i = ralss;              
                     81:                        break;
                     82:                case 'h': 
                     83:                        i = dip->hnl;   
                     84:                        break;
                     85:                case 'd':
                     86:                        if (dip != d)
                     87:                                i = dip->dnl; 
                     88:                        else 
                     89:                                i = v.nl;
                     90:                        break;
                     91:                case 'u': 
                     92:                        i = fi;         
                     93:                        break;
                     94:                case 'j': 
                     95:                        i = ad + 2 * admod;     
                     96:                        break;
                     97:                case 'w': 
                     98:                        i = width(*(pinchar-1));        /* XXX */
                     99:                        break;
                    100:                case 'x': 
                    101:                        i = nel;        
                    102:                        break;
                    103:                case 'y': 
                    104:                        i = un;         
                    105:                        break;
                    106:                case 'T': 
                    107:                        i = dotT;               
                    108:                        break; /*-Tterm used in nroff*/
                    109:                case 'V': 
                    110:                        i = VERT;               
                    111:                        break;
                    112:                case 'H': 
                    113:                        i = HOR;                
                    114:                        break;
                    115:                case 'k': 
                    116:                        i = ne;         
                    117:                        break;
                    118:                case 'P': 
                    119:                        i = print;              
                    120:                        break;
                    121:                case 'L': 
                    122:                        i = ls;         
                    123:                        break;
                    124:                case 'R': 
                    125:                        i = NN - regcnt;        
                    126:                        break;
                    127:                case 'z': 
                    128:                        i = dip->curd;
                    129:                        cbuf[0] = i & BMASK;
                    130:                        cbuf[1] = (i >> BYTE) & BMASK;
                    131:                        cbuf[2] = 0;
                    132:                        cp = cbuf;
                    133:                        return;
                    134:                case 'b': 
                    135:                        i = bdtab[font];
                    136:                        break;
                    137: 
                    138:                default:
                    139:                        goto s0;
                    140:                }
                    141:        else {
                    142: s0:
                    143:                if ((j = findr(i)) == -1)
                    144:                        i = 0;
                    145:                else {
                    146:                        i = (vlist[j] = (vlist[j] + inc[j] * f));
                    147:                        nform = fmt[j];
                    148:                }
                    149:        }
                    150:        setn1(i);
                    151:        cp = cbuf;
                    152: }
                    153: 
                    154: 
                    155: setn1(i)
                    156: int    i;
                    157: {
                    158:        extern int      wrc();
                    159: 
                    160:        cp = cbuf;
                    161:        nrbits = 0;
                    162:        fnumb(i, wrc);
                    163:        *cp = 0;
                    164:        cp = cbuf;
                    165: }
                    166: 
                    167: 
                    168: findr(i)
                    169: register int   i;
                    170: {
                    171:        register j;
                    172:        register int *p;
                    173: 
                    174:        if (i == 0)
                    175:                return(-1);
                    176:        for (p = r; p < &r[NN]; p++) {
                    177:                if (i == *p)
                    178:                        break;
                    179:        }
                    180:        if (p != &r[NN])
                    181:                return(p - r);
                    182:        for (p = r; p < &r[NN]; p++) {
                    183:                if (*p == 0) {
                    184:                        *p = i;
                    185:                        regcnt++;
                    186:                        break;
                    187:                }
                    188:        }
                    189:        if (p == &r[NN]) {
                    190:                fprintf(stderr, "troff: too many number registers (%d).\n", NN);
                    191:                done2(04); 
                    192:        }
                    193:        return(p - r);
                    194: }
                    195: 
                    196: usedr(i)       /* returns -1 if nr i has never been used */
                    197: register int   i;
                    198: {
                    199:        register j;
                    200:        register int *p;
                    201: 
                    202:        if (i == 0)
                    203:                return(-1);
                    204:        for (p = r; p < &r[NN]; p++) {
                    205:                if (i == *p)
                    206:                        break;
                    207:        }
                    208:        if (p != &r[NN])
                    209:                return(p - r);
                    210:        else
                    211:                return -1;
                    212: }
                    213: 
                    214: 
                    215: fnumb(i, f)
                    216: int    i, (*f)();
                    217: {
                    218:        register j;
                    219: 
                    220:        j = 0;
                    221:        if (i < 0) {
                    222:                j = (*f)('-' | nrbits);
                    223:                i = -i;
                    224:        }
                    225:        switch (nform) {
                    226:        default:
                    227:        case '1':
                    228:        case 0: 
                    229:                return(decml(i, f) + j);
                    230:        case 'i':
                    231:        case 'I': 
                    232:                return(roman(i, f) + j);
                    233:        case 'a':
                    234:        case 'A': 
                    235:                return(abc(i, f) + j);
                    236:        }
                    237: }
                    238: 
                    239: 
                    240: decml(i, f)
                    241: int    i, (*f)();
                    242: {
                    243:        register j, k;
                    244: 
                    245:        k = 0;
                    246:        nform--;
                    247:        if ((j = i / 10) || (nform > 0))
                    248:                k = decml(j, f);
                    249:        return(k + (*f)((i % 10 + '0') | nrbits));
                    250: }
                    251: 
                    252: 
                    253: roman(i, f)
                    254: int    i, (*f)();
                    255: {
                    256: 
                    257:        if (!i)
                    258:                return((*f)('0' | nrbits));
                    259:        if (nform == 'i')
                    260:                return(roman0(i, f, "ixcmz", "vldw"));
                    261:        else 
                    262:                return(roman0(i, f, "IXCMZ", "VLDW"));
                    263: }
                    264: 
                    265: 
                    266: roman0(i, f, onesp, fivesp)
                    267: int    i, (*f)();
                    268: char   *onesp, *fivesp;
                    269: {
                    270:        register q, rem, k;
                    271: 
                    272:        k = 0;
                    273:        if (!i)
                    274:                return(0);
                    275:        k = roman0(i / 10, f, onesp + 1, fivesp + 1);
                    276:        q = (i = i % 10) / 5;
                    277:        rem = i % 5;
                    278:        if (rem == 4) {
                    279:                k += (*f)(*onesp | nrbits);
                    280:                if (q)
                    281:                        i = *(onesp + 1);
                    282:                else 
                    283:                        i = *fivesp;
                    284:                return(k += (*f)(i | nrbits));
                    285:        }
                    286:        if (q)
                    287:                k += (*f)(*fivesp | nrbits);
                    288:        while (--rem >= 0)
                    289:                k += (*f)(*onesp | nrbits);
                    290:        return(k);
                    291: }
                    292: 
                    293: 
                    294: abc(i, f)
                    295: int    i, (*f)();
                    296: {
                    297:        if (!i)
                    298:                return((*f)('0' | nrbits));
                    299:        else 
                    300:                return(abc0(i - 1, f));
                    301: }
                    302: 
                    303: 
                    304: abc0(i, f)
                    305: int    i, (*f)();
                    306: {
                    307:        register j, k;
                    308: 
                    309:        k = 0;
                    310:        if (j = i / 26)
                    311:                k = abc0(j - 1, f);
                    312:        return(k + (*f)((i % 26 + nform) | nrbits));
                    313: }
                    314: 
                    315: 
                    316: wrc(i)
                    317: tchar i;
                    318: {
                    319:        if (cp >= &cbuf[NC])
                    320:                return(0);
                    321:        *cp++ = i;
                    322:        return(1);
                    323: }
                    324: 
                    325: 
                    326: long   atoi0()
                    327: {
                    328:        register c, k, cnt;
                    329:        tchar ii;
                    330:        long    i, acc;
                    331:        extern long     ckph();
                    332: 
                    333:        i = 0; 
                    334:        acc = 0;
                    335:        nonumb = 0;
                    336:        cnt = -1;
                    337: a0:
                    338:        cnt++;
                    339:        ii = getch();
                    340:        c = cbits(ii);
                    341:        switch (c) {
                    342:        default:
                    343:                ch = ii;
                    344:                if (cnt)
                    345:                        break;
                    346:        case '+':
                    347:                i = ckph();
                    348:                if (nonumb)
                    349:                        break;
                    350:                acc += i;
                    351:                goto a0;
                    352:        case '-':
                    353:                i = ckph();
                    354:                if (nonumb)
                    355:                        break;
                    356:                acc -= i;
                    357:                goto a0;
                    358:        case '*':
                    359:                i = ckph();
                    360:                if (nonumb)
                    361:                        break;
                    362:                acc *= i;
                    363:                goto a0;
                    364:        case '/':
                    365:                i = ckph();
                    366:                if (nonumb)
                    367:                        break;
                    368:                if (i == 0) {
                    369:                        flusho();
                    370:                        fprintf(stderr, "troff: divide by zero.\n");
                    371:                        acc = 0;
                    372:                } else 
                    373:                        acc /= i;
                    374:                goto a0;
                    375:        case '%':
                    376:                i = ckph();
                    377:                if (nonumb)
                    378:                        break;
                    379:                acc %= i;
                    380:                goto a0;
                    381:        case '&':       /*and*/
                    382:                i = ckph();
                    383:                if (nonumb)
                    384:                        break;
                    385:                if ((acc > 0) && (i > 0))
                    386:                        acc = 1; 
                    387:                else 
                    388:                        acc = 0;
                    389:                goto a0;
                    390:        case ':':       /*or*/
                    391:                i = ckph();
                    392:                if (nonumb)
                    393:                        break;
                    394:                if ((acc > 0) || (i > 0))
                    395:                        acc = 1; 
                    396:                else 
                    397:                        acc = 0;
                    398:                goto a0;
                    399:        case '=':
                    400:                if (cbits(ii = getch()) != '=')
                    401:                        ch = ii;
                    402:                i = ckph();
                    403:                if (nonumb) {
                    404:                        acc = 0; 
                    405:                        break;
                    406:                }
                    407:                if (i == acc)
                    408:                        acc = 1;
                    409:                else 
                    410:                        acc = 0;
                    411:                goto a0;
                    412:        case '>':
                    413:                k = 0;
                    414:                if (cbits(ii = getch()) == '=')
                    415:                        k++; 
                    416:                else 
                    417:                        ch = ii;
                    418:                i = ckph();
                    419:                if (nonumb) {
                    420:                        acc = 0; 
                    421:                        break;
                    422:                }
                    423:                if (acc > (i - k))
                    424:                        acc = 1; 
                    425:                else 
                    426:                        acc = 0;
                    427:                goto a0;
                    428:        case '<':
                    429:                k = 0;
                    430:                if (cbits(ii = getch()) == '=')
                    431:                        k++; 
                    432:                else 
                    433:                        ch = ii;
                    434:                i = ckph();
                    435:                if (nonumb) {
                    436:                        acc = 0; 
                    437:                        break;
                    438:                }
                    439:                if (acc < (i + k))
                    440:                        acc = 1; 
                    441:                else 
                    442:                        acc = 0;
                    443:                goto a0;
                    444:        case ')': 
                    445:                break;
                    446:        case '(':
                    447:                acc = atoi0();
                    448:                goto a0;
                    449:        }
                    450:        return(acc);
                    451: }
                    452: 
                    453: 
                    454: long   ckph()
                    455: {
                    456:        tchar i;
                    457:        long    j;
                    458:        extern long     atoi0();
                    459:        extern long     atoi1();
                    460: 
                    461:        if (cbits(i = getch()) == '(')
                    462:                j = atoi0();
                    463:        else {
                    464:                ch = i;
                    465:                j = atoi1();
                    466:        }
                    467:        return(j);
                    468: }
                    469: 
                    470: 
                    471: long   atoi1()
                    472: {
                    473:        register i, j, digits;
                    474:        tchar ii;
                    475:        long    acc;
                    476:        int     neg, abs, field;
                    477: 
                    478:        neg = abs = field = digits = 0;
                    479:        acc = 0;
                    480: a0:
                    481:        ii = getch();
                    482:        i = cbits(ii);
                    483:        switch (i) {
                    484:        default:
                    485:                ch = ii;
                    486:                break;
                    487:        case '+':
                    488:                goto a0;
                    489:        case '-':
                    490:                neg = 1;
                    491:                goto a0;
                    492:        case '|':
                    493:                abs = 1 + neg;
                    494:                neg = 0;
                    495:                goto a0;
                    496:        }
                    497: a1:
                    498:        while (((j = (cbits(ii = getch())) - '0') >= 0) && (j <= 9)) {
                    499:                field++;
                    500:                digits++;
                    501:                acc = 10 * acc + j;
                    502:        }
                    503:        if (cbits(ii) == '.') {
                    504:                field++;
                    505:                digits = 0;
                    506:                goto a1;
                    507:        }
                    508:        ch = ii;
                    509:        if (!field)
                    510:                goto a2;
                    511:        ii = getch();
                    512:        switch (i = cbits(ii)) {
                    513:        case 'u':
                    514:                i = j = 1;      /* should this be related to HOR?? */
                    515:                break;
                    516:        case 'v':       /*VSs - vert spacing*/
                    517:                j = lss;
                    518:                i = 1;
                    519:                break;
                    520:        case 'm':       /*Ems*/
                    521:                j = EM;
                    522:                i = 1;
                    523:                break;
                    524:        case 'n':       /*Ens*/
                    525:                j = EM;
                    526: #ifndef NROFF
                    527:                i = 2;
                    528: #endif
                    529: #ifdef NROFF
                    530:                i = 1;  /*Same as Ems in NROFF*/
                    531: #endif
                    532:                break;
                    533:        case 'p':       /*Points*/
                    534:                j = INCH;
                    535:                i = 72;
                    536:                break;
                    537:        case 'i':       /*Inches*/
                    538:                j = INCH;
                    539:                i = 1;
                    540:                break;
                    541:        case 'c':       /*Centimeters*/
                    542:                /* if INCH is too big, this will overflow */
                    543:                j = INCH * 50;
                    544:                i = 127;
                    545:                break;
                    546:        case 'P':       /*Picas*/
                    547:                j = INCH;
                    548:                i = 6;
                    549:                break;
                    550:        default:
                    551:                j = dfact;
                    552:                ch = ii;
                    553:                i = dfactd;
                    554:        }
                    555:        if (neg) 
                    556:                acc = -acc;
                    557:        if (!noscale) {
                    558:                acc = (acc * j) / i;
                    559:        }
                    560:        if ((field != digits) && (digits > 0))
                    561:                while (digits--)
                    562:                        acc /= 10;
                    563:        if (abs) {
                    564:                if (dip != d)
                    565:                        j = dip->dnl; 
                    566:                else 
                    567:                        j = v.nl;
                    568:                if (!vflag) {
                    569:                        j = v.hp = sumhp();     /* XXX */
                    570:                }
                    571:                if (abs == 2)
                    572:                        j = -j;
                    573:                acc -= j;
                    574:        }
                    575: a2:
                    576:        nonumb = !field;
                    577:        return(acc);
                    578: }
                    579: 
                    580: 
                    581: caserr()
                    582: {
                    583:        register i, j;
                    584: 
                    585:        lgf++;
                    586:        while (!skip() && (i = getrq()) ) {
                    587:                for (j = NNAMES; j < NN; j++) {  /*NNAMES predefined names*/
                    588:                        if (i == r[j])
                    589:                                break;
                    590:                }
                    591:                if (j != NN) {
                    592:                        r[j] = vlist[j] = inc[j] = fmt[j] = 0;
                    593:                        regcnt--;
                    594:                }
                    595:        }
                    596: }
                    597: 
                    598: 
                    599: casenr()
                    600: {
                    601:        register i, j;
                    602: 
                    603:        lgf++;
                    604:        skip();
                    605:        if ((i = findr(getrq())) == -1)
                    606:                goto rtn;
                    607:        skip();
                    608:        j = inumb(&vlist[i]);
                    609:        if (nonumb)
                    610:                goto rtn;
                    611:        vlist[i] = j;
                    612:        skip();
                    613:        j = atoi();
                    614:        if (nonumb)
                    615:                goto rtn;
                    616:        inc[i] = j;
                    617: rtn:
                    618:        return;
                    619: }
                    620: 
                    621: 
                    622: caseaf()
                    623: {
                    624:        register i, k;
                    625:        tchar j;
                    626: 
                    627:        lgf++;
                    628:        if (skip() || !(i = getrq()) || skip())
                    629:                return;
                    630:        k = 0;
                    631:        j = getch();
                    632:        if (!isalpha(cbits(j))) {
                    633:                ch = j;
                    634:                while ((j = cbits(getch())) >= '0' &&  j <= '9')
                    635:                        k++;
                    636:        }
                    637:        if (!k)
                    638:                k = j;
                    639:        fmt[findr(i)] = k & BMASK;
                    640: }
                    641: 
                    642: setaf()        /* return format of number register */
                    643: {
                    644:        register int i, j;
                    645: 
                    646:        i = usedr(getsn());
                    647:        if (i == -1)
                    648:                return;
                    649:        cp = cbuf;
                    650:        if (fmt[i] > 20)        /* it was probably a, A, i or I */
                    651:                *cp++ = fmt[i];
                    652:        else
                    653:                for (j = (fmt[i] ? fmt[i] : 1); j; j--)
                    654:                        *cp++ = '0';
                    655:        *cp = 0;
                    656:        cp = cbuf;
                    657: }
                    658: 
                    659: 
                    660: vnumb(i)
                    661: int    *i;
                    662: {
                    663:        vflag++;
                    664:        dfact = lss;
                    665:        res = VERT;
                    666:        return(inumb(i));
                    667: }
                    668: 
                    669: 
                    670: hnumb(i)
                    671: int    *i;
                    672: {
                    673:        dfact = EM;
                    674:        res = HOR;
                    675:        return(inumb(i));
                    676: }
                    677: 
                    678: 
                    679: inumb(n)
                    680: int    *n;
                    681: {
                    682:        register i, j, f;
                    683:        tchar ii;
                    684: 
                    685:        f = 0;
                    686:        if (n) {
                    687:                if ((j = cbits(ii = getch())) == '+')
                    688:                        f = 1;
                    689:                else if (j == '-')
                    690:                        f = -1;
                    691:                else 
                    692:                        ch = ii;
                    693:        }
                    694:        i = atoi();
                    695:        if (n && f)
                    696:                i = *n + f * i;
                    697:        i = quant(i, res);
                    698:        vflag = 0;
                    699:        res = dfactd = dfact = 1;
                    700:        if (nonumb)
                    701:                i = 0;
                    702:        return(i);
                    703: }
                    704: 
                    705: 
                    706: quant(n, m)
                    707: int    n, m;
                    708: {
                    709:        register i, neg;
                    710: 
                    711:        neg = 0;
                    712:        if (n < 0) {
                    713:                neg++;
                    714:                n = -n;
                    715:        }
                    716:        /* better as i = ((n + (m/2))/m)*m */
                    717:        i = n / m;
                    718:        if ((n - m * i) > (m / 2))
                    719:                i += 1;
                    720:        i *= m;
                    721:        if (neg)
                    722:                i = -i;
                    723:        return(i);
                    724: }
                    725: 
                    726: 

unix.superglobalmegacorp.com

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