1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1982-2012 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                 Eclipse Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *          http://www.eclipse.org/org/documents/epl-v10.html           *
11 *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *                  David Korn <dgk@research.att.com>                   *
18 *                                                                      *
19 ***********************************************************************/
20 #pragma prototyped
21 
22 /*
23  * D. G. Korn
24  * AT&T Labs
25  *
26  * arithmetic expression evaluator
27  *
28  * this version compiles the expression onto a stack
29  *	 and has a separate executor
30  */
31 
32 #include	"streval.h"
33 #include	<ctype.h>
34 #include	<error.h>
35 #include	<stak.h>
36 #include	"FEATURE/externs"
37 #include	"defs.h"	/* for sh.decomma */
38 
39 #ifndef ERROR_dictionary
40 #   define ERROR_dictionary(s)	(s)
41 #endif
42 #ifndef SH_DICT
43 #   define SH_DICT	"libshell"
44 #endif
45 
46 #define MAXLEVEL	9
47 #define SMALL_STACK	12
48 
49 /*
50  * The following are used with tokenbits() macro
51  */
52 #define T_OP		0x3f		/* mask for operator number */
53 #define T_BINARY	0x40		/* binary operators */
54 #define T_NOFLOAT	0x80		/* non floating point operator */
55 #define A_LVALUE	(2*MAXPREC+2)
56 
57 #define pow2size(x)		((x)<=2?2:(x)<=4?4:(x)<=8?8:(x)<=16?16:(x)<=32?32:64)
58 #define round(x,size)		(((x)+(size)-1)&~((size)-1))
59 #define stakpush(v,val,type)	((((v)->offset=round(staktell(),pow2size(sizeof(type)))),\
60 				stakseek((v)->offset+sizeof(type)), \
61 				*((type*)stakptr((v)->offset)) = (val)),(v)->offset)
62 #define roundptr(ep,cp,type)	(((unsigned char*)(ep))+round(cp-((unsigned char*)(ep)),pow2size(sizeof(type))))
63 
64 static int level;
65 
66 struct vars				/* vars stacked per invocation */
67 {
68 	Shell_t		*shp;
69 	const char	*expr;		/* current expression */
70 	const char	*nextchr;	/* next char in current expression */
71 	const char	*errchr; 	/* next char after error	*/
72 	const char	*errstr;	/* error string			*/
73 	struct lval	errmsg;	 	/* error message text		*/
74 	int		offset;		/* offset for pushchr macro	*/
75 	int		staksize;	/* current stack size needed	*/
76 	int		stakmaxsize;	/* maximum stack size needed	*/
77 	unsigned char	paren;	 	/* parenthesis level		*/
78 	char		infun;	/* incremented by comma inside function	*/
79 	int		emode;
80 	Sfdouble_t	(*convert)(const char**,struct lval*,int,Sfdouble_t);
81 };
82 
83 typedef Sfdouble_t (*Math_f)(Sfdouble_t,...);
84 typedef Sfdouble_t (*Math_1f_f)(Sfdouble_t);
85 typedef int	   (*Math_1i_f)(Sfdouble_t);
86 typedef Sfdouble_t (*Math_2f_f)(Sfdouble_t,Sfdouble_t);
87 typedef Sfdouble_t (*Math_2f_i)(Sfdouble_t,int);
88 typedef int        (*Math_2i_f)(Sfdouble_t,Sfdouble_t);
89 typedef Sfdouble_t (*Math_3f_f)(Sfdouble_t,Sfdouble_t,Sfdouble_t);
90 typedef int        (*Math_3i_f)(Sfdouble_t,Sfdouble_t,Sfdouble_t);
91 
92 #define getchr(vp)	(*(vp)->nextchr++)
93 #define peekchr(vp)	(*(vp)->nextchr)
94 #define ungetchr(vp)	((vp)->nextchr--)
95 
96 #if ('a'==97)	/* ASCII encodings */
97 #   define getop(c)	(((c) >= sizeof(strval_states))? \
98 				((c)=='|'?A_OR:((c)=='^'?A_XOR:((c)=='~'?A_TILDE:A_REG))):\
99 				strval_states[(c)])
100 #else
101 #   define getop(c)	(isdigit(c)?A_DIG:((c==' '||c=='\t'||c=='\n'||c=='"')?0: \
102 			(c=='<'?A_LT:(c=='>'?A_GT:(c=='='?A_ASSIGN: \
103 			(c=='+'?A_PLUS:(c=='-'?A_MINUS:(c=='*'?A_TIMES: \
104 			(c=='/'?A_DIV:(c=='%'?A_MOD:(c==','?A_COMMA: \
105 			(c=='&'?A_AND:(c=='!'?A_NOT:(c=='('?A_LPAR: \
106 			(c==')'?A_RPAR:(c==0?A_EOF:(c==':'?A_COLON: \
107 			(c=='?'?A_QUEST:(c=='|'?A_OR:(c=='^'?A_XOR: \
108 			(c=='\''?A_LIT: \
109 			(c=='.'?A_DOT:(c=='~'?A_TILDE:A_REG)))))))))))))))))))))))
110 #endif
111 
112 #define seterror(v,msg)		_seterror(v,ERROR_dictionary(msg))
113 #define ERROR(vp,msg)		return(seterror((vp),msg))
114 
115 /*
116  * set error message string and return(0)
117  */
_seterror(struct vars * vp,const char * msg)118 static int _seterror(struct vars *vp,const char *msg)
119 {
120 	if(!vp->errmsg.value)
121 		vp->errmsg.value = (char*)msg;
122 	vp->errchr = vp->nextchr;
123 	vp->nextchr = "";
124 	level = 0;
125 	return(0);
126 }
127 
128 
arith_error(const char * message,const char * expr,int mode)129 static void arith_error(const char *message,const char *expr, int mode)
130 {
131         level = 0;
132 	mode = (mode&3)!=0;
133         errormsg(SH_DICT,ERROR_exit(mode),message,expr);
134 }
135 
136 #if _ast_no_um2fm
U2F(Sfulong_t u)137 static Sfdouble_t U2F(Sfulong_t u)
138 {
139 	Sflong_t	s = u;
140 	Sfdouble_t	f;
141 
142 	if (s >= 0)
143 		return s;
144 	s = u / 2;
145 	f = s;
146 	f *= 2;
147 	if (u & 1)
148 		f++;
149 	return f;
150 }
151 #else
152 #define U2F(x)		x
153 #endif
154 
arith_exec(Arith_t * ep)155 Sfdouble_t	arith_exec(Arith_t *ep)
156 {
157 	register Sfdouble_t num=0,*dp,*sp;
158 	register unsigned char *cp = ep->code;
159 	register int c,type=0;
160 	register char *tp;
161 	Sfdouble_t small_stack[SMALL_STACK+1],arg[9];
162 	const char *ptr = "";
163 	char	*lastval=0;
164 	int	lastsub;
165 	Math_f fun;
166 	struct lval node;
167 	Shell_t	*shp = ep->shp;
168 	node.shp = shp;
169 	node.emode = ep->emode;
170 	node.expr = ep->expr;
171 	node.elen = ep->elen;
172 	node.value = 0;
173 	node.nosub = 0;
174 	node.ptr = 0;
175 	node.eflag = 0;
176 	if(level++ >=MAXLEVEL)
177 	{
178 		arith_error(e_recursive,ep->expr,ep->emode);
179 		return(0);
180 	}
181 	if(ep->staksize < SMALL_STACK)
182 		sp = small_stack;
183 	else
184 		sp = (Sfdouble_t*)stakalloc(ep->staksize*(sizeof(Sfdouble_t)+1));
185 	tp = (char*)(sp+ep->staksize);
186 	tp--,sp--;
187 	while(c = *cp++)
188 	{
189 		if(c&T_NOFLOAT)
190 		{
191 			if(type==1 || ((c&T_BINARY) && (c&T_OP)!=A_MOD  && tp[-1]==1))
192 				arith_error(e_incompatible,ep->expr,ep->emode);
193 		}
194 		switch(c&T_OP)
195 		{
196 		    case A_JMP: case A_JMPZ: case A_JMPNZ:
197 			c &= T_OP;
198 			cp = roundptr(ep,cp,short);
199 			if((c==A_JMPZ && num) || (c==A_JMPNZ &&!num))
200 				cp += sizeof(short);
201 			else
202 				cp = (unsigned char*)ep + *((short*)cp);
203 			continue;
204 		    case A_NOTNOT:
205 			num = (num!=0);
206 			type=0;
207 			break;
208 		    case A_PLUSPLUS:
209 			node.nosub = -1;
210 			(*ep->fun)(&ptr,&node,ASSIGN,num+1);
211 			break;
212 		    case A_MINUSMINUS:
213 			node.nosub = -1;
214 			(*ep->fun)(&ptr,&node,ASSIGN,num-1);
215 			break;
216 		    case A_INCR:
217 			num = num+1;
218 			node.nosub = -1;
219 			num = (*ep->fun)(&ptr,&node,ASSIGN,num);
220 			break;
221 		    case A_DECR:
222 			num = num-1;
223 			node.nosub = -1;
224 			num = (*ep->fun)(&ptr,&node,ASSIGN,num);
225 			break;
226 		    case A_SWAP:
227 			num = sp[-1];
228 			sp[-1] = *sp;
229 			type = tp[-1];
230 			tp[-1] = *tp;
231 			break;
232 		    case A_POP:
233 			sp--;
234 			continue;
235 		    case A_ASSIGNOP1:
236 			node.emode |= ARITH_ASSIGNOP;
237 			/* FALLTHROUGH */
238 		    case A_PUSHV:
239 			cp = roundptr(ep,cp,Sfdouble_t*);
240 			dp = *((Sfdouble_t**)cp);
241 			cp += sizeof(Sfdouble_t*);
242 			c = *(short*)cp;
243 			cp += sizeof(short);
244 			lastval = node.value = (char*)dp;
245 			if(node.flag = c)
246 				lastval = 0;
247 			node.isfloat=0;
248 			node.level = level;
249 			node.nosub = 0;
250 			num = (*ep->fun)(&ptr,&node,VALUE,num);
251 			if(node.emode&ARITH_ASSIGNOP)
252 			{
253 				lastsub = node.nosub;
254 				node.nosub = 0;
255 				node.emode &= ~ARITH_ASSIGNOP;
256 			}
257 			if(node.value != (char*)dp)
258 				arith_error(node.value,ptr,ep->emode);
259 			*++sp = num;
260 			type = node.isfloat;
261 			if(num > LDBL_ULLONG_MAX || num < LDBL_LLONG_MIN)
262 				type = 1;
263 			else
264 			{
265 				Sfdouble_t d=num;
266 				if(num > LDBL_LLONG_MAX && num <= LDBL_ULLONG_MAX)
267 				{
268 					type = 2;
269 					d -= LDBL_LLONG_MAX;
270 				}
271 				if((Sflong_t)d!=d)
272 					type = 1;
273 			}
274 			*++tp = type;
275 			c = 0;
276 			break;
277 		    case A_ENUM:
278 			node.eflag = 1;
279 			continue;
280 		    case A_ASSIGNOP:
281 			node.nosub = lastsub;
282 			/* FALLTHROUGH */
283 		    case A_STORE:
284 			cp = roundptr(ep,cp,Sfdouble_t*);
285 			dp = *((Sfdouble_t**)cp);
286 			cp += sizeof(Sfdouble_t*);
287 			c = *(short*)cp;
288 			if(c<0)
289 				c = 0;
290 			cp += sizeof(short);
291 			node.value = (char*)dp;
292 			node.flag = c;
293 			if(lastval)
294 				node.eflag = 1;
295 			node.ptr = 0;
296 			num = (*ep->fun)(&ptr,&node,ASSIGN,num);
297 			if(lastval && node.ptr)
298 			{
299 				Sfdouble_t r;
300 				node.flag = 0;
301 				node.value = lastval;
302 				r =  (*ep->fun)(&ptr,&node,VALUE,num);
303 				if(r!=num)
304 				{
305 					node.flag=c;
306 					node.value = (char*)dp;
307 					num = (*ep->fun)(&ptr,&node,ASSIGN,r);
308 				}
309 
310 			}
311 			lastval = 0;
312 			c=0;
313 			break;
314 		    case A_PUSHF:
315 			cp = roundptr(ep,cp,Math_f);
316 			*++sp = (Sfdouble_t)(cp-ep->code);
317 			cp += sizeof(Math_f);
318 			*++tp = *cp++;
319 			continue;
320 		    case A_PUSHN:
321 			cp = roundptr(ep,cp,Sfdouble_t);
322 			num = *((Sfdouble_t*)cp);
323 			cp += sizeof(Sfdouble_t);
324 			*++sp = num;
325 			*++tp = type = *cp++;
326 			break;
327 		    case A_NOT:
328 			type=0;
329 			num = !num;
330 			break;
331 		    case A_UMINUS:
332 			num = -num;
333 			break;
334 		    case A_TILDE:
335 			num = ~((Sflong_t)(num));
336 			break;
337 		    case A_PLUS:
338 			num += sp[-1];
339 			break;
340 		    case A_MINUS:
341 			num = sp[-1] - num;
342 			break;
343 		    case A_TIMES:
344 			num *= sp[-1];
345 			break;
346 		    case A_POW:
347 			num = pow(sp[-1],num);
348 			break;
349 		    case A_MOD:
350 			if(!(Sflong_t)num)
351 				arith_error(e_divzero,ep->expr,ep->emode);
352 			if(type==2 || tp[-1]==2)
353 				num = U2F((Sfulong_t)(sp[-1]) % (Sfulong_t)(num));
354 			else
355 				num = (Sflong_t)(sp[-1]) % (Sflong_t)(num);
356 			break;
357 		    case A_DIV:
358 			if(type==1 || tp[-1]==1)
359 			{
360 				num = sp[-1]/num;
361 				type = 1;
362 			}
363 			else if((Sfulong_t)(num)==0)
364 				arith_error(e_divzero,ep->expr,ep->emode);
365 			else if(type==2 || tp[-1]==2)
366 				num = U2F((Sfulong_t)(sp[-1]) / (Sfulong_t)(num));
367 			else
368 				num = (Sflong_t)(sp[-1]) / (Sflong_t)(num);
369 			break;
370 		    case A_LSHIFT:
371 			if((long)num >= CHAR_BIT*sizeof(Sfulong_t))
372 				num = 0;
373 			else if(tp[-1]==2)
374 				num = U2F((Sfulong_t)(sp[-1]) << (long)(num));
375 			else
376 				num = (Sflong_t)(sp[-1]) << (long)(num);
377 			break;
378 		    case A_RSHIFT:
379 			if((long)num >= CHAR_BIT*sizeof(Sfulong_t))
380 				num = 0;
381 			else if(tp[-1]==2)
382 				num = U2F((Sfulong_t)(sp[-1]) >> (long)(num));
383 			else
384 				num = (Sflong_t)(sp[-1]) >> (long)(num);
385 			break;
386 		    case A_XOR:
387 			if(type==2 || tp[-1]==2)
388 				num = U2F((Sfulong_t)(sp[-1]) ^ (Sfulong_t)(num));
389 			else
390 				num = (Sflong_t)(sp[-1]) ^ (Sflong_t)(num);
391 			break;
392 		    case A_OR:
393 			if(type==2 || tp[-1]==2)
394 				num = U2F((Sfulong_t)(sp[-1]) | (Sfulong_t)(num));
395 			else
396 				num = (Sflong_t)(sp[-1]) | (Sflong_t)(num);
397 			break;
398 		    case A_AND:
399 			if(type==2 || tp[-1]==2)
400 				num = U2F((Sfulong_t)(sp[-1]) & (Sfulong_t)(num));
401 			else
402 				num = (Sflong_t)(sp[-1]) & (Sflong_t)(num);
403 			break;
404 		    case A_EQ:
405 			num = (sp[-1]==num);
406 			type=0;
407 			break;
408 		    case A_NEQ:
409 			num = (sp[-1]!=num);
410 			type=0;
411 			break;
412 		    case A_LE:
413 			num = (sp[-1]<=num);
414 			type=0;
415 			break;
416 		    case A_GE:
417 			num = (sp[-1]>=num);
418 			type=0;
419 			break;
420 		    case A_GT:
421 			num = (sp[-1]>num);
422 			type=0;
423 			break;
424 		    case A_LT:
425 			num = (sp[-1]<num);
426 			type=0;
427 			break;
428 		    case A_CALL1F:
429 			sp--,tp--;
430 			fun = *((Math_f*)(ep->code+(int)(*sp)));
431 			type = *tp;
432 			if(c&T_BINARY)
433 			{
434 				c &= ~T_BINARY;
435 				arg[0] = num;
436 				arg[1] = 0;
437 				num = sh_mathfun(shp,(void*)fun,1,arg);
438 				break;
439 			}
440 			num = (*((Math_1f_f)fun))(num);
441 			break;
442 		    case A_CALL1I:
443 			sp--,tp--;
444 			fun = *((Math_f*)(ep->code+(int)(*sp)));
445 			type = *tp;
446 			num = (*((Math_1i_f)(uintptr_t)fun))(num);
447 			break;
448 		    case A_CALL2F:
449 			sp-=2,tp-=2;
450 			fun = *((Math_f*)(ep->code+(int)(*sp)));
451 			type = *tp;
452 			if(c&T_BINARY)
453 			{
454 				c &= ~T_BINARY;
455 				arg[0] = sp[1];
456 				arg[1] = num;
457 				arg[2] = 0;
458 				num = sh_mathfun(shp,(void*)fun,2,arg);
459 				break;
460 			}
461 			if(c&T_NOFLOAT)
462 				num = (*((Math_2f_i)fun))(sp[1],(int)num);
463 			else
464 				num = (*((Math_2f_f)fun))(sp[1],num);
465 			break;
466 		    case A_CALL2I:
467 			sp-=2,tp-=2;
468 			fun = *((Math_f*)(ep->code+(int)(*sp)));
469 			type = *tp;
470 			num = (*((Math_2i_f)(uintptr_t)fun))(sp[1],num);
471 			break;
472 		    case A_CALL3F:
473 			sp-=3,tp-=3;
474 			fun = *((Math_f*)(ep->code+(int)(*sp)));
475 			type = *tp;
476 			if(c&T_BINARY)
477 			{
478 				c &= ~T_BINARY;
479 				arg[0] = sp[1];
480 				arg[1] = sp[2];
481 				arg[2] = num;
482 				arg[3] = 0;
483 				num = sh_mathfun(shp,(void*)fun,3,arg);
484 				break;
485 			}
486 			num = (*((Math_3f_f)fun))(sp[1],sp[2],num);
487 			break;
488 		}
489 		if(c)
490 			lastval = 0;
491 		if(c&T_BINARY)
492 		{
493 			node.ptr = 0;
494 			sp--,tp--;
495 			type  |= (*tp!=0);
496 		}
497 		*sp = num;
498 		*tp = type;
499 	}
500 	if(level>0)
501 		level--;
502 	if(type==0 && !num)
503 		num = 0;
504 	return(num);
505 }
506 
507 /*
508  * This returns operator tokens or A_REG or A_NUM
509  */
gettok(register struct vars * vp)510 static int gettok(register struct vars *vp)
511 {
512 	register int c,op;
513 	vp->errchr = vp->nextchr;
514 	while(1)
515 	{
516 		c = getchr(vp);
517 		switch(op=getop(c))
518 		{
519 		    case 0:
520 			vp->errchr = vp->nextchr;
521 			continue;
522 		    case A_EOF:
523 			vp->nextchr--;
524 			break;
525 		    case A_COMMA:
526 			if(vp->shp->decomma && (c=peekchr(vp))>='0' && c<='9')
527 			{
528 				op = A_DIG;
529 		    		goto keep;
530 			}
531 			break;
532 		    case A_DOT:
533 			if((c=peekchr(vp))>='0' && c<='9')
534 				op = A_DIG;
535 			else
536 				op = A_REG;
537 			/*FALL THRU*/
538 		    case A_DIG: case A_REG: case A_LIT:
539 		    keep:
540 			ungetchr(vp);
541 			break;
542 		    case A_QUEST:
543 			if(peekchr(vp)==':')
544 			{
545 				getchr(vp);
546 				op = A_QCOLON;
547 			}
548 			break;
549 		    case A_LT:	case A_GT:
550 			if(peekchr(vp)==c)
551 			{
552 				getchr(vp);
553 				op -= 2;
554 				break;
555 			}
556 			/* FALL THRU */
557 		    case A_NOT:	case A_COLON:
558 			c = '=';
559 			/* FALL THRU */
560 		    case A_ASSIGN:
561 		    case A_TIMES:
562 		    case A_PLUS:	case A_MINUS:
563 		    case A_OR:	case A_AND:
564 			if(peekchr(vp)==c)
565 			{
566 				getchr(vp);
567 				op--;
568 			}
569 		}
570 		return(op);
571 	}
572 }
573 
574 /*
575  * evaluate a subexpression with precedence
576  */
577 
expr(register struct vars * vp,register int precedence)578 static int expr(register struct vars *vp,register int precedence)
579 {
580 	register int	c, op;
581 	int		invalid,wasop=0;
582 	struct lval	lvalue,assignop;
583 	const char	*pos;
584 	Sfdouble_t	d;
585 
586 	lvalue.value = 0;
587 	lvalue.nargs = 0;
588 	lvalue.fun = 0;
589 	lvalue.shp =  vp->shp;
590 again:
591 	op = gettok(vp);
592 	c = 2*MAXPREC+1;
593 	switch(op)
594 	{
595 	    case A_PLUS:
596 		goto again;
597 	    case A_EOF:
598 		if(precedence>2)
599 			ERROR(vp,e_moretokens);
600 		return(1);
601 	    case A_MINUS:
602 		op =  A_UMINUS;
603 		goto common;
604 	    case A_NOT:
605 		goto common;
606 	    case A_MINUSMINUS:
607 		c = A_LVALUE;
608 		op = A_DECR|T_NOFLOAT;
609 		goto common;
610 	    case A_PLUSPLUS:
611 		c = A_LVALUE;
612 		op = A_INCR|T_NOFLOAT;
613 		/* FALL THRU */
614 	    case A_TILDE:
615 		op |= T_NOFLOAT;
616 	    common:
617 		if(!expr(vp,c))
618 			return(0);
619 		stakputc(op);
620 		break;
621 	    default:
622 		vp->nextchr = vp->errchr;
623 		wasop = 1;
624 	}
625 	invalid = wasop;
626 	while(1)
627 	{
628 		assignop.value = 0;
629 		op = gettok(vp);
630 		if(op==A_DIG || op==A_REG || op==A_LIT)
631 		{
632 			if(!wasop)
633 				ERROR(vp,e_synbad);
634 			goto number;
635 		}
636 		if(wasop++ && op!=A_LPAR)
637 			ERROR(vp,e_synbad);
638 		/* check for assignment operation */
639 		if(peekchr(vp)== '=' && !(strval_precedence[op]&NOASSIGN))
640 		{
641 			if((!lvalue.value || precedence > 3))
642 				ERROR(vp,e_notlvalue);
643 			if(precedence==3)
644 				precedence = 2;
645 			assignop = lvalue;
646 			getchr(vp);
647 			c = 3;
648 		}
649 		else
650 		{
651 			c = (strval_precedence[op]&PRECMASK);
652 			if(c==MAXPREC || op==A_POW)
653 				c++;
654 			c *= 2;
655 		}
656 		/* from here on c is the new precedence level */
657 		if(lvalue.value && (op!=A_ASSIGN))
658 		{
659 			if(vp->staksize++>=vp->stakmaxsize)
660 				vp->stakmaxsize = vp->staksize;
661 			if(op==A_EQ || op==A_NEQ)
662 				stakputc(A_ENUM);
663 			stakputc(assignop.value?A_ASSIGNOP1:A_PUSHV);
664 			stakpush(vp,lvalue.value,char*);
665 			if(lvalue.flag<0)
666 				lvalue.flag = 0;
667 			stakpush(vp,lvalue.flag,short);
668 			if(vp->nextchr==0)
669 				ERROR(vp,e_badnum);
670 			if(!(strval_precedence[op]&SEQPOINT))
671 				lvalue.value = 0;
672 			invalid = 0;
673 		}
674 		else if(precedence==A_LVALUE)
675 			ERROR(vp,e_notlvalue);
676 		if(invalid && op>A_ASSIGN)
677 			ERROR(vp,e_synbad);
678 		if(precedence >= c)
679 			goto done;
680 		if(strval_precedence[op]&RASSOC)
681 			c--;
682 		if((c < (2*MAXPREC+1)) && !(strval_precedence[op]&SEQPOINT))
683 		{
684 			wasop = 0;
685 			if(!expr(vp,c))
686 				return(0);
687 		}
688 		switch(op)
689 		{
690 		case A_RPAR:
691 			if(!vp->paren)
692 				ERROR(vp,e_paren);
693 			if(invalid)
694 				ERROR(vp,e_synbad);
695 			goto done;
696 
697 		case A_COMMA:
698 			wasop = 0;
699 			if(vp->infun)
700 				vp->infun++;
701 			else
702 			{
703 				stakputc(A_POP);
704 				vp->staksize--;
705 			}
706 			if(!expr(vp,c))
707 			{
708 				stakseek(staktell()-1);
709 				return(0);
710 			}
711 			lvalue.value = 0;
712 			break;
713 
714 		case A_LPAR:
715 		{
716 			int	infun = vp->infun;
717 			int	userfun=0;
718 			Sfdouble_t (*fun)(Sfdouble_t,...);
719 			int nargs = lvalue.nargs;
720 			if(nargs<0)
721 				nargs = -nargs;
722 			fun = lvalue.fun;
723 			lvalue.fun = 0;
724 			if(fun)
725 			{
726 				if(vp->staksize++>=vp->stakmaxsize)
727 					vp->stakmaxsize = vp->staksize;
728 				vp->infun=1;
729 				if((int)lvalue.nargs<0)
730 					userfun = T_BINARY;
731 				else if((int)lvalue.nargs&040)
732 					userfun = T_NOFLOAT;
733 				stakputc(A_PUSHF);
734 				stakpush(vp,fun,Math_f);
735 				stakputc(1);
736 			}
737 			else
738 				vp->infun = 0;
739 			if(!invalid)
740 				ERROR(vp,e_synbad);
741 			vp->paren++;
742 			if(!expr(vp,1))
743 				return(0);
744 			vp->paren--;
745 			if(fun)
746 			{
747 				int  x= (nargs&010)?2:-1;
748 				nargs &= 7;
749 				if(vp->infun != nargs)
750 					ERROR(vp,e_argcount);
751 				if((vp->staksize+=nargs)>=vp->stakmaxsize)
752 					vp->stakmaxsize = vp->staksize+nargs;
753 				stakputc(A_CALL1F+userfun+nargs+x);
754 				vp->staksize -= nargs;
755 			}
756 			vp->infun = infun;
757 			if (gettok(vp) != A_RPAR)
758 				ERROR(vp,e_paren);
759 			wasop = 0;
760 			break;
761 		}
762 
763 		case A_PLUSPLUS:
764 		case A_MINUSMINUS:
765 			wasop=0;
766 			op |= T_NOFLOAT;
767 			/* FALLTHROUGH */
768 		case A_ASSIGN:
769 			if(!lvalue.value)
770 				ERROR(vp,e_notlvalue);
771 			if(op==A_ASSIGN)
772 			{
773 				stakputc(A_STORE);
774 				stakpush(vp,lvalue.value,char*);
775 				stakpush(vp,lvalue.flag,short);
776 				vp->staksize--;
777 			}
778 			else
779 				stakputc(op);
780 			lvalue.value = 0;
781 			break;
782 
783 		case A_QUEST:
784 		{
785 			int offset1,offset2;
786 			stakputc(A_JMPZ);
787 			offset1 = stakpush(vp,0,short);
788 			stakputc(A_POP);
789 			if(!expr(vp,1))
790 				return(0);
791 			if(gettok(vp)!=A_COLON)
792 				ERROR(vp,e_questcolon);
793 			stakputc(A_JMP);
794 			offset2 = stakpush(vp,0,short);
795 			*((short*)stakptr(offset1)) = staktell();
796 			stakputc(A_POP);
797 			if(!expr(vp,3))
798 				return(0);
799 			*((short*)stakptr(offset2)) = staktell();
800 			lvalue.value = 0;
801 			wasop = 0;
802 			break;
803 		}
804 
805 		case A_COLON:
806 			ERROR(vp,e_badcolon);
807 			break;
808 
809 		case A_QCOLON:
810 		case A_ANDAND:
811 		case A_OROR:
812 		{
813 			int offset;
814 			if(op==A_ANDAND)
815 				op = A_JMPZ;
816 			else
817 				op = A_JMPNZ;
818 			stakputc(op);
819 			offset = stakpush(vp,0,short);
820 			stakputc(A_POP);
821 			if(!expr(vp,c))
822 				return(0);
823 			*((short*)stakptr(offset)) = staktell();
824 			if(op!=A_QCOLON)
825 				stakputc(A_NOTNOT);
826 			lvalue.value = 0;
827 			wasop=0;
828 			break;
829 		}
830 		case A_AND:	case A_OR:	case A_XOR:	case A_LSHIFT:
831 		case A_RSHIFT:	case A_MOD:
832 			op |= T_NOFLOAT;
833 			/* FALL THRU */
834 		case A_PLUS:	case A_MINUS:	case A_TIMES:	case A_DIV:
835 		case A_EQ:	case A_NEQ:	case A_LT:	case A_LE:
836 		case A_GT:	case A_GE:	case A_POW:
837 			stakputc(op|T_BINARY);
838 			vp->staksize--;
839 			break;
840 		case A_NOT: case A_TILDE:
841 		default:
842 			ERROR(vp,e_synbad);
843 		number:
844 			wasop = 0;
845 			if(*vp->nextchr=='L' && vp->nextchr[1]=='\'')
846 			{
847 				vp->nextchr++;
848 				op = A_LIT;
849 			}
850 			pos = vp->nextchr;
851 			lvalue.isfloat = 0;
852 			lvalue.expr = vp->expr;
853 			lvalue.emode = vp->emode;
854 			if(op==A_LIT)
855 			{
856 				/* character constants */
857 				if(pos[1]=='\\' && pos[2]=='\'' && pos[3]!='\'')
858 				{
859 					d = '\\';
860 					vp->nextchr +=2;
861 				}
862 				else
863 					d = chresc(pos+1,(char**)&vp->nextchr);
864 				/* posix allows the trailing ' to be optional */
865 				if(*vp->nextchr=='\'')
866 					vp->nextchr++;
867 			}
868 			else
869 				d = (*vp->convert)(&vp->nextchr, &lvalue, LOOKUP, 0);
870 			if (vp->nextchr == pos)
871 			{
872 				if(vp->errmsg.value = lvalue.value)
873 					vp->errstr = pos;
874 				ERROR(vp,op==A_LIT?e_charconst:e_synbad);
875 			}
876 			if(op==A_DIG || op==A_LIT)
877 			{
878 				stakputc(A_PUSHN);
879 				if(vp->staksize++>=vp->stakmaxsize)
880 					vp->stakmaxsize = vp->staksize;
881 				stakpush(vp,d,Sfdouble_t);
882 				stakputc(lvalue.isfloat);
883 			}
884 
885 			/* check for function call */
886 			if(lvalue.fun)
887 				continue;
888 			break;
889 		}
890 		invalid = 0;
891 		if(assignop.value)
892 		{
893 			if(vp->staksize++>=vp->stakmaxsize)
894 				vp->stakmaxsize = vp->staksize;
895 			if(assignop.flag<0)
896 				assignop.flag = 0;
897 			stakputc(c&1?A_ASSIGNOP:A_STORE);
898 			stakpush(vp,assignop.value,char*);
899 			stakpush(vp,assignop.flag,short);
900 		}
901 	}
902  done:
903 	vp->nextchr = vp->errchr;
904 	return(1);
905 }
906 
arith_compile(Shell_t * shp,const char * string,char ** last,Sfdouble_t (* fun)(const char **,struct lval *,int,Sfdouble_t),int emode)907 Arith_t *arith_compile(Shell_t *shp,const char *string,char **last,Sfdouble_t(*fun)(const char**,struct lval*,int,Sfdouble_t),int emode)
908 {
909 	struct vars cur;
910 	register Arith_t *ep;
911 	int offset;
912 	memset((void*)&cur,0,sizeof(cur));
913 	cur.shp = shp;
914      	cur.expr = cur.nextchr = string;
915 	cur.convert = fun;
916 	cur.emode = emode;
917 	cur.errmsg.value = 0;
918 	cur.errmsg.emode = emode;
919 	stakseek(sizeof(Arith_t));
920 	if(!expr(&cur,0) && cur.errmsg.value)
921         {
922 		if(cur.errstr)
923 			string = cur.errstr;
924 		if((*fun)( &string , &cur.errmsg, MESSAGE, 0) < 0)
925 		{
926 			stakseek(0);
927 			*last = (char*)Empty;
928 			return(0);
929 		}
930 		cur.nextchr = cur.errchr;
931 	}
932 	stakputc(0);
933 	offset = staktell();
934 	ep = (Arith_t*)stakfreeze(0);
935 	ep->shp = shp;
936 	ep->expr = string;
937 	ep->elen = strlen(string);
938 	ep->code = (unsigned char*)(ep+1);
939 	ep->fun = fun;
940 	ep->emode = emode;
941 	ep->size = offset - sizeof(Arith_t);
942 	ep->staksize = cur.stakmaxsize+1;
943 	if(last)
944 		*last = (char*)(cur.nextchr);
945 	return(ep);
946 }
947 
948 /*
949  * evaluate an integer arithmetic expression in s
950  *
951  * (Sfdouble_t)(*convert)(char** end, struct lval* string, int type, Sfdouble_t value)
952  *     is a user supplied conversion routine that is called when unknown
953  *     chars are encountered.
954  * *end points to the part to be converted and must be adjusted by convert to
955  * point to the next non-converted character; if typ is MESSAGE then string
956  * points to an error message string
957  *
958  * NOTE: (*convert)() may call strval()
959  */
960 
strval(Shell_t * shp,const char * s,char ** end,Sfdouble_t (* conv)(const char **,struct lval *,int,Sfdouble_t),int emode)961 Sfdouble_t strval(Shell_t *shp,const char *s,char **end,Sfdouble_t(*conv)(const char**,struct lval*,int,Sfdouble_t),int emode)
962 {
963 	Arith_t *ep;
964 	Sfdouble_t d;
965 	char *sp=0;
966 	int offset;
967 	if(offset=staktell())
968 		sp = stakfreeze(1);
969 	ep = arith_compile(shp,s,end,conv,emode);
970 	ep->emode = emode;
971 	d = arith_exec(ep);
972 	stakset(sp?sp:(char*)ep,offset);
973 	return(d);
974 }
975 
976 #if _mem_name__exception
977 #undef	_mem_name_exception
978 #define	_mem_name_exception	1
979 #undef	exception
980 #define	exception		_exception
981 #undef	matherr
982 #endif
983 
984 #if _mem_name_exception
985 
986 #undef	error
987 
988 #if _BLD_shell && defined(__EXPORT__)
989 #define extern			__EXPORT__
990 #endif
991 
992 #ifndef DOMAIN
993 #define DOMAIN			_DOMAIN
994 #endif
995 #ifndef OVERFLOW
996 #define OVERFLOW		_OVERFLOW
997 #endif
998 #ifndef SING
999 #define SING			_SING
1000 #endif
1001 
matherr(struct exception * ep)1002     extern int matherr(struct exception *ep)
1003     {
1004 	const char *message;
1005 	switch(ep->type)
1006 	{
1007 #ifdef DOMAIN
1008 	    case DOMAIN:
1009 		message = ERROR_dictionary(e_domain);
1010 		break;
1011 #endif
1012 #ifdef OVERFLOW
1013 	    case OVERFLOW:
1014 		message = ERROR_dictionary(e_overflow);
1015 		break;
1016 #endif
1017 #ifdef SING
1018 	    case SING:
1019 		message = ERROR_dictionary(e_singularity);
1020 		break;
1021 #endif
1022 	    default:
1023 		return(1);
1024 	}
1025 	level=0;
1026 	errormsg(SH_DICT,ERROR_exit(1),message,ep->name);
1027 	return(0);
1028     }
1029 
1030 #undef	extern
1031 
1032 #endif /* _mem_name_exception */
1033