xref: /illumos-gate/usr/src/cmd/units/units.c (revision 9ccfd38e)
143a29105Srobbin /*
243a29105Srobbin  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
343a29105Srobbin  * Use is subject to license terms.
443a29105Srobbin  */
543a29105Srobbin 
67c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
7*9ccfd38eSToomas Soome /*	  All Rights Reserved	*/
87c478bd9Sstevel@tonic-gate 
97c478bd9Sstevel@tonic-gate /*
107c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
117c478bd9Sstevel@tonic-gate  * All rights reserved.  The Berkeley Software License Agreement
127c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
137c478bd9Sstevel@tonic-gate  */
147c478bd9Sstevel@tonic-gate 
157c478bd9Sstevel@tonic-gate #include <stdio.h>
167c478bd9Sstevel@tonic-gate #include <locale.h>
1743a29105Srobbin #include <signal.h>
187c478bd9Sstevel@tonic-gate 
197c478bd9Sstevel@tonic-gate #define	NDIM	10
207c478bd9Sstevel@tonic-gate #define	NTAB	1009
217c478bd9Sstevel@tonic-gate char	*dfile	= "/usr/share/lib/unittab";
227c478bd9Sstevel@tonic-gate char	*unames[NDIM];
237c478bd9Sstevel@tonic-gate struct unit
247c478bd9Sstevel@tonic-gate {
257c478bd9Sstevel@tonic-gate 	double	factor;
267c478bd9Sstevel@tonic-gate 	char	dim[NDIM];
277c478bd9Sstevel@tonic-gate };
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate struct table
307c478bd9Sstevel@tonic-gate {
317c478bd9Sstevel@tonic-gate 	double	factor;
327c478bd9Sstevel@tonic-gate 	char	dim[NDIM];
337c478bd9Sstevel@tonic-gate 	char	*name;
347c478bd9Sstevel@tonic-gate } table[NTAB];
357c478bd9Sstevel@tonic-gate char	names[NTAB*10];
367c478bd9Sstevel@tonic-gate struct prefix
377c478bd9Sstevel@tonic-gate {
387c478bd9Sstevel@tonic-gate 	double	factor;
397c478bd9Sstevel@tonic-gate 	char	*pname;
40*9ccfd38eSToomas Soome } prefix[] =
417c478bd9Sstevel@tonic-gate {
427c478bd9Sstevel@tonic-gate 	1e-21,	"zepto",
437c478bd9Sstevel@tonic-gate 	1e-24,	"yocto",
447c478bd9Sstevel@tonic-gate 	1e-18,	"atto",
457c478bd9Sstevel@tonic-gate 	1e-15,	"femto",
467c478bd9Sstevel@tonic-gate 	1e-12,	"pico",
477c478bd9Sstevel@tonic-gate 	1e-9,	"nano",
487c478bd9Sstevel@tonic-gate 	1e-6,	"micro",
497c478bd9Sstevel@tonic-gate 	1e-3,	"milli",
507c478bd9Sstevel@tonic-gate 	1e-2,	"centi",
517c478bd9Sstevel@tonic-gate 	1e-1,	"deci",
527c478bd9Sstevel@tonic-gate 	1e1,	"deka",
537c478bd9Sstevel@tonic-gate 	1e1,	"deca",
547c478bd9Sstevel@tonic-gate 	1e2,	"hecta",
557c478bd9Sstevel@tonic-gate 	1e2,	"hecto",
567c478bd9Sstevel@tonic-gate 	1e3,	"kilo",
577c478bd9Sstevel@tonic-gate 	1e6,	"mega",
587c478bd9Sstevel@tonic-gate 	1e6,	"meg",
597c478bd9Sstevel@tonic-gate 	1e9,	"giga",
607c478bd9Sstevel@tonic-gate 	1e12,	"tera",
617c478bd9Sstevel@tonic-gate 	1e15,	"peta",
627c478bd9Sstevel@tonic-gate 	1e18,	"exa",
637c478bd9Sstevel@tonic-gate 	1e21,	"zetta",
647c478bd9Sstevel@tonic-gate 	1e24,	"yotta",
657c478bd9Sstevel@tonic-gate 	1<<10,	"kibi",
667c478bd9Sstevel@tonic-gate 	1L<<20,	"mebi",
677c478bd9Sstevel@tonic-gate 	1L<<30,	"gibi",
687c478bd9Sstevel@tonic-gate 	1LL<<40,"tebi",
697c478bd9Sstevel@tonic-gate 	0.0,	0
707c478bd9Sstevel@tonic-gate };
717c478bd9Sstevel@tonic-gate FILE	*inp;
727c478bd9Sstevel@tonic-gate int	fperrc;
737c478bd9Sstevel@tonic-gate int	peekc;
747c478bd9Sstevel@tonic-gate int	dumpflg;
757c478bd9Sstevel@tonic-gate 
7643a29105Srobbin void fperr(int sig);
7743a29105Srobbin double getflt(void);
7843a29105Srobbin struct table *hash(char *name);
7943a29105Srobbin int get(void);
8043a29105Srobbin void init(void);
8143a29105Srobbin int equal(char *s1, char *s2);
8243a29105Srobbin int lookup(char *name, struct unit *up, int den, int c);
8343a29105Srobbin int convr(struct unit *up);
8443a29105Srobbin int pu(int u, int i, int f);
8543a29105Srobbin void units(struct unit *up);
8643a29105Srobbin 
8743a29105Srobbin int
main(int argc,char * argv[])8843a29105Srobbin main(int argc, char *argv[])
897c478bd9Sstevel@tonic-gate {
9043a29105Srobbin 	int i;
9143a29105Srobbin 	char *file;
927c478bd9Sstevel@tonic-gate 	struct unit u1, u2;
937c478bd9Sstevel@tonic-gate 	double f;
94*9ccfd38eSToomas Soome 
957c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
967c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
977c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST"
987c478bd9Sstevel@tonic-gate #endif
997c478bd9Sstevel@tonic-gate         (void) textdomain(TEXT_DOMAIN);
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	if(argc>1 && *argv[1]=='-') {
1027c478bd9Sstevel@tonic-gate 		argc--;
1037c478bd9Sstevel@tonic-gate 		argv++;
1047c478bd9Sstevel@tonic-gate 		dumpflg++;
1057c478bd9Sstevel@tonic-gate 	}
1067c478bd9Sstevel@tonic-gate 	file = dfile;
1077c478bd9Sstevel@tonic-gate 	if(argc > 1)
1087c478bd9Sstevel@tonic-gate 		file = argv[1];
1097c478bd9Sstevel@tonic-gate 	if ((inp = fopen(file, "r")) == NULL) {
1107c478bd9Sstevel@tonic-gate 		printf(gettext("no table\n"));
1117c478bd9Sstevel@tonic-gate 		exit(1);
1127c478bd9Sstevel@tonic-gate 	}
1137c478bd9Sstevel@tonic-gate 	signal(8, fperr);
1147c478bd9Sstevel@tonic-gate 	init();
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate loop:
1177c478bd9Sstevel@tonic-gate 	fperrc = 0;
1187c478bd9Sstevel@tonic-gate 	printf(gettext("you have: "));
1197c478bd9Sstevel@tonic-gate 	if(convr(&u1))
1207c478bd9Sstevel@tonic-gate 		goto loop;
1217c478bd9Sstevel@tonic-gate 	if(fperrc)
1227c478bd9Sstevel@tonic-gate 		goto fp;
1237c478bd9Sstevel@tonic-gate loop1:
1247c478bd9Sstevel@tonic-gate 	printf(gettext("you want: "));
1257c478bd9Sstevel@tonic-gate 	if(convr(&u2))
1267c478bd9Sstevel@tonic-gate 		goto loop1;
1277c478bd9Sstevel@tonic-gate 	for(i=0; i<NDIM; i++)
1287c478bd9Sstevel@tonic-gate 		if(u1.dim[i] != u2.dim[i])
1297c478bd9Sstevel@tonic-gate 			goto conform;
1307c478bd9Sstevel@tonic-gate 	f = u1.factor/u2.factor;
1317c478bd9Sstevel@tonic-gate 	if(fperrc || f == 0.0)
1327c478bd9Sstevel@tonic-gate 		goto fp;
1337c478bd9Sstevel@tonic-gate 	printf("\t* %e\n", f);
1347c478bd9Sstevel@tonic-gate 	printf("\t/ %e\n", 1./f);
1357c478bd9Sstevel@tonic-gate 	goto loop;
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate conform:
1387c478bd9Sstevel@tonic-gate 	if(fperrc)
1397c478bd9Sstevel@tonic-gate 		goto fp;
1407c478bd9Sstevel@tonic-gate 	printf(gettext("conformability\n"));
1417c478bd9Sstevel@tonic-gate 	units(&u1);
1427c478bd9Sstevel@tonic-gate 	units(&u2);
1437c478bd9Sstevel@tonic-gate 	goto loop;
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate fp:
1467c478bd9Sstevel@tonic-gate 	printf(gettext("underflow or overflow\n"));
1477c478bd9Sstevel@tonic-gate 	goto loop;
1487c478bd9Sstevel@tonic-gate }
1497c478bd9Sstevel@tonic-gate 
15043a29105Srobbin void
units(struct unit * up)15143a29105Srobbin units(struct unit *up)
1527c478bd9Sstevel@tonic-gate {
15343a29105Srobbin 	struct unit *p;
15443a29105Srobbin 	int f, i;
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 	p = up;
1577c478bd9Sstevel@tonic-gate 	printf("\t%e ", p->factor);
1587c478bd9Sstevel@tonic-gate 	f = 0;
1597c478bd9Sstevel@tonic-gate 	for(i=0; i<NDIM; i++)
1607c478bd9Sstevel@tonic-gate 		f |= pu(p->dim[i], i, f);
1617c478bd9Sstevel@tonic-gate 	if(f&1) {
1627c478bd9Sstevel@tonic-gate 		putchar('/');
1637c478bd9Sstevel@tonic-gate 		f = 0;
1647c478bd9Sstevel@tonic-gate 		for(i=0; i<NDIM; i++)
1657c478bd9Sstevel@tonic-gate 			f |= pu(-p->dim[i], i, f);
1667c478bd9Sstevel@tonic-gate 	}
1677c478bd9Sstevel@tonic-gate 	putchar('\n');
1687c478bd9Sstevel@tonic-gate }
1697c478bd9Sstevel@tonic-gate 
17043a29105Srobbin int
pu(int u,int i,int f)17143a29105Srobbin pu(int u, int i, int f)
1727c478bd9Sstevel@tonic-gate {
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate 	if(u > 0) {
1757c478bd9Sstevel@tonic-gate 		if(f&2)
1767c478bd9Sstevel@tonic-gate 			putchar('-');
1777c478bd9Sstevel@tonic-gate 		if(unames[i])
178*9ccfd38eSToomas Soome 			printf("%s", unames[i]);
179*9ccfd38eSToomas Soome 		else
1807c478bd9Sstevel@tonic-gate 			printf(gettext("*%c*"), i+'a');
1817c478bd9Sstevel@tonic-gate 		if(u > 1)
1827c478bd9Sstevel@tonic-gate 			putchar(u+'0');
183*9ccfd38eSToomas Soome 		return(2);
1847c478bd9Sstevel@tonic-gate 	}
1857c478bd9Sstevel@tonic-gate 	if(u < 0)
1867c478bd9Sstevel@tonic-gate 		return(1);
1877c478bd9Sstevel@tonic-gate 	return(0);
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate 
19043a29105Srobbin int
convr(struct unit * up)19143a29105Srobbin convr(struct unit *up)
1927c478bd9Sstevel@tonic-gate {
19343a29105Srobbin 	struct unit *p;
19443a29105Srobbin 	int c;
19543a29105Srobbin 	char *cp;
1967c478bd9Sstevel@tonic-gate 	char name[20];
1977c478bd9Sstevel@tonic-gate 	int den, err;
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 	p = up;
2007c478bd9Sstevel@tonic-gate 	for(c=0; c<NDIM; c++)
2017c478bd9Sstevel@tonic-gate 		p->dim[c] = 0;
2027c478bd9Sstevel@tonic-gate 	p->factor = getflt();
2037c478bd9Sstevel@tonic-gate 	if(p->factor == 0.)
2047c478bd9Sstevel@tonic-gate 		p->factor = 1.0;
2057c478bd9Sstevel@tonic-gate 	err = 0;
2067c478bd9Sstevel@tonic-gate 	den = 0;
2077c478bd9Sstevel@tonic-gate 	cp = name;
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate loop:
2107c478bd9Sstevel@tonic-gate 	switch(c=get()) {
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 	case '1':
2137c478bd9Sstevel@tonic-gate 	case '2':
2147c478bd9Sstevel@tonic-gate 	case '3':
2157c478bd9Sstevel@tonic-gate 	case '4':
2167c478bd9Sstevel@tonic-gate 	case '5':
2177c478bd9Sstevel@tonic-gate 	case '6':
2187c478bd9Sstevel@tonic-gate 	case '7':
2197c478bd9Sstevel@tonic-gate 	case '8':
2207c478bd9Sstevel@tonic-gate 	case '9':
2217c478bd9Sstevel@tonic-gate 	case '-':
2227c478bd9Sstevel@tonic-gate 	case '/':
2237c478bd9Sstevel@tonic-gate 	case ' ':
2247c478bd9Sstevel@tonic-gate 	case '\t':
2257c478bd9Sstevel@tonic-gate 	case '\n':
2267c478bd9Sstevel@tonic-gate 		if(cp != name) {
2277c478bd9Sstevel@tonic-gate 			*cp++ = 0;
2287c478bd9Sstevel@tonic-gate 			cp = name;
2297c478bd9Sstevel@tonic-gate 			err |= lookup(cp, p, den, c);
2307c478bd9Sstevel@tonic-gate 		}
2317c478bd9Sstevel@tonic-gate 		if(c == '/')
2327c478bd9Sstevel@tonic-gate 			den++;
2337c478bd9Sstevel@tonic-gate 		if(c == '\n')
2347c478bd9Sstevel@tonic-gate 			return(err);
2357c478bd9Sstevel@tonic-gate 		goto loop;
2367c478bd9Sstevel@tonic-gate 	}
2377c478bd9Sstevel@tonic-gate 	*cp++ = c;
2387c478bd9Sstevel@tonic-gate 	goto loop;
2397c478bd9Sstevel@tonic-gate }
2407c478bd9Sstevel@tonic-gate 
24143a29105Srobbin int
lookup(char * name,struct unit * up,int den,int c)24243a29105Srobbin lookup(char *name, struct unit *up, int den, int c)
2437c478bd9Sstevel@tonic-gate {
24443a29105Srobbin 	struct unit *p;
24543a29105Srobbin 	struct table *q;
24643a29105Srobbin 	int i;
2477c478bd9Sstevel@tonic-gate 	char *cp1, *cp2;
2487c478bd9Sstevel@tonic-gate 	double e;
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate 	p = up;
2517c478bd9Sstevel@tonic-gate 	e = 1.0;
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate loop:
2547c478bd9Sstevel@tonic-gate 	q = hash(name);
2557c478bd9Sstevel@tonic-gate 	if(q->name) {
2567c478bd9Sstevel@tonic-gate 		l1:
2577c478bd9Sstevel@tonic-gate 		if(den) {
2587c478bd9Sstevel@tonic-gate 			p->factor /= q->factor*e;
2597c478bd9Sstevel@tonic-gate 			for(i=0; i<NDIM; i++)
2607c478bd9Sstevel@tonic-gate 				p->dim[i] -= q->dim[i];
2617c478bd9Sstevel@tonic-gate 		} else {
2627c478bd9Sstevel@tonic-gate 			p->factor *= q->factor*e;
2637c478bd9Sstevel@tonic-gate 			for(i=0; i<NDIM; i++)
2647c478bd9Sstevel@tonic-gate 				p->dim[i] += q->dim[i];
2657c478bd9Sstevel@tonic-gate 		}
2667c478bd9Sstevel@tonic-gate 		if(c >= '2' && c <= '9') {
2677c478bd9Sstevel@tonic-gate 			c--;
2687c478bd9Sstevel@tonic-gate 			goto l1;
2697c478bd9Sstevel@tonic-gate 		}
2707c478bd9Sstevel@tonic-gate 		return(0);
2717c478bd9Sstevel@tonic-gate 	}
2727c478bd9Sstevel@tonic-gate 	for(i=0; cp1 = prefix[i].pname; i++) {
2737c478bd9Sstevel@tonic-gate 		cp2 = name;
2747c478bd9Sstevel@tonic-gate 		while(*cp1 == *cp2++)
2757c478bd9Sstevel@tonic-gate 			if(*cp1++ == 0) {
2767c478bd9Sstevel@tonic-gate 				cp1--;
2777c478bd9Sstevel@tonic-gate 				break;
2787c478bd9Sstevel@tonic-gate 			}
2797c478bd9Sstevel@tonic-gate 		if(*cp1 == 0) {
2807c478bd9Sstevel@tonic-gate 			e *= prefix[i].factor;
2817c478bd9Sstevel@tonic-gate 			name = cp2-1;
2827c478bd9Sstevel@tonic-gate 			goto loop;
2837c478bd9Sstevel@tonic-gate 		}
2847c478bd9Sstevel@tonic-gate 	}
2857c478bd9Sstevel@tonic-gate 	for(cp1 = name; *cp1; cp1++);
2867c478bd9Sstevel@tonic-gate 	if(cp1 > name+1 && *--cp1 == 's') {
2877c478bd9Sstevel@tonic-gate 		*cp1 = 0;
2887c478bd9Sstevel@tonic-gate 		goto loop;
2897c478bd9Sstevel@tonic-gate 	}
2907c478bd9Sstevel@tonic-gate 	printf(gettext("cannot recognize %s\n"), name);
2917c478bd9Sstevel@tonic-gate 	return(1);
2927c478bd9Sstevel@tonic-gate }
2937c478bd9Sstevel@tonic-gate 
29443a29105Srobbin int
equal(char * s1,char * s2)29543a29105Srobbin equal(char *s1, char *s2)
2967c478bd9Sstevel@tonic-gate {
29743a29105Srobbin 	char *c1, *c2;
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 	c1 = s1;
3007c478bd9Sstevel@tonic-gate 	c2 = s2;
3017c478bd9Sstevel@tonic-gate 	while(*c1++ == *c2)
3027c478bd9Sstevel@tonic-gate 		if(*c2++ == 0)
3037c478bd9Sstevel@tonic-gate 			return(1);
3047c478bd9Sstevel@tonic-gate 	return(0);
3057c478bd9Sstevel@tonic-gate }
3067c478bd9Sstevel@tonic-gate 
30743a29105Srobbin void
init(void)30843a29105Srobbin init(void)
3097c478bd9Sstevel@tonic-gate {
31043a29105Srobbin 	char *cp;
31143a29105Srobbin 	struct table *tp, *lp;
3127c478bd9Sstevel@tonic-gate 	int c, i, f, t;
3137c478bd9Sstevel@tonic-gate 	char *np;
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	cp = names;
3167c478bd9Sstevel@tonic-gate 	for(i=0; i<NDIM; i++) {
3177c478bd9Sstevel@tonic-gate 		np = cp;
3187c478bd9Sstevel@tonic-gate 		*cp++ = '*';
3197c478bd9Sstevel@tonic-gate 		*cp++ = i+'a';
3207c478bd9Sstevel@tonic-gate 		*cp++ = '*';
3217c478bd9Sstevel@tonic-gate 		*cp++ = 0;
3227c478bd9Sstevel@tonic-gate 		lp = hash(np);
3237c478bd9Sstevel@tonic-gate 		lp->name = np;
3247c478bd9Sstevel@tonic-gate 		lp->factor = 1.0;
3257c478bd9Sstevel@tonic-gate 		lp->dim[i] = 1;
3267c478bd9Sstevel@tonic-gate 	}
3277c478bd9Sstevel@tonic-gate 	lp = hash("");
3287c478bd9Sstevel@tonic-gate 	lp->name = cp-1;
3297c478bd9Sstevel@tonic-gate 	lp->factor = 1.0;
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate l0:
3327c478bd9Sstevel@tonic-gate 	c = get();
3337c478bd9Sstevel@tonic-gate 	if(c == 0) {
3347c478bd9Sstevel@tonic-gate 		if(dumpflg) {
3357c478bd9Sstevel@tonic-gate 		printf(gettext("%d units; %d bytes\n\n"), i, cp-names);
3367c478bd9Sstevel@tonic-gate 		for(tp = &table[0]; tp < &table[NTAB]; tp++) {
3377c478bd9Sstevel@tonic-gate 			if(tp->name == 0)
3387c478bd9Sstevel@tonic-gate 				continue;
3397c478bd9Sstevel@tonic-gate 			printf("%s", tp->name);
3407c478bd9Sstevel@tonic-gate 			units((struct unit *)tp);
3417c478bd9Sstevel@tonic-gate 		} }
3427c478bd9Sstevel@tonic-gate 		fclose(inp);
3437c478bd9Sstevel@tonic-gate 		inp = stdin;
3447c478bd9Sstevel@tonic-gate 		return;
3457c478bd9Sstevel@tonic-gate 	}
3467c478bd9Sstevel@tonic-gate 	if(c == '/') {
3477c478bd9Sstevel@tonic-gate 		while(c != '\n' && c != 0)
3487c478bd9Sstevel@tonic-gate 			c = get();
3497c478bd9Sstevel@tonic-gate 		goto l0;
3507c478bd9Sstevel@tonic-gate 	}
3517c478bd9Sstevel@tonic-gate 	if(c == '\n')
3527c478bd9Sstevel@tonic-gate 		goto l0;
3537c478bd9Sstevel@tonic-gate 	np = cp;
3547c478bd9Sstevel@tonic-gate 	while(c != ' ' && c != '\t') {
3557c478bd9Sstevel@tonic-gate 		*cp++ = c;
3567c478bd9Sstevel@tonic-gate 		c = get();
3577c478bd9Sstevel@tonic-gate 		if (c==0)
3587c478bd9Sstevel@tonic-gate 			goto l0;
3597c478bd9Sstevel@tonic-gate 		if(c == '\n') {
3607c478bd9Sstevel@tonic-gate 			*cp++ = 0;
3617c478bd9Sstevel@tonic-gate 			tp = hash(np);
3627c478bd9Sstevel@tonic-gate 			if(tp->name)
3637c478bd9Sstevel@tonic-gate 				goto redef;
3647c478bd9Sstevel@tonic-gate 			tp->name = np;
3657c478bd9Sstevel@tonic-gate 			tp->factor = lp->factor;
3667c478bd9Sstevel@tonic-gate 			for(c=0; c<NDIM; c++)
3677c478bd9Sstevel@tonic-gate 				tp->dim[c] = lp->dim[c];
3687c478bd9Sstevel@tonic-gate 			i++;
3697c478bd9Sstevel@tonic-gate 			goto l0;
3707c478bd9Sstevel@tonic-gate 		}
3717c478bd9Sstevel@tonic-gate 	}
3727c478bd9Sstevel@tonic-gate 	*cp++ = 0;
3737c478bd9Sstevel@tonic-gate 	lp = hash(np);
3747c478bd9Sstevel@tonic-gate 	if(lp->name)
3757c478bd9Sstevel@tonic-gate 		goto redef;
3767c478bd9Sstevel@tonic-gate 	convr((struct unit *)lp);
3777c478bd9Sstevel@tonic-gate 	lp->name = np;
3787c478bd9Sstevel@tonic-gate 	f = 0;
3797c478bd9Sstevel@tonic-gate 	i++;
3807c478bd9Sstevel@tonic-gate 	if(lp->factor != 1.0)
3817c478bd9Sstevel@tonic-gate 		goto l0;
3827c478bd9Sstevel@tonic-gate 	for(c=0; c<NDIM; c++) {
3837c478bd9Sstevel@tonic-gate 		t = lp->dim[c];
3847c478bd9Sstevel@tonic-gate 		if(t>1 || (f>0 && t!=0))
3857c478bd9Sstevel@tonic-gate 			goto l0;
3867c478bd9Sstevel@tonic-gate 		if(f==0 && t==1) {
3877c478bd9Sstevel@tonic-gate 			if(unames[c])
3887c478bd9Sstevel@tonic-gate 				goto l0;
3897c478bd9Sstevel@tonic-gate 			f = c+1;
3907c478bd9Sstevel@tonic-gate 		}
3917c478bd9Sstevel@tonic-gate 	}
3927c478bd9Sstevel@tonic-gate 	if(f>0)
3937c478bd9Sstevel@tonic-gate 		unames[f-1] = np;
3947c478bd9Sstevel@tonic-gate 	goto l0;
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate redef:
3977c478bd9Sstevel@tonic-gate 	printf(gettext("redefinition %s\n"), np);
3987c478bd9Sstevel@tonic-gate 	goto l0;
3997c478bd9Sstevel@tonic-gate }
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate double
getflt(void)40243a29105Srobbin getflt(void)
4037c478bd9Sstevel@tonic-gate {
40443a29105Srobbin 	int c, i, dp;
4057c478bd9Sstevel@tonic-gate 	double d, e;
4067c478bd9Sstevel@tonic-gate 	int f;
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate 	d = 0.;
4097c478bd9Sstevel@tonic-gate 	dp = 0;
4107c478bd9Sstevel@tonic-gate 	do
4117c478bd9Sstevel@tonic-gate 		c = get();
4127c478bd9Sstevel@tonic-gate 	while(c == ' ' || c == '\t');
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate l1:
4157c478bd9Sstevel@tonic-gate 	if(c >= '0' && c <= '9') {
4167c478bd9Sstevel@tonic-gate 		d = d*10. + c-'0';
4177c478bd9Sstevel@tonic-gate 		if(dp)
4187c478bd9Sstevel@tonic-gate 			dp++;
4197c478bd9Sstevel@tonic-gate 		c = get();
4207c478bd9Sstevel@tonic-gate 		goto l1;
4217c478bd9Sstevel@tonic-gate 	}
4227c478bd9Sstevel@tonic-gate 	if(c == '.') {
4237c478bd9Sstevel@tonic-gate 		dp++;
4247c478bd9Sstevel@tonic-gate 		c = get();
4257c478bd9Sstevel@tonic-gate 		goto l1;
4267c478bd9Sstevel@tonic-gate 	}
4277c478bd9Sstevel@tonic-gate 	if(dp)
4287c478bd9Sstevel@tonic-gate 		dp--;
4297c478bd9Sstevel@tonic-gate 	if(c == '+' || c == '-') {
4307c478bd9Sstevel@tonic-gate 		f = 0;
4317c478bd9Sstevel@tonic-gate 		if(c == '-')
4327c478bd9Sstevel@tonic-gate 			f++;
4337c478bd9Sstevel@tonic-gate 		i = 0;
4347c478bd9Sstevel@tonic-gate 		c = get();
4357c478bd9Sstevel@tonic-gate 		while(c >= '0' && c <= '9') {
4367c478bd9Sstevel@tonic-gate 			i = i*10 + c-'0';
4377c478bd9Sstevel@tonic-gate 			c = get();
4387c478bd9Sstevel@tonic-gate 		}
4397c478bd9Sstevel@tonic-gate 		if(f)
4407c478bd9Sstevel@tonic-gate 			i = -i;
4417c478bd9Sstevel@tonic-gate 		dp -= i;
4427c478bd9Sstevel@tonic-gate 	}
4437c478bd9Sstevel@tonic-gate 	e = 1.;
4447c478bd9Sstevel@tonic-gate 	i = dp;
4457c478bd9Sstevel@tonic-gate 	if(i < 0)
4467c478bd9Sstevel@tonic-gate 		i = -i;
4477c478bd9Sstevel@tonic-gate 	while(i--)
4487c478bd9Sstevel@tonic-gate 		e *= 10.;
4497c478bd9Sstevel@tonic-gate 	if(dp < 0)
4507c478bd9Sstevel@tonic-gate 		d *= e; else
4517c478bd9Sstevel@tonic-gate 		d /= e;
4527c478bd9Sstevel@tonic-gate 	if(c == '|')
4537c478bd9Sstevel@tonic-gate 		return(d/getflt());
4547c478bd9Sstevel@tonic-gate 	peekc = c;
4557c478bd9Sstevel@tonic-gate 	return(d);
4567c478bd9Sstevel@tonic-gate }
4577c478bd9Sstevel@tonic-gate 
45843a29105Srobbin int
get(void)45943a29105Srobbin get(void)
4607c478bd9Sstevel@tonic-gate {
46143a29105Srobbin 	int c;
4627c478bd9Sstevel@tonic-gate 
4637c478bd9Sstevel@tonic-gate 	if(c=peekc) {
4647c478bd9Sstevel@tonic-gate 		peekc = 0;
4657c478bd9Sstevel@tonic-gate 		return(c);
4667c478bd9Sstevel@tonic-gate 	}
4677c478bd9Sstevel@tonic-gate 	c = getc(inp);
4687c478bd9Sstevel@tonic-gate 	if (c == EOF) {
4697c478bd9Sstevel@tonic-gate 		if (inp == stdin) {
4707c478bd9Sstevel@tonic-gate 			printf("\n");
4717c478bd9Sstevel@tonic-gate 			exit(0);
4727c478bd9Sstevel@tonic-gate 		}
4737c478bd9Sstevel@tonic-gate 		return(0);
4747c478bd9Sstevel@tonic-gate 	}
4757c478bd9Sstevel@tonic-gate 	return(c);
4767c478bd9Sstevel@tonic-gate }
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate struct table *
hash(char * name)47943a29105Srobbin hash(char *name)
4807c478bd9Sstevel@tonic-gate {
48143a29105Srobbin 	struct table *tp;
48243a29105Srobbin 	char *np;
48343a29105Srobbin 	unsigned int h;
4847c478bd9Sstevel@tonic-gate 
4857c478bd9Sstevel@tonic-gate 	h = 0;
4867c478bd9Sstevel@tonic-gate 	np = name;
4877c478bd9Sstevel@tonic-gate 	while(*np)
4887c478bd9Sstevel@tonic-gate 		h = h*57 + *np++ - '0';
4897c478bd9Sstevel@tonic-gate 	if( ((int)h)<0) h= -(int)h;
4907c478bd9Sstevel@tonic-gate 	h %= NTAB;
4917c478bd9Sstevel@tonic-gate 	tp = &table[h];
4927c478bd9Sstevel@tonic-gate l0:
4937c478bd9Sstevel@tonic-gate 	if(tp->name == 0)
4947c478bd9Sstevel@tonic-gate 		return(tp);
4957c478bd9Sstevel@tonic-gate 	if(equal(name, tp->name))
4967c478bd9Sstevel@tonic-gate 		return(tp);
4977c478bd9Sstevel@tonic-gate 	tp++;
4987c478bd9Sstevel@tonic-gate 	if(tp >= &table[NTAB])
4997c478bd9Sstevel@tonic-gate 		tp = table;
5007c478bd9Sstevel@tonic-gate 	goto l0;
5017c478bd9Sstevel@tonic-gate }
5027c478bd9Sstevel@tonic-gate 
50343a29105Srobbin void
fperr(int sig)50443a29105Srobbin fperr(int sig)
5057c478bd9Sstevel@tonic-gate {
5067c478bd9Sstevel@tonic-gate 
5077c478bd9Sstevel@tonic-gate 	signal(8, fperr);
5087c478bd9Sstevel@tonic-gate 	fperrc++;
5097c478bd9Sstevel@tonic-gate }
510