]> git.ipfire.org Git - thirdparty/bash.git/blame - expr.c
Bash-4.2 patch 8
[thirdparty/bash.git] / expr.c
CommitLineData
726f6388
JA
1/* expr.c -- arithmetic expression evaluation. */
2
495aee44 3/* Copyright (C) 1990-2010 Free Software Foundation, Inc.
726f6388
JA
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
3185942a
JA
7 Bash 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.
726f6388 11
3185942a
JA
12 Bash 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.
726f6388
JA
16
17 You should have received a copy of the GNU General Public License
3185942a
JA
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19*/
726f6388
JA
20
21/*
7117c2d2 22 All arithmetic is done as intmax_t integers with no checking for overflow
726f6388
JA
23 (though division by 0 is caught and flagged as an error).
24
25 The following operators are handled, grouped into a set of levels in
26 order of decreasing precedence.
27
bb70624e
JA
28 "id++", "id--" [post-increment and post-decrement]
29 "++id", "--id" [pre-increment and pre-decrement]
726f6388
JA
30 "-", "+" [(unary operators)]
31 "!", "~"
cce855bc 32 "**" [(exponentiation)]
726f6388
JA
33 "*", "/", "%"
34 "+", "-"
35 "<<", ">>"
36 "<=", ">=", "<", ">"
37 "==", "!="
38 "&"
39 "^"
40 "|"
41 "&&"
42 "||"
ccc6cda3 43 "expr ? expr : expr"
cce855bc 44 "=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", "&=", "^=", "|="
b80f6443 45 , [comma]
726f6388
JA
46
47 (Note that most of these operators have special meaning to bash, 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.)
52
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).
57
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.
62
63 Implementation is a recursive-descent parser.
64
65 Chet Ramey
66 chet@ins.CWRU.Edu
67*/
68
ccc6cda3
JA
69#include "config.h"
70
726f6388
JA
71#include <stdio.h>
72#include "bashansi.h"
cce855bc 73
ccc6cda3 74#if defined (HAVE_UNISTD_H)
cce855bc
JA
75# ifdef _MINIX
76# include <sys/types.h>
77# endif
ccc6cda3
JA
78# include <unistd.h>
79#endif
726f6388 80
f73dda09 81#include "chartypes.h"
b80f6443 82#include "bashintl.h"
bb70624e 83
ccc6cda3 84#include "shell.h"
726f6388
JA
85
86/* Because of the $((...)) construct, expressions may include newlines.
87 Here is a macro which accepts newlines, tabs and spaces as whitespace. */
88#define cr_whitespace(c) (whitespace(c) || ((c) == '\n'))
89
726f6388
JA
90/* Size be which the expression stack grows when neccessary. */
91#define EXPR_STACK_GROW_SIZE 10
92
93/* Maximum amount of recursion allowed. This prevents a non-integer
94 variable such as "num=num+2" from infinitely adding to itself when
ccc6cda3 95 "let num=num+2" is given. */
726f6388
JA
96#define MAX_EXPR_RECURSION_LEVEL 1024
97
98/* The Tokens. Singing "The Lion Sleeps Tonight". */
99
100#define EQEQ 1 /* "==" */
101#define NEQ 2 /* "!=" */
102#define LEQ 3 /* "<=" */
103#define GEQ 4 /* ">=" */
104#define STR 5 /* string */
105#define NUM 6 /* number */
106#define LAND 7 /* "&&" Logical AND */
107#define LOR 8 /* "||" Logical OR */
108#define LSH 9 /* "<<" Left SHift */
109#define RSH 10 /* ">>" Right SHift */
110#define OP_ASSIGN 11 /* op= expassign as in Posix.2 */
cce855bc
JA
111#define COND 12 /* exp1 ? exp2 : exp3 */
112#define POWER 13 /* exp1**exp2 */
bb70624e
JA
113#define PREINC 14 /* ++var */
114#define PREDEC 15 /* --var */
115#define POSTINC 16 /* var++ */
116#define POSTDEC 17 /* var-- */
726f6388
JA
117#define EQ '='
118#define GT '>'
119#define LT '<'
120#define PLUS '+'
121#define MINUS '-'
122#define MUL '*'
123#define DIV '/'
124#define MOD '%'
125#define NOT '!'
126#define LPAR '('
127#define RPAR ')'
128#define BAND '&' /* Bitwise AND */
ccc6cda3 129#define BOR '|' /* Bitwise OR. */
726f6388
JA
130#define BXOR '^' /* Bitwise eXclusive OR. */
131#define BNOT '~' /* Bitwise NOT; Two's complement. */
ccc6cda3
JA
132#define QUES '?'
133#define COL ':'
bb70624e
JA
134#define COMMA ','
135
136/* This should be the function corresponding to the operator with the
137 highest precedence. */
138#define EXP_HIGHEST expcomma
ccc6cda3 139
495aee44
CR
140#ifndef MAX_INT_LEN
141# define MAX_INT_LEN 32
142#endif
143
144struct lvalue
145{
146 char *tokstr; /* possibly-rewritten lvalue if not NULL */
147 intmax_t tokval; /* expression evaluated value */
148 SHELL_VAR *tokvar; /* variable described by array or var reference */
149 intmax_t ind; /* array index if not -1 */
150};
151
152/* A structure defining a single expression context. */
153typedef struct {
154 int curtok, lasttok;
155 char *expression, *tp, *lasttp;
156 intmax_t tokval;
157 char *tokstr;
158 int noeval;
159 struct lvalue lval;
160} EXPR_CONTEXT;
161
ccc6cda3
JA
162static char *expression; /* The current expression */
163static char *tp; /* token lexical position */
164static char *lasttp; /* pointer to last token position */
165static int curtok; /* the current token */
166static int lasttok; /* the previous token */
167static int assigntok; /* the OP in OP= */
168static char *tokstr; /* current token string */
7117c2d2 169static intmax_t tokval; /* current token value */
ccc6cda3
JA
170static int noeval; /* set to 1 if no assignment to be done */
171static procenv_t evalbuf;
172
495aee44
CR
173static struct lvalue curlval = {0, 0, 0, -1};
174static struct lvalue lastlval = {0, 0, 0, -1};
175
0628567a 176static int _is_arithop __P((int));
f73dda09 177static void readtok __P((void)); /* lexical analyzer */
7117c2d2 178
495aee44
CR
179static void init_lvalue __P((struct lvalue *));
180static struct lvalue *alloc_lvalue __P((void));
181static void free_lvalue __P((struct lvalue *));
182
183static intmax_t expr_streval __P((char *, int, struct lvalue *));
7117c2d2 184static intmax_t strlong __P((char *));
3185942a 185static void evalerror __P((const char *));
f73dda09
JA
186
187static void pushexp __P((void));
188static void popexp __P((void));
7117c2d2 189static void expr_unwind __P((void));
b80f6443 190static void expr_bind_variable __P((char *, char *));
495aee44 191static void expr_bind_array_element __P((char *, arrayind_t, char *));
7117c2d2
JA
192
193static intmax_t subexpr __P((char *));
194
195static intmax_t expcomma __P((void));
196static intmax_t expassign __P((void));
197static intmax_t expcond __P((void));
198static intmax_t explor __P((void));
199static intmax_t expland __P((void));
200static intmax_t expbor __P((void));
201static intmax_t expbxor __P((void));
202static intmax_t expband __P((void));
203static intmax_t exp5 __P((void));
204static intmax_t exp4 __P((void));
205static intmax_t expshift __P((void));
206static intmax_t exp3 __P((void));
207static intmax_t exp2 __P((void));
208static intmax_t exppower __P((void));
209static intmax_t exp1 __P((void));
210static intmax_t exp0 __P((void));
ccc6cda3 211
ccc6cda3
JA
212/* Global var which contains the stack of expression contexts. */
213static EXPR_CONTEXT **expr_stack;
214static int expr_depth; /* Location in the stack. */
215static int expr_stack_size; /* Number of slots already allocated. */
216
217extern char *this_command_name;
0001803f 218extern int unbound_vars_is_error, last_command_exit_value;
726f6388 219
b80f6443 220#if defined (ARRAY_VARS)
3185942a 221extern const char * const bash_badsub_errmsg;
b80f6443
JA
222#endif
223
bb70624e
JA
224#define SAVETOK(X) \
225 do { \
226 (X)->curtok = curtok; \
227 (X)->lasttok = lasttok; \
228 (X)->tp = tp; \
229 (X)->lasttp = lasttp; \
230 (X)->tokval = tokval; \
231 (X)->tokstr = tokstr; \
232 (X)->noeval = noeval; \
495aee44 233 (X)->lval = curlval; \
bb70624e
JA
234 } while (0)
235
236#define RESTORETOK(X) \
237 do { \
238 curtok = (X)->curtok; \
239 lasttok = (X)->lasttok; \
240 tp = (X)->tp; \
241 lasttp = (X)->lasttp; \
242 tokval = (X)->tokval; \
243 tokstr = (X)->tokstr; \
244 noeval = (X)->noeval; \
495aee44 245 curlval = (X)->lval; \
bb70624e
JA
246 } while (0)
247
726f6388
JA
248/* Push and save away the contents of the globals describing the
249 current expression context. */
250static void
251pushexp ()
252{
253 EXPR_CONTEXT *context;
254
726f6388 255 if (expr_depth >= MAX_EXPR_RECURSION_LEVEL)
b80f6443 256 evalerror (_("expression recursion level exceeded"));
726f6388
JA
257
258 if (expr_depth >= expr_stack_size)
259 {
f73dda09
JA
260 expr_stack_size += EXPR_STACK_GROW_SIZE;
261 expr_stack = (EXPR_CONTEXT **)xrealloc (expr_stack, expr_stack_size * sizeof (EXPR_CONTEXT *));
726f6388
JA
262 }
263
d166f048
JA
264 context = (EXPR_CONTEXT *)xmalloc (sizeof (EXPR_CONTEXT));
265
726f6388 266 context->expression = expression;
bb70624e
JA
267 SAVETOK(context);
268
726f6388
JA
269 expr_stack[expr_depth++] = context;
270}
271
272/* Pop the the contents of the expression context stack into the
273 globals describing the current expression context. */
274static void
275popexp ()
276{
277 EXPR_CONTEXT *context;
278
279 if (expr_depth == 0)
b80f6443 280 evalerror (_("recursion stack underflow"));
726f6388
JA
281
282 context = expr_stack[--expr_depth];
bb70624e 283
726f6388 284 expression = context->expression;
bb70624e
JA
285 RESTORETOK (context);
286
726f6388
JA
287 free (context);
288}
289
7117c2d2
JA
290static void
291expr_unwind ()
292{
293 while (--expr_depth > 0)
294 {
295 if (expr_stack[expr_depth]->tokstr)
296 free (expr_stack[expr_depth]->tokstr);
297
298 if (expr_stack[expr_depth]->expression)
299 free (expr_stack[expr_depth]->expression);
300
301 free (expr_stack[expr_depth]);
302 }
303 free (expr_stack[expr_depth]); /* free the allocated EXPR_CONTEXT */
f1be666c
JA
304
305 noeval = 0; /* XXX */
7117c2d2
JA
306}
307
b80f6443
JA
308static void
309expr_bind_variable (lhs, rhs)
310 char *lhs, *rhs;
311{
312 (void)bind_int_variable (lhs, rhs);
313 stupidly_hack_special_variables (lhs);
314}
315
495aee44
CR
316/* Rewrite tok, which is of the form vname[expression], to vname[ind], where
317 IND is the already-calculated value of expression. */
318static void
319expr_bind_array_element (tok, ind, rhs)
320 char *tok;
321 arrayind_t ind;
322 char *rhs;
323{
324 char *lhs, *vname;
325 size_t llen;
326 char ibuf[INT_STRLEN_BOUND (arrayind_t) + 1], *istr;
327
328 istr = fmtumax (ind, 10, ibuf, sizeof (ibuf), 0);
329 vname = array_variable_name (tok, (char **)NULL, (int *)NULL);
330
331 llen = strlen (vname) + sizeof (ibuf) + 3;
332 lhs = xmalloc (llen);
333
334 sprintf (lhs, "%s[%s]", vname, istr); /* XXX */
335
336 expr_bind_variable (lhs, rhs);
337/*itrace("expr_bind_array_element: %s=%s", lhs, rhs);*/
338 free (vname);
339 free (lhs);
340}
341
d166f048
JA
342/* Evaluate EXPR, and return the arithmetic result. If VALIDP is
343 non-null, a zero is stored into the location to which it points
344 if the expression is invalid, non-zero otherwise. If a non-zero
345 value is returned in *VALIDP, the return value of evalexp() may
346 be used.
726f6388
JA
347
348 The `while' loop after the longjmp is caught relies on the above
349 implementation of pushexp and popexp leaving in expr_stack[0] the
350 values that the variables had when the program started. That is,
ccc6cda3 351 the first things saved are the initial values of the variables that
726f6388
JA
352 were assigned at program startup or by the compiler. Therefore, it is
353 safe to let the loop terminate when expr_depth == 0, without freeing up
354 any of the expr_depth[0] stuff. */
7117c2d2 355intmax_t
d166f048 356evalexp (expr, validp)
726f6388 357 char *expr;
d166f048 358 int *validp;
726f6388 359{
7117c2d2 360 intmax_t val;
b80f6443
JA
361 int c;
362 procenv_t oevalbuf;
726f6388 363
f73dda09 364 val = 0;
f1be666c 365 noeval = 0;
726f6388 366
b80f6443
JA
367 FASTCOPY (evalbuf, oevalbuf, sizeof (evalbuf));
368
369 c = setjmp (evalbuf);
370
371 if (c)
726f6388 372 {
d166f048
JA
373 FREE (tokstr);
374 FREE (expression);
375 tokstr = expression = (char *)NULL;
726f6388 376
7117c2d2 377 expr_unwind ();
d166f048
JA
378
379 if (validp)
380 *validp = 0;
f73dda09 381 return (0);
726f6388
JA
382 }
383
d166f048
JA
384 val = subexpr (expr);
385
d166f048
JA
386 if (validp)
387 *validp = 1;
388
b80f6443
JA
389 FASTCOPY (oevalbuf, evalbuf, sizeof (evalbuf));
390
d166f048
JA
391 return (val);
392}
393
7117c2d2 394static intmax_t
d166f048
JA
395subexpr (expr)
396 char *expr;
397{
7117c2d2 398 intmax_t val;
d166f048
JA
399 char *p;
400
401 for (p = expr; p && *p && cr_whitespace (*p); p++)
402 ;
403
404 if (p == NULL || *p == '\0')
f73dda09 405 return (0);
d166f048 406
726f6388 407 pushexp ();
726f6388
JA
408 expression = savestring (expr);
409 tp = expression;
410
495aee44 411 curtok = lasttok = 0;
726f6388 412 tokstr = (char *)NULL;
f73dda09 413 tokval = 0;
495aee44
CR
414 init_lvalue (&curlval);
415 lastlval = curlval;
726f6388
JA
416
417 readtok ();
418
bb70624e 419 val = EXP_HIGHEST ();
726f6388 420
ccc6cda3 421 if (curtok != 0)
b80f6443 422 evalerror (_("syntax error in expression"));
726f6388 423
d166f048
JA
424 FREE (tokstr);
425 FREE (expression);
726f6388
JA
426
427 popexp ();
428
d166f048 429 return val;
726f6388
JA
430}
431
7117c2d2 432static intmax_t
bb70624e 433expcomma ()
726f6388 434{
7117c2d2 435 register intmax_t value;
726f6388 436
bb70624e
JA
437 value = expassign ();
438 while (curtok == COMMA)
726f6388 439 {
bb70624e
JA
440 readtok ();
441 value = expassign ();
726f6388
JA
442 }
443
bb70624e 444 return value;
726f6388 445}
bb70624e 446
7117c2d2 447static intmax_t
726f6388
JA
448expassign ()
449{
7117c2d2 450 register intmax_t value;
726f6388 451 char *lhs, *rhs;
495aee44 452 arrayind_t lind;
726f6388 453
ccc6cda3 454 value = expcond ();
726f6388
JA
455 if (curtok == EQ || curtok == OP_ASSIGN)
456 {
ccc6cda3 457 int special, op;
7117c2d2 458 intmax_t lvalue;
726f6388 459
ccc6cda3
JA
460 special = curtok == OP_ASSIGN;
461
726f6388 462 if (lasttok != STR)
b80f6443 463 evalerror (_("attempted assignment to non-variable"));
726f6388
JA
464
465 if (special)
466 {
467 op = assigntok; /* a OP= b */
468 lvalue = value;
469 }
470
471 lhs = savestring (tokstr);
495aee44
CR
472 /* save ind in case rhs is string var and evaluation overwrites it */
473 lind = curlval.ind;
726f6388
JA
474 readtok ();
475 value = expassign ();
476
477 if (special)
478 {
479 switch (op)
480 {
481 case MUL:
482 lvalue *= value;
483 break;
484 case DIV:
7117c2d2 485 if (value == 0)
b80f6443 486 evalerror (_("division by 0"));
726f6388
JA
487 lvalue /= value;
488 break;
489 case MOD:
7117c2d2 490 if (value == 0)
b80f6443 491 evalerror (_("division by 0"));
726f6388
JA
492 lvalue %= value;
493 break;
494 case PLUS:
495 lvalue += value;
496 break;
497 case MINUS:
498 lvalue -= value;
499 break;
500 case LSH:
501 lvalue <<= value;
502 break;
503 case RSH:
504 lvalue >>= value;
505 break;
506 case BAND:
507 lvalue &= value;
508 break;
509 case BOR:
510 lvalue |= value;
511 break;
28ef6c31
JA
512 case BXOR:
513 lvalue ^= value;
514 break;
726f6388 515 default:
d166f048 516 free (lhs);
b80f6443 517 evalerror (_("bug: bad expassign token"));
726f6388
JA
518 break;
519 }
520 value = lvalue;
521 }
522
523 rhs = itos (value);
ccc6cda3 524 if (noeval == 0)
495aee44
CR
525 {
526 if (lind != -1)
527 expr_bind_array_element (lhs, lind, rhs);
528 else
529 expr_bind_variable (lhs, rhs);
530 }
726f6388
JA
531 free (rhs);
532 free (lhs);
d166f048 533 FREE (tokstr);
726f6388
JA
534 tokstr = (char *)NULL; /* For freeing on errors. */
535 }
536 return (value);
537}
538
ccc6cda3 539/* Conditional expression (expr?expr:expr) */
7117c2d2 540static intmax_t
ccc6cda3
JA
541expcond ()
542{
7117c2d2 543 intmax_t cval, val1, val2, rval;
d166f048
JA
544 int set_noeval;
545
546 set_noeval = 0;
ccc6cda3
JA
547 rval = cval = explor ();
548 if (curtok == QUES) /* found conditional expr */
549 {
550 readtok ();
551 if (curtok == 0 || curtok == COL)
b80f6443 552 evalerror (_("expression expected"));
ccc6cda3 553 if (cval == 0)
d166f048
JA
554 {
555 set_noeval = 1;
556 noeval++;
557 }
f73dda09 558
bb70624e 559 val1 = EXP_HIGHEST ();
f73dda09 560
d166f048 561 if (set_noeval)
28ef6c31 562 noeval--;
ccc6cda3 563 if (curtok != COL)
b80f6443 564 evalerror (_("`:' expected for conditional expression"));
ccc6cda3
JA
565 readtok ();
566 if (curtok == 0)
b80f6443 567 evalerror (_("expression expected"));
d166f048 568 set_noeval = 0;
ccc6cda3 569 if (cval)
d166f048
JA
570 {
571 set_noeval = 1;
572 noeval++;
573 }
f1be666c
JA
574
575 val2 = expcond ();
d166f048 576 if (set_noeval)
28ef6c31 577 noeval--;
ccc6cda3
JA
578 rval = cval ? val1 : val2;
579 lasttok = COND;
580 }
581 return rval;
582}
583
726f6388 584/* Logical OR. */
7117c2d2 585static intmax_t
726f6388
JA
586explor ()
587{
7117c2d2 588 register intmax_t val1, val2;
d166f048 589 int set_noeval;
726f6388
JA
590
591 val1 = expland ();
592
593 while (curtok == LOR)
594 {
d166f048 595 set_noeval = 0;
ccc6cda3 596 if (val1 != 0)
d166f048
JA
597 {
598 noeval++;
599 set_noeval = 1;
600 }
601 readtok ();
726f6388 602 val2 = expland ();
d166f048 603 if (set_noeval)
ccc6cda3 604 noeval--;
726f6388 605 val1 = val1 || val2;
d166f048 606 lasttok = LOR;
726f6388
JA
607 }
608
609 return (val1);
610}
611
612/* Logical AND. */
7117c2d2 613static intmax_t
726f6388
JA
614expland ()
615{
7117c2d2 616 register intmax_t val1, val2;
d166f048 617 int set_noeval;
726f6388
JA
618
619 val1 = expbor ();
620
621 while (curtok == LAND)
622 {
d166f048 623 set_noeval = 0;
ccc6cda3 624 if (val1 == 0)
d166f048
JA
625 {
626 set_noeval = 1;
627 noeval++;
628 }
629 readtok ();
726f6388 630 val2 = expbor ();
d166f048 631 if (set_noeval)
ccc6cda3 632 noeval--;
726f6388 633 val1 = val1 && val2;
d166f048 634 lasttok = LAND;
726f6388
JA
635 }
636
637 return (val1);
638}
639
640/* Bitwise OR. */
7117c2d2 641static intmax_t
726f6388
JA
642expbor ()
643{
7117c2d2 644 register intmax_t val1, val2;
726f6388
JA
645
646 val1 = expbxor ();
647
648 while (curtok == BOR)
649 {
650 readtok ();
651 val2 = expbxor ();
652 val1 = val1 | val2;
653 }
654
655 return (val1);
656}
657
658/* Bitwise XOR. */
7117c2d2 659static intmax_t
726f6388
JA
660expbxor ()
661{
7117c2d2 662 register intmax_t val1, val2;
726f6388
JA
663
664 val1 = expband ();
665
666 while (curtok == BXOR)
667 {
668 readtok ();
669 val2 = expband ();
670 val1 = val1 ^ val2;
671 }
672
673 return (val1);
674}
675
676/* Bitwise AND. */
7117c2d2 677static intmax_t
726f6388
JA
678expband ()
679{
7117c2d2 680 register intmax_t val1, val2;
726f6388
JA
681
682 val1 = exp5 ();
683
684 while (curtok == BAND)
685 {
686 readtok ();
687 val2 = exp5 ();
688 val1 = val1 & val2;
689 }
690
691 return (val1);
692}
693
7117c2d2 694static intmax_t
726f6388
JA
695exp5 ()
696{
7117c2d2 697 register intmax_t val1, val2;
726f6388
JA
698
699 val1 = exp4 ();
700
701 while ((curtok == EQEQ) || (curtok == NEQ))
702 {
703 int op = curtok;
704
705 readtok ();
706 val2 = exp4 ();
707 if (op == EQEQ)
708 val1 = (val1 == val2);
709 else if (op == NEQ)
710 val1 = (val1 != val2);
711 }
712 return (val1);
713}
714
7117c2d2 715static intmax_t
726f6388
JA
716exp4 ()
717{
7117c2d2 718 register intmax_t val1, val2;
726f6388
JA
719
720 val1 = expshift ();
721 while ((curtok == LEQ) ||
722 (curtok == GEQ) ||
723 (curtok == LT) ||
724 (curtok == GT))
725 {
726 int op = curtok;
727
728 readtok ();
729 val2 = expshift ();
730
731 if (op == LEQ)
732 val1 = val1 <= val2;
733 else if (op == GEQ)
734 val1 = val1 >= val2;
735 else if (op == LT)
736 val1 = val1 < val2;
d166f048 737 else /* (op == GT) */
726f6388
JA
738 val1 = val1 > val2;
739 }
740 return (val1);
741}
742
743/* Left and right shifts. */
7117c2d2 744static intmax_t
726f6388
JA
745expshift ()
746{
7117c2d2 747 register intmax_t val1, val2;
726f6388
JA
748
749 val1 = exp3 ();
750
751 while ((curtok == LSH) || (curtok == RSH))
752 {
753 int op = curtok;
754
755 readtok ();
756 val2 = exp3 ();
757
758 if (op == LSH)
759 val1 = val1 << val2;
760 else
761 val1 = val1 >> val2;
762 }
763
764 return (val1);
765}
766
7117c2d2 767static intmax_t
726f6388
JA
768exp3 ()
769{
7117c2d2 770 register intmax_t val1, val2;
726f6388
JA
771
772 val1 = exp2 ();
773
774 while ((curtok == PLUS) || (curtok == MINUS))
775 {
776 int op = curtok;
777
778 readtok ();
779 val2 = exp2 ();
780
781 if (op == PLUS)
782 val1 += val2;
783 else if (op == MINUS)
784 val1 -= val2;
785 }
786 return (val1);
787}
788
7117c2d2 789static intmax_t
726f6388
JA
790exp2 ()
791{
7117c2d2 792 register intmax_t val1, val2;
726f6388 793
cce855bc 794 val1 = exppower ();
726f6388
JA
795
796 while ((curtok == MUL) ||
28ef6c31
JA
797 (curtok == DIV) ||
798 (curtok == MOD))
726f6388
JA
799 {
800 int op = curtok;
801
802 readtok ();
803
cce855bc 804 val2 = exppower ();
726f6388
JA
805
806 if (((op == DIV) || (op == MOD)) && (val2 == 0))
b80f6443 807 evalerror (_("division by 0"));
726f6388
JA
808
809 if (op == MUL)
28ef6c31 810 val1 *= val2;
726f6388 811 else if (op == DIV)
28ef6c31 812 val1 /= val2;
726f6388 813 else if (op == MOD)
28ef6c31 814 val1 %= val2;
726f6388
JA
815 }
816 return (val1);
817}
818
7117c2d2 819static intmax_t
cce855bc
JA
820exppower ()
821{
7117c2d2 822 register intmax_t val1, val2, c;
cce855bc
JA
823
824 val1 = exp1 ();
b80f6443 825 while (curtok == POWER)
cce855bc
JA
826 {
827 readtok ();
95732b49 828 val2 = exppower (); /* exponentiation is right-associative */
cce855bc 829 if (val2 == 0)
f73dda09 830 return (1);
bb70624e 831 if (val2 < 0)
b80f6443 832 evalerror (_("exponent less than 0"));
cce855bc
JA
833 for (c = 1; val2--; c *= val1)
834 ;
835 val1 = c;
836 }
837 return (val1);
838}
839
7117c2d2 840static intmax_t
726f6388
JA
841exp1 ()
842{
7117c2d2 843 register intmax_t val;
726f6388
JA
844
845 if (curtok == NOT)
846 {
847 readtok ();
848 val = !exp1 ();
849 }
850 else if (curtok == BNOT)
851 {
852 readtok ();
853 val = ~exp1 ();
854 }
495aee44
CR
855 else if (curtok == MINUS)
856 {
857 readtok ();
858 val = - exp1 ();
859 }
860 else if (curtok == PLUS)
861 {
862 readtok ();
863 val = exp1 ();
864 }
726f6388
JA
865 else
866 val = exp0 ();
867
868 return (val);
869}
870
7117c2d2 871static intmax_t
726f6388
JA
872exp0 ()
873{
7117c2d2 874 register intmax_t val = 0, v2;
bb70624e
JA
875 char *vincdec;
876 int stok;
b80f6443 877 EXPR_CONTEXT ec;
bb70624e
JA
878
879 /* XXX - might need additional logic here to decide whether or not
880 pre-increment or pre-decrement is legal at this point. */
881 if (curtok == PREINC || curtok == PREDEC)
882 {
883 stok = lasttok = curtok;
884 readtok ();
885 if (curtok != STR)
28ef6c31 886 /* readtok() catches this */
b80f6443 887 evalerror (_("identifier expected after pre-increment or pre-decrement"));
726f6388 888
bb70624e
JA
889 v2 = tokval + ((stok == PREINC) ? 1 : -1);
890 vincdec = itos (v2);
891 if (noeval == 0)
495aee44
CR
892 {
893 if (curlval.ind != -1)
894 expr_bind_array_element (curlval.tokstr, curlval.ind, vincdec);
895 else
896 expr_bind_variable (tokstr, vincdec);
897 }
bb70624e
JA
898 free (vincdec);
899 val = v2;
900
901 curtok = NUM; /* make sure --x=7 is flagged as an error */
902 readtok ();
903 }
726f6388
JA
904 else if (curtok == LPAR)
905 {
906 readtok ();
bb70624e 907 val = EXP_HIGHEST ();
726f6388 908
b80f6443
JA
909 if (curtok != RPAR) /* ( */
910 evalerror (_("missing `)'"));
726f6388
JA
911
912 /* Skip over closing paren. */
913 readtok ();
914 }
915 else if ((curtok == NUM) || (curtok == STR))
916 {
917 val = tokval;
b80f6443 918 if (curtok == STR)
bb70624e 919 {
b80f6443
JA
920 SAVETOK (&ec);
921 tokstr = (char *)NULL; /* keep it from being freed */
922 noeval = 1;
923 readtok ();
924 stok = curtok;
925
bb70624e 926 /* post-increment or post-decrement */
b80f6443
JA
927 if (stok == POSTINC || stok == POSTDEC)
928 {
929 /* restore certain portions of EC */
930 tokstr = ec.tokstr;
931 noeval = ec.noeval;
495aee44 932 curlval = ec.lval;
b80f6443
JA
933 lasttok = STR; /* ec.curtok */
934
935 v2 = val + ((stok == POSTINC) ? 1 : -1);
936 vincdec = itos (v2);
937 if (noeval == 0)
495aee44
CR
938 {
939 if (curlval.ind != -1)
940 expr_bind_array_element (curlval.tokstr, curlval.ind, vincdec);
941 else
942 expr_bind_variable (tokstr, vincdec);
943 }
b80f6443
JA
944 free (vincdec);
945 curtok = NUM; /* make sure x++=7 is flagged as an error */
946 }
947 else
948 {
949 if (stok == STR) /* free new tokstr before old one is restored */
950 FREE (tokstr);
951 RESTORETOK (&ec);
952 }
953
bb70624e
JA
954 }
955
726f6388
JA
956 readtok ();
957 }
958 else
b80f6443 959 evalerror (_("syntax error: operand expected"));
726f6388
JA
960
961 return (val);
962}
963
495aee44
CR
964static void
965init_lvalue (lv)
966 struct lvalue *lv;
967{
968 lv->tokstr = 0;
969 lv->tokvar = 0;
970 lv->tokval = lv->ind = -1;
971}
972
973static struct lvalue *
974alloc_lvalue ()
975{
976 struct lvalue *lv;
977
978 lv = xmalloc (sizeof (struct lvalue));
979 init_lvalue (lv);
980 return (lv);
981}
982
983static void
984free_lvalue (lv)
985 struct lvalue *lv;
986{
987 free (lv); /* should be inlined */
988}
989
7117c2d2 990static intmax_t
495aee44 991expr_streval (tok, e, lvalue)
7117c2d2
JA
992 char *tok;
993 int e;
495aee44 994 struct lvalue *lvalue;
7117c2d2
JA
995{
996 SHELL_VAR *v;
997 char *value;
998 intmax_t tval;
495aee44
CR
999#if defined (ARRAY_VARS)
1000 arrayind_t ind;
1001#endif
7117c2d2
JA
1002
1003 /* [[[[[ */
1004#if defined (ARRAY_VARS)
1005 v = (e == ']') ? array_variable_part (tok, (char **)0, (int *)0) : find_variable (tok);
1006#else
1007 v = find_variable (tok);
1008#endif
1009
1010 if ((v == 0 || invisible_p (v)) && unbound_vars_is_error)
1011 {
1012#if defined (ARRAY_VARS)
1013 value = (e == ']') ? array_variable_name (tok, (char **)0, (int *)0) : tok;
1014#else
1015 value = tok;
1016#endif
1017
0001803f 1018 last_command_exit_value = EXECUTION_FAILURE;
7117c2d2
JA
1019 err_unboundvar (value);
1020
1021#if defined (ARRAY_VARS)
1022 if (e == ']')
1023 FREE (value); /* array_variable_name returns new memory */
1024#endif
1025
1026 if (interactive_shell)
1027 {
1028 expr_unwind ();
f1be666c 1029 top_level_cleanup ();
7117c2d2
JA
1030 jump_to_top_level (DISCARD);
1031 }
1032 else
1033 jump_to_top_level (FORCE_EOF);
1034 }
1035
495aee44 1036 ind = -1;
7117c2d2
JA
1037#if defined (ARRAY_VARS)
1038 /* Second argument of 0 to get_array_value means that we don't allow
1039 references like array[@]. In this case, get_array_value is just
1040 like get_variable_value in that it does not return newly-allocated
1041 memory or quote the results. */
495aee44 1042 value = (e == ']') ? get_array_value (tok, 0, (int *)NULL, &ind) : get_variable_value (v);
7117c2d2
JA
1043#else
1044 value = get_variable_value (v);
1045#endif
1046
1047 tval = (value && *value) ? subexpr (value) : 0;
1048
495aee44
CR
1049 if (lvalue)
1050 {
1051 lvalue->tokstr = tok; /* XXX */
1052 lvalue->tokval = tval;
1053 lvalue->tokvar = v; /* XXX */
1054 lvalue->ind = ind;
1055 }
1056
7117c2d2
JA
1057 return (tval);
1058}
1059
0628567a
JA
1060static int
1061_is_multiop (c)
1062 int c;
1063{
1064 switch (c)
1065 {
1066 case EQEQ:
1067 case NEQ:
1068 case LEQ:
1069 case GEQ:
1070 case LAND:
1071 case LOR:
1072 case LSH:
1073 case RSH:
1074 case OP_ASSIGN:
1075 case COND:
1076 case POWER:
1077 case PREINC:
1078 case PREDEC:
1079 case POSTINC:
1080 case POSTDEC:
1081 return 1;
1082 default:
1083 return 0;
1084 }
1085}
1086
1087static int
1088_is_arithop (c)
1089 int c;
1090{
1091 switch (c)
1092 {
1093 case EQ:
1094 case GT:
1095 case LT:
1096 case PLUS:
1097 case MINUS:
1098 case MUL:
1099 case DIV:
1100 case MOD:
1101 case NOT:
1102 case LPAR:
1103 case RPAR:
1104 case BAND:
1105 case BOR:
1106 case BXOR:
1107 case BNOT:
1108 return 1; /* operator tokens */
1109 case QUES:
1110 case COL:
1111 case COMMA:
1112 return 1; /* questionable */
1113 default:
1114 return 0; /* anything else is invalid */
1115 }
1116}
1117
726f6388
JA
1118/* Lexical analyzer/token reader for the expression evaluator. Reads the
1119 next token and puts its value into curtok, while advancing past it.
1120 Updates value of tp. May also set tokval (for number) or tokstr (for
1121 string). */
1122static void
1123readtok ()
1124{
b80f6443 1125 register char *cp, *xp;
f73dda09
JA
1126 register unsigned char c, c1;
1127 register int e;
495aee44 1128 struct lvalue lval;
726f6388
JA
1129
1130 /* Skip leading whitespace. */
ccc6cda3
JA
1131 cp = tp;
1132 c = e = 0;
726f6388
JA
1133 while (cp && (c = *cp) && (cr_whitespace (c)))
1134 cp++;
1135
1136 if (c)
1137 cp++;
ccc6cda3 1138
726f6388
JA
1139 if (c == '\0')
1140 {
1141 lasttok = curtok;
1142 curtok = 0;
1143 tp = cp;
1144 return;
1145 }
3185942a 1146 lasttp = tp = cp - 1;
726f6388 1147
ccc6cda3 1148 if (legal_variable_starter (c))
726f6388 1149 {
bb70624e 1150 /* variable names not preceded with a dollar sign are shell variables. */
7117c2d2 1151 char *savecp;
bb70624e
JA
1152 EXPR_CONTEXT ec;
1153 int peektok;
726f6388 1154
ccc6cda3 1155 while (legal_variable_char (c))
726f6388
JA
1156 c = *cp++;
1157
1158 c = *--cp;
ccc6cda3
JA
1159
1160#if defined (ARRAY_VARS)
1161 if (c == '[')
1162 {
0001803f 1163 e = skipsubscript (cp, 0, 0);
ccc6cda3
JA
1164 if (cp[e] == ']')
1165 {
1166 cp += e + 1;
1167 c = *cp;
1168 e = ']';
1169 }
1170 else
b80f6443 1171 evalerror (bash_badsub_errmsg);
ccc6cda3
JA
1172 }
1173#endif /* ARRAY_VARS */
1174
726f6388 1175 *cp = '\0';
ccc6cda3 1176 FREE (tokstr);
726f6388 1177 tokstr = savestring (tp);
bb70624e 1178 *cp = c;
ccc6cda3 1179
495aee44 1180 /* XXX - make peektok part of saved token state? */
bb70624e
JA
1181 SAVETOK (&ec);
1182 tokstr = (char *)NULL; /* keep it from being freed */
1183 tp = savecp = cp;
1184 noeval = 1;
b80f6443 1185 curtok = STR;
bb70624e
JA
1186 readtok ();
1187 peektok = curtok;
1188 if (peektok == STR) /* free new tokstr before old one is restored */
1189 FREE (tokstr);
1190 RESTORETOK (&ec);
1191 cp = savecp;
1192
1193 /* The tests for PREINC and PREDEC aren't strictly correct, but they
1194 preserve old behavior if a construct like --x=9 is given. */
1195 if (lasttok == PREINC || lasttok == PREDEC || peektok != EQ)
495aee44
CR
1196 {
1197 lastlval = curlval;
1198 tokval = expr_streval (tokstr, e, &curlval);
1199 }
bb70624e 1200 else
28ef6c31 1201 tokval = 0;
726f6388 1202
726f6388
JA
1203 lasttok = curtok;
1204 curtok = STR;
1205 }
f73dda09 1206 else if (DIGIT(c))
726f6388 1207 {
f73dda09 1208 while (ISALNUM (c) || c == '#' || c == '@' || c == '_')
726f6388
JA
1209 c = *cp++;
1210
1211 c = *--cp;
1212 *cp = '\0';
1213
1214 tokval = strlong (tp);
1215 *cp = c;
1216 lasttok = curtok;
1217 curtok = NUM;
1218 }
1219 else
1220 {
1221 c1 = *cp++;
ccc6cda3 1222 if ((c == EQ) && (c1 == EQ))
726f6388
JA
1223 c = EQEQ;
1224 else if ((c == NOT) && (c1 == EQ))
1225 c = NEQ;
1226 else if ((c == GT) && (c1 == EQ))
1227 c = GEQ;
1228 else if ((c == LT) && (c1 == EQ))
1229 c = LEQ;
1230 else if ((c == LT) && (c1 == LT))
1231 {
1232 if (*cp == '=') /* a <<= b */
1233 {
1234 assigntok = LSH;
1235 c = OP_ASSIGN;
1236 cp++;
1237 }
1238 else
1239 c = LSH;
1240 }
1241 else if ((c == GT) && (c1 == GT))
1242 {
1243 if (*cp == '=')
1244 {
1245 assigntok = RSH; /* a >>= b */
1246 c = OP_ASSIGN;
1247 cp++;
1248 }
1249 else
1250 c = RSH;
1251 }
1252 else if ((c == BAND) && (c1 == BAND))
1253 c = LAND;
1254 else if ((c == BOR) && (c1 == BOR))
1255 c = LOR;
cce855bc 1256 else if ((c == '*') && (c1 == '*'))
28ef6c31 1257 c = POWER;
b80f6443
JA
1258 else if ((c == '-' || c == '+') && c1 == c && curtok == STR)
1259 c = (c == '-') ? POSTDEC : POSTINC;
1260 else if ((c == '-' || c == '+') && c1 == c)
1261 {
1262 /* Quickly scan forward to see if this is followed by optional
1263 whitespace and an identifier. */
1264 xp = cp;
1265 while (xp && *xp && cr_whitespace (*xp))
1266 xp++;
1267 if (legal_variable_starter ((unsigned char)*xp))
1268 c = (c == '-') ? PREDEC : PREINC;
1269 else
1270 cp--; /* not preinc or predec, so unget the character */
1271 }
28ef6c31 1272 else if (c1 == EQ && member (c, "*/%+-&^|"))
726f6388
JA
1273 {
1274 assigntok = c; /* a OP= b */
1275 c = OP_ASSIGN;
1276 }
0628567a
JA
1277 else if (_is_arithop (c) == 0)
1278 {
1279 cp--;
1280 /* use curtok, since it hasn't been copied to lasttok yet */
1281 if (curtok == 0 || _is_arithop (curtok) || _is_multiop (curtok))
1282 evalerror (_("syntax error: operand expected"));
1283 else
1284 evalerror (_("syntax error: invalid arithmetic operator"));
1285 }
726f6388
JA
1286 else
1287 cp--; /* `unget' the character */
0628567a
JA
1288
1289 /* Should check here to make sure that the current character is one
1290 of the recognized operators and flag an error if not. Could create
1291 a character map the first time through and check it on subsequent
1292 calls. */
726f6388
JA
1293 lasttok = curtok;
1294 curtok = c;
1295 }
1296 tp = cp;
1297}
1298
1299static void
1300evalerror (msg)
3185942a 1301 const char *msg;
726f6388
JA
1302{
1303 char *name, *t;
1304
1305 name = this_command_name;
726f6388
JA
1306 for (t = expression; whitespace (*t); t++)
1307 ;
3185942a 1308 internal_error (_("%s%s%s: %s (error token is \"%s\")"),
ccc6cda3
JA
1309 name ? name : "", name ? ": " : "", t,
1310 msg, (lasttp && *lasttp) ? lasttp : "");
726f6388
JA
1311 longjmp (evalbuf, 1);
1312}
1313
7117c2d2 1314/* Convert a string to an intmax_t integer, with an arbitrary base.
726f6388 1315 0nnn -> base 8
cce855bc 1316 0[Xx]nn -> base 16
ccc6cda3
JA
1317 Anything else: [base#]number (this is implemented to match ksh93)
1318
1319 Base may be >=2 and <=64. If base is <= 36, the numbers are drawn
1320 from [0-9][a-zA-Z], and lowercase and uppercase letters may be used
1321 interchangably. If base is > 36 and <= 64, the numbers are drawn
95732b49 1322 from [0-9][a-z][A-Z]_@ (a = 10, z = 35, A = 36, Z = 61, @ = 62, _ = 63 --
ccc6cda3
JA
1323 you get the picture). */
1324
7117c2d2 1325static intmax_t
726f6388
JA
1326strlong (num)
1327 char *num;
1328{
ccc6cda3 1329 register char *s;
f73dda09 1330 register unsigned char c;
ccc6cda3 1331 int base, foundbase;
7117c2d2 1332 intmax_t val;
726f6388 1333
ccc6cda3 1334 s = num;
726f6388 1335
ccc6cda3
JA
1336 base = 10;
1337 foundbase = 0;
726f6388
JA
1338 if (*s == '0')
1339 {
1340 s++;
1341
f73dda09
JA
1342 if (*s == '\0')
1343 return 0;
ccc6cda3 1344
726f6388
JA
1345 /* Base 16? */
1346 if (*s == 'x' || *s == 'X')
1347 {
1348 base = 16;
1349 s++;
1350 }
1351 else
1352 base = 8;
ccc6cda3 1353 foundbase++;
726f6388
JA
1354 }
1355
f73dda09 1356 val = 0;
726f6388
JA
1357 for (c = *s++; c; c = *s++)
1358 {
1359 if (c == '#')
1360 {
ccc6cda3 1361 if (foundbase)
b80f6443 1362 evalerror (_("invalid number"));
ccc6cda3 1363
ccc6cda3 1364 /* Illegal base specifications raise an evaluation error. */
f73dda09 1365 if (val < 2 || val > 64)
b80f6443 1366 evalerror (_("invalid arithmetic base"));
726f6388 1367
f73dda09
JA
1368 base = val;
1369 val = 0;
ccc6cda3
JA
1370 foundbase++;
1371 }
f73dda09 1372 else if (ISALNUM(c) || (c == '_') || (c == '@'))
ccc6cda3 1373 {
f73dda09
JA
1374 if (DIGIT(c))
1375 c = TODIGIT(c);
ccc6cda3
JA
1376 else if (c >= 'a' && c <= 'z')
1377 c -= 'a' - 10;
1378 else if (c >= 'A' && c <= 'Z')
1379 c -= 'A' - ((base <= 36) ? 10 : 36);
ccc6cda3 1380 else if (c == '@')
f73dda09
JA
1381 c = 62;
1382 else if (c == '_')
ccc6cda3
JA
1383 c = 63;
1384
1385 if (c >= base)
b80f6443 1386 evalerror (_("value too great for base"));
ccc6cda3
JA
1387
1388 val = (val * base) + c;
726f6388
JA
1389 }
1390 else
ccc6cda3 1391 break;
726f6388 1392 }
95732b49 1393
726f6388
JA
1394 return (val);
1395}
1396
1397#if defined (EXPR_TEST)
f73dda09 1398void *
726f6388
JA
1399xmalloc (n)
1400 int n;
1401{
1402 return (malloc (n));
1403}
1404
f73dda09 1405void *
726f6388
JA
1406xrealloc (s, n)
1407 char *s;
1408 int n;
1409{
1410 return (realloc (s, n));
1411}
1412
1413SHELL_VAR *find_variable () { return 0;}
1414SHELL_VAR *bind_variable () { return 0; }
1415
1416char *get_string_value () { return 0; }
1417
ccc6cda3 1418procenv_t top_level;
726f6388
JA
1419
1420main (argc, argv)
1421 int argc;
1422 char **argv;
1423{
1424 register int i;
7117c2d2 1425 intmax_t v;
d166f048 1426 int expok;
726f6388
JA
1427
1428 if (setjmp (top_level))
1429 exit (0);
1430
1431 for (i = 1; i < argc; i++)
1432 {
d166f048
JA
1433 v = evalexp (argv[i], &expok);
1434 if (expok == 0)
3185942a 1435 fprintf (stderr, _("%s: expression error\n"), argv[i]);
d166f048 1436 else
28ef6c31 1437 printf ("'%s' -> %ld\n", argv[i], v);
726f6388
JA
1438 }
1439 exit (0);
1440}
1441
1442int
1443builtin_error (format, arg1, arg2, arg3, arg4, arg5)
1444 char *format;
1445{
1446 fprintf (stderr, "expr: ");
1447 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
1448 fprintf (stderr, "\n");
1449 return 0;
1450}
1451
1452char *
1453itos (n)
7117c2d2 1454 intmax_t n;
726f6388
JA
1455{
1456 return ("42");
1457}
1458
1459#endif /* EXPR_TEST */