Annotation of 3BSD/cmd/troff/n4.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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