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 		    case A_PUSHV:
238 			cp = roundptr(ep,cp,Sfdouble_t*);
239 			dp = *((Sfdouble_t**)cp);
240 			cp += sizeof(Sfdouble_t*);
241 			c = *(short*)cp;
242 			cp += sizeof(short);
243 			lastval = node.value = (char*)dp;
244 			if(node.flag = c)
245 				lastval = 0;
246 			node.isfloat=0;
247 			node.level = level;
248 			node.nosub = 0;
249 			num = (*ep->fun)(&ptr,&node,VALUE,num);
250 			if(node.emode&ARITH_ASSIGNOP)
251 			{
252 				lastsub = node.nosub;
253 				node.nosub = 0;
254 				node.emode &= ~ARITH_ASSIGNOP;
255 			}
256 			if(node.value != (char*)dp)
257 				arith_error(node.value,ptr,ep->emode);
258 			*++sp = num;
259 			type = node.isfloat;
260 			if(num > LDBL_ULLONG_MAX || num < LDBL_LLONG_MIN)
261 				type = 1;
262 			else
263 			{
264 				Sfdouble_t d=num;
265 				if(num > LDBL_LLONG_MAX && num <= LDBL_ULLONG_MAX)
266 				{
267 					type = 2;
268 					d -= LDBL_LLONG_MAX;
269 				}
270 				if((Sflong_t)d!=d)
271 					type = 1;
272 			}
273 			*++tp = type;
274 			c = 0;
275 			break;
276 		    case A_ENUM:
277 			node.eflag = 1;
278 			continue;
279 		    case A_ASSIGNOP:
280 			node.nosub = lastsub;
281 		    case A_STORE:
282 			cp = roundptr(ep,cp,Sfdouble_t*);
283 			dp = *((Sfdouble_t**)cp);
284 			cp += sizeof(Sfdouble_t*);
285 			c = *(short*)cp;
286 			if(c<0)
287 				c = 0;
288 			cp += sizeof(short);
289 			node.value = (char*)dp;
290 			node.flag = c;
291 			if(lastval)
292 				node.eflag = 1;
293 			node.ptr = 0;
294 			num = (*ep->fun)(&ptr,&node,ASSIGN,num);
295 			if(lastval && node.ptr)
296 			{
297 				Sfdouble_t r;
298 				node.flag = 0;
299 				node.value = lastval;
300 				r =  (*ep->fun)(&ptr,&node,VALUE,num);
301 				if(r!=num)
302 				{
303 					node.flag=c;
304 					node.value = (char*)dp;
305 					num = (*ep->fun)(&ptr,&node,ASSIGN,r);
306 				}
307 
308 			}
309 			lastval = 0;
310 			c=0;
311 			break;
312 		    case A_PUSHF:
313 			cp = roundptr(ep,cp,Math_f);
314 			*++sp = (Sfdouble_t)(cp-ep->code);
315 			cp += sizeof(Math_f);
316 			*++tp = *cp++;
317 			continue;
318 		    case A_PUSHN:
319 			cp = roundptr(ep,cp,Sfdouble_t);
320 			num = *((Sfdouble_t*)cp);
321 			cp += sizeof(Sfdouble_t);
322 			*++sp = num;
323 			*++tp = type = *cp++;
324 			break;
325 		    case A_NOT:
326 			type=0;
327 			num = !num;
328 			break;
329 		    case A_UMINUS:
330 			num = -num;
331 			break;
332 		    case A_TILDE:
333 			num = ~((Sflong_t)(num));
334 			break;
335 		    case A_PLUS:
336 			num += sp[-1];
337 			break;
338 		    case A_MINUS:
339 			num = sp[-1] - num;
340 			break;
341 		    case A_TIMES:
342 			num *= sp[-1];
343 			break;
344 		    case A_POW:
345 			num = pow(sp[-1],num);
346 			break;
347 		    case A_MOD:
348 			if(!(Sflong_t)num)
349 				arith_error(e_divzero,ep->expr,ep->emode);
350 			if(type==2 || tp[-1]==2)
351 				num = U2F((Sfulong_t)(sp[-1]) % (Sfulong_t)(num));
352 			else
353 				num = (Sflong_t)(sp[-1]) % (Sflong_t)(num);
354 			break;
355 		    case A_DIV:
356 			if(type==1 || tp[-1]==1)
357 			{
358 				num = sp[-1]/num;
359 				type = 1;
360 			}
361 			else if((Sfulong_t)(num)==0)
362 				arith_error(e_divzero,ep->expr,ep->emode);
363 			else if(type==2 || tp[-1]==2)
364 				num = U2F((Sfulong_t)(sp[-1]) / (Sfulong_t)(num));
365 			else
366 				num = (Sflong_t)(sp[-1]) / (Sflong_t)(num);
367 			break;
368 		    case A_LSHIFT:
369 			if(tp[-1]==2)
370 				num = U2F((Sfulong_t)(sp[-1]) << (long)(num));
371 			else
372 				num = (Sflong_t)(sp[-1]) << (long)(num);
373 			break;
374 		    case A_RSHIFT:
375 			if(tp[-1]==2)
376 				num = U2F((Sfulong_t)(sp[-1]) >> (long)(num));
377 			else
378 				num = (Sflong_t)(sp[-1]) >> (long)(num);
379 			break;
380 		    case A_XOR:
381 			if(type==2 || tp[-1]==2)
382 				num = U2F((Sfulong_t)(sp[-1]) ^ (Sfulong_t)(num));
383 			else
384 				num = (Sflong_t)(sp[-1]) ^ (Sflong_t)(num);
385 			break;
386 		    case A_OR:
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_AND:
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_EQ:
399 			num = (sp[-1]==num);
400 			type=0;
401 			break;
402 		    case A_NEQ:
403 			num = (sp[-1]!=num);
404 			type=0;
405 			break;
406 		    case A_LE:
407 			num = (sp[-1]<=num);
408 			type=0;
409 			break;
410 		    case A_GE:
411 			num = (sp[-1]>=num);
412 			type=0;
413 			break;
414 		    case A_GT:
415 			num = (sp[-1]>num);
416 			type=0;
417 			break;
418 		    case A_LT:
419 			num = (sp[-1]<num);
420 			type=0;
421 			break;
422 		    case A_CALL1F:
423 			sp--,tp--;
424 			fun = *((Math_f*)(ep->code+(int)(*sp)));
425 			type = *tp;
426 			if(c&T_BINARY)
427 			{
428 				c &= ~T_BINARY;
429 				arg[0] = num;
430 				arg[1] = 0;
431 				num = sh_mathfun(shp,(void*)fun,1,arg);
432 				break;
433 			}
434 			num = (*((Math_1f_f)fun))(num);
435 			break;
436 		    case A_CALL1I:
437 			sp--,tp--;
438 			fun = *((Math_f*)(ep->code+(int)(*sp)));
439 			type = *tp;
440 			num = (*((Math_1i_f)fun))(num);
441 			break;
442 		    case A_CALL2F:
443 			sp-=2,tp-=2;
444 			fun = *((Math_f*)(ep->code+(int)(*sp)));
445 			type = *tp;
446 			if(c&T_BINARY)
447 			{
448 				c &= ~T_BINARY;
449 				arg[0] = sp[1];
450 				arg[1] = num;
451 				arg[2] = 0;
452 				num = sh_mathfun(shp,(void*)fun,2,arg);
453 				break;
454 			}
455 			if(c&T_NOFLOAT)
456 				num = (*((Math_2f_i)fun))(sp[1],(int)num);
457 			else
458 				num = (*((Math_2f_f)fun))(sp[1],num);
459 			break;
460 		    case A_CALL2I:
461 			sp-=2,tp-=2;
462 			fun = *((Math_f*)(ep->code+(int)(*sp)));
463 			type = *tp;
464 			num = (*((Math_2i_f)fun))(sp[1],num);
465 			break;
466 		    case A_CALL3F:
467 			sp-=3,tp-=3;
468 			fun = *((Math_f*)(ep->code+(int)(*sp)));
469 			type = *tp;
470 			if(c&T_BINARY)
471 			{
472 				c &= ~T_BINARY;
473 				arg[0] = sp[1];
474 				arg[1] = sp[2];
475 				arg[2] = num;
476 				arg[3] = 0;
477 				num = sh_mathfun(shp,(void*)fun,3,arg);
478 				break;
479 			}
480 			num = (*((Math_3f_f)fun))(sp[1],sp[2],num);
481 			break;
482 		}
483 		if(c)
484 			lastval = 0;
485 		if(c&T_BINARY)
486 		{
487 			node.ptr = 0;
488 			sp--,tp--;
489 			type  |= (*tp!=0);
490 		}
491 		*sp = num;
492 		*tp = type;
493 	}
494 	if(level>0)
495 		level--;
496 	if(type==0 && !num)
497 		num = 0;
498 	return(num);
499 }
500 
501 /*
502  * This returns operator tokens or A_REG or A_NUM
503  */
gettok(register struct vars * vp)504 static int gettok(register struct vars *vp)
505 {
506 	register int c,op;
507 	vp->errchr = vp->nextchr;
508 	while(1)
509 	{
510 		c = getchr(vp);
511 		switch(op=getop(c))
512 		{
513 		    case 0:
514 			vp->errchr = vp->nextchr;
515 			continue;
516 		    case A_EOF:
517 			vp->nextchr--;
518 			break;
519 		    case A_COMMA:
520 			if(vp->shp->decomma && (c=peekchr(vp))>='0' && c<='9')
521 			{
522 				op = A_DIG;
523 		    		goto keep;
524 			}
525 			break;
526 		    case A_DOT:
527 			if((c=peekchr(vp))>='0' && c<='9')
528 				op = A_DIG;
529 			else
530 				op = A_REG;
531 			/*FALL THRU*/
532 		    case A_DIG: case A_REG: case A_LIT:
533 		    keep:
534 			ungetchr(vp);
535 			break;
536 		    case A_QUEST:
537 			if(peekchr(vp)==':')
538 			{
539 				getchr(vp);
540 				op = A_QCOLON;
541 			}
542 			break;
543 		    case A_LT:	case A_GT:
544 			if(peekchr(vp)==c)
545 			{
546 				getchr(vp);
547 				op -= 2;
548 				break;
549 			}
550 			/* FALL THRU */
551 		    case A_NOT:	case A_COLON:
552 			c = '=';
553 			/* FALL THRU */
554 		    case A_ASSIGN:
555 		    case A_TIMES:
556 		    case A_PLUS:	case A_MINUS:
557 		    case A_OR:	case A_AND:
558 			if(peekchr(vp)==c)
559 			{
560 				getchr(vp);
561 				op--;
562 			}
563 		}
564 		return(op);
565 	}
566 }
567 
568 /*
569  * evaluate a subexpression with precedence
570  */
571 
expr(register struct vars * vp,register int precedence)572 static int expr(register struct vars *vp,register int precedence)
573 {
574 	register int	c, op;
575 	int		invalid,wasop=0;
576 	struct lval	lvalue,assignop;
577 	const char	*pos;
578 	Sfdouble_t	d;
579 
580 	lvalue.value = 0;
581 	lvalue.nargs = 0;
582 	lvalue.fun = 0;
583 	lvalue.shp =  vp->shp;
584 again:
585 	op = gettok(vp);
586 	c = 2*MAXPREC+1;
587 	switch(op)
588 	{
589 	    case A_PLUS:
590 		goto again;
591 	    case A_EOF:
592 		if(precedence>2)
593 			ERROR(vp,e_moretokens);
594 		return(1);
595 	    case A_MINUS:
596 		op =  A_UMINUS;
597 		goto common;
598 	    case A_NOT:
599 		goto common;
600 	    case A_MINUSMINUS:
601 		c = A_LVALUE;
602 		op = A_DECR|T_NOFLOAT;
603 		goto common;
604 	    case A_PLUSPLUS:
605 		c = A_LVALUE;
606 		op = A_INCR|T_NOFLOAT;
607 		/* FALL THRU */
608 	    case A_TILDE:
609 		op |= T_NOFLOAT;
610 	    common:
611 		if(!expr(vp,c))
612 			return(0);
613 		stakputc(op);
614 		break;
615 	    default:
616 		vp->nextchr = vp->errchr;
617 		wasop = 1;
618 	}
619 	invalid = wasop;
620 	while(1)
621 	{
622 		assignop.value = 0;
623 		op = gettok(vp);
624 		if(op==A_DIG || op==A_REG || op==A_LIT)
625 		{
626 			if(!wasop)
627 				ERROR(vp,e_synbad);
628 			goto number;
629 		}
630 		if(wasop++ && op!=A_LPAR)
631 			ERROR(vp,e_synbad);
632 		/* check for assignment operation */
633 		if(peekchr(vp)== '=' && !(strval_precedence[op]&NOASSIGN))
634 		{
635 			if((!lvalue.value || precedence > 3))
636 				ERROR(vp,e_notlvalue);
637 			if(precedence==3)
638 				precedence = 2;
639 			assignop = lvalue;
640 			getchr(vp);
641 			c = 3;
642 		}
643 		else
644 		{
645 			c = (strval_precedence[op]&PRECMASK);
646 			if(c==MAXPREC || op==A_POW)
647 				c++;
648 			c *= 2;
649 		}
650 		/* from here on c is the new precedence level */
651 		if(lvalue.value && (op!=A_ASSIGN))
652 		{
653 			if(vp->staksize++>=vp->stakmaxsize)
654 				vp->stakmaxsize = vp->staksize;
655 			if(op==A_EQ || op==A_NEQ)
656 				stakputc(A_ENUM);
657 			stakputc(assignop.value?A_ASSIGNOP1:A_PUSHV);
658 			stakpush(vp,lvalue.value,char*);
659 			if(lvalue.flag<0)
660 				lvalue.flag = 0;
661 			stakpush(vp,lvalue.flag,short);
662 			if(vp->nextchr==0)
663 				ERROR(vp,e_badnum);
664 			if(!(strval_precedence[op]&SEQPOINT))
665 				lvalue.value = 0;
666 			invalid = 0;
667 		}
668 		else if(precedence==A_LVALUE)
669 			ERROR(vp,e_notlvalue);
670 		if(invalid && op>A_ASSIGN)
671 			ERROR(vp,e_synbad);
672 		if(precedence >= c)
673 			goto done;
674 		if(strval_precedence[op]&RASSOC)
675 			c--;
676 		if((c < (2*MAXPREC+1)) && !(strval_precedence[op]&SEQPOINT))
677 		{
678 			wasop = 0;
679 			if(!expr(vp,c))
680 				return(0);
681 		}
682 		switch(op)
683 		{
684 		case A_RPAR:
685 			if(!vp->paren)
686 				ERROR(vp,e_paren);
687 			if(invalid)
688 				ERROR(vp,e_synbad);
689 			goto done;
690 
691 		case A_COMMA:
692 			wasop = 0;
693 			if(vp->infun)
694 				vp->infun++;
695 			else
696 			{
697 				stakputc(A_POP);
698 				vp->staksize--;
699 			}
700 			if(!expr(vp,c))
701 			{
702 				stakseek(staktell()-1);
703 				return(0);
704 			}
705 			lvalue.value = 0;
706 			break;
707 
708 		case A_LPAR:
709 		{
710 			int	infun = vp->infun;
711 			int	userfun=0;
712 			Sfdouble_t (*fun)(Sfdouble_t,...);
713 			int nargs = lvalue.nargs;
714 			if(nargs<0)
715 				nargs = -nargs;
716 			fun = lvalue.fun;
717 			lvalue.fun = 0;
718 			if(fun)
719 			{
720 				if(vp->staksize++>=vp->stakmaxsize)
721 					vp->stakmaxsize = vp->staksize;
722 				vp->infun=1;
723 				if((int)lvalue.nargs<0)
724 					userfun = T_BINARY;
725 				else if((int)lvalue.nargs&040)
726 					userfun = T_NOFLOAT;
727 				stakputc(A_PUSHF);
728 				stakpush(vp,fun,Math_f);
729 				stakputc(1);
730 			}
731 			else
732 				vp->infun = 0;
733 			if(!invalid)
734 				ERROR(vp,e_synbad);
735 			vp->paren++;
736 			if(!expr(vp,1))
737 				return(0);
738 			vp->paren--;
739 			if(fun)
740 			{
741 				int  x= (nargs&010)?2:-1;
742 				nargs &= 7;
743 				if(vp->infun != nargs)
744 					ERROR(vp,e_argcount);
745 				if((vp->staksize+=nargs)>=vp->stakmaxsize)
746 					vp->stakmaxsize = vp->staksize+nargs;
747 				stakputc(A_CALL1F+userfun+nargs+x);
748 				vp->staksize -= nargs;
749 			}
750 			vp->infun = infun;
751 			if (gettok(vp) != A_RPAR)
752 				ERROR(vp,e_paren);
753 			wasop = 0;
754 			break;
755 		}
756 
757 		case A_PLUSPLUS:
758 		case A_MINUSMINUS:
759 			wasop=0;
760 			op |= T_NOFLOAT;
761 		case A_ASSIGN:
762 			if(!lvalue.value)
763 				ERROR(vp,e_notlvalue);
764 			if(op==A_ASSIGN)
765 			{
766 				stakputc(A_STORE);
767 				stakpush(vp,lvalue.value,char*);
768 				stakpush(vp,lvalue.flag,short);
769 				vp->staksize--;
770 			}
771 			else
772 				stakputc(op);
773 			lvalue.value = 0;
774 			break;
775 
776 		case A_QUEST:
777 		{
778 			int offset1,offset2;
779 			stakputc(A_JMPZ);
780 			offset1 = stakpush(vp,0,short);
781 			stakputc(A_POP);
782 			if(!expr(vp,1))
783 				return(0);
784 			if(gettok(vp)!=A_COLON)
785 				ERROR(vp,e_questcolon);
786 			stakputc(A_JMP);
787 			offset2 = stakpush(vp,0,short);
788 			*((short*)stakptr(offset1)) = staktell();
789 			stakputc(A_POP);
790 			if(!expr(vp,3))
791 				return(0);
792 			*((short*)stakptr(offset2)) = staktell();
793 			lvalue.value = 0;
794 			wasop = 0;
795 			break;
796 		}
797 
798 		case A_COLON:
799 			ERROR(vp,e_badcolon);
800 			break;
801 
802 		case A_QCOLON:
803 		case A_ANDAND:
804 		case A_OROR:
805 		{
806 			int offset;
807 			if(op==A_ANDAND)
808 				op = A_JMPZ;
809 			else
810 				op = A_JMPNZ;
811 			stakputc(op);
812 			offset = stakpush(vp,0,short);
813 			stakputc(A_POP);
814 			if(!expr(vp,c))
815 				return(0);
816 			*((short*)stakptr(offset)) = staktell();
817 			if(op!=A_QCOLON)
818 				stakputc(A_NOTNOT);
819 			lvalue.value = 0;
820 			wasop=0;
821 			break;
822 		}
823 		case A_AND:	case A_OR:	case A_XOR:	case A_LSHIFT:
824 		case A_RSHIFT:	case A_MOD:
825 			op |= T_NOFLOAT;
826 			/* FALL THRU */
827 		case A_PLUS:	case A_MINUS:	case A_TIMES:	case A_DIV:
828 		case A_EQ:	case A_NEQ:	case A_LT:	case A_LE:
829 		case A_GT:	case A_GE:	case A_POW:
830 			stakputc(op|T_BINARY);
831 			vp->staksize--;
832 			break;
833 		case A_NOT: case A_TILDE:
834 		default:
835 			ERROR(vp,e_synbad);
836 		number:
837 			wasop = 0;
838 			if(*vp->nextchr=='L' && vp->nextchr[1]=='\'')
839 			{
840 				vp->nextchr++;
841 				op = A_LIT;
842 			}
843 			pos = vp->nextchr;
844 			lvalue.isfloat = 0;
845 			lvalue.expr = vp->expr;
846 			lvalue.emode = vp->emode;
847 			if(op==A_LIT)
848 			{
849 				/* character constants */
850 				if(pos[1]=='\\' && pos[2]=='\'' && pos[3]!='\'')
851 				{
852 					d = '\\';
853 					vp->nextchr +=2;
854 				}
855 				else
856 					d = chresc(pos+1,(char**)&vp->nextchr);
857 				/* posix allows the trailing ' to be optional */
858 				if(*vp->nextchr=='\'')
859 					vp->nextchr++;
860 			}
861 			else
862 				d = (*vp->convert)(&vp->nextchr, &lvalue, LOOKUP, 0);
863 			if (vp->nextchr == pos)
864 			{
865 				if(vp->errmsg.value = lvalue.value)
866 					vp->errstr = pos;
867 				ERROR(vp,op==A_LIT?e_charconst:e_synbad);
868 			}
869 			if(op==A_DIG || op==A_LIT)
870 			{
871 				stakputc(A_PUSHN);
872 				if(vp->staksize++>=vp->stakmaxsize)
873 					vp->stakmaxsize = vp->staksize;
874 				stakpush(vp,d,Sfdouble_t);
875 				stakputc(lvalue.isfloat);
876 			}
877 
878 			/* check for function call */
879 			if(lvalue.fun)
880 				continue;
881 			break;
882 		}
883 		invalid = 0;
884 		if(assignop.value)
885 		{
886 			if(vp->staksize++>=vp->stakmaxsize)
887 				vp->stakmaxsize = vp->staksize;
888 			if(assignop.flag<0)
889 				assignop.flag = 0;
890 			stakputc(c&1?A_ASSIGNOP:A_STORE);
891 			stakpush(vp,assignop.value,char*);
892 			stakpush(vp,assignop.flag,short);
893 		}
894 	}
895  done:
896 	vp->nextchr = vp->errchr;
897 	return(1);
898 }
899 
arith_compile(Shell_t * shp,const char * string,char ** last,Sfdouble_t (* fun)(const char **,struct lval *,int,Sfdouble_t),int emode)900 Arith_t *arith_compile(Shell_t *shp,const char *string,char **last,Sfdouble_t(*fun)(const char**,struct lval*,int,Sfdouble_t),int emode)
901 {
902 	struct vars cur;
903 	register Arith_t *ep;
904 	int offset;
905 	memset((void*)&cur,0,sizeof(cur));
906 	cur.shp = shp;
907      	cur.expr = cur.nextchr = string;
908 	cur.convert = fun;
909 	cur.emode = emode;
910 	cur.errmsg.value = 0;
911 	cur.errmsg.emode = emode;
912 	stakseek(sizeof(Arith_t));
913 	if(!expr(&cur,0) && cur.errmsg.value)
914         {
915 		if(cur.errstr)
916 			string = cur.errstr;
917 		if((*fun)( &string , &cur.errmsg, MESSAGE, 0) < 0)
918 		{
919 			stakseek(0);
920 			*last = (char*)Empty;
921 			return(0);
922 		}
923 		cur.nextchr = cur.errchr;
924 	}
925 	stakputc(0);
926 	offset = staktell();
927 	ep = (Arith_t*)stakfreeze(0);
928 	ep->shp = shp;
929 	ep->expr = string;
930 	ep->elen = strlen(string);
931 	ep->code = (unsigned char*)(ep+1);
932 	ep->fun = fun;
933 	ep->emode = emode;
934 	ep->size = offset - sizeof(Arith_t);
935 	ep->staksize = cur.stakmaxsize+1;
936 	if(last)
937 		*last = (char*)(cur.nextchr);
938 	return(ep);
939 }
940 
941 /*
942  * evaluate an integer arithmetic expression in s
943  *
944  * (Sfdouble_t)(*convert)(char** end, struct lval* string, int type, Sfdouble_t value)
945  *     is a user supplied conversion routine that is called when unknown
946  *     chars are encountered.
947  * *end points to the part to be converted and must be adjusted by convert to
948  * point to the next non-converted character; if typ is MESSAGE then string
949  * points to an error message string
950  *
951  * NOTE: (*convert)() may call strval()
952  */
953 
strval(Shell_t * shp,const char * s,char ** end,Sfdouble_t (* conv)(const char **,struct lval *,int,Sfdouble_t),int emode)954 Sfdouble_t strval(Shell_t *shp,const char *s,char **end,Sfdouble_t(*conv)(const char**,struct lval*,int,Sfdouble_t),int emode)
955 {
956 	Arith_t *ep;
957 	Sfdouble_t d;
958 	char *sp=0;
959 	int offset;
960 	if(offset=staktell())
961 		sp = stakfreeze(1);
962 	ep = arith_compile(shp,s,end,conv,emode);
963 	ep->emode = emode;
964 	d = arith_exec(ep);
965 	stakset(sp?sp:(char*)ep,offset);
966 	return(d);
967 }
968 
969 #if _mem_name__exception
970 #undef	_mem_name_exception
971 #define	_mem_name_exception	1
972 #undef	exception
973 #define	exception		_exception
974 #undef	matherr
975 #endif
976 
977 #if _mem_name_exception
978 
979 #undef	error
980 
981 #if _BLD_shell && defined(__EXPORT__)
982 #define extern			__EXPORT__
983 #endif
984 
985 #ifndef DOMAIN
986 #define DOMAIN			_DOMAIN
987 #endif
988 #ifndef OVERFLOW
989 #define OVERFLOW		_OVERFLOW
990 #endif
991 #ifndef SING
992 #define SING			_SING
993 #endif
994 
matherr(struct exception * ep)995     extern int matherr(struct exception *ep)
996     {
997 	const char *message;
998 	switch(ep->type)
999 	{
1000 #ifdef DOMAIN
1001 	    case DOMAIN:
1002 		message = ERROR_dictionary(e_domain);
1003 		break;
1004 #endif
1005 #ifdef OVERFLOW
1006 	    case OVERFLOW:
1007 		message = ERROR_dictionary(e_overflow);
1008 		break;
1009 #endif
1010 #ifdef SING
1011 	    case SING:
1012 		message = ERROR_dictionary(e_singularity);
1013 		break;
1014 #endif
1015 	    default:
1016 		return(1);
1017 	}
1018 	level=0;
1019 	errormsg(SH_DICT,ERROR_exit(1),message,ep->name);
1020 	return(0);
1021     }
1022 
1023 #undef	extern
1024 
1025 #endif /* _mem_name_exception */
1026