|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.