xref: /titanic_44/usr/src/cmd/units/units.c (revision 43a291055ab3951f6372241323fd4e2486098fff)
1*43a29105Srobbin /*
2*43a29105Srobbin  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3*43a29105Srobbin  * Use is subject to license terms.
4*43a29105Srobbin  */
5*43a29105Srobbin 
67c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
77c478bd9Sstevel@tonic-gate /*	  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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate #include <stdio.h>
187c478bd9Sstevel@tonic-gate #include <locale.h>
19*43a29105Srobbin #include <signal.h>
207c478bd9Sstevel@tonic-gate 
217c478bd9Sstevel@tonic-gate #define	NDIM	10
227c478bd9Sstevel@tonic-gate #define	NTAB	1009
237c478bd9Sstevel@tonic-gate char	*dfile	= "/usr/share/lib/unittab";
247c478bd9Sstevel@tonic-gate char	*unames[NDIM];
257c478bd9Sstevel@tonic-gate struct unit
267c478bd9Sstevel@tonic-gate {
277c478bd9Sstevel@tonic-gate 	double	factor;
287c478bd9Sstevel@tonic-gate 	char	dim[NDIM];
297c478bd9Sstevel@tonic-gate };
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate struct table
327c478bd9Sstevel@tonic-gate {
337c478bd9Sstevel@tonic-gate 	double	factor;
347c478bd9Sstevel@tonic-gate 	char	dim[NDIM];
357c478bd9Sstevel@tonic-gate 	char	*name;
367c478bd9Sstevel@tonic-gate } table[NTAB];
377c478bd9Sstevel@tonic-gate char	names[NTAB*10];
387c478bd9Sstevel@tonic-gate struct prefix
397c478bd9Sstevel@tonic-gate {
407c478bd9Sstevel@tonic-gate 	double	factor;
417c478bd9Sstevel@tonic-gate 	char	*pname;
427c478bd9Sstevel@tonic-gate } prefix[] =
437c478bd9Sstevel@tonic-gate {
447c478bd9Sstevel@tonic-gate 	1e-21,	"zepto",
457c478bd9Sstevel@tonic-gate 	1e-24,	"yocto",
467c478bd9Sstevel@tonic-gate 	1e-18,	"atto",
477c478bd9Sstevel@tonic-gate 	1e-15,	"femto",
487c478bd9Sstevel@tonic-gate 	1e-12,	"pico",
497c478bd9Sstevel@tonic-gate 	1e-9,	"nano",
507c478bd9Sstevel@tonic-gate 	1e-6,	"micro",
517c478bd9Sstevel@tonic-gate 	1e-3,	"milli",
527c478bd9Sstevel@tonic-gate 	1e-2,	"centi",
537c478bd9Sstevel@tonic-gate 	1e-1,	"deci",
547c478bd9Sstevel@tonic-gate 	1e1,	"deka",
557c478bd9Sstevel@tonic-gate 	1e1,	"deca",
567c478bd9Sstevel@tonic-gate 	1e2,	"hecta",
577c478bd9Sstevel@tonic-gate 	1e2,	"hecto",
587c478bd9Sstevel@tonic-gate 	1e3,	"kilo",
597c478bd9Sstevel@tonic-gate 	1e6,	"mega",
607c478bd9Sstevel@tonic-gate 	1e6,	"meg",
617c478bd9Sstevel@tonic-gate 	1e9,	"giga",
627c478bd9Sstevel@tonic-gate 	1e12,	"tera",
637c478bd9Sstevel@tonic-gate 	1e15,	"peta",
647c478bd9Sstevel@tonic-gate 	1e18,	"exa",
657c478bd9Sstevel@tonic-gate 	1e21,	"zetta",
667c478bd9Sstevel@tonic-gate 	1e24,	"yotta",
677c478bd9Sstevel@tonic-gate 	1<<10,	"kibi",
687c478bd9Sstevel@tonic-gate 	1L<<20,	"mebi",
697c478bd9Sstevel@tonic-gate 	1L<<30,	"gibi",
707c478bd9Sstevel@tonic-gate 	1LL<<40,"tebi",
717c478bd9Sstevel@tonic-gate 	0.0,	0
727c478bd9Sstevel@tonic-gate };
737c478bd9Sstevel@tonic-gate FILE	*inp;
747c478bd9Sstevel@tonic-gate int	fperrc;
757c478bd9Sstevel@tonic-gate int	peekc;
767c478bd9Sstevel@tonic-gate int	dumpflg;
777c478bd9Sstevel@tonic-gate 
78*43a29105Srobbin void fperr(int sig);
79*43a29105Srobbin double getflt(void);
80*43a29105Srobbin struct table *hash(char *name);
81*43a29105Srobbin int get(void);
82*43a29105Srobbin void init(void);
83*43a29105Srobbin int equal(char *s1, char *s2);
84*43a29105Srobbin int lookup(char *name, struct unit *up, int den, int c);
85*43a29105Srobbin int convr(struct unit *up);
86*43a29105Srobbin int pu(int u, int i, int f);
87*43a29105Srobbin void units(struct unit *up);
88*43a29105Srobbin 
89*43a29105Srobbin int
main(int argc,char * argv[])90*43a29105Srobbin main(int argc, char *argv[])
917c478bd9Sstevel@tonic-gate {
92*43a29105Srobbin 	int i;
93*43a29105Srobbin 	char *file;
947c478bd9Sstevel@tonic-gate 	struct unit u1, u2;
957c478bd9Sstevel@tonic-gate 	double f;
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
987c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
997c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST"
1007c478bd9Sstevel@tonic-gate #endif
1017c478bd9Sstevel@tonic-gate         (void) textdomain(TEXT_DOMAIN);
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate 	if(argc>1 && *argv[1]=='-') {
1047c478bd9Sstevel@tonic-gate 		argc--;
1057c478bd9Sstevel@tonic-gate 		argv++;
1067c478bd9Sstevel@tonic-gate 		dumpflg++;
1077c478bd9Sstevel@tonic-gate 	}
1087c478bd9Sstevel@tonic-gate 	file = dfile;
1097c478bd9Sstevel@tonic-gate 	if(argc > 1)
1107c478bd9Sstevel@tonic-gate 		file = argv[1];
1117c478bd9Sstevel@tonic-gate 	if ((inp = fopen(file, "r")) == NULL) {
1127c478bd9Sstevel@tonic-gate 		printf(gettext("no table\n"));
1137c478bd9Sstevel@tonic-gate 		exit(1);
1147c478bd9Sstevel@tonic-gate 	}
1157c478bd9Sstevel@tonic-gate 	signal(8, fperr);
1167c478bd9Sstevel@tonic-gate 	init();
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate loop:
1197c478bd9Sstevel@tonic-gate 	fperrc = 0;
1207c478bd9Sstevel@tonic-gate 	printf(gettext("you have: "));
1217c478bd9Sstevel@tonic-gate 	if(convr(&u1))
1227c478bd9Sstevel@tonic-gate 		goto loop;
1237c478bd9Sstevel@tonic-gate 	if(fperrc)
1247c478bd9Sstevel@tonic-gate 		goto fp;
1257c478bd9Sstevel@tonic-gate loop1:
1267c478bd9Sstevel@tonic-gate 	printf(gettext("you want: "));
1277c478bd9Sstevel@tonic-gate 	if(convr(&u2))
1287c478bd9Sstevel@tonic-gate 		goto loop1;
1297c478bd9Sstevel@tonic-gate 	for(i=0; i<NDIM; i++)
1307c478bd9Sstevel@tonic-gate 		if(u1.dim[i] != u2.dim[i])
1317c478bd9Sstevel@tonic-gate 			goto conform;
1327c478bd9Sstevel@tonic-gate 	f = u1.factor/u2.factor;
1337c478bd9Sstevel@tonic-gate 	if(fperrc || f == 0.0)
1347c478bd9Sstevel@tonic-gate 		goto fp;
1357c478bd9Sstevel@tonic-gate 	printf("\t* %e\n", f);
1367c478bd9Sstevel@tonic-gate 	printf("\t/ %e\n", 1./f);
1377c478bd9Sstevel@tonic-gate 	goto loop;
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate conform:
1407c478bd9Sstevel@tonic-gate 	if(fperrc)
1417c478bd9Sstevel@tonic-gate 		goto fp;
1427c478bd9Sstevel@tonic-gate 	printf(gettext("conformability\n"));
1437c478bd9Sstevel@tonic-gate 	units(&u1);
1447c478bd9Sstevel@tonic-gate 	units(&u2);
1457c478bd9Sstevel@tonic-gate 	goto loop;
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate fp:
1487c478bd9Sstevel@tonic-gate 	printf(gettext("underflow or overflow\n"));
1497c478bd9Sstevel@tonic-gate 	goto loop;
1507c478bd9Sstevel@tonic-gate }
1517c478bd9Sstevel@tonic-gate 
152*43a29105Srobbin void
units(struct unit * up)153*43a29105Srobbin units(struct unit *up)
1547c478bd9Sstevel@tonic-gate {
155*43a29105Srobbin 	struct unit *p;
156*43a29105Srobbin 	int f, i;
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 	p = up;
1597c478bd9Sstevel@tonic-gate 	printf("\t%e ", p->factor);
1607c478bd9Sstevel@tonic-gate 	f = 0;
1617c478bd9Sstevel@tonic-gate 	for(i=0; i<NDIM; i++)
1627c478bd9Sstevel@tonic-gate 		f |= pu(p->dim[i], i, f);
1637c478bd9Sstevel@tonic-gate 	if(f&1) {
1647c478bd9Sstevel@tonic-gate 		putchar('/');
1657c478bd9Sstevel@tonic-gate 		f = 0;
1667c478bd9Sstevel@tonic-gate 		for(i=0; i<NDIM; i++)
1677c478bd9Sstevel@tonic-gate 			f |= pu(-p->dim[i], i, f);
1687c478bd9Sstevel@tonic-gate 	}
1697c478bd9Sstevel@tonic-gate 	putchar('\n');
1707c478bd9Sstevel@tonic-gate }
1717c478bd9Sstevel@tonic-gate 
172*43a29105Srobbin int
pu(int u,int i,int f)173*43a29105Srobbin pu(int u, int i, int f)
1747c478bd9Sstevel@tonic-gate {
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate 	if(u > 0) {
1777c478bd9Sstevel@tonic-gate 		if(f&2)
1787c478bd9Sstevel@tonic-gate 			putchar('-');
1797c478bd9Sstevel@tonic-gate 		if(unames[i])
1807c478bd9Sstevel@tonic-gate 			printf("%s", unames[i]); else
1817c478bd9Sstevel@tonic-gate 			printf(gettext("*%c*"), i+'a');
1827c478bd9Sstevel@tonic-gate 		if(u > 1)
1837c478bd9Sstevel@tonic-gate 			putchar(u+'0');
1847c478bd9Sstevel@tonic-gate 			return(2);
1857c478bd9Sstevel@tonic-gate 	}
1867c478bd9Sstevel@tonic-gate 	if(u < 0)
1877c478bd9Sstevel@tonic-gate 		return(1);
1887c478bd9Sstevel@tonic-gate 	return(0);
1897c478bd9Sstevel@tonic-gate }
1907c478bd9Sstevel@tonic-gate 
191*43a29105Srobbin int
convr(struct unit * up)192*43a29105Srobbin convr(struct unit *up)
1937c478bd9Sstevel@tonic-gate {
194*43a29105Srobbin 	struct unit *p;
195*43a29105Srobbin 	int c;
196*43a29105Srobbin 	char *cp;
1977c478bd9Sstevel@tonic-gate 	char name[20];
1987c478bd9Sstevel@tonic-gate 	int den, err;
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 	p = up;
2017c478bd9Sstevel@tonic-gate 	for(c=0; c<NDIM; c++)
2027c478bd9Sstevel@tonic-gate 		p->dim[c] = 0;
2037c478bd9Sstevel@tonic-gate 	p->factor = getflt();
2047c478bd9Sstevel@tonic-gate 	if(p->factor == 0.)
2057c478bd9Sstevel@tonic-gate 		p->factor = 1.0;
2067c478bd9Sstevel@tonic-gate 	err = 0;
2077c478bd9Sstevel@tonic-gate 	den = 0;
2087c478bd9Sstevel@tonic-gate 	cp = name;
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate loop:
2117c478bd9Sstevel@tonic-gate 	switch(c=get()) {
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate 	case '1':
2147c478bd9Sstevel@tonic-gate 	case '2':
2157c478bd9Sstevel@tonic-gate 	case '3':
2167c478bd9Sstevel@tonic-gate 	case '4':
2177c478bd9Sstevel@tonic-gate 	case '5':
2187c478bd9Sstevel@tonic-gate 	case '6':
2197c478bd9Sstevel@tonic-gate 	case '7':
2207c478bd9Sstevel@tonic-gate 	case '8':
2217c478bd9Sstevel@tonic-gate 	case '9':
2227c478bd9Sstevel@tonic-gate 	case '-':
2237c478bd9Sstevel@tonic-gate 	case '/':
2247c478bd9Sstevel@tonic-gate 	case ' ':
2257c478bd9Sstevel@tonic-gate 	case '\t':
2267c478bd9Sstevel@tonic-gate 	case '\n':
2277c478bd9Sstevel@tonic-gate 		if(cp != name) {
2287c478bd9Sstevel@tonic-gate 			*cp++ = 0;
2297c478bd9Sstevel@tonic-gate 			cp = name;
2307c478bd9Sstevel@tonic-gate 			err |= lookup(cp, p, den, c);
2317c478bd9Sstevel@tonic-gate 		}
2327c478bd9Sstevel@tonic-gate 		if(c == '/')
2337c478bd9Sstevel@tonic-gate 			den++;
2347c478bd9Sstevel@tonic-gate 		if(c == '\n')
2357c478bd9Sstevel@tonic-gate 			return(err);
2367c478bd9Sstevel@tonic-gate 		goto loop;
2377c478bd9Sstevel@tonic-gate 	}
2387c478bd9Sstevel@tonic-gate 	*cp++ = c;
2397c478bd9Sstevel@tonic-gate 	goto loop;
2407c478bd9Sstevel@tonic-gate }
2417c478bd9Sstevel@tonic-gate 
242*43a29105Srobbin int
lookup(char * name,struct unit * up,int den,int c)243*43a29105Srobbin lookup(char *name, struct unit *up, int den, int c)
2447c478bd9Sstevel@tonic-gate {
245*43a29105Srobbin 	struct unit *p;
246*43a29105Srobbin 	struct table *q;
247*43a29105Srobbin 	int i;
2487c478bd9Sstevel@tonic-gate 	char *cp1, *cp2;
2497c478bd9Sstevel@tonic-gate 	double e;
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 	p = up;
2527c478bd9Sstevel@tonic-gate 	e = 1.0;
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate loop:
2557c478bd9Sstevel@tonic-gate 	q = hash(name);
2567c478bd9Sstevel@tonic-gate 	if(q->name) {
2577c478bd9Sstevel@tonic-gate 		l1:
2587c478bd9Sstevel@tonic-gate 		if(den) {
2597c478bd9Sstevel@tonic-gate 			p->factor /= q->factor*e;
2607c478bd9Sstevel@tonic-gate 			for(i=0; i<NDIM; i++)
2617c478bd9Sstevel@tonic-gate 				p->dim[i] -= q->dim[i];
2627c478bd9Sstevel@tonic-gate 		} else {
2637c478bd9Sstevel@tonic-gate 			p->factor *= q->factor*e;
2647c478bd9Sstevel@tonic-gate 			for(i=0; i<NDIM; i++)
2657c478bd9Sstevel@tonic-gate 				p->dim[i] += q->dim[i];
2667c478bd9Sstevel@tonic-gate 		}
2677c478bd9Sstevel@tonic-gate 		if(c >= '2' && c <= '9') {
2687c478bd9Sstevel@tonic-gate 			c--;
2697c478bd9Sstevel@tonic-gate 			goto l1;
2707c478bd9Sstevel@tonic-gate 		}
2717c478bd9Sstevel@tonic-gate 		return(0);
2727c478bd9Sstevel@tonic-gate 	}
2737c478bd9Sstevel@tonic-gate 	for(i=0; cp1 = prefix[i].pname; i++) {
2747c478bd9Sstevel@tonic-gate 		cp2 = name;
2757c478bd9Sstevel@tonic-gate 		while(*cp1 == *cp2++)
2767c478bd9Sstevel@tonic-gate 			if(*cp1++ == 0) {
2777c478bd9Sstevel@tonic-gate 				cp1--;
2787c478bd9Sstevel@tonic-gate 				break;
2797c478bd9Sstevel@tonic-gate 			}
2807c478bd9Sstevel@tonic-gate 		if(*cp1 == 0) {
2817c478bd9Sstevel@tonic-gate 			e *= prefix[i].factor;
2827c478bd9Sstevel@tonic-gate 			name = cp2-1;
2837c478bd9Sstevel@tonic-gate 			goto loop;
2847c478bd9Sstevel@tonic-gate 		}
2857c478bd9Sstevel@tonic-gate 	}
2867c478bd9Sstevel@tonic-gate 	for(cp1 = name; *cp1; cp1++);
2877c478bd9Sstevel@tonic-gate 	if(cp1 > name+1 && *--cp1 == 's') {
2887c478bd9Sstevel@tonic-gate 		*cp1 = 0;
2897c478bd9Sstevel@tonic-gate 		goto loop;
2907c478bd9Sstevel@tonic-gate 	}
2917c478bd9Sstevel@tonic-gate 	printf(gettext("cannot recognize %s\n"), name);
2927c478bd9Sstevel@tonic-gate 	return(1);
2937c478bd9Sstevel@tonic-gate }
2947c478bd9Sstevel@tonic-gate 
295*43a29105Srobbin int
equal(char * s1,char * s2)296*43a29105Srobbin equal(char *s1, char *s2)
2977c478bd9Sstevel@tonic-gate {
298*43a29105Srobbin 	char *c1, *c2;
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate 	c1 = s1;
3017c478bd9Sstevel@tonic-gate 	c2 = s2;
3027c478bd9Sstevel@tonic-gate 	while(*c1++ == *c2)
3037c478bd9Sstevel@tonic-gate 		if(*c2++ == 0)
3047c478bd9Sstevel@tonic-gate 			return(1);
3057c478bd9Sstevel@tonic-gate 	return(0);
3067c478bd9Sstevel@tonic-gate }
3077c478bd9Sstevel@tonic-gate 
308*43a29105Srobbin void
init(void)309*43a29105Srobbin init(void)
3107c478bd9Sstevel@tonic-gate {
311*43a29105Srobbin 	char *cp;
312*43a29105Srobbin 	struct table *tp, *lp;
3137c478bd9Sstevel@tonic-gate 	int c, i, f, t;
3147c478bd9Sstevel@tonic-gate 	char *np;
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate 	cp = names;
3177c478bd9Sstevel@tonic-gate 	for(i=0; i<NDIM; i++) {
3187c478bd9Sstevel@tonic-gate 		np = cp;
3197c478bd9Sstevel@tonic-gate 		*cp++ = '*';
3207c478bd9Sstevel@tonic-gate 		*cp++ = i+'a';
3217c478bd9Sstevel@tonic-gate 		*cp++ = '*';
3227c478bd9Sstevel@tonic-gate 		*cp++ = 0;
3237c478bd9Sstevel@tonic-gate 		lp = hash(np);
3247c478bd9Sstevel@tonic-gate 		lp->name = np;
3257c478bd9Sstevel@tonic-gate 		lp->factor = 1.0;
3267c478bd9Sstevel@tonic-gate 		lp->dim[i] = 1;
3277c478bd9Sstevel@tonic-gate 	}
3287c478bd9Sstevel@tonic-gate 	lp = hash("");
3297c478bd9Sstevel@tonic-gate 	lp->name = cp-1;
3307c478bd9Sstevel@tonic-gate 	lp->factor = 1.0;
3317c478bd9Sstevel@tonic-gate 
3327c478bd9Sstevel@tonic-gate l0:
3337c478bd9Sstevel@tonic-gate 	c = get();
3347c478bd9Sstevel@tonic-gate 	if(c == 0) {
3357c478bd9Sstevel@tonic-gate 		if(dumpflg) {
3367c478bd9Sstevel@tonic-gate 		printf(gettext("%d units; %d bytes\n\n"), i, cp-names);
3377c478bd9Sstevel@tonic-gate 		for(tp = &table[0]; tp < &table[NTAB]; tp++) {
3387c478bd9Sstevel@tonic-gate 			if(tp->name == 0)
3397c478bd9Sstevel@tonic-gate 				continue;
3407c478bd9Sstevel@tonic-gate 			printf("%s", tp->name);
3417c478bd9Sstevel@tonic-gate 			units((struct unit *)tp);
3427c478bd9Sstevel@tonic-gate 		} }
3437c478bd9Sstevel@tonic-gate 		fclose(inp);
3447c478bd9Sstevel@tonic-gate 		inp = stdin;
3457c478bd9Sstevel@tonic-gate 		return;
3467c478bd9Sstevel@tonic-gate 	}
3477c478bd9Sstevel@tonic-gate 	if(c == '/') {
3487c478bd9Sstevel@tonic-gate 		while(c != '\n' && c != 0)
3497c478bd9Sstevel@tonic-gate 			c = get();
3507c478bd9Sstevel@tonic-gate 		goto l0;
3517c478bd9Sstevel@tonic-gate 	}
3527c478bd9Sstevel@tonic-gate 	if(c == '\n')
3537c478bd9Sstevel@tonic-gate 		goto l0;
3547c478bd9Sstevel@tonic-gate 	np = cp;
3557c478bd9Sstevel@tonic-gate 	while(c != ' ' && c != '\t') {
3567c478bd9Sstevel@tonic-gate 		*cp++ = c;
3577c478bd9Sstevel@tonic-gate 		c = get();
3587c478bd9Sstevel@tonic-gate 		if (c==0)
3597c478bd9Sstevel@tonic-gate 			goto l0;
3607c478bd9Sstevel@tonic-gate 		if(c == '\n') {
3617c478bd9Sstevel@tonic-gate 			*cp++ = 0;
3627c478bd9Sstevel@tonic-gate 			tp = hash(np);
3637c478bd9Sstevel@tonic-gate 			if(tp->name)
3647c478bd9Sstevel@tonic-gate 				goto redef;
3657c478bd9Sstevel@tonic-gate 			tp->name = np;
3667c478bd9Sstevel@tonic-gate 			tp->factor = lp->factor;
3677c478bd9Sstevel@tonic-gate 			for(c=0; c<NDIM; c++)
3687c478bd9Sstevel@tonic-gate 				tp->dim[c] = lp->dim[c];
3697c478bd9Sstevel@tonic-gate 			i++;
3707c478bd9Sstevel@tonic-gate 			goto l0;
3717c478bd9Sstevel@tonic-gate 		}
3727c478bd9Sstevel@tonic-gate 	}
3737c478bd9Sstevel@tonic-gate 	*cp++ = 0;
3747c478bd9Sstevel@tonic-gate 	lp = hash(np);
3757c478bd9Sstevel@tonic-gate 	if(lp->name)
3767c478bd9Sstevel@tonic-gate 		goto redef;
3777c478bd9Sstevel@tonic-gate 	convr((struct unit *)lp);
3787c478bd9Sstevel@tonic-gate 	lp->name = np;
3797c478bd9Sstevel@tonic-gate 	f = 0;
3807c478bd9Sstevel@tonic-gate 	i++;
3817c478bd9Sstevel@tonic-gate 	if(lp->factor != 1.0)
3827c478bd9Sstevel@tonic-gate 		goto l0;
3837c478bd9Sstevel@tonic-gate 	for(c=0; c<NDIM; c++) {
3847c478bd9Sstevel@tonic-gate 		t = lp->dim[c];
3857c478bd9Sstevel@tonic-gate 		if(t>1 || (f>0 && t!=0))
3867c478bd9Sstevel@tonic-gate 			goto l0;
3877c478bd9Sstevel@tonic-gate 		if(f==0 && t==1) {
3887c478bd9Sstevel@tonic-gate 			if(unames[c])
3897c478bd9Sstevel@tonic-gate 				goto l0;
3907c478bd9Sstevel@tonic-gate 			f = c+1;
3917c478bd9Sstevel@tonic-gate 		}
3927c478bd9Sstevel@tonic-gate 	}
3937c478bd9Sstevel@tonic-gate 	if(f>0)
3947c478bd9Sstevel@tonic-gate 		unames[f-1] = np;
3957c478bd9Sstevel@tonic-gate 	goto l0;
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate redef:
3987c478bd9Sstevel@tonic-gate 	printf(gettext("redefinition %s\n"), np);
3997c478bd9Sstevel@tonic-gate 	goto l0;
4007c478bd9Sstevel@tonic-gate }
4017c478bd9Sstevel@tonic-gate 
4027c478bd9Sstevel@tonic-gate double
getflt(void)403*43a29105Srobbin getflt(void)
4047c478bd9Sstevel@tonic-gate {
405*43a29105Srobbin 	int c, i, dp;
4067c478bd9Sstevel@tonic-gate 	double d, e;
4077c478bd9Sstevel@tonic-gate 	int f;
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate 	d = 0.;
4107c478bd9Sstevel@tonic-gate 	dp = 0;
4117c478bd9Sstevel@tonic-gate 	do
4127c478bd9Sstevel@tonic-gate 		c = get();
4137c478bd9Sstevel@tonic-gate 	while(c == ' ' || c == '\t');
4147c478bd9Sstevel@tonic-gate 
4157c478bd9Sstevel@tonic-gate l1:
4167c478bd9Sstevel@tonic-gate 	if(c >= '0' && c <= '9') {
4177c478bd9Sstevel@tonic-gate 		d = d*10. + c-'0';
4187c478bd9Sstevel@tonic-gate 		if(dp)
4197c478bd9Sstevel@tonic-gate 			dp++;
4207c478bd9Sstevel@tonic-gate 		c = get();
4217c478bd9Sstevel@tonic-gate 		goto l1;
4227c478bd9Sstevel@tonic-gate 	}
4237c478bd9Sstevel@tonic-gate 	if(c == '.') {
4247c478bd9Sstevel@tonic-gate 		dp++;
4257c478bd9Sstevel@tonic-gate 		c = get();
4267c478bd9Sstevel@tonic-gate 		goto l1;
4277c478bd9Sstevel@tonic-gate 	}
4287c478bd9Sstevel@tonic-gate 	if(dp)
4297c478bd9Sstevel@tonic-gate 		dp--;
4307c478bd9Sstevel@tonic-gate 	if(c == '+' || c == '-') {
4317c478bd9Sstevel@tonic-gate 		f = 0;
4327c478bd9Sstevel@tonic-gate 		if(c == '-')
4337c478bd9Sstevel@tonic-gate 			f++;
4347c478bd9Sstevel@tonic-gate 		i = 0;
4357c478bd9Sstevel@tonic-gate 		c = get();
4367c478bd9Sstevel@tonic-gate 		while(c >= '0' && c <= '9') {
4377c478bd9Sstevel@tonic-gate 			i = i*10 + c-'0';
4387c478bd9Sstevel@tonic-gate 			c = get();
4397c478bd9Sstevel@tonic-gate 		}
4407c478bd9Sstevel@tonic-gate 		if(f)
4417c478bd9Sstevel@tonic-gate 			i = -i;
4427c478bd9Sstevel@tonic-gate 		dp -= i;
4437c478bd9Sstevel@tonic-gate 	}
4447c478bd9Sstevel@tonic-gate 	e = 1.;
4457c478bd9Sstevel@tonic-gate 	i = dp;
4467c478bd9Sstevel@tonic-gate 	if(i < 0)
4477c478bd9Sstevel@tonic-gate 		i = -i;
4487c478bd9Sstevel@tonic-gate 	while(i--)
4497c478bd9Sstevel@tonic-gate 		e *= 10.;
4507c478bd9Sstevel@tonic-gate 	if(dp < 0)
4517c478bd9Sstevel@tonic-gate 		d *= e; else
4527c478bd9Sstevel@tonic-gate 		d /= e;
4537c478bd9Sstevel@tonic-gate 	if(c == '|')
4547c478bd9Sstevel@tonic-gate 		return(d/getflt());
4557c478bd9Sstevel@tonic-gate 	peekc = c;
4567c478bd9Sstevel@tonic-gate 	return(d);
4577c478bd9Sstevel@tonic-gate }
4587c478bd9Sstevel@tonic-gate 
459*43a29105Srobbin int
get(void)460*43a29105Srobbin get(void)
4617c478bd9Sstevel@tonic-gate {
462*43a29105Srobbin 	int c;
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate 	if(c=peekc) {
4657c478bd9Sstevel@tonic-gate 		peekc = 0;
4667c478bd9Sstevel@tonic-gate 		return(c);
4677c478bd9Sstevel@tonic-gate 	}
4687c478bd9Sstevel@tonic-gate 	c = getc(inp);
4697c478bd9Sstevel@tonic-gate 	if (c == EOF) {
4707c478bd9Sstevel@tonic-gate 		if (inp == stdin) {
4717c478bd9Sstevel@tonic-gate 			printf("\n");
4727c478bd9Sstevel@tonic-gate 			exit(0);
4737c478bd9Sstevel@tonic-gate 		}
4747c478bd9Sstevel@tonic-gate 		return(0);
4757c478bd9Sstevel@tonic-gate 	}
4767c478bd9Sstevel@tonic-gate 	return(c);
4777c478bd9Sstevel@tonic-gate }
4787c478bd9Sstevel@tonic-gate 
4797c478bd9Sstevel@tonic-gate struct table *
hash(char * name)480*43a29105Srobbin hash(char *name)
4817c478bd9Sstevel@tonic-gate {
482*43a29105Srobbin 	struct table *tp;
483*43a29105Srobbin 	char *np;
484*43a29105Srobbin 	unsigned int h;
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate 	h = 0;
4877c478bd9Sstevel@tonic-gate 	np = name;
4887c478bd9Sstevel@tonic-gate 	while(*np)
4897c478bd9Sstevel@tonic-gate 		h = h*57 + *np++ - '0';
4907c478bd9Sstevel@tonic-gate 	if( ((int)h)<0) h= -(int)h;
4917c478bd9Sstevel@tonic-gate 	h %= NTAB;
4927c478bd9Sstevel@tonic-gate 	tp = &table[h];
4937c478bd9Sstevel@tonic-gate l0:
4947c478bd9Sstevel@tonic-gate 	if(tp->name == 0)
4957c478bd9Sstevel@tonic-gate 		return(tp);
4967c478bd9Sstevel@tonic-gate 	if(equal(name, tp->name))
4977c478bd9Sstevel@tonic-gate 		return(tp);
4987c478bd9Sstevel@tonic-gate 	tp++;
4997c478bd9Sstevel@tonic-gate 	if(tp >= &table[NTAB])
5007c478bd9Sstevel@tonic-gate 		tp = table;
5017c478bd9Sstevel@tonic-gate 	goto l0;
5027c478bd9Sstevel@tonic-gate }
5037c478bd9Sstevel@tonic-gate 
504*43a29105Srobbin void
fperr(int sig)505*43a29105Srobbin fperr(int sig)
5067c478bd9Sstevel@tonic-gate {
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 	signal(8, fperr);
5097c478bd9Sstevel@tonic-gate 	fperrc++;
5107c478bd9Sstevel@tonic-gate }
511