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

unix.superglobalmegacorp.com

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