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