Annotation of 41BSD/cmd/units.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)units.c     4.1 (Berkeley) 10/1/80";
                      2: #include <stdio.h>
                      3: 
                      4: #define        NDIM    10
                      5: #define        NTAB    601
                      6: char   *dfile  = "/usr/lib/units";
                      7: char   *unames[NDIM];
                      8: double getflt();
                      9: int    fperr();
                     10: struct table   *hash();
                     11: struct unit
                     12: {
                     13:        double  factor;
                     14:        char    dim[NDIM];
                     15: };
                     16: 
                     17: struct table
                     18: {
                     19:        double  factor;
                     20:        char    dim[NDIM];
                     21:        char    *name;
                     22: } table[NTAB];
                     23: char   names[NTAB*10];
                     24: struct prefix
                     25: {
                     26:        double  factor;
                     27:        char    *pname;
                     28: } prefix[] = 
                     29: {
                     30:        1e-18,  "atto",
                     31:        1e-15,  "femto",
                     32:        1e-12,  "pico",
                     33:        1e-9,   "nano",
                     34:        1e-6,   "micro",
                     35:        1e-3,   "milli",
                     36:        1e-2,   "centi",
                     37:        1e-1,   "deci",
                     38:        1e1,    "deka",
                     39:        1e2,    "hecta",
                     40:        1e2,    "hecto",
                     41:        1e3,    "kilo",
                     42:        1e6,    "mega",
                     43:        1e6,    "meg",
                     44:        1e9,    "giga",
                     45:        1e12,   "tera",
                     46:        0.0,    0
                     47: };
                     48: FILE   *inp;
                     49: int    fperrc;
                     50: int    peekc;
                     51: int    dumpflg;
                     52: 
                     53: main(argc, argv)
                     54: char *argv[];
                     55: {
                     56:        register i;
                     57:        register char *file;
                     58:        struct unit u1, u2;
                     59:        double f;
                     60: 
                     61:        if(argc>1 && *argv[1]=='-') {
                     62:                argc--;
                     63:                argv++;
                     64:                dumpflg++;
                     65:        }
                     66:        file = dfile;
                     67:        if(argc > 1)
                     68:                file = argv[1];
                     69:        if ((inp = fopen(file, "r")) == NULL) {
                     70:                printf("no table\n");
                     71:                exit(1);
                     72:        }
                     73:        signal(8, fperr);
                     74:        init();
                     75: 
                     76: loop:
                     77:        fperrc = 0;
                     78:        printf("you have: ");
                     79:        if(convr(&u1))
                     80:                goto loop;
                     81:        if(fperrc)
                     82:                goto fp;
                     83: loop1:
                     84:        printf("you want: ");
                     85:        if(convr(&u2))
                     86:                goto loop1;
                     87:        for(i=0; i<NDIM; i++)
                     88:                if(u1.dim[i] != u2.dim[i])
                     89:                        goto conform;
                     90:        f = u1.factor/u2.factor;
                     91:        if(fperrc)
                     92:                goto fp;
                     93:        printf("\t* %e\n", f);
                     94:        printf("\t/ %e\n", 1./f);
                     95:        goto loop;
                     96: 
                     97: conform:
                     98:        if(fperrc)
                     99:                goto fp;
                    100:        printf("conformability\n");
                    101:        units(&u1);
                    102:        units(&u2);
                    103:        goto loop;
                    104: 
                    105: fp:
                    106:        printf("underflow or overflow\n");
                    107:        goto loop;
                    108: }
                    109: 
                    110: units(up)
                    111: struct unit *up;
                    112: {
                    113:        register struct unit *p;
                    114:        register f, i;
                    115: 
                    116:        p = up;
                    117:        printf("\t%e ", p->factor);
                    118:        f = 0;
                    119:        for(i=0; i<NDIM; i++)
                    120:                f |= pu(p->dim[i], i, f);
                    121:        if(f&1) {
                    122:                putchar('/');
                    123:                f = 0;
                    124:                for(i=0; i<NDIM; i++)
                    125:                        f |= pu(-p->dim[i], i, f);
                    126:        }
                    127:        putchar('\n');
                    128: }
                    129: 
                    130: pu(u, i, f)
                    131: {
                    132: 
                    133:        if(u > 0) {
                    134:                if(f&2)
                    135:                        putchar('-');
                    136:                if(unames[i])
                    137:                        printf("%s", unames[i]); else
                    138:                        printf("*%c*", i+'a');
                    139:                if(u > 1)
                    140:                        putchar(u+'0');
                    141:                        return(2);
                    142:        }
                    143:        if(u < 0)
                    144:                return(1);
                    145:        return(0);
                    146: }
                    147: 
                    148: convr(up)
                    149: struct unit *up;
                    150: {
                    151:        register struct unit *p;
                    152:        register c;
                    153:        register char *cp;
                    154:        char name[20];
                    155:        int den, err;
                    156: 
                    157:        p = up;
                    158:        for(c=0; c<NDIM; c++)
                    159:                p->dim[c] = 0;
                    160:        p->factor = getflt();
                    161:        if(p->factor == 0.)
                    162:                p->factor = 1.0;
                    163:        err = 0;
                    164:        den = 0;
                    165:        cp = name;
                    166: 
                    167: loop:
                    168:        switch(c=get()) {
                    169: 
                    170:        case '1':
                    171:        case '2':
                    172:        case '3':
                    173:        case '4':
                    174:        case '5':
                    175:        case '6':
                    176:        case '7':
                    177:        case '8':
                    178:        case '9':
                    179:        case '-':
                    180:        case '/':
                    181:        case ' ':
                    182:        case '\t':
                    183:        case '\n':
                    184:                if(cp != name) {
                    185:                        *cp++ = 0;
                    186:                        cp = name;
                    187:                        err |= lookup(cp, p, den, c);
                    188:                }
                    189:                if(c == '/')
                    190:                        den++;
                    191:                if(c == '\n')
                    192:                        return(err);
                    193:                goto loop;
                    194:        }
                    195:        *cp++ = c;
                    196:        goto loop;
                    197: }
                    198: 
                    199: lookup(name, up, den, c)
                    200: char *name;
                    201: struct unit *up;
                    202: {
                    203:        register struct unit *p;
                    204:        register struct table *q;
                    205:        register i;
                    206:        char *cp1, *cp2;
                    207:        double e;
                    208: 
                    209:        p = up;
                    210:        e = 1.0;
                    211: 
                    212: loop:
                    213:        q = hash(name);
                    214:        if(q->name) {
                    215:                l1:
                    216:                if(den) {
                    217:                        p->factor /= q->factor*e;
                    218:                        for(i=0; i<NDIM; i++)
                    219:                                p->dim[i] -= q->dim[i];
                    220:                } else {
                    221:                        p->factor *= q->factor*e;
                    222:                        for(i=0; i<NDIM; i++)
                    223:                                p->dim[i] += q->dim[i];
                    224:                }
                    225:                if(c >= '2' && c <= '9') {
                    226:                        c--;
                    227:                        goto l1;
                    228:                }
                    229:                return(0);
                    230:        }
                    231:        for(i=0; cp1 = prefix[i].pname; i++) {
                    232:                cp2 = name;
                    233:                while(*cp1 == *cp2++)
                    234:                        if(*cp1++ == 0) {
                    235:                                cp1--;
                    236:                                break;
                    237:                        }
                    238:                if(*cp1 == 0) {
                    239:                        e *= prefix[i].factor;
                    240:                        name = cp2-1;
                    241:                        goto loop;
                    242:                }
                    243:        }
                    244:        for(cp1 = name; *cp1; cp1++);
                    245:        if(cp1 > name+1 && *--cp1 == 's') {
                    246:                *cp1 = 0;
                    247:                goto loop;
                    248:        }
                    249:        printf("cannot recognize %s\n", name);
                    250:        return(1);
                    251: }
                    252: 
                    253: equal(s1, s2)
                    254: char *s1, *s2;
                    255: {
                    256:        register char *c1, *c2;
                    257: 
                    258:        c1 = s1;
                    259:        c2 = s2;
                    260:        while(*c1++ == *c2)
                    261:                if(*c2++ == 0)
                    262:                        return(1);
                    263:        return(0);
                    264: }
                    265: 
                    266: init()
                    267: {
                    268:        register char *cp;
                    269:        register struct table *tp, *lp;
                    270:        int c, i, f, t;
                    271:        char *np;
                    272: 
                    273:        cp = names;
                    274:        for(i=0; i<NDIM; i++) {
                    275:                np = cp;
                    276:                *cp++ = '*';
                    277:                *cp++ = i+'a';
                    278:                *cp++ = '*';
                    279:                *cp++ = 0;
                    280:                lp = hash(np);
                    281:                lp->name = np;
                    282:                lp->factor = 1.0;
                    283:                lp->dim[i] = 1;
                    284:        }
                    285:        lp = hash("");
                    286:        lp->name = cp-1;
                    287:        lp->factor = 1.0;
                    288: 
                    289: l0:
                    290:        c = get();
                    291:        if(c == 0) {
                    292:                printf("%d units; %d bytes\n\n", i, cp-names);
                    293:                if(dumpflg)
                    294:                for(tp = &table[0]; tp < &table[NTAB]; tp++) {
                    295:                        if(tp->name == 0)
                    296:                                continue;
                    297:                        printf("%s", tp->name);
                    298:                        units(tp);
                    299:                }
                    300:                fclose(inp);
                    301:                inp = stdin;
                    302:                return;
                    303:        }
                    304:        if(c == '/') {
                    305:                while(c != '\n' && c != 0)
                    306:                        c = get();
                    307:                goto l0;
                    308:        }
                    309:        if(c == '\n')
                    310:                goto l0;
                    311:        np = cp;
                    312:        while(c != ' ' && c != '\t') {
                    313:                *cp++ = c;
                    314:                c = get();
                    315:                if (c==0)
                    316:                        goto l0;
                    317:                if(c == '\n') {
                    318:                        *cp++ = 0;
                    319:                        tp = hash(np);
                    320:                        if(tp->name)
                    321:                                goto redef;
                    322:                        tp->name = np;
                    323:                        tp->factor = lp->factor;
                    324:                        for(c=0; c<NDIM; c++)
                    325:                                tp->dim[c] = lp->dim[c];
                    326:                        i++;
                    327:                        goto l0;
                    328:                }
                    329:        }
                    330:        *cp++ = 0;
                    331:        lp = hash(np);
                    332:        if(lp->name)
                    333:                goto redef;
                    334:        convr(lp);
                    335:        lp->name = np;
                    336:        f = 0;
                    337:        i++;
                    338:        if(lp->factor != 1.0)
                    339:                goto l0;
                    340:        for(c=0; c<NDIM; c++) {
                    341:                t = lp->dim[c];
                    342:                if(t>1 || (f>0 && t!=0))
                    343:                        goto l0;
                    344:                if(f==0 && t==1) {
                    345:                        if(unames[c])
                    346:                                goto l0;
                    347:                        f = c+1;
                    348:                }
                    349:        }
                    350:        if(f>0)
                    351:                unames[f-1] = np;
                    352:        goto l0;
                    353: 
                    354: redef:
                    355:        printf("redefinition %s\n", np);
                    356:        goto l0;
                    357: }
                    358: 
                    359: double
                    360: getflt()
                    361: {
                    362:        register c, i, dp;
                    363:        double d, e;
                    364:        int f;
                    365: 
                    366:        d = 0.;
                    367:        dp = 0;
                    368:        do
                    369:                c = get();
                    370:        while(c == ' ' || c == '\t');
                    371: 
                    372: l1:
                    373:        if(c >= '0' && c <= '9') {
                    374:                d = d*10. + c-'0';
                    375:                if(dp)
                    376:                        dp++;
                    377:                c = get();
                    378:                goto l1;
                    379:        }
                    380:        if(c == '.') {
                    381:                dp++;
                    382:                c = get();
                    383:                goto l1;
                    384:        }
                    385:        if(dp)
                    386:                dp--;
                    387:        if(c == '+' || c == '-') {
                    388:                f = 0;
                    389:                if(c == '-')
                    390:                        f++;
                    391:                i = 0;
                    392:                c = get();
                    393:                while(c >= '0' && c <= '9') {
                    394:                        i = i*10 + c-'0';
                    395:                        c = get();
                    396:                }
                    397:                if(f)
                    398:                        i = -i;
                    399:                dp -= i;
                    400:        }
                    401:        e = 1.;
                    402:        i = dp;
                    403:        if(i < 0)
                    404:                i = -i;
                    405:        while(i--)
                    406:                e *= 10.;
                    407:        if(dp < 0)
                    408:                d *= e; else
                    409:                d /= e;
                    410:        if(c == '|')
                    411:                return(d/getflt());
                    412:        peekc = c;
                    413:        return(d);
                    414: }
                    415: 
                    416: get()
                    417: {
                    418:        register c;
                    419: 
                    420:        if(c=peekc) {
                    421:                peekc = 0;
                    422:                return(c);
                    423:        }
                    424:        c = getc(inp);
                    425:        if (c == EOF) {
                    426:                if (inp == stdin) {
                    427:                        printf("\n");
                    428:                        exit(0);
                    429:                }
                    430:                return(0);
                    431:        }
                    432:        return(c);
                    433: }
                    434: 
                    435: struct table *
                    436: hash(name)
                    437: char *name;
                    438: {
                    439:        register struct table *tp;
                    440:        register char *np;
                    441:        register unsigned h;
                    442: 
                    443:        h = 0;
                    444:        np = name;
                    445:        while(*np)
                    446:                h = h*57 + *np++ - '0';
                    447:        if( ((int)h)<0) h= -(int)h;
                    448:        h %= NTAB;
                    449:        tp = &table[h];
                    450: l0:
                    451:        if(tp->name == 0)
                    452:                return(tp);
                    453:        if(equal(name, tp->name))
                    454:                return(tp);
                    455:        tp++;
                    456:        if(tp >= &table[NTAB])
                    457:                tp = table;
                    458:        goto l0;
                    459: }
                    460: 
                    461: fperr()
                    462: {
                    463: 
                    464:        signal(8, fperr);
                    465:        fperrc++;
                    466: }

unix.superglobalmegacorp.com

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