1: #define NDIM    10
   2: #define NTAB    601
   3: char    *dfile  "/usr/lib/units";
   4: char    *unames[NDIM];
   5: double  getflt();
   6: int fperr();
   7: struct unit
   8: {
   9:     double  factor;
  10:     char    dim[NDIM];
  11: };
  12: 
  13: struct table
  14: {
  15:     double  factor;
  16:     char    dim[NDIM];
  17:     char    *name;
  18: } table[NTAB];
  19: char    names[NTAB*10];
  20: struct prefix
  21: {
  22:     double  factor;
  23:     char    *pname;
  24: } prefix[]
  25: {
  26:     1e-18,  "atto",
  27:     1e-15,  "femto",
  28:     1e-12,  "pico",
  29:     1e-9,   "nano",
  30:     1e-6,   "micro",
  31:     1e-3,   "milli",
  32:     1e-2,   "centi",
  33:     1e-1,   "deci",
  34:     1e1,    "deka",
  35:     1e2,    "hecta",
  36:     1e2,    "hecto",
  37:     1e3,    "kilo",
  38:     1e6,    "mega",
  39:     1e6,    "meg",
  40:     1e9,    "giga",
  41:     1e12,   "tera",
  42:     0.0,    0
  43: };
  44: int ibuf[259];
  45: int fperrc;
  46: int peekc;
  47: int dumpflg;
  48: 
  49: main(argc, argv)
  50: char *argv[];
  51: {
  52:     register i;
  53:     register char *file;
  54:     struct unit u1, u2;
  55:     double f;
  56: 
  57:     if(argc>1 && *argv[1]=='-') {
  58:         argc--;
  59:         argv++;
  60:         dumpflg++;
  61:     }
  62:     file = dfile;
  63:     if(argc > 1)
  64:         file = argv[1];
  65:     if(fopen(file, ibuf) < 0) {
  66:         printf("no table\n");
  67:         exit();
  68:     }
  69:     ldfps(07600); /* interrupt on fp errors */
  70:     signal(8, fperr);
  71:     init();
  72:     close(ibuf[0]);
  73:     ibuf[0] = 0;
  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:         return;
 300:     }
 301:     if(c == '/')
 302:         while(c != '\n')
 303:             c = get();
 304:     if(c == '\n')
 305:         goto l0;
 306:     np = cp;
 307:     while(c != ' ' && c != '\t') {
 308:         *cp++ = c;
 309:         c = get();
 310:         if(c == '\n') {
 311:             *cp++ = 0;
 312:             tp = hash(np);
 313:             if(tp->name)
 314:                 goto redef;
 315:             tp->name = np;
 316:             tp->factor = lp->factor;
 317:             for(c=0; c<NDIM; c++)
 318:                 tp->dim[c] = lp->dim[c];
 319:             i++;
 320:             goto l0;
 321:         }
 322:     }
 323:     *cp++ = 0;
 324:     lp = hash(np);
 325:     if(lp->name)
 326:         goto redef;
 327:     convr(lp);
 328:     lp->name = np;
 329:     f = 0;
 330:     i++;
 331:     if(lp->factor != 1.0)
 332:         goto l0;
 333:     for(c=0; c<NDIM; c++) {
 334:         t = lp->dim[c];
 335:         if(t>1 || (f>0 && t!=0))
 336:             goto l0;
 337:         if(f==0 && t==1) {
 338:             if(unames[c])
 339:                 goto l0;
 340:             f = c+1;
 341:         }
 342:     }
 343:     if(f>0)
 344:         unames[f-1] = np;
 345:     goto l0;
 346: 
 347: redef:
 348:     printf("redefination %s\n", np);
 349:     goto l0;
 350: }
 351: 
 352: double
 353: getflt()
 354: {
 355:     register c, i, dp;
 356:     double d, e;
 357:     int f;
 358: 
 359:     d = 0.;
 360:     dp = 0;
 361:     do
 362:         c = get();
 363:     while(c == ' ' || c == '\t');
 364: 
 365: l1:
 366:     if(c >= '0' && c <= '9') {
 367:         d = d*10. + c-'0';
 368:         if(dp)
 369:             dp++;
 370:         c = get();
 371:         goto l1;
 372:     }
 373:     if(c == '.') {
 374:         dp++;
 375:         c = get();
 376:         goto l1;
 377:     }
 378:     if(dp)
 379:         dp--;
 380:     if(c == '+' || c == '-') {
 381:         f = 0;
 382:         if(c == '-')
 383:             f++;
 384:         i = 0;
 385:         c = get();
 386:         while(c >= '0' && c <= '9') {
 387:             i = i*10 + c-'0';
 388:             c = get();
 389:         }
 390:         if(f)
 391:             i = -i;
 392:         dp =- i;
 393:     }
 394:     e = 1.;
 395:     i = dp;
 396:     if(i < 0)
 397:         i = -i;
 398:     while(i--)
 399:         e =* 10.;
 400:     if(dp < 0)
 401:         d =* e; else
 402:         d =/ e;
 403:     if(c == '|')
 404:         return(d/getflt());
 405:     peekc = c;
 406:     return(d);
 407: }
 408: 
 409: get()
 410: {
 411:     register c;
 412: 
 413:     if(c=peekc) {
 414:         peekc = 0;
 415:         return(c);
 416:     }
 417:     c = getc(ibuf);
 418:     if(c <= 0) {
 419:         if(ibuf[0])
 420:             return(0);
 421:         printf("\n");
 422:         exit();
 423:     }
 424:     return(c);
 425: }
 426: 
 427: hash(name)
 428: char *name;
 429: {
 430:     register struct table *tp;
 431:     register char *np;
 432:     register h;
 433: 
 434:     h = 0;
 435:     np = name;
 436:     while(*np)
 437:         h = h*57 + *np++ - '0';
 438:     h = lrem(0, h, NTAB);
 439:     tp = &table[h];
 440: l0:
 441:     if(tp->name == 0)
 442:         return(tp);
 443:     if(equal(name, tp->name))
 444:         return(tp);
 445:     tp++;
 446:     if(tp >= &table[NTAB])
 447:         tp = table;
 448:     goto l0;
 449: }
 450: 
 451: fperr()
 452: {
 453: 
 454:     signal(8, fperr);
 455:     fperrc++;
 456: }

Defined functions

convr defined in line 147; used 3 times
equal defined in line 252; used 1 times
fperr defined in line 451; used 3 times
get defined in line 409; used 9 times
getflt defined in line 352; used 3 times
hash defined in line 427; used 5 times
init defined in line 265; used 1 times
  • in line 71
lookup defined in line 198; used 1 times
main defined in line 49; never used
pu defined in line 129; used 2 times
units defined in line 109; used 3 times

Defined variables

dfile defined in line 3; used 1 times
  • in line 62
dumpflg defined in line 47; used 2 times
fperrc defined in line 45; used 5 times
ibuf defined in line 44; used 5 times
names defined in line 19; used 2 times
peekc defined in line 46; used 3 times
prefix defined in line 24; used 2 times
table defined in line 18; used 5 times
unames defined in line 4; used 4 times

Defined struct's

prefix defined in line 20; never used
table defined in line 13; used 6 times
unit defined in line 7; used 14 times

Defined macros

NDIM defined in line 1; used 12 times
NTAB defined in line 2; used 5 times
Last modified: 1975-05-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1131
Valid CSS Valid XHTML 1.0 Strict