Annotation of researchv9/cmd/troff/n4.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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