improve of cmpl.
[bush.git] / src / runner / expr.c
blob0f2de541f6d08fb3b5491e5fb2a62535e4e57370
1 /* expr.c -- arithmetic expression evaluation. */
3 /* Copyright (C) 1990-2020 Free Software Foundation, Inc.
5 This file is part of GNU Bush, the Bourne Again SHell.
7 Bush is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 Bush is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bush. If not, see <http://www.gnu.org/licenses/>.
22 All arithmetic is done as intmax_t integers with no checking for overflow
23 (though division by 0 is caught and flagged as an error).
25 The following operators are handled, grouped into a set of levels in
26 order of decreasing precedence.
28 "id++", "id--" [post-increment and post-decrement]
29 "-", "+" [(unary operators)]
30 "++id", "--id" [pre-increment and pre-decrement]
31 "!", "~"
32 "**" [(exponentiation)]
33 "*", "/", "%"
34 "+", "-"
35 "<<", ">>"
36 "<=", ">=", "<", ">"
37 "==", "!="
38 "&"
39 "^"
40 "|"
41 "&&"
42 "||"
43 "expr ? expr : expr"
44 "=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", "&=", "^=", "|="
45 , [comma]
47 (Note that most of these operators have special meaning to bush, and an
48 entire expression should be quoted, e.g. "a=$a+1" or "a=a+1" to ensure
49 that it is passed intact to the evaluator when using `let'. When using
50 the $[] or $(( )) forms, the text between the `[' and `]' or `((' and `))'
51 is treated as if in double quotes.)
53 Sub-expressions within parentheses have a precedence level greater than
54 all of the above levels and are evaluated first. Within a single prece-
55 dence group, evaluation is left-to-right, except for the arithmetic
56 assignment operator (`='), which is evaluated right-to-left (as in C).
58 The expression evaluator returns the value of the expression (assignment
59 statements have as a value what is returned by the RHS). The `let'
60 builtin, on the other hand, returns 0 if the last expression evaluates to
61 a non-zero, and 1 otherwise.
63 Implementation is a recursive-descent parser.
65 Chet Ramey
66 chet@po.cwru.edu
69 #include "config.h"
71 #include <stdio.h>
72 #include "bushansi.h"
74 #if defined (HAVE_UNISTD_H)
75 # ifdef _MINIX
76 # include <sys/types.h>
77 # endif
78 # include <unistd.h>
79 #endif
81 #include "chartypes.h"
82 #include "bushintl.h"
84 #include "shell.h"
85 #include "var/arrayfunc.h"
86 #include "runner/execute_cmd.h"
87 #include "flags.h"
88 #include "lxrgmr/subst.h"
89 #include "typemax.h" /* INTMAX_MAX, INTMAX_MIN */
91 /* Because of the $((...)) construct, expressions may include newlines.
92 Here is a macro which accepts newlines, tabs and spaces as whitespace. */
93 #define cr_whitespace(c) (whitespace(c) || ((c) == '\n'))
95 /* Size be which the expression stack grows when necessary. */
96 #define EXPR_STACK_GROW_SIZE 10
98 /* Maximum amount of recursion allowed. This prevents a non-integer
99 variable such as "num=num+2" from infinitely adding to itself when
100 "let num=num+2" is given. */
101 #define MAX_EXPR_RECURSION_LEVEL 1024
103 /* The Tokens. Singing "The Lion Sleeps Tonight". */
105 #define EQEQ 1 /* "==" */
106 #define NEQ 2 /* "!=" */
107 #define LEQ 3 /* "<=" */
108 #define GEQ 4 /* ">=" */
109 #define STR 5 /* string */
110 #define NUM 6 /* number */
111 #define LAND 7 /* "&&" Logical AND */
112 #define LOR 8 /* "||" Logical OR */
113 #define LSH 9 /* "<<" Left SHift */
114 #define RSH 10 /* ">>" Right SHift */
115 #define OP_ASSIGN 11 /* op= expassign as in Posix.2 */
116 #define COND 12 /* exp1 ? exp2 : exp3 */
117 #define POWER 13 /* exp1**exp2 */
118 #define PREINC 14 /* ++var */
119 #define PREDEC 15 /* --var */
120 #define POSTINC 16 /* var++ */
121 #define POSTDEC 17 /* var-- */
122 #define EQ '='
123 #define GT '>'
124 #define LT '<'
125 #define PLUS '+'
126 #define MINUS '-'
127 #define MUL '*'
128 #define DIV '/'
129 #define MOD '%'
130 #define NOT '!'
131 #define LPAR '('
132 #define RPAR ')'
133 #define BAND '&' /* Bitwise AND */
134 #define BOR '|' /* Bitwise OR. */
135 #define BXOR '^' /* Bitwise eXclusive OR. */
136 #define BNOT '~' /* Bitwise NOT; Two's complement. */
137 #define QUES '?'
138 #define COL ':'
139 #define COMMA ','
141 /* This should be the function corresponding to the operator with the
142 highest precedence. */
143 #define EXP_HIGHEST expcomma
145 #ifndef MAX_INT_LEN
146 # define MAX_INT_LEN 32
147 #endif
149 struct lvalue
151 char *tokstr; /* possibly-rewritten lvalue if not NULL */
152 intmax_t tokval; /* expression evaluated value */
153 SHELL_VAR *tokvar; /* variable described by array or var reference */
154 intmax_t ind; /* array index if not -1 */
157 /* A structure defining a single expression context. */
158 typedef struct {
159 int curtok, lasttok;
160 char *expression, *tp, *lasttp;
161 intmax_t tokval;
162 char *tokstr;
163 int noeval;
164 struct lvalue lval;
165 } EXPR_CONTEXT;
167 static char *expression; /* The current expression */
168 static char *tp; /* token lexical position */
169 static char *lasttp; /* pointer to last token position */
170 static int curtok; /* the current token */
171 static int lasttok; /* the previous token */
172 static int assigntok; /* the OP in OP= */
173 static char *tokstr; /* current token string */
174 static intmax_t tokval; /* current token value */
175 static int noeval; /* set to 1 if no assignment to be done */
176 static procenv_t evalbuf;
178 /* set to 1 if the expression has already been run through word expansion */
179 static int already_expanded;
181 static struct lvalue curlval = {0, 0, 0, -1};
182 static struct lvalue lastlval = {0, 0, 0, -1};
184 static int _is_arithop PARAMS((int));
185 static void readtok PARAMS((void)); /* lexical analyzer */
187 static void init_lvalue PARAMS((struct lvalue *));
188 static struct lvalue *alloc_lvalue PARAMS((void));
189 static void free_lvalue PARAMS((struct lvalue *));
191 static intmax_t expr_streval PARAMS((char *, int, struct lvalue *));
192 static intmax_t strlong PARAMS((char *));
193 static void evalerror PARAMS((const char *));
195 static void pushexp PARAMS((void));
196 static void popexp PARAMS((void));
197 static void expr_unwind PARAMS((void));
198 static void expr_bind_variable PARAMS((char *, char *));
199 #if defined (ARRAY_VARS)
200 static void expr_bind_array_element PARAMS((char *, arrayind_t, char *));
201 #endif
203 static intmax_t subexpr PARAMS((char *));
205 static intmax_t expcomma PARAMS((void));
206 static intmax_t expassign PARAMS((void));
207 static intmax_t expcond PARAMS((void));
208 static intmax_t explor PARAMS((void));
209 static intmax_t expland PARAMS((void));
210 static intmax_t expbor PARAMS((void));
211 static intmax_t expbxor PARAMS((void));
212 static intmax_t expband PARAMS((void));
213 static intmax_t exp5 PARAMS((void));
214 static intmax_t exp4 PARAMS((void));
215 static intmax_t expshift PARAMS((void));
216 static intmax_t exp3 PARAMS((void));
217 static intmax_t expmuldiv PARAMS((void));
218 static intmax_t exppower PARAMS((void));
219 static intmax_t exp1 PARAMS((void));
220 static intmax_t exp0 PARAMS((void));
222 /* Global var which contains the stack of expression contexts. */
223 static EXPR_CONTEXT **expr_stack;
224 static int expr_depth; /* Location in the stack. */
225 static int expr_stack_size; /* Number of slots already allocated. */
227 #if defined (ARRAY_VARS)
228 extern const char * const bush_badsub_errmsg;
229 #endif
231 #define SAVETOK(X) \
232 do { \
233 (X)->curtok = curtok; \
234 (X)->lasttok = lasttok; \
235 (X)->tp = tp; \
236 (X)->lasttp = lasttp; \
237 (X)->tokval = tokval; \
238 (X)->tokstr = tokstr; \
239 (X)->noeval = noeval; \
240 (X)->lval = curlval; \
241 } while (0)
243 #define RESTORETOK(X) \
244 do { \
245 curtok = (X)->curtok; \
246 lasttok = (X)->lasttok; \
247 tp = (X)->tp; \
248 lasttp = (X)->lasttp; \
249 tokval = (X)->tokval; \
250 tokstr = (X)->tokstr; \
251 noeval = (X)->noeval; \
252 curlval = (X)->lval; \
253 } while (0)
255 /* Push and save away the contents of the globals describing the
256 current expression context. */
257 static void
258 pushexp ()
260 EXPR_CONTEXT *context;
262 if (expr_depth >= MAX_EXPR_RECURSION_LEVEL)
263 evalerror (_("expression recursion level exceeded"));
265 if (expr_depth >= expr_stack_size)
267 expr_stack_size += EXPR_STACK_GROW_SIZE;
268 expr_stack = (EXPR_CONTEXT **)xrealloc (expr_stack, expr_stack_size * sizeof (EXPR_CONTEXT *));
271 context = (EXPR_CONTEXT *)xmalloc (sizeof (EXPR_CONTEXT));
273 context->expression = expression;
274 SAVETOK(context);
276 expr_stack[expr_depth++] = context;
279 /* Pop the the contents of the expression context stack into the
280 globals describing the current expression context. */
281 static void
282 popexp ()
284 EXPR_CONTEXT *context;
286 if (expr_depth <= 0)
288 /* See the comment at the top of evalexp() for an explanation of why
289 this is done. */
290 expression = lasttp = 0;
291 evalerror (_("recursion stack underflow"));
294 context = expr_stack[--expr_depth];
296 expression = context->expression;
297 RESTORETOK (context);
299 free (context);
302 static void
303 expr_unwind ()
305 while (--expr_depth > 0)
307 if (expr_stack[expr_depth]->tokstr)
308 free (expr_stack[expr_depth]->tokstr);
310 if (expr_stack[expr_depth]->expression)
311 free (expr_stack[expr_depth]->expression);
313 free (expr_stack[expr_depth]);
315 if (expr_depth == 0)
316 free (expr_stack[expr_depth]); /* free the allocated EXPR_CONTEXT */
318 noeval = 0; /* XXX */
321 static void
322 expr_bind_variable (lhs, rhs)
323 char *lhs, *rhs;
325 SHELL_VAR *v;
326 int aflags;
328 if (lhs == 0 || *lhs == 0)
329 return; /* XXX */
331 #if defined (ARRAY_VARS)
332 aflags = (assoc_expand_once && already_expanded) ? ASS_NOEXPAND : 0;
333 #else
334 aflags = 0;
335 #endif
336 v = bind_int_variable (lhs, rhs, aflags);
337 if (v && (readonly_p (v) || noassign_p (v)))
338 sh_longjmp (evalbuf, 1); /* variable assignment error */
339 stupidly_hack_special_variables (lhs);
342 #if defined (ARRAY_VARS)
343 /* This is similar to the logic in arrayfunc.c:valid_array_subscript when
344 you pass VA_NOEXPAND. */
345 static int
346 expr_skipsubscript (vp, cp)
347 char *vp, *cp;
349 int flags, isassoc;
350 SHELL_VAR *entry;
352 isassoc = 0;
353 entry = 0;
354 if (assoc_expand_once & already_expanded)
356 *cp = '\0';
357 isassoc = legal_identifier (vp) && (entry = find_variable (vp)) && assoc_p (entry);
358 *cp = '['; /* ] */
360 flags = (isassoc && assoc_expand_once && already_expanded) ? VA_NOEXPAND : 0;
361 return (skipsubscript (cp, 0, flags));
364 /* Rewrite tok, which is of the form vname[expression], to vname[ind], where
365 IND is the already-calculated value of expression. */
366 static void
367 expr_bind_array_element (tok, ind, rhs)
368 char *tok;
369 arrayind_t ind;
370 char *rhs;
372 char *lhs, *vname;
373 size_t llen;
374 char ibuf[INT_STRLEN_BOUND (arrayind_t) + 1], *istr;
376 istr = fmtumax (ind, 10, ibuf, sizeof (ibuf), 0);
377 vname = array_variable_name (tok, 0, (char **)NULL, (int *)NULL);
379 llen = strlen (vname) + sizeof (ibuf) + 3;
380 lhs = xmalloc (llen);
382 sprintf (lhs, "%s[%s]", vname, istr); /* XXX */
384 /*itrace("expr_bind_array_element: %s=%s", lhs, rhs);*/
385 expr_bind_variable (lhs, rhs);
386 free (vname);
387 free (lhs);
389 #endif /* ARRAY_VARS */
391 /* Evaluate EXPR, and return the arithmetic result. If VALIDP is
392 non-null, a zero is stored into the location to which it points
393 if the expression is invalid, non-zero otherwise. If a non-zero
394 value is returned in *VALIDP, the return value of evalexp() may
395 be used.
397 The `while' loop after the longjmp is caught relies on the above
398 implementation of pushexp and popexp leaving in expr_stack[0] the
399 values that the variables had when the program started. That is,
400 the first things saved are the initial values of the variables that
401 were assigned at program startup or by the compiler. Therefore, it is
402 safe to let the loop terminate when expr_depth == 0, without freeing up
403 any of the expr_depth[0] stuff. */
404 intmax_t
405 evalexp (expr, flags, validp)
406 char *expr;
407 int flags;
408 int *validp;
410 intmax_t val;
411 int c;
412 procenv_t oevalbuf;
414 val = 0;
415 noeval = 0;
416 already_expanded = (flags&EXP_EXPANDED);
418 FASTCOPY (evalbuf, oevalbuf, sizeof (evalbuf));
420 c = setjmp_nosigs (evalbuf);
422 if (c)
424 FREE (tokstr);
425 FREE (expression);
426 tokstr = expression = (char *)NULL;
428 expr_unwind ();
429 expr_depth = 0; /* XXX - make sure */
431 /* We copy in case we've called evalexp recursively */
432 FASTCOPY (oevalbuf, evalbuf, sizeof (evalbuf));
434 if (validp)
435 *validp = 0;
436 return (0);
439 val = subexpr (expr);
441 if (validp)
442 *validp = 1;
444 FASTCOPY (oevalbuf, evalbuf, sizeof (evalbuf));
446 return (val);
449 static intmax_t
450 subexpr (expr)
451 char *expr;
453 intmax_t val;
454 char *p;
456 for (p = expr; p && *p && cr_whitespace (*p); p++)
459 if (p == NULL || *p == '\0')
460 return (0);
462 pushexp ();
463 expression = savestring (expr);
464 tp = expression;
466 curtok = lasttok = 0;
467 tokstr = (char *)NULL;
468 tokval = 0;
469 init_lvalue (&curlval);
470 lastlval = curlval;
472 readtok ();
474 val = EXP_HIGHEST ();
476 if (curtok != 0)
477 evalerror (_("syntax error in expression"));
479 FREE (tokstr);
480 FREE (expression);
482 popexp ();
484 return val;
487 static intmax_t
488 expcomma ()
490 register intmax_t value;
492 value = expassign ();
493 while (curtok == COMMA)
495 readtok ();
496 value = expassign ();
499 return value;
502 static intmax_t
503 expassign ()
505 register intmax_t value;
506 char *lhs, *rhs;
507 arrayind_t lind;
508 #if defined (HAVE_IMAXDIV)
509 imaxdiv_t idiv;
510 #endif
512 value = expcond ();
513 if (curtok == EQ || curtok == OP_ASSIGN)
515 int special, op;
516 intmax_t lvalue;
518 special = curtok == OP_ASSIGN;
520 if (lasttok != STR)
521 evalerror (_("attempted assignment to non-variable"));
523 if (special)
525 op = assigntok; /* a OP= b */
526 lvalue = value;
529 if (tokstr == 0)
530 evalerror (_("syntax error in variable assignment"));
532 /* XXX - watch out for pointer aliasing issues here */
533 lhs = savestring (tokstr);
534 /* save ind in case rhs is string var and evaluation overwrites it */
535 lind = curlval.ind;
536 readtok ();
537 value = expassign ();
539 if (special)
541 if ((op == DIV || op == MOD) && value == 0)
543 if (noeval == 0)
544 evalerror (_("division by 0"));
545 else
546 value = 1;
549 switch (op)
551 case MUL:
552 /* Handle INTMAX_MIN and INTMAX_MAX * -1 specially here? */
553 lvalue *= value;
554 break;
555 case DIV:
556 case MOD:
557 if (lvalue == INTMAX_MIN && value == -1)
558 lvalue = (op == DIV) ? INTMAX_MIN : 0;
559 else
560 #if HAVE_IMAXDIV
562 idiv = imaxdiv (lvalue, value);
563 lvalue = (op == DIV) ? idiv.quot : idiv.rem;
565 #else
566 lvalue = (op == DIV) ? lvalue / value : lvalue % value;
567 #endif
568 break;
569 case PLUS:
570 lvalue += value;
571 break;
572 case MINUS:
573 lvalue -= value;
574 break;
575 case LSH:
576 lvalue <<= value;
577 break;
578 case RSH:
579 lvalue >>= value;
580 break;
581 case BAND:
582 lvalue &= value;
583 break;
584 case BOR:
585 lvalue |= value;
586 break;
587 case BXOR:
588 lvalue ^= value;
589 break;
590 default:
591 free (lhs);
592 evalerror (_("bug: bad expassign token"));
593 break;
595 value = lvalue;
598 rhs = itos (value);
599 if (noeval == 0)
601 #if defined (ARRAY_VARS)
602 if (lind != -1)
603 expr_bind_array_element (lhs, lind, rhs);
604 else
605 #endif
606 expr_bind_variable (lhs, rhs);
608 if (curlval.tokstr && curlval.tokstr == tokstr)
609 init_lvalue (&curlval);
611 free (rhs);
612 free (lhs);
613 FREE (tokstr);
614 tokstr = (char *)NULL; /* For freeing on errors. */
617 return (value);
620 /* Conditional expression (expr?expr:expr) */
621 static intmax_t
622 expcond ()
624 intmax_t cval, val1, val2, rval;
625 int set_noeval;
627 set_noeval = 0;
628 rval = cval = explor ();
629 if (curtok == QUES) /* found conditional expr */
631 if (cval == 0)
633 set_noeval = 1;
634 noeval++;
637 readtok ();
638 if (curtok == 0 || curtok == COL)
639 evalerror (_("expression expected"));
641 val1 = EXP_HIGHEST ();
643 if (set_noeval)
644 noeval--;
645 if (curtok != COL)
646 evalerror (_("`:' expected for conditional expression"));
648 set_noeval = 0;
649 if (cval)
651 set_noeval = 1;
652 noeval++;
655 readtok ();
656 if (curtok == 0)
657 evalerror (_("expression expected"));
658 val2 = expcond ();
660 if (set_noeval)
661 noeval--;
662 rval = cval ? val1 : val2;
663 lasttok = COND;
665 return rval;
668 /* Logical OR. */
669 static intmax_t
670 explor ()
672 register intmax_t val1, val2;
673 int set_noeval;
675 val1 = expland ();
677 while (curtok == LOR)
679 set_noeval = 0;
680 if (val1 != 0)
682 noeval++;
683 set_noeval = 1;
685 readtok ();
686 val2 = expland ();
687 if (set_noeval)
688 noeval--;
689 val1 = val1 || val2;
690 lasttok = LOR;
693 return (val1);
696 /* Logical AND. */
697 static intmax_t
698 expland ()
700 register intmax_t val1, val2;
701 int set_noeval;
703 val1 = expbor ();
705 while (curtok == LAND)
707 set_noeval = 0;
708 if (val1 == 0)
710 set_noeval = 1;
711 noeval++;
713 readtok ();
714 val2 = expbor ();
715 if (set_noeval)
716 noeval--;
717 val1 = val1 && val2;
718 lasttok = LAND;
721 return (val1);
724 /* Bitwise OR. */
725 static intmax_t
726 expbor ()
728 register intmax_t val1, val2;
730 val1 = expbxor ();
732 while (curtok == BOR)
734 readtok ();
735 val2 = expbxor ();
736 val1 = val1 | val2;
737 lasttok = NUM;
740 return (val1);
743 /* Bitwise XOR. */
744 static intmax_t
745 expbxor ()
747 register intmax_t val1, val2;
749 val1 = expband ();
751 while (curtok == BXOR)
753 readtok ();
754 val2 = expband ();
755 val1 = val1 ^ val2;
756 lasttok = NUM;
759 return (val1);
762 /* Bitwise AND. */
763 static intmax_t
764 expband ()
766 register intmax_t val1, val2;
768 val1 = exp5 ();
770 while (curtok == BAND)
772 readtok ();
773 val2 = exp5 ();
774 val1 = val1 & val2;
775 lasttok = NUM;
778 return (val1);
781 static intmax_t
782 exp5 ()
784 register intmax_t val1, val2;
786 val1 = exp4 ();
788 while ((curtok == EQEQ) || (curtok == NEQ))
790 int op = curtok;
792 readtok ();
793 val2 = exp4 ();
794 if (op == EQEQ)
795 val1 = (val1 == val2);
796 else if (op == NEQ)
797 val1 = (val1 != val2);
798 lasttok = NUM;
800 return (val1);
803 static intmax_t
804 exp4 ()
806 register intmax_t val1, val2;
808 val1 = expshift ();
809 while ((curtok == LEQ) ||
810 (curtok == GEQ) ||
811 (curtok == LT) ||
812 (curtok == GT))
814 int op = curtok;
816 readtok ();
817 val2 = expshift ();
819 if (op == LEQ)
820 val1 = val1 <= val2;
821 else if (op == GEQ)
822 val1 = val1 >= val2;
823 else if (op == LT)
824 val1 = val1 < val2;
825 else /* (op == GT) */
826 val1 = val1 > val2;
827 lasttok = NUM;
829 return (val1);
832 /* Left and right shifts. */
833 static intmax_t
834 expshift ()
836 register intmax_t val1, val2;
838 val1 = exp3 ();
840 while ((curtok == LSH) || (curtok == RSH))
842 int op = curtok;
844 readtok ();
845 val2 = exp3 ();
847 if (op == LSH)
848 val1 = val1 << val2;
849 else
850 val1 = val1 >> val2;
851 lasttok = NUM;
854 return (val1);
857 static intmax_t
858 exp3 ()
860 register intmax_t val1, val2;
862 val1 = expmuldiv ();
864 while ((curtok == PLUS) || (curtok == MINUS))
866 int op = curtok;
868 readtok ();
869 val2 = expmuldiv ();
871 if (op == PLUS)
872 val1 += val2;
873 else if (op == MINUS)
874 val1 -= val2;
875 lasttok = NUM;
877 return (val1);
880 static intmax_t
881 expmuldiv ()
883 register intmax_t val1, val2;
884 #if defined (HAVE_IMAXDIV)
885 imaxdiv_t idiv;
886 #endif
888 val1 = exppower ();
890 while ((curtok == MUL) ||
891 (curtok == DIV) ||
892 (curtok == MOD))
894 int op = curtok;
895 char *stp, *sltp;
897 stp = tp;
898 readtok ();
900 val2 = exppower ();
902 /* Handle division by 0 and twos-complement arithmetic overflow */
903 if (((op == DIV) || (op == MOD)) && (val2 == 0))
905 if (noeval == 0)
907 sltp = lasttp;
908 lasttp = stp;
909 while (lasttp && *lasttp && whitespace (*lasttp))
910 lasttp++;
911 evalerror (_("division by 0"));
912 lasttp = sltp;
914 else
915 val2 = 1;
917 else if (op == MOD && val1 == INTMAX_MIN && val2 == -1)
919 val1 = 0;
920 continue;
922 else if (op == DIV && val1 == INTMAX_MIN && val2 == -1)
923 val2 = 1;
925 if (op == MUL)
926 val1 *= val2;
927 else if (op == DIV || op == MOD)
928 #if defined (HAVE_IMAXDIV)
930 idiv = imaxdiv (val1, val2);
931 val1 = (op == DIV) ? idiv.quot : idiv.rem;
933 #else
934 val1 = (op == DIV) ? val1 / val2 : val1 % val2;
935 #endif
936 lasttok = NUM;
938 return (val1);
941 static intmax_t
942 ipow (base, exp)
943 intmax_t base, exp;
945 intmax_t result;
947 result = 1;
948 while (exp)
950 if (exp & 1)
951 result *= base;
952 exp >>= 1;
953 base *= base;
955 return result;
958 static intmax_t
959 exppower ()
961 register intmax_t val1, val2, c;
963 val1 = exp1 ();
964 while (curtok == POWER)
966 readtok ();
967 val2 = exppower (); /* exponentiation is right-associative */
968 lasttok = NUM;
969 if (val2 == 0)
970 return (1);
971 if (val2 < 0)
972 evalerror (_("exponent less than 0"));
973 val1 = ipow (val1, val2);
975 return (val1);
978 static intmax_t
979 exp1 ()
981 register intmax_t val;
983 if (curtok == NOT)
985 readtok ();
986 val = !exp1 ();
987 lasttok = NUM;
989 else if (curtok == BNOT)
991 readtok ();
992 val = ~exp1 ();
993 lasttok = NUM;
995 else if (curtok == MINUS)
997 readtok ();
998 val = - exp1 ();
999 lasttok = NUM;
1001 else if (curtok == PLUS)
1003 readtok ();
1004 val = exp1 ();
1005 lasttok = NUM;
1007 else
1008 val = exp0 ();
1010 return (val);
1013 static intmax_t
1014 exp0 ()
1016 register intmax_t val = 0, v2;
1017 char *vincdec;
1018 int stok;
1019 EXPR_CONTEXT ec;
1021 /* XXX - might need additional logic here to decide whether or not
1022 pre-increment or pre-decrement is legal at this point. */
1023 if (curtok == PREINC || curtok == PREDEC)
1025 stok = lasttok = curtok;
1026 readtok ();
1027 if (curtok != STR)
1028 /* readtok() catches this */
1029 evalerror (_("identifier expected after pre-increment or pre-decrement"));
1031 v2 = tokval + ((stok == PREINC) ? 1 : -1);
1032 vincdec = itos (v2);
1033 if (noeval == 0)
1035 #if defined (ARRAY_VARS)
1036 if (curlval.ind != -1)
1037 expr_bind_array_element (curlval.tokstr, curlval.ind, vincdec);
1038 else
1039 #endif
1040 if (tokstr)
1041 expr_bind_variable (tokstr, vincdec);
1043 free (vincdec);
1044 val = v2;
1046 curtok = NUM; /* make sure --x=7 is flagged as an error */
1047 readtok ();
1049 else if (curtok == LPAR)
1051 /* XXX - save curlval here? Or entire expression context? */
1052 readtok ();
1053 val = EXP_HIGHEST ();
1055 if (curtok != RPAR) /* ( */
1056 evalerror (_("missing `)'"));
1058 /* Skip over closing paren. */
1059 readtok ();
1061 else if ((curtok == NUM) || (curtok == STR))
1063 val = tokval;
1064 if (curtok == STR)
1066 SAVETOK (&ec);
1067 tokstr = (char *)NULL; /* keep it from being freed */
1068 noeval = 1;
1069 readtok ();
1070 stok = curtok;
1072 /* post-increment or post-decrement */
1073 if (stok == POSTINC || stok == POSTDEC)
1075 /* restore certain portions of EC */
1076 tokstr = ec.tokstr;
1077 noeval = ec.noeval;
1078 curlval = ec.lval;
1079 lasttok = STR; /* ec.curtok */
1081 v2 = val + ((stok == POSTINC) ? 1 : -1);
1082 vincdec = itos (v2);
1083 if (noeval == 0)
1085 #if defined (ARRAY_VARS)
1086 if (curlval.ind != -1)
1087 expr_bind_array_element (curlval.tokstr, curlval.ind, vincdec);
1088 else
1089 #endif
1090 expr_bind_variable (tokstr, vincdec);
1092 free (vincdec);
1093 curtok = NUM; /* make sure x++=7 is flagged as an error */
1095 else
1097 /* XXX - watch out for pointer aliasing issues here */
1098 if (stok == STR) /* free new tokstr before old one is restored */
1099 FREE (tokstr);
1100 RESTORETOK (&ec);
1104 readtok ();
1106 else
1107 evalerror (_("syntax error: operand expected"));
1109 return (val);
1112 static void
1113 init_lvalue (lv)
1114 struct lvalue *lv;
1116 lv->tokstr = 0;
1117 lv->tokvar = 0;
1118 lv->tokval = lv->ind = -1;
1121 static struct lvalue *
1122 alloc_lvalue ()
1124 struct lvalue *lv;
1126 lv = xmalloc (sizeof (struct lvalue));
1127 init_lvalue (lv);
1128 return (lv);
1131 static void
1132 free_lvalue (lv)
1133 struct lvalue *lv;
1135 free (lv); /* should be inlined */
1138 static intmax_t
1139 expr_streval (tok, e, lvalue)
1140 char *tok;
1141 int e;
1142 struct lvalue *lvalue;
1144 SHELL_VAR *v;
1145 char *value;
1146 intmax_t tval;
1147 int initial_depth;
1148 #if defined (ARRAY_VARS)
1149 arrayind_t ind;
1150 int tflag, aflag;
1151 #endif
1153 /*itrace("expr_streval: %s: noeval = %d expanded=%d", tok, noeval, already_expanded);*/
1154 /* If we are suppressing evaluation, just short-circuit here instead of
1155 going through the rest of the evaluator. */
1156 if (noeval)
1157 return (0);
1159 initial_depth = expr_depth;
1161 #if defined (ARRAY_VARS)
1162 tflag = assoc_expand_once && already_expanded; /* for a start */
1163 #endif
1165 /* [[[[[ */
1166 #if defined (ARRAY_VARS)
1167 aflag = (tflag) ? AV_NOEXPAND : 0;
1168 v = (e == ']') ? array_variable_part (tok, tflag, (char **)0, (int *)0) : find_variable (tok);
1169 #else
1170 v = find_variable (tok);
1171 #endif
1172 if (v == 0 && e != ']')
1173 v = find_variable_last_nameref (tok, 0);
1175 if ((v == 0 || invisible_p (v)) && unbound_vars_is_error)
1177 #if defined (ARRAY_VARS)
1178 value = (e == ']') ? array_variable_name (tok, tflag, (char **)0, (int *)0) : tok;
1179 #else
1180 value = tok;
1181 #endif
1183 set_exit_status (EXECUTION_FAILURE);
1184 err_unboundvar (value);
1186 #if defined (ARRAY_VARS)
1187 if (e == ']')
1188 FREE (value); /* array_variable_name returns new memory */
1189 #endif
1191 if (no_longjmp_on_fatal_error && interactive_shell)
1192 sh_longjmp (evalbuf, 1);
1194 if (interactive_shell)
1196 expr_unwind ();
1197 top_level_cleanup ();
1198 jump_to_top_level (DISCARD);
1200 else
1201 jump_to_top_level (FORCE_EOF);
1204 #if defined (ARRAY_VARS)
1205 ind = -1;
1206 /* If the second argument to get_array_value doesn't include AV_ALLOWALL,
1207 we don't allow references like array[@]. In this case, get_array_value
1208 is just like get_variable_value in that it does not return newly-allocated
1209 memory or quote the results. AFLAG is set above and is either AV_NOEXPAND
1210 or 0. */
1211 value = (e == ']') ? get_array_value (tok, aflag, (int *)NULL, &ind) : get_variable_value (v);
1212 #else
1213 value = get_variable_value (v);
1214 #endif
1216 if (expr_depth < initial_depth)
1218 if (no_longjmp_on_fatal_error && interactive_shell)
1219 sh_longjmp (evalbuf, 1);
1220 return (0);
1223 tval = (value && *value) ? subexpr (value) : 0;
1225 if (lvalue)
1227 lvalue->tokstr = tok; /* XXX */
1228 lvalue->tokval = tval;
1229 lvalue->tokvar = v; /* XXX */
1230 #if defined (ARRAY_VARS)
1231 lvalue->ind = ind;
1232 #else
1233 lvalue->ind = -1;
1234 #endif
1237 return (tval);
1240 static int
1241 _is_multiop (c)
1242 int c;
1244 switch (c)
1246 case EQEQ:
1247 case NEQ:
1248 case LEQ:
1249 case GEQ:
1250 case LAND:
1251 case LOR:
1252 case LSH:
1253 case RSH:
1254 case OP_ASSIGN:
1255 case COND:
1256 case POWER:
1257 case PREINC:
1258 case PREDEC:
1259 case POSTINC:
1260 case POSTDEC:
1261 return 1;
1262 default:
1263 return 0;
1267 static int
1268 _is_arithop (c)
1269 int c;
1271 switch (c)
1273 case EQ:
1274 case GT:
1275 case LT:
1276 case PLUS:
1277 case MINUS:
1278 case MUL:
1279 case DIV:
1280 case MOD:
1281 case NOT:
1282 case LPAR:
1283 case RPAR:
1284 case BAND:
1285 case BOR:
1286 case BXOR:
1287 case BNOT:
1288 return 1; /* operator tokens */
1289 case QUES:
1290 case COL:
1291 case COMMA:
1292 return 1; /* questionable */
1293 default:
1294 return 0; /* anything else is invalid */
1298 /* Lexical analyzer/token reader for the expression evaluator. Reads the
1299 next token and puts its value into curtok, while advancing past it.
1300 Updates value of tp. May also set tokval (for number) or tokstr (for
1301 string). */
1302 static void
1303 readtok ()
1305 register char *cp, *xp;
1306 register unsigned char c, c1;
1307 register int e;
1308 struct lvalue lval;
1310 /* Skip leading whitespace. */
1311 cp = tp;
1312 c = e = 0;
1313 while (cp && (c = *cp) && (cr_whitespace (c)))
1314 cp++;
1316 if (c)
1317 cp++;
1319 if (c == '\0')
1321 lasttok = curtok;
1322 curtok = 0;
1323 tp = cp;
1324 return;
1326 lasttp = tp = cp - 1;
1328 if (legal_variable_starter (c))
1330 /* variable names not preceded with a dollar sign are shell variables. */
1331 char *savecp;
1332 char *bakcp;
1333 EXPR_CONTEXT ec;
1334 int peektok;
1336 bakcp = cp;
1337 while (legal_variable_char (c))
1339 #if 1
1340 if (legal_variable_char2 (cp) == 0)
1341 break;
1342 #else
1343 if (c == ':')
1345 if (*(cp+1) == ':')
1346 cp++;
1347 else
1348 break;
1350 #endif
1351 c = *cp++;
1353 c = *--cp;
1355 #if defined (ARRAY_VARS)
1356 if (c == '[')
1358 e = expr_skipsubscript (tp, cp); /* XXX - was skipsubscript */
1359 if (cp[e] == ']')
1361 cp += e + 1;
1362 c = *cp;
1363 e = ']';
1365 else
1366 evalerror (bush_badsub_errmsg);
1368 #endif /* ARRAY_VARS */
1370 *cp = '\0';
1371 /* XXX - watch out for pointer aliasing issues here */
1372 if (curlval.tokstr && curlval.tokstr == tokstr)
1373 init_lvalue (&curlval);
1375 FREE (tokstr);
1376 tokstr = savestring (tp);
1377 *cp = c;
1379 /* XXX - make peektok part of saved token state? */
1380 SAVETOK (&ec);
1381 tokstr = (char *)NULL; /* keep it from being freed */
1382 tp = savecp = cp;
1383 noeval = 1;
1384 curtok = STR;
1385 readtok ();
1386 peektok = curtok;
1387 if (peektok == STR) /* free new tokstr before old one is restored */
1388 FREE (tokstr);
1389 RESTORETOK (&ec);
1390 cp = savecp;
1392 /* The tests for PREINC and PREDEC aren't strictly correct, but they
1393 preserve old behavior if a construct like --x=9 is given. */
1394 if (lasttok == PREINC || lasttok == PREDEC || peektok != EQ)
1396 lastlval = curlval;
1397 tokval = expr_streval (tokstr, e, &curlval);
1399 else
1400 tokval = 0;
1402 lasttok = curtok;
1403 curtok = STR;
1405 else if (DIGIT(c))
1407 while (ISALNUM (c) || c == '#' || c == '@' || c == '_')
1408 c = *cp++;
1410 c = *--cp;
1411 *cp = '\0';
1413 tokval = strlong (tp);
1414 *cp = c;
1415 lasttok = curtok;
1416 curtok = NUM;
1418 else
1420 c1 = *cp++;
1421 if ((c == EQ) && (c1 == EQ))
1422 c = EQEQ;
1423 else if ((c == NOT) && (c1 == EQ))
1424 c = NEQ;
1425 else if ((c == GT) && (c1 == EQ))
1426 c = GEQ;
1427 else if ((c == LT) && (c1 == EQ))
1428 c = LEQ;
1429 else if ((c == LT) && (c1 == LT))
1431 if (*cp == '=') /* a <<= b */
1433 assigntok = LSH;
1434 c = OP_ASSIGN;
1435 cp++;
1437 else
1438 c = LSH;
1440 else if ((c == GT) && (c1 == GT))
1442 if (*cp == '=')
1444 assigntok = RSH; /* a >>= b */
1445 c = OP_ASSIGN;
1446 cp++;
1448 else
1449 c = RSH;
1451 else if ((c == BAND) && (c1 == BAND))
1452 c = LAND;
1453 else if ((c == BOR) && (c1 == BOR))
1454 c = LOR;
1455 else if ((c == '*') && (c1 == '*'))
1456 c = POWER;
1457 else if ((c == '-' || c == '+') && c1 == c && curtok == STR)
1458 c = (c == '-') ? POSTDEC : POSTINC;
1459 else if ((c == '-' || c == '+') && c1 == c && curtok == NUM && (lasttok == PREINC || lasttok == PREDEC))
1461 /* This catches something like --FOO++ */
1462 if (c == '-')
1463 evalerror ("--: assignment requires lvalue");
1464 else
1465 evalerror ("++: assignment requires lvalue");
1467 else if ((c == '-' || c == '+') && c1 == c)
1469 /* Quickly scan forward to see if this is followed by optional
1470 whitespace and an identifier. */
1471 xp = cp;
1472 while (xp && *xp && cr_whitespace (*xp))
1473 xp++;
1474 if (legal_variable_starter ((unsigned char)*xp))
1475 c = (c == '-') ? PREDEC : PREINC;
1476 else
1477 /* Could force parsing as preinc or predec and throw an error */
1478 #if 0
1480 /* Posix says unary plus and minus have higher priority than
1481 preinc and predec. */
1482 /* This catches something like --4++ */
1483 if (c == '-')
1484 evalerror ("--: assignment requires lvalue");
1485 else
1486 evalerror ("++: assignment requires lvalue");
1488 #else
1489 cp--; /* not preinc or predec, so unget the character */
1490 #endif
1492 else if (c1 == EQ && member (c, "*/%+-&^|"))
1494 assigntok = c; /* a OP= b */
1495 c = OP_ASSIGN;
1497 else if (_is_arithop (c) == 0)
1499 cp--;
1500 /* use curtok, since it hasn't been copied to lasttok yet */
1501 if (curtok == 0 || _is_arithop (curtok) || _is_multiop (curtok))
1502 evalerror (_("syntax error: operand expected"));
1503 else
1504 evalerror (_("syntax error: invalid arithmetic operator"));
1506 else
1507 cp--; /* `unget' the character */
1509 /* Should check here to make sure that the current character is one
1510 of the recognized operators and flag an error if not. Could create
1511 a character map the first time through and check it on subsequent
1512 calls. */
1513 lasttok = curtok;
1514 curtok = c;
1516 tp = cp;
1519 static void
1520 evalerror (msg)
1521 const char *msg;
1523 char *name, *t;
1525 name = this_command_name;
1526 for (t = expression; t && whitespace (*t); t++)
1528 internal_error (_("%s%s%s: %s (error token is \"%s\")"),
1529 name ? name : "", name ? ": " : "",
1530 t ? t : "", msg, (lasttp && *lasttp) ? lasttp : "");
1531 sh_longjmp (evalbuf, 1);
1534 /* Convert a string to an intmax_t integer, with an arbitrary base.
1535 0nnn -> base 8
1536 0[Xx]nn -> base 16
1537 Anything else: [base#]number (this is implemented to match ksh93)
1539 Base may be >=2 and <=64. If base is <= 36, the numbers are drawn
1540 from [0-9][a-zA-Z], and lowercase and uppercase letters may be used
1541 interchangeably. If base is > 36 and <= 64, the numbers are drawn
1542 from [0-9][a-z][A-Z]_@ (a = 10, z = 35, A = 36, Z = 61, @ = 62, _ = 63 --
1543 you get the picture). */
1545 #define VALID_NUMCHAR(c) (ISALNUM(c) || ((c) == '_') || ((c) == '@'))
1547 static intmax_t
1548 strlong (num)
1549 char *num;
1551 register char *s;
1552 register unsigned char c;
1553 int base, foundbase;
1554 intmax_t val;
1556 s = num;
1558 base = 10;
1559 foundbase = 0;
1560 if (*s == '0')
1562 s++;
1564 if (*s == '\0')
1565 return 0;
1567 /* Base 16? */
1568 if (*s == 'x' || *s == 'X')
1570 base = 16;
1571 s++;
1573 else
1574 base = 8;
1575 foundbase++;
1578 val = 0;
1579 for (c = *s++; c; c = *s++)
1581 if (c == '#')
1583 if (foundbase)
1584 evalerror (_("invalid number"));
1586 /* Illegal base specifications raise an evaluation error. */
1587 if (val < 2 || val > 64)
1588 evalerror (_("invalid arithmetic base"));
1590 base = val;
1591 val = 0;
1592 foundbase++;
1594 /* Make sure a base# is followed by a character that can compose a
1595 valid integer constant. Jeremy Townshend <jeremy.townshend@gmail.com> */
1596 if (VALID_NUMCHAR (*s) == 0)
1597 evalerror (_("invalid integer constant"));
1599 else if (VALID_NUMCHAR (c))
1601 if (DIGIT(c))
1602 c = TODIGIT(c);
1603 else if (c >= 'a' && c <= 'z')
1604 c -= 'a' - 10;
1605 else if (c >= 'A' && c <= 'Z')
1606 c -= 'A' - ((base <= 36) ? 10 : 36);
1607 else if (c == '@')
1608 c = 62;
1609 else if (c == '_')
1610 c = 63;
1612 if (c >= base)
1613 evalerror (_("value too great for base"));
1615 val = (val * base) + c;
1617 else
1618 break;
1621 return (val);
1624 #if defined (EXPR_TEST)
1625 void *
1626 xmalloc (n)
1627 int n;
1629 return (malloc (n));
1632 void *
1633 xrealloc (s, n)
1634 char *s;
1635 int n;
1637 return (realloc (s, n));
1640 SHELL_VAR *find_variable () { return 0;}
1641 SHELL_VAR *bind_variable () { return 0; }
1643 char *get_string_value () { return 0; }
1645 procenv_t top_level;
1647 main (argc, argv)
1648 int argc;
1649 char **argv;
1651 register int i;
1652 intmax_t v;
1653 int expok;
1655 if (setjmp (top_level))
1656 exit (0);
1658 for (i = 1; i < argc; i++)
1660 v = evalexp (argv[i], 0, &expok);
1661 if (expok == 0)
1662 fprintf (stderr, _("%s: expression error\n"), argv[i]);
1663 else
1664 printf ("'%s' -> %ld\n", argv[i], v);
1666 exit (0);
1670 builtin_error (format, arg1, arg2, arg3, arg4, arg5)
1671 char *format;
1673 fprintf (stderr, "expr: ");
1674 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
1675 fprintf (stderr, "\n");
1676 return 0;
1679 char *
1680 itos (n)
1681 intmax_t n;
1683 return ("42");
1686 #endif /* EXPR_TEST */