PageRenderTime 59ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/modlunit/units.c

https://bitbucket.org/nrnhines/nrn
C | 974 lines | 872 code | 80 blank | 22 comment | 205 complexity | 824c07add1ab0cdf8af211eb4049d832 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0
  1. #include <../../nmodlconf.h>
  2. /* /local/src/master/nrn/src/modlunit/units.c,v 1.5 1997/11/24 16:19:13 hines Exp */
  3. /* Mostly from Berkeley */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <signal.h>
  7. #include <string.h>
  8. #include "units.h"
  9. #include <assert.h>
  10. #if defined(CYGWIN)
  11. #include "../mswin/extra/d2upath.c"
  12. #endif
  13. #if defined(WIN32)
  14. #include <windows.h>
  15. #endif
  16. int unitonflag = 1;
  17. static int UnitsOn = 0;
  18. extern double fabs();
  19. extern void diag();
  20. #define IFUNITS {if (!UnitsOn) return;}
  21. #define OUTTOLERANCE(arg1,arg2) (fabs(arg2/arg1 - 1.) > 1.e-5)
  22. #define NTAB 601
  23. /* if MODLUNIT environment variable not set then look in the following places*/
  24. #if MAC
  25. static char *dfile = ":lib:nrnunits.lib";
  26. #else
  27. #if defined(NEURON_DATA_DIR)
  28. static char *dfile = NEURON_DATA_DIR"/lib/nrnunits.lib";
  29. #else
  30. static char *dfile = "/usr/lib/units";
  31. #endif
  32. #endif
  33. #if defined(__TURBOC__) || defined(__GO32__)
  34. static char *dfilealt = "/nrn/lib/nrnunits.lib";
  35. #else
  36. #if MAC
  37. static char *dfilealt = "::lib:nrnunits.lib";
  38. #else
  39. static char *dfilealt = "../../share/lib/nrnunits.lib";
  40. #endif
  41. #endif
  42. static char *unames[NDIM];
  43. static double getflt();
  44. static void fperr();
  45. static int lookup();
  46. static struct table *hash();
  47. static void chkfperror();
  48. static void units();
  49. static int pu();
  50. static int convr();
  51. static void init();
  52. static int get();
  53. extern void Unit_push(char*);
  54. static struct table
  55. {
  56. double factor;
  57. #if -1 == '\377'
  58. char dim[NDIM];
  59. #else
  60. signed char dim[NDIM];
  61. #endif
  62. char *name;
  63. } table[NTAB];
  64. static char names[NTAB*10];
  65. static struct prefix
  66. {
  67. double factor;
  68. char *pname;
  69. } prefix[] =
  70. {
  71. 1e-18, "atto",
  72. 1e-15, "femto",
  73. 1e-12, "pico",
  74. 1e-9, "nano",
  75. 1e-6, "micro",
  76. 1e-3, "milli",
  77. 1e-2, "centi",
  78. 1e-1, "deci",
  79. 1e1, "deka",
  80. 1e2, "hecta",
  81. 1e2, "hecto",
  82. 1e3, "kilo",
  83. 1e6, "mega",
  84. 1e6, "meg",
  85. 1e9, "giga",
  86. 1e12, "tera",
  87. 0.0, 0
  88. };
  89. static FILE *inpfile;
  90. static int fperrc;
  91. static int peekc;
  92. static int dumpflg;
  93. static char *pc;
  94. static int Getc(inp)
  95. FILE *inp;
  96. {
  97. if (inp != stdin) {
  98. #if MAC
  99. int c = getc(inp);
  100. if (c == '\r') { c = '\n';}
  101. return c;
  102. #else
  103. return getc(inp);
  104. #endif
  105. }else if (pc && *pc) {
  106. return (int)(*pc++);
  107. }else{
  108. return (int)('\n');
  109. }
  110. }
  111. #define UNIT_STK_SIZE 20
  112. static struct unit unit_stack[UNIT_STK_SIZE], *usp;
  113. static char* neuronhome() {
  114. #if defined(WIN32)
  115. int i;
  116. static char buf[256];
  117. GetModuleFileName(NULL, buf, 256);
  118. for (i=strlen(buf); i >= 0 && buf[i] != '\\'; --i) {;}
  119. buf[i] = '\0'; // /neuron.exe gone
  120. // printf("setneuronhome |%s|\n", buf);
  121. for (i=strlen(buf); i >= 0 && buf[i] != '\\'; --i) {;}
  122. buf[i] = '\0'; // /bin gone
  123. #if defined(CYGWIN)
  124. {
  125. char* u = hoc_dos2unixpath(buf);
  126. strcpy(buf, hoc_dos2unixpath(u));
  127. free(u);
  128. }
  129. #endif
  130. return buf;
  131. #else
  132. return getenv("NEURONHOME");
  133. #endif
  134. }
  135. void unit_pop() {
  136. IFUNITS
  137. assert(usp >= unit_stack);
  138. --usp;
  139. }
  140. void unit_swap() { /*exchange top two elements of stack*/
  141. struct unit *up;
  142. int i, j;
  143. double d;
  144. IFUNITS
  145. assert(usp > unit_stack);
  146. up = usp -1;
  147. d = usp->factor;
  148. usp->factor = up->factor;
  149. up->factor = d;
  150. for (i=0; i<NDIM; i++) {
  151. j = usp->dim[i];
  152. usp->dim[i] = up->dim[i];
  153. up->dim[i] = j;
  154. }
  155. }
  156. double
  157. unit_mag() { /* return unit magnitude that is on stack */
  158. return usp->factor;
  159. }
  160. void unit_mag_mul(d)
  161. double d;
  162. {
  163. usp->factor *= d;
  164. }
  165. void punit() {
  166. struct unit * i;
  167. for (i=usp; i!=unit_stack-1; --i) {
  168. printf("%s\n", Unit_str(i));
  169. }
  170. }
  171. void ucopypop(up)
  172. struct unit *up;
  173. {
  174. int i;
  175. for (i=0; i<NDIM; i++) {
  176. up->dim[i] = usp->dim[i];
  177. }
  178. up->factor = usp->factor;
  179. up->isnum = usp->isnum;
  180. unit_pop();
  181. }
  182. void ucopypush(up)
  183. struct unit *up;
  184. {
  185. int i;
  186. Unit_push("");
  187. for (i=0; i<NDIM; i++) {
  188. usp->dim[i] = up->dim[i];
  189. }
  190. usp->factor = up->factor;
  191. usp->isnum = up->isnum;
  192. }
  193. void Unit_push(string)
  194. char *string;
  195. {
  196. IFUNITS
  197. assert(usp < unit_stack + (UNIT_STK_SIZE - 1));
  198. ++usp;
  199. pc = string;
  200. if (string) {
  201. usp->isnum = 0;
  202. }else{
  203. pc = "";
  204. usp->isnum = 1;
  205. }
  206. convr(usp);
  207. /*printf("unit_push %s\n", string); units(usp);*/
  208. }
  209. void unit_push_num(d)
  210. double d;
  211. {
  212. Unit_push("");
  213. usp->factor = d;
  214. }
  215. void unitcheck(s)
  216. char *s;
  217. {
  218. Unit_push(s);
  219. unit_pop();
  220. }
  221. char *
  222. unit_str() {
  223. /* return top of stack as units string */
  224. if (!UnitsOn) return "";
  225. return Unit_str(usp);
  226. }
  227. void install_units(s1, s2) /* define s1 as s2 */
  228. char *s1, *s2;
  229. {
  230. struct table *tp;
  231. int i;
  232. IFUNITS
  233. Unit_push(s2);
  234. tp = hash(s1);
  235. if (tp->name) {
  236. printf("Redefinition of units (%s) to:", s1);
  237. units(usp);
  238. printf(" is ignored.\nThey remain:");
  239. Unit_push(s1); units(usp);
  240. diag("Units redefinition", (char *)0);
  241. }
  242. tp->name = s1;
  243. tp->factor = usp->factor;
  244. for (i=0; i<NDIM; i++) {
  245. tp->dim[i] = usp->dim[i];
  246. }
  247. unit_pop();
  248. }
  249. void check_num()
  250. {
  251. struct unit * up = usp -1;
  252. /*EMPTY*/
  253. if (up->isnum && usp->isnum) {
  254. ;
  255. } else {
  256. up->isnum = 0;
  257. }
  258. }
  259. void unit_mul() {
  260. /* multiply next element by top of stack and leave on stack */
  261. struct unit *up;
  262. int i;
  263. IFUNITS
  264. assert(usp > unit_stack);
  265. check_num();
  266. up = usp -1;
  267. for (i=0; i<NDIM; i++) {
  268. up->dim[i] += usp->dim[i];
  269. }
  270. up->factor *= usp->factor;
  271. unit_pop();
  272. }
  273. void unit_div() {
  274. /* divide next element by top of stack and leave on stack */
  275. struct unit *up;
  276. int i;
  277. IFUNITS
  278. assert(usp > unit_stack);
  279. check_num();
  280. up = usp -1;
  281. for (i=0; i<NDIM; i++) {
  282. up->dim[i] -= usp->dim[i];
  283. }
  284. up->factor /= usp->factor;
  285. unit_pop();
  286. }
  287. void Unit_exponent(val)
  288. int val;
  289. {
  290. /* multiply top of stack by val and leave on stack */
  291. int i;
  292. double d;
  293. IFUNITS
  294. assert(usp >= unit_stack);
  295. for (i=0; i<NDIM; i++) {
  296. usp->dim[i] *= val;
  297. }
  298. d = usp->factor;
  299. for (i=1; i<val; i++) {
  300. usp->factor *= d;
  301. }
  302. }
  303. int
  304. unit_cmp_exact() { /* returns 1 if top two units on stack are same */
  305. struct unit *up;
  306. int i;
  307. {if (!UnitsOn) return 0;}
  308. up = usp - 1;
  309. if (unitonflag) {
  310. if (up->dim[0] == 9 || usp->dim[0] == 9) {
  311. return 1;
  312. }
  313. for (i=0; i<NDIM; i++) {
  314. if (up->dim[i] != usp->dim[i]) {
  315. chkfperror();
  316. return 0;
  317. }
  318. }
  319. if (OUTTOLERANCE(up->factor, usp->factor)) {
  320. chkfperror();
  321. return 0;
  322. }
  323. }
  324. return 1;
  325. }
  326. /* ARGSUSED */
  327. static void print_unit_expr(i) int i; {}
  328. void Unit_cmp() {
  329. /*compares top two units on stack. If not conformable then
  330. gives error. If not same factor then gives error.
  331. */
  332. struct unit *up;
  333. int i;
  334. IFUNITS
  335. assert(usp > unit_stack);
  336. up = usp - 1;
  337. if (usp->isnum) {
  338. unit_pop();
  339. return;
  340. }
  341. if (up->isnum) {
  342. for (i=0; i < NDIM; i++) {
  343. up->dim[i] = usp->dim[i];
  344. }
  345. up->factor = usp->factor;
  346. up->isnum = 0;
  347. }
  348. if (unitonflag && up->dim[0] != 9 && usp->dim[0] != 9) {
  349. for (i=0; i<NDIM; i++) {
  350. if (up->dim[i] != usp->dim[i]) {
  351. chkfperror();
  352. print_unit_expr(2);
  353. fprintf(stderr, "\nunits:");
  354. units(usp);
  355. print_unit_expr(1);
  356. fprintf(stderr, "\nunits:");
  357. units(up);
  358. diag("The units of the previous two expressions are not conformable","\n");
  359. }
  360. }
  361. if (OUTTOLERANCE(up->factor, usp->factor)) {
  362. chkfperror();
  363. fprintf(stderr, "The previous primary expression with units: %s\n\
  364. is missing a conversion factor and should read:\n (%g)*(",
  365. Unit_str(usp), usp->factor/up->factor);
  366. print_unit_expr(2);
  367. diag(")\n", (char *)0);
  368. }
  369. }
  370. unit_pop();
  371. return;
  372. }
  373. int unit_diff() {
  374. /*compares top two units on stack. If not conformable then
  375. return 1, if not same factor return 2 if same return 0
  376. */
  377. struct unit *up;
  378. int i;
  379. if (!UnitsOn) return 0;
  380. assert(usp > unit_stack);
  381. up = usp - 1;
  382. if (up->dim[0] == 9 || usp->dim[0] == 9) {
  383. unit_pop();
  384. return 0;
  385. }
  386. if (usp->isnum) {
  387. unit_pop();
  388. return 0;
  389. }
  390. if (up->isnum) {
  391. for (i=0; i < NDIM; i++) {
  392. up->dim[i] = usp->dim[i];
  393. }
  394. up->factor = usp->factor;
  395. up->isnum = 0;
  396. }
  397. for (i=0; i<NDIM; i++) {
  398. if (up->dim[i] != usp->dim[i]) {
  399. return 1;
  400. }
  401. }
  402. if (OUTTOLERANCE(up->factor, usp->factor)) {
  403. return 2;
  404. }
  405. unit_pop();
  406. return 0;
  407. }
  408. static void chkfperror()
  409. {
  410. if (fperrc) {
  411. diag("underflow or overflow in units calculation", (char *)0);
  412. }
  413. }
  414. void dimensionless() {
  415. /* ensures top element is dimensionless */
  416. int i;
  417. IFUNITS
  418. assert(usp >= unit_stack);
  419. if (usp->dim[0] == 9) {return;}
  420. for (i=0; i<NDIM; i++) {
  421. if (usp->dim[i] != 0) {
  422. units(usp);
  423. diag("The previous expression is not dimensionless", (char *)0);
  424. }
  425. }
  426. }
  427. void unit_less() {
  428. /* ensures top element is dimensionless with factor 1*/
  429. IFUNITS
  430. if (unitonflag) {
  431. dimensionless();
  432. if (usp->dim[0]!=9 && OUTTOLERANCE(usp->factor,1.0)) {
  433. fprintf(stderr, "The previous expression needs the conversion factor (%g)\n",
  434. 1./(usp->factor));
  435. diag("", (char *)0);
  436. }
  437. }
  438. unit_pop();
  439. }
  440. void unit_stk_clean() {
  441. IFUNITS
  442. usp = unit_stack - 1;
  443. }
  444. #if MODL||NMODL||HMODL||SIMSYS
  445. extern void unit_init();
  446. void modl_units() {
  447. static int first=1;
  448. unitonflag = 1;
  449. if (first) {
  450. unit_init();
  451. first = 0;
  452. }
  453. }
  454. #endif
  455. void unit_init() {
  456. char* s;
  457. char buf[256];
  458. inpfile = (FILE*)0;
  459. UnitsOn = 1;
  460. s = getenv("MODLUNIT");
  461. if (s) {
  462. if ((inpfile = fopen(s, "r")) == (FILE *)0) {
  463. diag("Bad MODLUNIT environment variable. Cant open:", s);
  464. }
  465. }
  466. if (!inpfile && (inpfile = fopen(dfile, "r")) == (FILE *)0) {
  467. if ((inpfile = fopen(dfilealt, "r")) == (FILE *)0) {
  468. s = neuronhome();
  469. if (s) {
  470. sprintf(buf, "%s/lib/nrnunits.lib", s);
  471. inpfile = fopen(buf, "r");
  472. }
  473. }
  474. }
  475. if (!inpfile) {
  476. fprintf(stderr, "Set a MODLUNIT environment variable path to the units table file\n");
  477. fprintf(stderr, "Cant open units table in either of:\n%s\n", buf);
  478. diag(dfile, dfilealt);
  479. }
  480. signal(8, fperr);
  481. init();
  482. unit_stk_clean();
  483. }
  484. #if 0
  485. void main(argc, argv)
  486. char *argv[];
  487. {
  488. register i;
  489. register char *file;
  490. struct unit u1, u2;
  491. double f;
  492. if(argc>1 && *argv[1]=='-') {
  493. argc--;
  494. argv++;
  495. dumpflg++;
  496. }
  497. file = dfile;
  498. if(argc > 1)
  499. file = argv[1];
  500. if ((inpfile = fopen(file, "r")) == NULL) {
  501. printf("no table\n");
  502. exit(1);
  503. }
  504. signal(8, fperr);
  505. init();
  506. loop:
  507. fperrc = 0;
  508. printf("you have: ");
  509. if(convr(&u1))
  510. goto loop;
  511. if(fperrc)
  512. goto fp;
  513. loop1:
  514. printf("you want: ");
  515. if(convr(&u2))
  516. goto loop1;
  517. for(i=0; i<NDIM; i++)
  518. if(u1.dim[i] != u2.dim[i])
  519. goto conform;
  520. f = u1.factor/u2.factor;
  521. if(fperrc)
  522. goto fp;
  523. printf("\t* %e\n", f);
  524. printf("\t/ %e\n", 1./f);
  525. goto loop;
  526. conform:
  527. if(fperrc)
  528. goto fp;
  529. printf("conformability\n");
  530. units(&u1);
  531. units(&u2);
  532. goto loop;
  533. fp:
  534. printf("underflow or overflow\n");
  535. goto loop;
  536. }
  537. #endif
  538. static void units(up)
  539. struct unit *up;
  540. {
  541. printf("\t%s\n", Unit_str(up));
  542. }
  543. static char *ucp;
  544. char *Unit_str(up)
  545. struct unit *up;
  546. {
  547. register struct unit *p;
  548. register int f, i;
  549. static char buf[256];
  550. p = up;
  551. sprintf(buf, "%g ", p->factor);
  552. {int seee=0; for (ucp=buf; *ucp; ucp++) {
  553. if (*ucp == 'e') seee=1;
  554. if (seee) *ucp = ucp[1];
  555. } if (seee) ucp--;}
  556. f = 0;
  557. for(i=0; i<NDIM; i++)
  558. f |= pu(p->dim[i], i, f);
  559. if(f&1) {
  560. *ucp++ = '/';
  561. f = 0;
  562. for(i=0; i<NDIM; i++)
  563. f |= pu(-p->dim[i], i, f);
  564. }
  565. *ucp = '\0';
  566. return buf;
  567. }
  568. static int pu(u, i, f)
  569. {
  570. if(u > 0) {
  571. if(f&2)
  572. *ucp++ = '-';
  573. if(unames[i]) {
  574. sprintf(ucp,"%s", unames[i]);
  575. ucp += strlen(ucp);
  576. } else{
  577. sprintf(ucp,"*%c*", i+'a');
  578. ucp += strlen(ucp);
  579. }
  580. if(u > 1)
  581. *ucp++ = (u+'0');
  582. return(2);
  583. }
  584. if(u < 0)
  585. return(1);
  586. return(0);
  587. }
  588. static int convr(up)
  589. struct unit *up;
  590. {
  591. register struct unit *p;
  592. register int c;
  593. register char *cp;
  594. char name[20];
  595. int den, err;
  596. p = up;
  597. for(c=0; c<NDIM; c++)
  598. p->dim[c] = 0;
  599. p->factor = getflt();
  600. if(p->factor == 0.) {
  601. p->factor = 1.0;
  602. }
  603. err = 0;
  604. den = 0;
  605. cp = name;
  606. loop:
  607. switch(c=get()) {
  608. case '1':
  609. case '2':
  610. case '3':
  611. case '4':
  612. case '5':
  613. case '6':
  614. case '7':
  615. case '8':
  616. case '9':
  617. case '-':
  618. case '/':
  619. case ' ':
  620. case '\t':
  621. case '\n':
  622. if(cp != name) {
  623. *cp++ = 0;
  624. cp = name;
  625. err |= lookup(cp, p, den, c);
  626. }
  627. if(c == '/')
  628. den++;
  629. if(c == '\n')
  630. return(err);
  631. goto loop;
  632. }
  633. *cp++ = c;
  634. goto loop;
  635. }
  636. static int lookup(name, up, den, c)
  637. char *name;
  638. struct unit *up;
  639. {
  640. register struct unit *p;
  641. register struct table *q;
  642. register int i;
  643. char *cp1, *cp2;
  644. double e;
  645. p = up;
  646. e = 1.0;
  647. loop:
  648. q = hash(name);
  649. if(q->name) {
  650. l1:
  651. if(den) {
  652. p->factor /= q->factor*e;
  653. for(i=0; i<NDIM; i++)
  654. p->dim[i] -= q->dim[i];
  655. } else {
  656. p->factor *= q->factor*e;
  657. for(i=0; i<NDIM; i++)
  658. p->dim[i] += q->dim[i];
  659. }
  660. if(c >= '2' && c <= '9') {
  661. c--;
  662. goto l1;
  663. }
  664. return(0);
  665. }
  666. for(i=0; (cp1 = prefix[i].pname) != 0; i++) {
  667. cp2 = name;
  668. while(*cp1 == *cp2++)
  669. if(*cp1++ == 0) {
  670. cp1--;
  671. break;
  672. }
  673. if(*cp1 == 0) {
  674. e *= prefix[i].factor;
  675. name = cp2-1;
  676. goto loop;
  677. }
  678. }
  679. /*EMPTY*/
  680. for(cp1 = name; *cp1; cp1++);
  681. if(cp1 > name+1 && *--cp1 == 's') {
  682. *cp1 = 0;
  683. goto loop;
  684. }
  685. fprintf(stderr, "Need declaration in UNITS block of the form:\n\
  686. (%s) (units)\n", name);
  687. diag("Cannot recognize the units: ", name);
  688. /* printf("cannot recognize %s\n", name);*/
  689. return(1);
  690. }
  691. static int equal(s1, s2)
  692. char *s1, *s2;
  693. {
  694. register char *c1, *c2;
  695. c1 = s1;
  696. c2 = s2;
  697. while(*c1++ == *c2)
  698. if(*c2++ == 0)
  699. return(1);
  700. return(0);
  701. }
  702. static void init()
  703. {
  704. register char *cp;
  705. register struct table *tp, *lp;
  706. int c, i, f, t;
  707. char *np;
  708. cp = names;
  709. for(i=0; i<NDIM; i++) {
  710. np = cp;
  711. *cp++ = '*';
  712. *cp++ = i+'a';
  713. *cp++ = '*';
  714. *cp++ = 0;
  715. lp = hash(np);
  716. lp->name = np;
  717. lp->factor = 1.0;
  718. lp->dim[i] = 1;
  719. }
  720. lp = hash("");
  721. lp->name = cp-1;
  722. lp->factor = 1.0;
  723. l0:
  724. c = get();
  725. if(c == 0) {
  726. #if 0
  727. printf("%d units; %d bytes\n\n", i, cp-names);
  728. #endif
  729. if(dumpflg)
  730. for(tp = table; tp < table+NTAB; tp++) {
  731. if(tp->name == 0)
  732. continue;
  733. printf("%s", tp->name);
  734. units((struct unit *)tp);
  735. }
  736. fclose(inpfile);
  737. inpfile = stdin;
  738. return;
  739. }
  740. if(c == '/') {
  741. while(c != '\n' && c != 0)
  742. c = get();
  743. goto l0;
  744. }
  745. if(c == '\n')
  746. goto l0;
  747. np = cp;
  748. while(c != ' ' && c != '\t') {
  749. *cp++ = c;
  750. c = get();
  751. if (c==0)
  752. goto l0;
  753. if(c == '\n') {
  754. *cp++ = 0;
  755. tp = hash(np);
  756. if(tp->name)
  757. goto redef;
  758. tp->name = np;
  759. tp->factor = lp->factor;
  760. for(c=0; c<NDIM; c++)
  761. tp->dim[c] = lp->dim[c];
  762. i++;
  763. goto l0;
  764. }
  765. }
  766. *cp++ = 0;
  767. lp = hash(np);
  768. if(lp->name)
  769. goto redef;
  770. convr((struct unit *)lp);
  771. lp->name = np;
  772. f = 0;
  773. i++;
  774. if(lp->factor != 1.0)
  775. goto l0;
  776. for(c=0; c<NDIM; c++) {
  777. t = lp->dim[c];
  778. if(t>1 || (f>0 && t!=0))
  779. goto l0;
  780. if(f==0 && t==1) {
  781. if(unames[c])
  782. goto l0;
  783. f = c+1;
  784. }
  785. }
  786. if(f>0)
  787. unames[f-1] = np;
  788. goto l0;
  789. redef:
  790. printf("redefinition %s\n", np);
  791. goto l0;
  792. }
  793. static double
  794. getflt()
  795. {
  796. register int c, i, dp;
  797. double d, e;
  798. int f;
  799. d = 0.;
  800. dp = 0;
  801. do
  802. c = get();
  803. while(c == ' ' || c == '\t');
  804. l1:
  805. if(c >= '0' && c <= '9') {
  806. d = d*10. + c-'0';
  807. if(dp)
  808. dp++;
  809. c = get();
  810. goto l1;
  811. }
  812. if(c == '.') {
  813. dp++;
  814. c = get();
  815. goto l1;
  816. }
  817. if(dp)
  818. dp--;
  819. if(c == '+' || c == '-') {
  820. f = 0;
  821. if(c == '-')
  822. f++;
  823. i = 0;
  824. c = get();
  825. while(c >= '0' && c <= '9') {
  826. i = i*10 + c-'0';
  827. c = get();
  828. }
  829. if(f)
  830. i = -i;
  831. dp -= i;
  832. }
  833. e = 1.;
  834. i = dp;
  835. if(i < 0)
  836. i = -i;
  837. while(i--)
  838. e *= 10.;
  839. if(dp < 0)
  840. d *= e; else
  841. d /= e;
  842. if(c == '|')
  843. return(d/getflt());
  844. peekc = c;
  845. return(d);
  846. }
  847. static int get()
  848. {
  849. register int c;
  850. /*SUPPRESS 560*/
  851. if((c=peekc) != 0) {
  852. peekc = 0;
  853. return(c);
  854. }
  855. c = Getc(inpfile);
  856. if (c == '\r') { c = Getc(inpfile); }
  857. if (c == EOF) {
  858. if (inpfile == stdin) {
  859. printf("\n");
  860. exit(0);
  861. }
  862. return(0);
  863. }
  864. return(c);
  865. }
  866. static struct table *
  867. hash(name)
  868. char *name;
  869. {
  870. register struct table *tp;
  871. register char *np;
  872. register unsigned h;
  873. h = 0;
  874. np = name;
  875. while(*np)
  876. h = h*57 + *np++ - '0';
  877. if( ((int)h)<0) h= -(int)h;
  878. h %= NTAB;
  879. tp = &table[h];
  880. l0:
  881. if(tp->name == 0)
  882. return(tp);
  883. if(equal(name, tp->name))
  884. return(tp);
  885. tp++;
  886. if(tp >= table+NTAB)
  887. tp = table;
  888. goto l0;
  889. }
  890. static void fperr(sig) int sig;
  891. {
  892. signal(8, fperr);
  893. fperrc++;
  894. }