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

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

unix.superglobalmegacorp.com

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