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

unix.superglobalmegacorp.com

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