xref: /titanic_54/usr/src/cmd/units/units.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
2*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
3*7c478bd9Sstevel@tonic-gate 
4*7c478bd9Sstevel@tonic-gate 
5*7c478bd9Sstevel@tonic-gate /*
6*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
7*7c478bd9Sstevel@tonic-gate  * All rights reserved.  The Berkeley Software License Agreement
8*7c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
9*7c478bd9Sstevel@tonic-gate  */
10*7c478bd9Sstevel@tonic-gate 
11*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
12*7c478bd9Sstevel@tonic-gate 
13*7c478bd9Sstevel@tonic-gate #include <stdio.h>
14*7c478bd9Sstevel@tonic-gate #include <locale.h>
15*7c478bd9Sstevel@tonic-gate 
16*7c478bd9Sstevel@tonic-gate #define	NDIM	10
17*7c478bd9Sstevel@tonic-gate #define	NTAB	1009
18*7c478bd9Sstevel@tonic-gate extern int *signal();
19*7c478bd9Sstevel@tonic-gate char	*dfile	= "/usr/share/lib/unittab";
20*7c478bd9Sstevel@tonic-gate char	*unames[NDIM];
21*7c478bd9Sstevel@tonic-gate double	getflt();
22*7c478bd9Sstevel@tonic-gate int	fperr();
23*7c478bd9Sstevel@tonic-gate struct	table	*hash();
24*7c478bd9Sstevel@tonic-gate struct unit
25*7c478bd9Sstevel@tonic-gate {
26*7c478bd9Sstevel@tonic-gate 	double	factor;
27*7c478bd9Sstevel@tonic-gate 	char	dim[NDIM];
28*7c478bd9Sstevel@tonic-gate };
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate struct table
31*7c478bd9Sstevel@tonic-gate {
32*7c478bd9Sstevel@tonic-gate 	double	factor;
33*7c478bd9Sstevel@tonic-gate 	char	dim[NDIM];
34*7c478bd9Sstevel@tonic-gate 	char	*name;
35*7c478bd9Sstevel@tonic-gate } table[NTAB];
36*7c478bd9Sstevel@tonic-gate char	names[NTAB*10];
37*7c478bd9Sstevel@tonic-gate struct prefix
38*7c478bd9Sstevel@tonic-gate {
39*7c478bd9Sstevel@tonic-gate 	double	factor;
40*7c478bd9Sstevel@tonic-gate 	char	*pname;
41*7c478bd9Sstevel@tonic-gate } prefix[] =
42*7c478bd9Sstevel@tonic-gate {
43*7c478bd9Sstevel@tonic-gate 	1e-21,	"zepto",
44*7c478bd9Sstevel@tonic-gate 	1e-24,	"yocto",
45*7c478bd9Sstevel@tonic-gate 	1e-18,	"atto",
46*7c478bd9Sstevel@tonic-gate 	1e-15,	"femto",
47*7c478bd9Sstevel@tonic-gate 	1e-12,	"pico",
48*7c478bd9Sstevel@tonic-gate 	1e-9,	"nano",
49*7c478bd9Sstevel@tonic-gate 	1e-6,	"micro",
50*7c478bd9Sstevel@tonic-gate 	1e-3,	"milli",
51*7c478bd9Sstevel@tonic-gate 	1e-2,	"centi",
52*7c478bd9Sstevel@tonic-gate 	1e-1,	"deci",
53*7c478bd9Sstevel@tonic-gate 	1e1,	"deka",
54*7c478bd9Sstevel@tonic-gate 	1e1,	"deca",
55*7c478bd9Sstevel@tonic-gate 	1e2,	"hecta",
56*7c478bd9Sstevel@tonic-gate 	1e2,	"hecto",
57*7c478bd9Sstevel@tonic-gate 	1e3,	"kilo",
58*7c478bd9Sstevel@tonic-gate 	1e6,	"mega",
59*7c478bd9Sstevel@tonic-gate 	1e6,	"meg",
60*7c478bd9Sstevel@tonic-gate 	1e9,	"giga",
61*7c478bd9Sstevel@tonic-gate 	1e12,	"tera",
62*7c478bd9Sstevel@tonic-gate 	1e15,	"peta",
63*7c478bd9Sstevel@tonic-gate 	1e18,	"exa",
64*7c478bd9Sstevel@tonic-gate 	1e21,	"zetta",
65*7c478bd9Sstevel@tonic-gate 	1e24,	"yotta",
66*7c478bd9Sstevel@tonic-gate 	1<<10,	"kibi",
67*7c478bd9Sstevel@tonic-gate 	1L<<20,	"mebi",
68*7c478bd9Sstevel@tonic-gate 	1L<<30,	"gibi",
69*7c478bd9Sstevel@tonic-gate 	1LL<<40,"tebi",
70*7c478bd9Sstevel@tonic-gate 	0.0,	0
71*7c478bd9Sstevel@tonic-gate };
72*7c478bd9Sstevel@tonic-gate FILE	*inp;
73*7c478bd9Sstevel@tonic-gate int	fperrc;
74*7c478bd9Sstevel@tonic-gate int	peekc;
75*7c478bd9Sstevel@tonic-gate int	dumpflg;
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate main(argc, argv)
78*7c478bd9Sstevel@tonic-gate char *argv[];
79*7c478bd9Sstevel@tonic-gate {
80*7c478bd9Sstevel@tonic-gate 	register i;
81*7c478bd9Sstevel@tonic-gate 	register char *file;
82*7c478bd9Sstevel@tonic-gate 	struct unit u1, u2;
83*7c478bd9Sstevel@tonic-gate 	double f;
84*7c478bd9Sstevel@tonic-gate 
85*7c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
86*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
87*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST"
88*7c478bd9Sstevel@tonic-gate #endif
89*7c478bd9Sstevel@tonic-gate         (void) textdomain(TEXT_DOMAIN);
90*7c478bd9Sstevel@tonic-gate 
91*7c478bd9Sstevel@tonic-gate 	if(argc>1 && *argv[1]=='-') {
92*7c478bd9Sstevel@tonic-gate 		argc--;
93*7c478bd9Sstevel@tonic-gate 		argv++;
94*7c478bd9Sstevel@tonic-gate 		dumpflg++;
95*7c478bd9Sstevel@tonic-gate 	}
96*7c478bd9Sstevel@tonic-gate 	file = dfile;
97*7c478bd9Sstevel@tonic-gate 	if(argc > 1)
98*7c478bd9Sstevel@tonic-gate 		file = argv[1];
99*7c478bd9Sstevel@tonic-gate 	if ((inp = fopen(file, "r")) == NULL) {
100*7c478bd9Sstevel@tonic-gate 		printf(gettext("no table\n"));
101*7c478bd9Sstevel@tonic-gate 		exit(1);
102*7c478bd9Sstevel@tonic-gate 	}
103*7c478bd9Sstevel@tonic-gate 	signal(8, fperr);
104*7c478bd9Sstevel@tonic-gate 	init();
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate loop:
107*7c478bd9Sstevel@tonic-gate 	fperrc = 0;
108*7c478bd9Sstevel@tonic-gate 	printf(gettext("you have: "));
109*7c478bd9Sstevel@tonic-gate 	if(convr(&u1))
110*7c478bd9Sstevel@tonic-gate 		goto loop;
111*7c478bd9Sstevel@tonic-gate 	if(fperrc)
112*7c478bd9Sstevel@tonic-gate 		goto fp;
113*7c478bd9Sstevel@tonic-gate loop1:
114*7c478bd9Sstevel@tonic-gate 	printf(gettext("you want: "));
115*7c478bd9Sstevel@tonic-gate 	if(convr(&u2))
116*7c478bd9Sstevel@tonic-gate 		goto loop1;
117*7c478bd9Sstevel@tonic-gate 	for(i=0; i<NDIM; i++)
118*7c478bd9Sstevel@tonic-gate 		if(u1.dim[i] != u2.dim[i])
119*7c478bd9Sstevel@tonic-gate 			goto conform;
120*7c478bd9Sstevel@tonic-gate 	f = u1.factor/u2.factor;
121*7c478bd9Sstevel@tonic-gate 	if(fperrc || f == 0.0)
122*7c478bd9Sstevel@tonic-gate 		goto fp;
123*7c478bd9Sstevel@tonic-gate 	printf("\t* %e\n", f);
124*7c478bd9Sstevel@tonic-gate 	printf("\t/ %e\n", 1./f);
125*7c478bd9Sstevel@tonic-gate 	goto loop;
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate conform:
128*7c478bd9Sstevel@tonic-gate 	if(fperrc)
129*7c478bd9Sstevel@tonic-gate 		goto fp;
130*7c478bd9Sstevel@tonic-gate 	printf(gettext("conformability\n"));
131*7c478bd9Sstevel@tonic-gate 	units(&u1);
132*7c478bd9Sstevel@tonic-gate 	units(&u2);
133*7c478bd9Sstevel@tonic-gate 	goto loop;
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate fp:
136*7c478bd9Sstevel@tonic-gate 	printf(gettext("underflow or overflow\n"));
137*7c478bd9Sstevel@tonic-gate 	goto loop;
138*7c478bd9Sstevel@tonic-gate }
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate units(up)
141*7c478bd9Sstevel@tonic-gate struct unit *up;
142*7c478bd9Sstevel@tonic-gate {
143*7c478bd9Sstevel@tonic-gate 	register struct unit *p;
144*7c478bd9Sstevel@tonic-gate 	register f, i;
145*7c478bd9Sstevel@tonic-gate 
146*7c478bd9Sstevel@tonic-gate 	p = up;
147*7c478bd9Sstevel@tonic-gate 	printf("\t%e ", p->factor);
148*7c478bd9Sstevel@tonic-gate 	f = 0;
149*7c478bd9Sstevel@tonic-gate 	for(i=0; i<NDIM; i++)
150*7c478bd9Sstevel@tonic-gate 		f |= pu(p->dim[i], i, f);
151*7c478bd9Sstevel@tonic-gate 	if(f&1) {
152*7c478bd9Sstevel@tonic-gate 		putchar('/');
153*7c478bd9Sstevel@tonic-gate 		f = 0;
154*7c478bd9Sstevel@tonic-gate 		for(i=0; i<NDIM; i++)
155*7c478bd9Sstevel@tonic-gate 			f |= pu(-p->dim[i], i, f);
156*7c478bd9Sstevel@tonic-gate 	}
157*7c478bd9Sstevel@tonic-gate 	putchar('\n');
158*7c478bd9Sstevel@tonic-gate }
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate pu(u, i, f)
161*7c478bd9Sstevel@tonic-gate {
162*7c478bd9Sstevel@tonic-gate 
163*7c478bd9Sstevel@tonic-gate 	if(u > 0) {
164*7c478bd9Sstevel@tonic-gate 		if(f&2)
165*7c478bd9Sstevel@tonic-gate 			putchar('-');
166*7c478bd9Sstevel@tonic-gate 		if(unames[i])
167*7c478bd9Sstevel@tonic-gate 			printf("%s", unames[i]); else
168*7c478bd9Sstevel@tonic-gate 			printf(gettext("*%c*"), i+'a');
169*7c478bd9Sstevel@tonic-gate 		if(u > 1)
170*7c478bd9Sstevel@tonic-gate 			putchar(u+'0');
171*7c478bd9Sstevel@tonic-gate 			return(2);
172*7c478bd9Sstevel@tonic-gate 	}
173*7c478bd9Sstevel@tonic-gate 	if(u < 0)
174*7c478bd9Sstevel@tonic-gate 		return(1);
175*7c478bd9Sstevel@tonic-gate 	return(0);
176*7c478bd9Sstevel@tonic-gate }
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate convr(up)
179*7c478bd9Sstevel@tonic-gate struct unit *up;
180*7c478bd9Sstevel@tonic-gate {
181*7c478bd9Sstevel@tonic-gate 	register struct unit *p;
182*7c478bd9Sstevel@tonic-gate 	register c;
183*7c478bd9Sstevel@tonic-gate 	register char *cp;
184*7c478bd9Sstevel@tonic-gate 	char name[20];
185*7c478bd9Sstevel@tonic-gate 	int den, err;
186*7c478bd9Sstevel@tonic-gate 
187*7c478bd9Sstevel@tonic-gate 	p = up;
188*7c478bd9Sstevel@tonic-gate 	for(c=0; c<NDIM; c++)
189*7c478bd9Sstevel@tonic-gate 		p->dim[c] = 0;
190*7c478bd9Sstevel@tonic-gate 	p->factor = getflt();
191*7c478bd9Sstevel@tonic-gate 	if(p->factor == 0.)
192*7c478bd9Sstevel@tonic-gate 		p->factor = 1.0;
193*7c478bd9Sstevel@tonic-gate 	err = 0;
194*7c478bd9Sstevel@tonic-gate 	den = 0;
195*7c478bd9Sstevel@tonic-gate 	cp = name;
196*7c478bd9Sstevel@tonic-gate 
197*7c478bd9Sstevel@tonic-gate loop:
198*7c478bd9Sstevel@tonic-gate 	switch(c=get()) {
199*7c478bd9Sstevel@tonic-gate 
200*7c478bd9Sstevel@tonic-gate 	case '1':
201*7c478bd9Sstevel@tonic-gate 	case '2':
202*7c478bd9Sstevel@tonic-gate 	case '3':
203*7c478bd9Sstevel@tonic-gate 	case '4':
204*7c478bd9Sstevel@tonic-gate 	case '5':
205*7c478bd9Sstevel@tonic-gate 	case '6':
206*7c478bd9Sstevel@tonic-gate 	case '7':
207*7c478bd9Sstevel@tonic-gate 	case '8':
208*7c478bd9Sstevel@tonic-gate 	case '9':
209*7c478bd9Sstevel@tonic-gate 	case '-':
210*7c478bd9Sstevel@tonic-gate 	case '/':
211*7c478bd9Sstevel@tonic-gate 	case ' ':
212*7c478bd9Sstevel@tonic-gate 	case '\t':
213*7c478bd9Sstevel@tonic-gate 	case '\n':
214*7c478bd9Sstevel@tonic-gate 		if(cp != name) {
215*7c478bd9Sstevel@tonic-gate 			*cp++ = 0;
216*7c478bd9Sstevel@tonic-gate 			cp = name;
217*7c478bd9Sstevel@tonic-gate 			err |= lookup(cp, p, den, c);
218*7c478bd9Sstevel@tonic-gate 		}
219*7c478bd9Sstevel@tonic-gate 		if(c == '/')
220*7c478bd9Sstevel@tonic-gate 			den++;
221*7c478bd9Sstevel@tonic-gate 		if(c == '\n')
222*7c478bd9Sstevel@tonic-gate 			return(err);
223*7c478bd9Sstevel@tonic-gate 		goto loop;
224*7c478bd9Sstevel@tonic-gate 	}
225*7c478bd9Sstevel@tonic-gate 	*cp++ = c;
226*7c478bd9Sstevel@tonic-gate 	goto loop;
227*7c478bd9Sstevel@tonic-gate }
228*7c478bd9Sstevel@tonic-gate 
229*7c478bd9Sstevel@tonic-gate lookup(name, up, den, c)
230*7c478bd9Sstevel@tonic-gate char *name;
231*7c478bd9Sstevel@tonic-gate struct unit *up;
232*7c478bd9Sstevel@tonic-gate {
233*7c478bd9Sstevel@tonic-gate 	register struct unit *p;
234*7c478bd9Sstevel@tonic-gate 	register struct table *q;
235*7c478bd9Sstevel@tonic-gate 	register i;
236*7c478bd9Sstevel@tonic-gate 	char *cp1, *cp2;
237*7c478bd9Sstevel@tonic-gate 	double e;
238*7c478bd9Sstevel@tonic-gate 
239*7c478bd9Sstevel@tonic-gate 	p = up;
240*7c478bd9Sstevel@tonic-gate 	e = 1.0;
241*7c478bd9Sstevel@tonic-gate 
242*7c478bd9Sstevel@tonic-gate loop:
243*7c478bd9Sstevel@tonic-gate 	q = hash(name);
244*7c478bd9Sstevel@tonic-gate 	if(q->name) {
245*7c478bd9Sstevel@tonic-gate 		l1:
246*7c478bd9Sstevel@tonic-gate 		if(den) {
247*7c478bd9Sstevel@tonic-gate 			p->factor /= q->factor*e;
248*7c478bd9Sstevel@tonic-gate 			for(i=0; i<NDIM; i++)
249*7c478bd9Sstevel@tonic-gate 				p->dim[i] -= q->dim[i];
250*7c478bd9Sstevel@tonic-gate 		} else {
251*7c478bd9Sstevel@tonic-gate 			p->factor *= q->factor*e;
252*7c478bd9Sstevel@tonic-gate 			for(i=0; i<NDIM; i++)
253*7c478bd9Sstevel@tonic-gate 				p->dim[i] += q->dim[i];
254*7c478bd9Sstevel@tonic-gate 		}
255*7c478bd9Sstevel@tonic-gate 		if(c >= '2' && c <= '9') {
256*7c478bd9Sstevel@tonic-gate 			c--;
257*7c478bd9Sstevel@tonic-gate 			goto l1;
258*7c478bd9Sstevel@tonic-gate 		}
259*7c478bd9Sstevel@tonic-gate 		return(0);
260*7c478bd9Sstevel@tonic-gate 	}
261*7c478bd9Sstevel@tonic-gate 	for(i=0; cp1 = prefix[i].pname; i++) {
262*7c478bd9Sstevel@tonic-gate 		cp2 = name;
263*7c478bd9Sstevel@tonic-gate 		while(*cp1 == *cp2++)
264*7c478bd9Sstevel@tonic-gate 			if(*cp1++ == 0) {
265*7c478bd9Sstevel@tonic-gate 				cp1--;
266*7c478bd9Sstevel@tonic-gate 				break;
267*7c478bd9Sstevel@tonic-gate 			}
268*7c478bd9Sstevel@tonic-gate 		if(*cp1 == 0) {
269*7c478bd9Sstevel@tonic-gate 			e *= prefix[i].factor;
270*7c478bd9Sstevel@tonic-gate 			name = cp2-1;
271*7c478bd9Sstevel@tonic-gate 			goto loop;
272*7c478bd9Sstevel@tonic-gate 		}
273*7c478bd9Sstevel@tonic-gate 	}
274*7c478bd9Sstevel@tonic-gate 	for(cp1 = name; *cp1; cp1++);
275*7c478bd9Sstevel@tonic-gate 	if(cp1 > name+1 && *--cp1 == 's') {
276*7c478bd9Sstevel@tonic-gate 		*cp1 = 0;
277*7c478bd9Sstevel@tonic-gate 		goto loop;
278*7c478bd9Sstevel@tonic-gate 	}
279*7c478bd9Sstevel@tonic-gate 	printf(gettext("cannot recognize %s\n"), name);
280*7c478bd9Sstevel@tonic-gate 	return(1);
281*7c478bd9Sstevel@tonic-gate }
282*7c478bd9Sstevel@tonic-gate 
283*7c478bd9Sstevel@tonic-gate equal(s1, s2)
284*7c478bd9Sstevel@tonic-gate char *s1, *s2;
285*7c478bd9Sstevel@tonic-gate {
286*7c478bd9Sstevel@tonic-gate 	register char *c1, *c2;
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate 	c1 = s1;
289*7c478bd9Sstevel@tonic-gate 	c2 = s2;
290*7c478bd9Sstevel@tonic-gate 	while(*c1++ == *c2)
291*7c478bd9Sstevel@tonic-gate 		if(*c2++ == 0)
292*7c478bd9Sstevel@tonic-gate 			return(1);
293*7c478bd9Sstevel@tonic-gate 	return(0);
294*7c478bd9Sstevel@tonic-gate }
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate init()
297*7c478bd9Sstevel@tonic-gate {
298*7c478bd9Sstevel@tonic-gate 	register char *cp;
299*7c478bd9Sstevel@tonic-gate 	register struct table *tp, *lp;
300*7c478bd9Sstevel@tonic-gate 	int c, i, f, t;
301*7c478bd9Sstevel@tonic-gate 	char *np;
302*7c478bd9Sstevel@tonic-gate 
303*7c478bd9Sstevel@tonic-gate 	cp = names;
304*7c478bd9Sstevel@tonic-gate 	for(i=0; i<NDIM; i++) {
305*7c478bd9Sstevel@tonic-gate 		np = cp;
306*7c478bd9Sstevel@tonic-gate 		*cp++ = '*';
307*7c478bd9Sstevel@tonic-gate 		*cp++ = i+'a';
308*7c478bd9Sstevel@tonic-gate 		*cp++ = '*';
309*7c478bd9Sstevel@tonic-gate 		*cp++ = 0;
310*7c478bd9Sstevel@tonic-gate 		lp = hash(np);
311*7c478bd9Sstevel@tonic-gate 		lp->name = np;
312*7c478bd9Sstevel@tonic-gate 		lp->factor = 1.0;
313*7c478bd9Sstevel@tonic-gate 		lp->dim[i] = 1;
314*7c478bd9Sstevel@tonic-gate 	}
315*7c478bd9Sstevel@tonic-gate 	lp = hash("");
316*7c478bd9Sstevel@tonic-gate 	lp->name = cp-1;
317*7c478bd9Sstevel@tonic-gate 	lp->factor = 1.0;
318*7c478bd9Sstevel@tonic-gate 
319*7c478bd9Sstevel@tonic-gate l0:
320*7c478bd9Sstevel@tonic-gate 	c = get();
321*7c478bd9Sstevel@tonic-gate 	if(c == 0) {
322*7c478bd9Sstevel@tonic-gate 		if(dumpflg) {
323*7c478bd9Sstevel@tonic-gate 		printf(gettext("%d units; %d bytes\n\n"), i, cp-names);
324*7c478bd9Sstevel@tonic-gate 		for(tp = &table[0]; tp < &table[NTAB]; tp++) {
325*7c478bd9Sstevel@tonic-gate 			if(tp->name == 0)
326*7c478bd9Sstevel@tonic-gate 				continue;
327*7c478bd9Sstevel@tonic-gate 			printf("%s", tp->name);
328*7c478bd9Sstevel@tonic-gate 			units((struct unit *)tp);
329*7c478bd9Sstevel@tonic-gate 		} }
330*7c478bd9Sstevel@tonic-gate 		fclose(inp);
331*7c478bd9Sstevel@tonic-gate 		inp = stdin;
332*7c478bd9Sstevel@tonic-gate 		return;
333*7c478bd9Sstevel@tonic-gate 	}
334*7c478bd9Sstevel@tonic-gate 	if(c == '/') {
335*7c478bd9Sstevel@tonic-gate 		while(c != '\n' && c != 0)
336*7c478bd9Sstevel@tonic-gate 			c = get();
337*7c478bd9Sstevel@tonic-gate 		goto l0;
338*7c478bd9Sstevel@tonic-gate 	}
339*7c478bd9Sstevel@tonic-gate 	if(c == '\n')
340*7c478bd9Sstevel@tonic-gate 		goto l0;
341*7c478bd9Sstevel@tonic-gate 	np = cp;
342*7c478bd9Sstevel@tonic-gate 	while(c != ' ' && c != '\t') {
343*7c478bd9Sstevel@tonic-gate 		*cp++ = c;
344*7c478bd9Sstevel@tonic-gate 		c = get();
345*7c478bd9Sstevel@tonic-gate 		if (c==0)
346*7c478bd9Sstevel@tonic-gate 			goto l0;
347*7c478bd9Sstevel@tonic-gate 		if(c == '\n') {
348*7c478bd9Sstevel@tonic-gate 			*cp++ = 0;
349*7c478bd9Sstevel@tonic-gate 			tp = hash(np);
350*7c478bd9Sstevel@tonic-gate 			if(tp->name)
351*7c478bd9Sstevel@tonic-gate 				goto redef;
352*7c478bd9Sstevel@tonic-gate 			tp->name = np;
353*7c478bd9Sstevel@tonic-gate 			tp->factor = lp->factor;
354*7c478bd9Sstevel@tonic-gate 			for(c=0; c<NDIM; c++)
355*7c478bd9Sstevel@tonic-gate 				tp->dim[c] = lp->dim[c];
356*7c478bd9Sstevel@tonic-gate 			i++;
357*7c478bd9Sstevel@tonic-gate 			goto l0;
358*7c478bd9Sstevel@tonic-gate 		}
359*7c478bd9Sstevel@tonic-gate 	}
360*7c478bd9Sstevel@tonic-gate 	*cp++ = 0;
361*7c478bd9Sstevel@tonic-gate 	lp = hash(np);
362*7c478bd9Sstevel@tonic-gate 	if(lp->name)
363*7c478bd9Sstevel@tonic-gate 		goto redef;
364*7c478bd9Sstevel@tonic-gate 	convr((struct unit *)lp);
365*7c478bd9Sstevel@tonic-gate 	lp->name = np;
366*7c478bd9Sstevel@tonic-gate 	f = 0;
367*7c478bd9Sstevel@tonic-gate 	i++;
368*7c478bd9Sstevel@tonic-gate 	if(lp->factor != 1.0)
369*7c478bd9Sstevel@tonic-gate 		goto l0;
370*7c478bd9Sstevel@tonic-gate 	for(c=0; c<NDIM; c++) {
371*7c478bd9Sstevel@tonic-gate 		t = lp->dim[c];
372*7c478bd9Sstevel@tonic-gate 		if(t>1 || (f>0 && t!=0))
373*7c478bd9Sstevel@tonic-gate 			goto l0;
374*7c478bd9Sstevel@tonic-gate 		if(f==0 && t==1) {
375*7c478bd9Sstevel@tonic-gate 			if(unames[c])
376*7c478bd9Sstevel@tonic-gate 				goto l0;
377*7c478bd9Sstevel@tonic-gate 			f = c+1;
378*7c478bd9Sstevel@tonic-gate 		}
379*7c478bd9Sstevel@tonic-gate 	}
380*7c478bd9Sstevel@tonic-gate 	if(f>0)
381*7c478bd9Sstevel@tonic-gate 		unames[f-1] = np;
382*7c478bd9Sstevel@tonic-gate 	goto l0;
383*7c478bd9Sstevel@tonic-gate 
384*7c478bd9Sstevel@tonic-gate redef:
385*7c478bd9Sstevel@tonic-gate 	printf(gettext("redefinition %s\n"), np);
386*7c478bd9Sstevel@tonic-gate 	goto l0;
387*7c478bd9Sstevel@tonic-gate }
388*7c478bd9Sstevel@tonic-gate 
389*7c478bd9Sstevel@tonic-gate double
390*7c478bd9Sstevel@tonic-gate getflt()
391*7c478bd9Sstevel@tonic-gate {
392*7c478bd9Sstevel@tonic-gate 	register c, i, dp;
393*7c478bd9Sstevel@tonic-gate 	double d, e;
394*7c478bd9Sstevel@tonic-gate 	int f;
395*7c478bd9Sstevel@tonic-gate 
396*7c478bd9Sstevel@tonic-gate 	d = 0.;
397*7c478bd9Sstevel@tonic-gate 	dp = 0;
398*7c478bd9Sstevel@tonic-gate 	do
399*7c478bd9Sstevel@tonic-gate 		c = get();
400*7c478bd9Sstevel@tonic-gate 	while(c == ' ' || c == '\t');
401*7c478bd9Sstevel@tonic-gate 
402*7c478bd9Sstevel@tonic-gate l1:
403*7c478bd9Sstevel@tonic-gate 	if(c >= '0' && c <= '9') {
404*7c478bd9Sstevel@tonic-gate 		d = d*10. + c-'0';
405*7c478bd9Sstevel@tonic-gate 		if(dp)
406*7c478bd9Sstevel@tonic-gate 			dp++;
407*7c478bd9Sstevel@tonic-gate 		c = get();
408*7c478bd9Sstevel@tonic-gate 		goto l1;
409*7c478bd9Sstevel@tonic-gate 	}
410*7c478bd9Sstevel@tonic-gate 	if(c == '.') {
411*7c478bd9Sstevel@tonic-gate 		dp++;
412*7c478bd9Sstevel@tonic-gate 		c = get();
413*7c478bd9Sstevel@tonic-gate 		goto l1;
414*7c478bd9Sstevel@tonic-gate 	}
415*7c478bd9Sstevel@tonic-gate 	if(dp)
416*7c478bd9Sstevel@tonic-gate 		dp--;
417*7c478bd9Sstevel@tonic-gate 	if(c == '+' || c == '-') {
418*7c478bd9Sstevel@tonic-gate 		f = 0;
419*7c478bd9Sstevel@tonic-gate 		if(c == '-')
420*7c478bd9Sstevel@tonic-gate 			f++;
421*7c478bd9Sstevel@tonic-gate 		i = 0;
422*7c478bd9Sstevel@tonic-gate 		c = get();
423*7c478bd9Sstevel@tonic-gate 		while(c >= '0' && c <= '9') {
424*7c478bd9Sstevel@tonic-gate 			i = i*10 + c-'0';
425*7c478bd9Sstevel@tonic-gate 			c = get();
426*7c478bd9Sstevel@tonic-gate 		}
427*7c478bd9Sstevel@tonic-gate 		if(f)
428*7c478bd9Sstevel@tonic-gate 			i = -i;
429*7c478bd9Sstevel@tonic-gate 		dp -= i;
430*7c478bd9Sstevel@tonic-gate 	}
431*7c478bd9Sstevel@tonic-gate 	e = 1.;
432*7c478bd9Sstevel@tonic-gate 	i = dp;
433*7c478bd9Sstevel@tonic-gate 	if(i < 0)
434*7c478bd9Sstevel@tonic-gate 		i = -i;
435*7c478bd9Sstevel@tonic-gate 	while(i--)
436*7c478bd9Sstevel@tonic-gate 		e *= 10.;
437*7c478bd9Sstevel@tonic-gate 	if(dp < 0)
438*7c478bd9Sstevel@tonic-gate 		d *= e; else
439*7c478bd9Sstevel@tonic-gate 		d /= e;
440*7c478bd9Sstevel@tonic-gate 	if(c == '|')
441*7c478bd9Sstevel@tonic-gate 		return(d/getflt());
442*7c478bd9Sstevel@tonic-gate 	peekc = c;
443*7c478bd9Sstevel@tonic-gate 	return(d);
444*7c478bd9Sstevel@tonic-gate }
445*7c478bd9Sstevel@tonic-gate 
446*7c478bd9Sstevel@tonic-gate get()
447*7c478bd9Sstevel@tonic-gate {
448*7c478bd9Sstevel@tonic-gate 	register c;
449*7c478bd9Sstevel@tonic-gate 
450*7c478bd9Sstevel@tonic-gate 	if(c=peekc) {
451*7c478bd9Sstevel@tonic-gate 		peekc = 0;
452*7c478bd9Sstevel@tonic-gate 		return(c);
453*7c478bd9Sstevel@tonic-gate 	}
454*7c478bd9Sstevel@tonic-gate 	c = getc(inp);
455*7c478bd9Sstevel@tonic-gate 	if (c == EOF) {
456*7c478bd9Sstevel@tonic-gate 		if (inp == stdin) {
457*7c478bd9Sstevel@tonic-gate 			printf("\n");
458*7c478bd9Sstevel@tonic-gate 			exit(0);
459*7c478bd9Sstevel@tonic-gate 		}
460*7c478bd9Sstevel@tonic-gate 		return(0);
461*7c478bd9Sstevel@tonic-gate 	}
462*7c478bd9Sstevel@tonic-gate 	return(c);
463*7c478bd9Sstevel@tonic-gate }
464*7c478bd9Sstevel@tonic-gate 
465*7c478bd9Sstevel@tonic-gate struct table *
466*7c478bd9Sstevel@tonic-gate hash(name)
467*7c478bd9Sstevel@tonic-gate char *name;
468*7c478bd9Sstevel@tonic-gate {
469*7c478bd9Sstevel@tonic-gate 	register struct table *tp;
470*7c478bd9Sstevel@tonic-gate 	register char *np;
471*7c478bd9Sstevel@tonic-gate 	register unsigned h;
472*7c478bd9Sstevel@tonic-gate 
473*7c478bd9Sstevel@tonic-gate 	h = 0;
474*7c478bd9Sstevel@tonic-gate 	np = name;
475*7c478bd9Sstevel@tonic-gate 	while(*np)
476*7c478bd9Sstevel@tonic-gate 		h = h*57 + *np++ - '0';
477*7c478bd9Sstevel@tonic-gate 	if( ((int)h)<0) h= -(int)h;
478*7c478bd9Sstevel@tonic-gate 	h %= NTAB;
479*7c478bd9Sstevel@tonic-gate 	tp = &table[h];
480*7c478bd9Sstevel@tonic-gate l0:
481*7c478bd9Sstevel@tonic-gate 	if(tp->name == 0)
482*7c478bd9Sstevel@tonic-gate 		return(tp);
483*7c478bd9Sstevel@tonic-gate 	if(equal(name, tp->name))
484*7c478bd9Sstevel@tonic-gate 		return(tp);
485*7c478bd9Sstevel@tonic-gate 	tp++;
486*7c478bd9Sstevel@tonic-gate 	if(tp >= &table[NTAB])
487*7c478bd9Sstevel@tonic-gate 		tp = table;
488*7c478bd9Sstevel@tonic-gate 	goto l0;
489*7c478bd9Sstevel@tonic-gate }
490*7c478bd9Sstevel@tonic-gate 
491*7c478bd9Sstevel@tonic-gate fperr()
492*7c478bd9Sstevel@tonic-gate {
493*7c478bd9Sstevel@tonic-gate 
494*7c478bd9Sstevel@tonic-gate 	signal(8, fperr);
495*7c478bd9Sstevel@tonic-gate 	fperrc++;
496*7c478bd9Sstevel@tonic-gate }
497