Annotation of 43BSD/usr.bin/troff/n4.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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