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

1.1       root        1: #include "tdef.hd"
                      2: #include "strs.hd"
                      3: #ifdef NROFF
                      4: #include "tw.hd"
                      5: extern struct ttable t;
                      6: #endif
                      7: /*
                      8: troff4.c
                      9: 
                     10: number registers, conversion, arithmetic
                     11: */
                     12: 
                     13: extern struct s *frame;
                     14: #ifndef INCORE
                     15: extern struct envblock eblock;
                     16: #else
                     17: extern struct envblock eblock[NEV];
                     18: extern int ev;
                     19: #endif
                     20: extern struct d d[NDI], *dip;
                     21: extern struct datablock dblock;
                     22: 
                     23: extern int tch[];
                     24: extern int cd;
                     25: extern int freenslot;
                     26: extern int *cstk[], cstkl;
                     27: extern int ch_CMASK;
                     28: extern int dilev;
                     29: extern int ascii;
                     30: extern int cbuf[NC];
                     31: extern int *cp;
                     32: extern int ch;
                     33: extern int lgf;
                     34: extern int pl;
                     35: extern int ralss;
                     36: extern int totout;
                     37: extern int nrbits;
                     38: extern int nonumb;
                     39: extern int vflag;
                     40: extern int noscale;
                     41: extern int dfact;
                     42: extern int dfactd;
                     43: extern int po;
                     44: extern int nform;
                     45: extern int bdtab[];
                     46: extern int res;
                     47: extern int cwidth;
                     48: extern int dotT;
                     49: extern int print;
                     50: int regcnt = NNAMES;
                     51: extern char cfname[NSO][NS];
                     52: extern int ifi;
                     53: setn()
                     54: {
                     55:        register i,j;
                     56:        int f;
                     57: 
                     58:        f = nform = 0;
                     59:        if (getch() && (ch_CMASK == '+')) f = 1;
                     60:                else if(ch_CMASK== '-')f = -1;
                     61:                        else ch = ch_CMASK;
                     62:        if((i=getsn()) == 0)return;
                     63:        if((i & 0177) == '.')switch(i>>BYTE){
                     64:                case 's': i = pts & 077;        break;
                     65:                case 'v': i = lss;              break;
                     66:                case 'f': i = font + 1; break;
                     67:                case 'p': i = pl;               break;
                     68:                case 't':  i = findt1();        break;
                     69:                case 'o': i = po;               break;
                     70:                case 'l': i = ll;               break;
                     71:                case 'i': i = in;               break;
                     72:                case '$': i = frame->nargs;             break;
                     73:                case 'A': i = ascii;            break;
                     74:                case 'c': i = cd;               break;
                     75:                case 'n': i = lastl;            break;
                     76:                case 'a': i = ralss;            break;
                     77:                case 'h': i = dip->hnl; break;
                     78:                case 'd':
                     79:                        if(dip != d)i = dip->dnl; else i = v_nl;
                     80:                        break;
                     81:                case 'u': i = fi;               break;
                     82:                case 'j': i = ad + 2*admod;     break;
                     83:                case 'w': i = cwidth;           break;
                     84:                case 'x': i = nel;      break;
                     85:                case 'y': i = un;               break;
                     86:                case 'T': i = dotT;             break; /*-Tterm used in nroff*/
                     87:                case 'V': i = VERT;             break;
                     88:                case 'H': i = HOR;              break;
                     89:                case 'k': i = ne;               break;
                     90:                case 'P': i = print;            break;
                     91:                case 'L': i = ls;               break;
                     92:                case 'R': i = NN - regcnt;      break;
                     93:                case 'z': i = dip->curd;
                     94:                        cbuf[0] = i & BMASK;
                     95:                        cbuf[1] = (i >> BYTE) & BMASK;
                     96:                        cbuf[2] = 0;
                     97:                        setcp(cbuf);
                     98:                        return;
                     99:                case 'b': i = bdtab[font];              break;
                    100:                case 'F': for (i=0; cbuf[i] = cfname[ifi][i]; i++) ;
                    101:                          setcp(cbuf);          /* give current filename */
                    102:                          return;
                    103: 
                    104:                default:
                    105:                        goto s0;
                    106:        }
                    107:        else{
                    108: s0:
                    109:                if((j=findr(i)) == -1)i = 0;
                    110:                else{
                    111:                        i = (vlist[j] = (vlist[j] + inc[j]*f));
                    112:                        nform = fmt[j];
                    113:                }
                    114:        }
                    115:        setn1(i);
                    116:        setcp(cbuf);
                    117: }
                    118: setn1(i)
                    119: int i;
                    120: {
                    121:        extern int wrc();
                    122: 
                    123:        cp = cbuf;
                    124:        nrbits = 0;
                    125:        fnumb(i,wrc);
                    126:        *cp = 0;
                    127:        setcp(cbuf);
                    128: }
                    129: findr(i)
                    130: int i;
                    131: {
                    132:        register j;
                    133:        static int numerr = 0;
                    134: 
                    135:        if (!i) return -1;
                    136:        if ((j = fnrname(i)) != -1) return j;
                    137: 
                    138:        if (freenslot != -1)    {
                    139:                r[freenslot] = i;
                    140:                regcnt++;
                    141:                return freenslot;       }
                    142: 
                    143:        if(!numerr)prstrfl("Too many number registers.\n");
                    144:        if(++numerr > 1)done2(04); else edone(04);
                    145:        return -1;
                    146: }
                    147: fnumb(i,f)
                    148: int i, (*f)();
                    149: {
                    150:        register j;
                    151: 
                    152:        j = 0;
                    153:        if(i < 0){
                    154:                j = (*f)('-' | nrbits);
                    155:                i = -i;
                    156:        }
                    157:        switch(nform){
                    158:                default:
                    159:                case '1':
                    160:                case 0: return(decml(i,f) + j);
                    161:                case 'i':
                    162:                case 'I': return(roman(i,f) + j);
                    163:                case 'a':
                    164:                case 'A': return(abc(i,f) + j);
                    165:        }
                    166: }
                    167: decml(i,f)
                    168: int i, (*f)();
                    169: {
                    170:        register j,k;
                    171: 
                    172:        k = 0;
                    173:        nform--;
                    174:        if((j=i/10) || (nform > 0))k = decml(j,f);
                    175:        return(k + (*f)((i%10 + '0') | nrbits));
                    176: }
                    177: roman(i,f)
                    178: int i, (*f)();
                    179: {
                    180: 
                    181:        if(!i)return((*f)('0' | nrbits));
                    182:        if(nform == 'i')return(roman0(i,f,"\151\170\143\155\172"/*ixcmz*/,"\166\154\144\167"/*vldw*/));
                    183:        else return(roman0(i,f,"\111\130\103\115\132"/*IXCMZ*/,"\126\114\104\127"/*VLDW*/));
                    184: }
                    185: roman0(i,f,onesp,fivesp)
                    186: int i, (*f)();
                    187: char *onesp, *fivesp;
                    188: {
                    189:        register q, rem, k;
                    190: 
                    191:        k = 0;
                    192:        if(!i)return(0);
                    193:        k = roman0(i/10,f,onesp+1,fivesp+1);
                    194:        q = (i=i%10)/5;
                    195:        rem = i%5;
                    196:        if(rem == 4){
                    197:                k += (*f)(*onesp | nrbits);
                    198:                if(q)i = *(onesp+1);
                    199:                        else i = *fivesp;
                    200:                return(k += (*f)(i | nrbits));
                    201:        }
                    202:        if(q)k += (*f)(*fivesp | nrbits);
                    203:        while(--rem >= 0)
                    204:                k += (*f)(*onesp | nrbits);
                    205:        return(k);
                    206: }
                    207: abc(i,f)
                    208: int i, (*f)();
                    209: {
                    210:        if(!i)return((*f)('0' | nrbits));
                    211:        else return(abc0(i-1,f));
                    212: }
                    213: abc0(i,f)
                    214: int i, (*f)();
                    215: {
                    216:        register j, k;
                    217: 
                    218:        k = 0;
                    219:        if(j=i/26)k = abc0(j-1,f);
                    220:        return(k + (*f)((i%26 + nform) | nrbits));
                    221: }
                    222: wrc(i)
                    223: int i;
                    224: {
                    225:        if(cp >= &cbuf[NC])return(0);
                    226:        *cp++ = i;
                    227:        return(1);
                    228: }
                    229: long atoi0()
                    230: {
                    231:        register ii, k, cnt;
                    232:        long i, acc;
                    233:        extern long ckph();
                    234: 
                    235:        i = 0; acc = 0;
                    236:        nonumb = 0;
                    237:        cnt = -1;
                    238: a0:
                    239:        cnt++;
                    240:        ii = getch();
                    241:        switch (ch_CMASK)       {
                    242:                default:
                    243:                        ch = ii;
                    244:                        if(cnt)break;
                    245:                case '+':
                    246:                        i = ckph();
                    247:                        if(nonumb)break;
                    248:                        acc += i;
                    249:                        goto a0;
                    250:                case '-':
                    251:                        i = ckph();
                    252:                        if(nonumb)break;
                    253:                        acc -= i;
                    254:                        goto a0;
                    255:                case '*':
                    256:                        i = ckph();
                    257:                        if(nonumb)break;
                    258:                        acc *= i;
                    259:                        goto a0;
                    260:                case '/':
                    261:                        i = ckph();
                    262:                        if(nonumb)break;
                    263:                        if(i == 0){
                    264:                                prstrfl("Divide by zero.\n");
                    265:                                acc = 0;
                    266:                        }else acc /= i;
                    267:                        goto a0;
                    268:                case '%':
                    269:                        i = ckph();
                    270:                        if(nonumb)break;
                    271:                        acc %= i;
                    272:                        goto a0;
                    273:                case '&':       /*and*/
                    274:                        i = ckph();
                    275:                        if(nonumb)break;
                    276:                        if((acc > 0) && (i > 0))acc = 1; else acc = 0;
                    277:                        goto a0;
                    278:                case ':':       /*or*/
                    279:                        i = ckph();
                    280:                        if(nonumb)break;
                    281:                        if((acc > 0) || (i > 0))acc = 1; else acc = 0;
                    282:                        goto a0;
                    283:                case '=':
                    284:                        if ((ii = getch()) && (ch_CMASK != '=')) ch = ii;
                    285:                        i = ckph();
                    286:                        if(nonumb){acc = 0; break;}
                    287:                        if(i == acc)acc = 1;
                    288:                        else acc = 0;
                    289:                        goto a0;
                    290:                case '>':
                    291:                        k = 0;
                    292:                        if ((ii = getch()) && (ch_CMASK == '=')) k++;
                    293:                                else ch = ii;
                    294:                        i = ckph();
                    295:                        if(nonumb){acc = 0; break;}
                    296:                        if(acc > (i - k))acc = 1; else acc = 0;
                    297:                        goto a0;
                    298:                case '<':
                    299:                        k = 0;
                    300:                        if ((ii = getch()) && (ch_CMASK == '=')) k++;
                    301:                                else ch = ii;
                    302:                        i = ckph();
                    303:                        if(nonumb){acc = 0; break;}
                    304:                        if(acc < (i + k))acc = 1; else acc = 0;
                    305:                        goto a0;
                    306:                case ')': break;
                    307:                case '(':
                    308:                        acc = atoi0();
                    309:                        goto a0;
                    310:        }
                    311:        return(acc);
                    312: }
                    313: long ckph(){
                    314:        extern long atoi0();
                    315:        extern long atoi1();
                    316: 
                    317:        if ((ch = getch()) && (ch_CMASK != '(')) return ((long) atoi1());
                    318:        else{
                    319:                ch = 0;
                    320:                return ((long) atoi0());
                    321:        }
                    322: }
                    323: long atoi1()
                    324: {
                    325:        register i, j, digits;
                    326:        long acc;
                    327:        int neg, aabs, field;
                    328: 
                    329:        neg = aabs = field = digits = 0;
                    330:        acc = 0;
                    331: a0:
                    332:        i = getch();
                    333:        switch (ch_CMASK) {
                    334:                default:
                    335:                        ch = i;
                    336:                        break;
                    337:                case '+':
                    338:                        goto a0;
                    339:                case '-':
                    340:                        neg = 1;
                    341:                        goto a0;
                    342:                case '|':
                    343:                        aabs = 1 + neg;
                    344:                        neg = 0;
                    345:                        goto a0;
                    346:        }
                    347: a1:
                    348:        while ((i = getch()) && ((j = ch_CMASK - '0') >= 0) && (j <= 9)) {
                    349:                field++;
                    350:                digits++;
                    351:                acc = 10*acc + j;
                    352:        }
                    353:        if(ch_CMASK == '.'){
                    354:                field++;
                    355:                digits = 0;
                    356:                goto a1;
                    357:        }
                    358:        ch = i;
                    359:        if(!field)goto a2;
                    360:        i = getch();
                    361:        switch (ch_CMASK) {
                    362:                case 'u':
                    363:                        i = j = 1;
                    364:                        break;
                    365:                case 'v':       /*VSs - vert spacing*/
                    366:                        j = lss;
                    367:                        i = 1;
                    368:                        break;
                    369:                case 'm':       /*Ems*/
                    370:                        j = EM;
                    371:                        i = 1;
                    372:                        break;
                    373:                case 'n':       /*Ens*/
                    374:                        j = EM;
                    375: #ifndef NROFF
                    376:                        i = 2;
                    377: #endif
                    378: #ifdef NROFF
                    379:                        i = 1;  /*Same as Ems in NROFF*/
                    380: #endif
                    381:                        break;
                    382:                case 'p':       /*Points*/
                    383:                        j = INCH;
                    384:                        i = 72;
                    385:                        break;
                    386:                case 'i':       /*Inches*/
                    387:                        j = INCH;
                    388:                        i = 1;
                    389:                        break;
                    390:                case 'c':       /*Centimeters*/
                    391:                        j = INCH*50;
                    392:                        i = 127;
                    393:                        break;
                    394:                case 'P':       /*Picas*/
                    395:                        j = INCH;
                    396:                        i = 6;
                    397:                        break;
                    398:                default:
                    399:                        j = dfact;
                    400:                        ch = i;
                    401:                        i = dfactd;
                    402:        }
                    403:        if(neg) acc = -acc;
                    404:        if(!noscale){
                    405:                acc = (acc*j)/i;
                    406:        }
                    407:        if((field != digits) && (digits > 0))while(digits--)acc /= 10;
                    408:        if(aabs){
                    409:                if(dip != d)j = dip->dnl; else j = v_nl;
                    410:                if(!vflag)j = v_hp;
                    411:                if(aabs == 2)j = -j;
                    412:                acc -= j;
                    413:        }
                    414: a2:
                    415:        nonumb = !field;
                    416:        return(acc);
                    417: }
                    418: caserr(){
                    419:        register i;
                    420: 
                    421:        lgf++;
                    422:        while (!skip() && (i = getrq()))
                    423:            if ((i = fnrname(i)) != -1) {       /* do this number reg */
                    424:                r[i] = -1;
                    425:                vlist[i] = inc[i] = fmt[i] = 0; }
                    426: }
                    427: casenr(){
                    428:        register i, j;
                    429: 
                    430:        lgf++;
                    431:        skip();
                    432:        if((i = findr(getrq())) == -1)goto rtn;
                    433:        skip();
                    434:        j = inumb(&vlist[i]);
                    435:        if(nonumb)goto rtn;
                    436:        vlist[i] = j;
                    437:        skip();
                    438:        j = atoi();
                    439:        if(nonumb)goto rtn;
                    440:        inc[i] = j;
                    441: rtn:
                    442:        return;
                    443: }
                    444: caseaf(){
                    445:        register i, j, k;
                    446: 
                    447:        lgf++;
                    448:        if(skip() || !(i = getrq()) || skip())return;
                    449:        k = 0;
                    450:        if(!alph(j=getch())){
                    451:                ch = j;
                    452:                while (getch() && ((j = ch_CMASK) >= '0') && (j <= '9'))
                    453:                        k++;
                    454:                if (k > 20) k = 20;
                    455:        }
                    456:                        /* force unusual formats into '1' form */
                    457:        else switch (j & BMASK) {
                    458:                case 'A':
                    459:                case 'a':
                    460:                case 'I':
                    461:                case 'i':       break;
                    462:                default:        k++;    }
                    463:        if(!k)k=j;
                    464:        fmt[findr(i)] = k & BMASK;
                    465: }
                    466: setaf()                /* return the format of a number reg - in the .af form */
                    467: {
                    468:        register int i, j;
                    469:        register int *p;
                    470: 
                    471:        if ((i=fnrname(getsn())) == -1) return; /* no register */
                    472:        if (fmt[i] > 20)        /* A, a, I, or i. NOTE: 20 is arbitrary */
                    473:                setch0(fmt[i])
                    474:            else        {       /* 0001 format */
                    475:                p = cbuf;
                    476:                for (j=(fmt[i])?fmt[i]:1; j; j--)
                    477:                        *p++ = '0';
                    478:                *p = 0;
                    479:                setcp(cbuf);    }
                    480: }
                    481: vnumb(i)
                    482: int *i;
                    483: {
                    484:        vflag++;
                    485:        dfact = lss;
                    486:        res = VERT;
                    487:        return(inumb(i));
                    488: }
                    489: hnumb(i)
                    490: int *i;
                    491: {
                    492:        dfact = EM;
                    493:        res = HOR;
                    494:        return(inumb(i));
                    495: }
                    496: inumb(n)
                    497: int *n;
                    498: {
                    499:        register i, f;
                    500: 
                    501:        f = 0;
                    502:        if(n){
                    503:                if ((i = getch()) && (ch_CMASK == '+')) f = 1;
                    504:                        else if (ch_CMASK == '-') f = -1;
                    505:                                else ch = i;    }
                    506:        i = atoi();
                    507:        if(n && f)i = *n + f*i;
                    508:        i = quant(i,res);
                    509:        vflag = 0;
                    510:        res = dfactd = dfact = 1;
                    511:        if(nonumb)i = 0;
                    512:        return(i);
                    513: }
                    514: quant(n,m)
                    515: int n, m;
                    516: {
                    517:        register i, neg;
                    518: 
                    519:        neg = 0;
                    520:        if(n<0){
                    521:                neg++;
                    522:                n = -n;
                    523:        }
                    524:        i = n/m;
                    525:        if((n - m*i) > (m/2))i += 1;
                    526:        i *= m;
                    527:        if(neg && (i != 0))i = -i;
                    528:        return(i);
                    529: }

unix.superglobalmegacorp.com

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