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