Annotation of 43BSDReno/usr.bin/units/units.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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