]> git.ipfire.org Git - thirdparty/bash.git/blame - expr.c
Bash-4.2 direxpand with patch 23
[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 {
cf391c36
CR
479 if ((op == DIV || op == MOD) && value == 0)
480 {
481 if (noeval == 0)
482 evalerror (_("division by 0"));
483 else
484 value = 1;
485 }
486
726f6388
JA
487 switch (op)
488 {
489 case MUL:
490 lvalue *= value;
491 break;
492 case DIV:
493 lvalue /= value;
494 break;
495 case MOD:
496 lvalue %= value;
497 break;
498 case PLUS:
499 lvalue += value;
500 break;
501 case MINUS:
502 lvalue -= value;
503 break;
504 case LSH:
505 lvalue <<= value;
506 break;
507 case RSH:
508 lvalue >>= value;
509 break;
510 case BAND:
511 lvalue &= value;
512 break;
513 case BOR:
514 lvalue |= value;
515 break;
28ef6c31
JA
516 case BXOR:
517 lvalue ^= value;
518 break;
726f6388 519 default:
d166f048 520 free (lhs);
b80f6443 521 evalerror (_("bug: bad expassign token"));
726f6388
JA
522 break;
523 }
524 value = lvalue;
525 }
526
527 rhs = itos (value);
ccc6cda3 528 if (noeval == 0)
495aee44
CR
529 {
530 if (lind != -1)
531 expr_bind_array_element (lhs, lind, rhs);
532 else
533 expr_bind_variable (lhs, rhs);
534 }
726f6388
JA
535 free (rhs);
536 free (lhs);
d166f048 537 FREE (tokstr);
726f6388
JA
538 tokstr = (char *)NULL; /* For freeing on errors. */
539 }
540 return (value);
541}
542
ccc6cda3 543/* Conditional expression (expr?expr:expr) */
7117c2d2 544static intmax_t
ccc6cda3
JA
545expcond ()
546{
7117c2d2 547 intmax_t cval, val1, val2, rval;
d166f048
JA
548 int set_noeval;
549
550 set_noeval = 0;
ccc6cda3
JA
551 rval = cval = explor ();
552 if (curtok == QUES) /* found conditional expr */
553 {
554 readtok ();
555 if (curtok == 0 || curtok == COL)
b80f6443 556 evalerror (_("expression expected"));
ccc6cda3 557 if (cval == 0)
d166f048
JA
558 {
559 set_noeval = 1;
560 noeval++;
561 }
f73dda09 562
bb70624e 563 val1 = EXP_HIGHEST ();
f73dda09 564
d166f048 565 if (set_noeval)
28ef6c31 566 noeval--;
ccc6cda3 567 if (curtok != COL)
b80f6443 568 evalerror (_("`:' expected for conditional expression"));
ccc6cda3
JA
569 readtok ();
570 if (curtok == 0)
b80f6443 571 evalerror (_("expression expected"));
d166f048 572 set_noeval = 0;
ccc6cda3 573 if (cval)
d166f048
JA
574 {
575 set_noeval = 1;
576 noeval++;
577 }
f1be666c
JA
578
579 val2 = expcond ();
d166f048 580 if (set_noeval)
28ef6c31 581 noeval--;
ccc6cda3
JA
582 rval = cval ? val1 : val2;
583 lasttok = COND;
584 }
585 return rval;
586}
587
726f6388 588/* Logical OR. */
7117c2d2 589static intmax_t
726f6388
JA
590explor ()
591{
7117c2d2 592 register intmax_t val1, val2;
d166f048 593 int set_noeval;
726f6388
JA
594
595 val1 = expland ();
596
597 while (curtok == LOR)
598 {
d166f048 599 set_noeval = 0;
ccc6cda3 600 if (val1 != 0)
d166f048
JA
601 {
602 noeval++;
603 set_noeval = 1;
604 }
605 readtok ();
726f6388 606 val2 = expland ();
d166f048 607 if (set_noeval)
ccc6cda3 608 noeval--;
726f6388 609 val1 = val1 || val2;
d166f048 610 lasttok = LOR;
726f6388
JA
611 }
612
613 return (val1);
614}
615
616/* Logical AND. */
7117c2d2 617static intmax_t
726f6388
JA
618expland ()
619{
7117c2d2 620 register intmax_t val1, val2;
d166f048 621 int set_noeval;
726f6388
JA
622
623 val1 = expbor ();
624
625 while (curtok == LAND)
626 {
d166f048 627 set_noeval = 0;
ccc6cda3 628 if (val1 == 0)
d166f048
JA
629 {
630 set_noeval = 1;
631 noeval++;
632 }
633 readtok ();
726f6388 634 val2 = expbor ();
d166f048 635 if (set_noeval)
ccc6cda3 636 noeval--;
726f6388 637 val1 = val1 && val2;
d166f048 638 lasttok = LAND;
726f6388
JA
639 }
640
641 return (val1);
642}
643
644/* Bitwise OR. */
7117c2d2 645static intmax_t
726f6388
JA
646expbor ()
647{
7117c2d2 648 register intmax_t val1, val2;
726f6388
JA
649
650 val1 = expbxor ();
651
652 while (curtok == BOR)
653 {
654 readtok ();
655 val2 = expbxor ();
656 val1 = val1 | val2;
657 }
658
659 return (val1);
660}
661
662/* Bitwise XOR. */
7117c2d2 663static intmax_t
726f6388
JA
664expbxor ()
665{
7117c2d2 666 register intmax_t val1, val2;
726f6388
JA
667
668 val1 = expband ();
669
670 while (curtok == BXOR)
671 {
672 readtok ();
673 val2 = expband ();
674 val1 = val1 ^ val2;
675 }
676
677 return (val1);
678}
679
680/* Bitwise AND. */
7117c2d2 681static intmax_t
726f6388
JA
682expband ()
683{
7117c2d2 684 register intmax_t val1, val2;
726f6388
JA
685
686 val1 = exp5 ();
687
688 while (curtok == BAND)
689 {
690 readtok ();
691 val2 = exp5 ();
692 val1 = val1 & val2;
693 }
694
695 return (val1);
696}
697
7117c2d2 698static intmax_t
726f6388
JA
699exp5 ()
700{
7117c2d2 701 register intmax_t val1, val2;
726f6388
JA
702
703 val1 = exp4 ();
704
705 while ((curtok == EQEQ) || (curtok == NEQ))
706 {
707 int op = curtok;
708
709 readtok ();
710 val2 = exp4 ();
711 if (op == EQEQ)
712 val1 = (val1 == val2);
713 else if (op == NEQ)
714 val1 = (val1 != val2);
715 }
716 return (val1);
717}
718
7117c2d2 719static intmax_t
726f6388
JA
720exp4 ()
721{
7117c2d2 722 register intmax_t val1, val2;
726f6388
JA
723
724 val1 = expshift ();
725 while ((curtok == LEQ) ||
726 (curtok == GEQ) ||
727 (curtok == LT) ||
728 (curtok == GT))
729 {
730 int op = curtok;
731
732 readtok ();
733 val2 = expshift ();
734
735 if (op == LEQ)
736 val1 = val1 <= val2;
737 else if (op == GEQ)
738 val1 = val1 >= val2;
739 else if (op == LT)
740 val1 = val1 < val2;
d166f048 741 else /* (op == GT) */
726f6388
JA
742 val1 = val1 > val2;
743 }
744 return (val1);
745}
746
747/* Left and right shifts. */
7117c2d2 748static intmax_t
726f6388
JA
749expshift ()
750{
7117c2d2 751 register intmax_t val1, val2;
726f6388
JA
752
753 val1 = exp3 ();
754
755 while ((curtok == LSH) || (curtok == RSH))
756 {
757 int op = curtok;
758
759 readtok ();
760 val2 = exp3 ();
761
762 if (op == LSH)
763 val1 = val1 << val2;
764 else
765 val1 = val1 >> val2;
766 }
767
768 return (val1);
769}
770
7117c2d2 771static intmax_t
726f6388
JA
772exp3 ()
773{
7117c2d2 774 register intmax_t val1, val2;
726f6388
JA
775
776 val1 = exp2 ();
777
778 while ((curtok == PLUS) || (curtok == MINUS))
779 {
780 int op = curtok;
781
782 readtok ();
783 val2 = exp2 ();
784
785 if (op == PLUS)
786 val1 += val2;
787 else if (op == MINUS)
788 val1 -= val2;
789 }
790 return (val1);
791}
792
7117c2d2 793static intmax_t
726f6388
JA
794exp2 ()
795{
7117c2d2 796 register intmax_t val1, val2;
726f6388 797
cce855bc 798 val1 = exppower ();
726f6388
JA
799
800 while ((curtok == MUL) ||
28ef6c31
JA
801 (curtok == DIV) ||
802 (curtok == MOD))
726f6388
JA
803 {
804 int op = curtok;
805
806 readtok ();
807
cce855bc 808 val2 = exppower ();
726f6388
JA
809
810 if (((op == DIV) || (op == MOD)) && (val2 == 0))
cf391c36
CR
811 {
812 if (noeval == 0)
813 evalerror (_("division by 0"));
814 else
815 val2 = 1;
816 }
726f6388
JA
817
818 if (op == MUL)
28ef6c31 819 val1 *= val2;
726f6388 820 else if (op == DIV)
28ef6c31 821 val1 /= val2;
726f6388 822 else if (op == MOD)
28ef6c31 823 val1 %= val2;
726f6388
JA
824 }
825 return (val1);
826}
827
7117c2d2 828static intmax_t
cce855bc
JA
829exppower ()
830{
7117c2d2 831 register intmax_t val1, val2, c;
cce855bc
JA
832
833 val1 = exp1 ();
b80f6443 834 while (curtok == POWER)
cce855bc
JA
835 {
836 readtok ();
95732b49 837 val2 = exppower (); /* exponentiation is right-associative */
cce855bc 838 if (val2 == 0)
f73dda09 839 return (1);
bb70624e 840 if (val2 < 0)
b80f6443 841 evalerror (_("exponent less than 0"));
cce855bc
JA
842 for (c = 1; val2--; c *= val1)
843 ;
844 val1 = c;
845 }
846 return (val1);
847}
848
7117c2d2 849static intmax_t
726f6388
JA
850exp1 ()
851{
7117c2d2 852 register intmax_t val;
726f6388
JA
853
854 if (curtok == NOT)
855 {
856 readtok ();
857 val = !exp1 ();
858 }
859 else if (curtok == BNOT)
860 {
861 readtok ();
862 val = ~exp1 ();
863 }
495aee44
CR
864 else if (curtok == MINUS)
865 {
866 readtok ();
867 val = - exp1 ();
868 }
869 else if (curtok == PLUS)
870 {
871 readtok ();
872 val = exp1 ();
873 }
726f6388
JA
874 else
875 val = exp0 ();
876
877 return (val);
878}
879
7117c2d2 880static intmax_t
726f6388
JA
881exp0 ()
882{
7117c2d2 883 register intmax_t val = 0, v2;
bb70624e
JA
884 char *vincdec;
885 int stok;
b80f6443 886 EXPR_CONTEXT ec;
bb70624e
JA
887
888 /* XXX - might need additional logic here to decide whether or not
889 pre-increment or pre-decrement is legal at this point. */
890 if (curtok == PREINC || curtok == PREDEC)
891 {
892 stok = lasttok = curtok;
893 readtok ();
894 if (curtok != STR)
28ef6c31 895 /* readtok() catches this */
b80f6443 896 evalerror (_("identifier expected after pre-increment or pre-decrement"));
726f6388 897
bb70624e
JA
898 v2 = tokval + ((stok == PREINC) ? 1 : -1);
899 vincdec = itos (v2);
900 if (noeval == 0)
495aee44
CR
901 {
902 if (curlval.ind != -1)
903 expr_bind_array_element (curlval.tokstr, curlval.ind, vincdec);
904 else
905 expr_bind_variable (tokstr, vincdec);
906 }
bb70624e
JA
907 free (vincdec);
908 val = v2;
909
910 curtok = NUM; /* make sure --x=7 is flagged as an error */
911 readtok ();
912 }
726f6388
JA
913 else if (curtok == LPAR)
914 {
915 readtok ();
bb70624e 916 val = EXP_HIGHEST ();
726f6388 917
b80f6443
JA
918 if (curtok != RPAR) /* ( */
919 evalerror (_("missing `)'"));
726f6388
JA
920
921 /* Skip over closing paren. */
922 readtok ();
923 }
924 else if ((curtok == NUM) || (curtok == STR))
925 {
926 val = tokval;
b80f6443 927 if (curtok == STR)
bb70624e 928 {
b80f6443
JA
929 SAVETOK (&ec);
930 tokstr = (char *)NULL; /* keep it from being freed */
931 noeval = 1;
932 readtok ();
933 stok = curtok;
934
bb70624e 935 /* post-increment or post-decrement */
b80f6443
JA
936 if (stok == POSTINC || stok == POSTDEC)
937 {
938 /* restore certain portions of EC */
939 tokstr = ec.tokstr;
940 noeval = ec.noeval;
495aee44 941 curlval = ec.lval;
b80f6443
JA
942 lasttok = STR; /* ec.curtok */
943
944 v2 = val + ((stok == POSTINC) ? 1 : -1);
945 vincdec = itos (v2);
946 if (noeval == 0)
495aee44
CR
947 {
948 if (curlval.ind != -1)
949 expr_bind_array_element (curlval.tokstr, curlval.ind, vincdec);
950 else
951 expr_bind_variable (tokstr, vincdec);
952 }
b80f6443
JA
953 free (vincdec);
954 curtok = NUM; /* make sure x++=7 is flagged as an error */
955 }
956 else
957 {
958 if (stok == STR) /* free new tokstr before old one is restored */
959 FREE (tokstr);
960 RESTORETOK (&ec);
961 }
962
bb70624e
JA
963 }
964
726f6388
JA
965 readtok ();
966 }
967 else
b80f6443 968 evalerror (_("syntax error: operand expected"));
726f6388
JA
969
970 return (val);
971}
972
495aee44
CR
973static void
974init_lvalue (lv)
975 struct lvalue *lv;
976{
977 lv->tokstr = 0;
978 lv->tokvar = 0;
979 lv->tokval = lv->ind = -1;
980}
981
982static struct lvalue *
983alloc_lvalue ()
984{
985 struct lvalue *lv;
986
987 lv = xmalloc (sizeof (struct lvalue));
988 init_lvalue (lv);
989 return (lv);
990}
991
992static void
993free_lvalue (lv)
994 struct lvalue *lv;
995{
996 free (lv); /* should be inlined */
997}
998
7117c2d2 999static intmax_t
495aee44 1000expr_streval (tok, e, lvalue)
7117c2d2
JA
1001 char *tok;
1002 int e;
495aee44 1003 struct lvalue *lvalue;
7117c2d2
JA
1004{
1005 SHELL_VAR *v;
1006 char *value;
1007 intmax_t tval;
495aee44
CR
1008#if defined (ARRAY_VARS)
1009 arrayind_t ind;
1010#endif
7117c2d2
JA
1011
1012 /* [[[[[ */
1013#if defined (ARRAY_VARS)
1014 v = (e == ']') ? array_variable_part (tok, (char **)0, (int *)0) : find_variable (tok);
1015#else
1016 v = find_variable (tok);
1017#endif
1018
1019 if ((v == 0 || invisible_p (v)) && unbound_vars_is_error)
1020 {
1021#if defined (ARRAY_VARS)
1022 value = (e == ']') ? array_variable_name (tok, (char **)0, (int *)0) : tok;
1023#else
1024 value = tok;
1025#endif
1026
0001803f 1027 last_command_exit_value = EXECUTION_FAILURE;
7117c2d2
JA
1028 err_unboundvar (value);
1029
1030#if defined (ARRAY_VARS)
1031 if (e == ']')
1032 FREE (value); /* array_variable_name returns new memory */
1033#endif
1034
1035 if (interactive_shell)
1036 {
1037 expr_unwind ();
f1be666c 1038 top_level_cleanup ();
7117c2d2
JA
1039 jump_to_top_level (DISCARD);
1040 }
1041 else
1042 jump_to_top_level (FORCE_EOF);
1043 }
1044
495aee44 1045 ind = -1;
7117c2d2
JA
1046#if defined (ARRAY_VARS)
1047 /* Second argument of 0 to get_array_value means that we don't allow
1048 references like array[@]. In this case, get_array_value is just
1049 like get_variable_value in that it does not return newly-allocated
1050 memory or quote the results. */
495aee44 1051 value = (e == ']') ? get_array_value (tok, 0, (int *)NULL, &ind) : get_variable_value (v);
7117c2d2
JA
1052#else
1053 value = get_variable_value (v);
1054#endif
1055
1056 tval = (value && *value) ? subexpr (value) : 0;
1057
495aee44
CR
1058 if (lvalue)
1059 {
1060 lvalue->tokstr = tok; /* XXX */
1061 lvalue->tokval = tval;
1062 lvalue->tokvar = v; /* XXX */
1063 lvalue->ind = ind;
1064 }
1065
7117c2d2
JA
1066 return (tval);
1067}
1068
0628567a
JA
1069static int
1070_is_multiop (c)
1071 int c;
1072{
1073 switch (c)
1074 {
1075 case EQEQ:
1076 case NEQ:
1077 case LEQ:
1078 case GEQ:
1079 case LAND:
1080 case LOR:
1081 case LSH:
1082 case RSH:
1083 case OP_ASSIGN:
1084 case COND:
1085 case POWER:
1086 case PREINC:
1087 case PREDEC:
1088 case POSTINC:
1089 case POSTDEC:
1090 return 1;
1091 default:
1092 return 0;
1093 }
1094}
1095
1096static int
1097_is_arithop (c)
1098 int c;
1099{
1100 switch (c)
1101 {
1102 case EQ:
1103 case GT:
1104 case LT:
1105 case PLUS:
1106 case MINUS:
1107 case MUL:
1108 case DIV:
1109 case MOD:
1110 case NOT:
1111 case LPAR:
1112 case RPAR:
1113 case BAND:
1114 case BOR:
1115 case BXOR:
1116 case BNOT:
1117 return 1; /* operator tokens */
1118 case QUES:
1119 case COL:
1120 case COMMA:
1121 return 1; /* questionable */
1122 default:
1123 return 0; /* anything else is invalid */
1124 }
1125}
1126
726f6388
JA
1127/* Lexical analyzer/token reader for the expression evaluator. Reads the
1128 next token and puts its value into curtok, while advancing past it.
1129 Updates value of tp. May also set tokval (for number) or tokstr (for
1130 string). */
1131static void
1132readtok ()
1133{
b80f6443 1134 register char *cp, *xp;
f73dda09
JA
1135 register unsigned char c, c1;
1136 register int e;
495aee44 1137 struct lvalue lval;
726f6388
JA
1138
1139 /* Skip leading whitespace. */
ccc6cda3
JA
1140 cp = tp;
1141 c = e = 0;
726f6388
JA
1142 while (cp && (c = *cp) && (cr_whitespace (c)))
1143 cp++;
1144
1145 if (c)
1146 cp++;
ccc6cda3 1147
726f6388
JA
1148 if (c == '\0')
1149 {
1150 lasttok = curtok;
1151 curtok = 0;
1152 tp = cp;
1153 return;
1154 }
3185942a 1155 lasttp = tp = cp - 1;
726f6388 1156
ccc6cda3 1157 if (legal_variable_starter (c))
726f6388 1158 {
bb70624e 1159 /* variable names not preceded with a dollar sign are shell variables. */
7117c2d2 1160 char *savecp;
bb70624e
JA
1161 EXPR_CONTEXT ec;
1162 int peektok;
726f6388 1163
ccc6cda3 1164 while (legal_variable_char (c))
726f6388
JA
1165 c = *cp++;
1166
1167 c = *--cp;
ccc6cda3
JA
1168
1169#if defined (ARRAY_VARS)
1170 if (c == '[')
1171 {
0001803f 1172 e = skipsubscript (cp, 0, 0);
ccc6cda3
JA
1173 if (cp[e] == ']')
1174 {
1175 cp += e + 1;
1176 c = *cp;
1177 e = ']';
1178 }
1179 else
b80f6443 1180 evalerror (bash_badsub_errmsg);
ccc6cda3
JA
1181 }
1182#endif /* ARRAY_VARS */
1183
726f6388 1184 *cp = '\0';
ccc6cda3 1185 FREE (tokstr);
726f6388 1186 tokstr = savestring (tp);
bb70624e 1187 *cp = c;
ccc6cda3 1188
495aee44 1189 /* XXX - make peektok part of saved token state? */
bb70624e
JA
1190 SAVETOK (&ec);
1191 tokstr = (char *)NULL; /* keep it from being freed */
1192 tp = savecp = cp;
1193 noeval = 1;
b80f6443 1194 curtok = STR;
bb70624e
JA
1195 readtok ();
1196 peektok = curtok;
1197 if (peektok == STR) /* free new tokstr before old one is restored */
1198 FREE (tokstr);
1199 RESTORETOK (&ec);
1200 cp = savecp;
1201
1202 /* The tests for PREINC and PREDEC aren't strictly correct, but they
1203 preserve old behavior if a construct like --x=9 is given. */
1204 if (lasttok == PREINC || lasttok == PREDEC || peektok != EQ)
495aee44
CR
1205 {
1206 lastlval = curlval;
1207 tokval = expr_streval (tokstr, e, &curlval);
1208 }
bb70624e 1209 else
28ef6c31 1210 tokval = 0;
726f6388 1211
726f6388
JA
1212 lasttok = curtok;
1213 curtok = STR;
1214 }
f73dda09 1215 else if (DIGIT(c))
726f6388 1216 {
f73dda09 1217 while (ISALNUM (c) || c == '#' || c == '@' || c == '_')
726f6388
JA
1218 c = *cp++;
1219
1220 c = *--cp;
1221 *cp = '\0';
1222
1223 tokval = strlong (tp);
1224 *cp = c;
1225 lasttok = curtok;
1226 curtok = NUM;
1227 }
1228 else
1229 {
1230 c1 = *cp++;
ccc6cda3 1231 if ((c == EQ) && (c1 == EQ))
726f6388
JA
1232 c = EQEQ;
1233 else if ((c == NOT) && (c1 == EQ))
1234 c = NEQ;
1235 else if ((c == GT) && (c1 == EQ))
1236 c = GEQ;
1237 else if ((c == LT) && (c1 == EQ))
1238 c = LEQ;
1239 else if ((c == LT) && (c1 == LT))
1240 {
1241 if (*cp == '=') /* a <<= b */
1242 {
1243 assigntok = LSH;
1244 c = OP_ASSIGN;
1245 cp++;
1246 }
1247 else
1248 c = LSH;
1249 }
1250 else if ((c == GT) && (c1 == GT))
1251 {
1252 if (*cp == '=')
1253 {
1254 assigntok = RSH; /* a >>= b */
1255 c = OP_ASSIGN;
1256 cp++;
1257 }
1258 else
1259 c = RSH;
1260 }
1261 else if ((c == BAND) && (c1 == BAND))
1262 c = LAND;
1263 else if ((c == BOR) && (c1 == BOR))
1264 c = LOR;
cce855bc 1265 else if ((c == '*') && (c1 == '*'))
28ef6c31 1266 c = POWER;
b80f6443
JA
1267 else if ((c == '-' || c == '+') && c1 == c && curtok == STR)
1268 c = (c == '-') ? POSTDEC : POSTINC;
1269 else if ((c == '-' || c == '+') && c1 == c)
1270 {
1271 /* Quickly scan forward to see if this is followed by optional
1272 whitespace and an identifier. */
1273 xp = cp;
1274 while (xp && *xp && cr_whitespace (*xp))
1275 xp++;
1276 if (legal_variable_starter ((unsigned char)*xp))
1277 c = (c == '-') ? PREDEC : PREINC;
1278 else
1279 cp--; /* not preinc or predec, so unget the character */
1280 }
28ef6c31 1281 else if (c1 == EQ && member (c, "*/%+-&^|"))
726f6388
JA
1282 {
1283 assigntok = c; /* a OP= b */
1284 c = OP_ASSIGN;
1285 }
0628567a
JA
1286 else if (_is_arithop (c) == 0)
1287 {
1288 cp--;
1289 /* use curtok, since it hasn't been copied to lasttok yet */
1290 if (curtok == 0 || _is_arithop (curtok) || _is_multiop (curtok))
1291 evalerror (_("syntax error: operand expected"));
1292 else
1293 evalerror (_("syntax error: invalid arithmetic operator"));
1294 }
726f6388
JA
1295 else
1296 cp--; /* `unget' the character */
0628567a
JA
1297
1298 /* Should check here to make sure that the current character is one
1299 of the recognized operators and flag an error if not. Could create
1300 a character map the first time through and check it on subsequent
1301 calls. */
726f6388
JA
1302 lasttok = curtok;
1303 curtok = c;
1304 }
1305 tp = cp;
1306}
1307
1308static void
1309evalerror (msg)
3185942a 1310 const char *msg;
726f6388
JA
1311{
1312 char *name, *t;
1313
1314 name = this_command_name;
726f6388
JA
1315 for (t = expression; whitespace (*t); t++)
1316 ;
3185942a 1317 internal_error (_("%s%s%s: %s (error token is \"%s\")"),
ccc6cda3
JA
1318 name ? name : "", name ? ": " : "", t,
1319 msg, (lasttp && *lasttp) ? lasttp : "");
726f6388
JA
1320 longjmp (evalbuf, 1);
1321}
1322
7117c2d2 1323/* Convert a string to an intmax_t integer, with an arbitrary base.
726f6388 1324 0nnn -> base 8
cce855bc 1325 0[Xx]nn -> base 16
ccc6cda3
JA
1326 Anything else: [base#]number (this is implemented to match ksh93)
1327
1328 Base may be >=2 and <=64. If base is <= 36, the numbers are drawn
1329 from [0-9][a-zA-Z], and lowercase and uppercase letters may be used
1330 interchangably. If base is > 36 and <= 64, the numbers are drawn
95732b49 1331 from [0-9][a-z][A-Z]_@ (a = 10, z = 35, A = 36, Z = 61, @ = 62, _ = 63 --
ccc6cda3
JA
1332 you get the picture). */
1333
7117c2d2 1334static intmax_t
726f6388
JA
1335strlong (num)
1336 char *num;
1337{
ccc6cda3 1338 register char *s;
f73dda09 1339 register unsigned char c;
ccc6cda3 1340 int base, foundbase;
7117c2d2 1341 intmax_t val;
726f6388 1342
ccc6cda3 1343 s = num;
726f6388 1344
ccc6cda3
JA
1345 base = 10;
1346 foundbase = 0;
726f6388
JA
1347 if (*s == '0')
1348 {
1349 s++;
1350
f73dda09
JA
1351 if (*s == '\0')
1352 return 0;
ccc6cda3 1353
726f6388
JA
1354 /* Base 16? */
1355 if (*s == 'x' || *s == 'X')
1356 {
1357 base = 16;
1358 s++;
1359 }
1360 else
1361 base = 8;
ccc6cda3 1362 foundbase++;
726f6388
JA
1363 }
1364
f73dda09 1365 val = 0;
726f6388
JA
1366 for (c = *s++; c; c = *s++)
1367 {
1368 if (c == '#')
1369 {
ccc6cda3 1370 if (foundbase)
b80f6443 1371 evalerror (_("invalid number"));
ccc6cda3 1372
ccc6cda3 1373 /* Illegal base specifications raise an evaluation error. */
f73dda09 1374 if (val < 2 || val > 64)
b80f6443 1375 evalerror (_("invalid arithmetic base"));
726f6388 1376
f73dda09
JA
1377 base = val;
1378 val = 0;
ccc6cda3
JA
1379 foundbase++;
1380 }
f73dda09 1381 else if (ISALNUM(c) || (c == '_') || (c == '@'))
ccc6cda3 1382 {
f73dda09
JA
1383 if (DIGIT(c))
1384 c = TODIGIT(c);
ccc6cda3
JA
1385 else if (c >= 'a' && c <= 'z')
1386 c -= 'a' - 10;
1387 else if (c >= 'A' && c <= 'Z')
1388 c -= 'A' - ((base <= 36) ? 10 : 36);
ccc6cda3 1389 else if (c == '@')
f73dda09
JA
1390 c = 62;
1391 else if (c == '_')
ccc6cda3
JA
1392 c = 63;
1393
1394 if (c >= base)
b80f6443 1395 evalerror (_("value too great for base"));
ccc6cda3
JA
1396
1397 val = (val * base) + c;
726f6388
JA
1398 }
1399 else
ccc6cda3 1400 break;
726f6388 1401 }
95732b49 1402
726f6388
JA
1403 return (val);
1404}
1405
1406#if defined (EXPR_TEST)
f73dda09 1407void *
726f6388
JA
1408xmalloc (n)
1409 int n;
1410{
1411 return (malloc (n));
1412}
1413
f73dda09 1414void *
726f6388
JA
1415xrealloc (s, n)
1416 char *s;
1417 int n;
1418{
1419 return (realloc (s, n));
1420}
1421
1422SHELL_VAR *find_variable () { return 0;}
1423SHELL_VAR *bind_variable () { return 0; }
1424
1425char *get_string_value () { return 0; }
1426
ccc6cda3 1427procenv_t top_level;
726f6388
JA
1428
1429main (argc, argv)
1430 int argc;
1431 char **argv;
1432{
1433 register int i;
7117c2d2 1434 intmax_t v;
d166f048 1435 int expok;
726f6388
JA
1436
1437 if (setjmp (top_level))
1438 exit (0);
1439
1440 for (i = 1; i < argc; i++)
1441 {
d166f048
JA
1442 v = evalexp (argv[i], &expok);
1443 if (expok == 0)
3185942a 1444 fprintf (stderr, _("%s: expression error\n"), argv[i]);
d166f048 1445 else
28ef6c31 1446 printf ("'%s' -> %ld\n", argv[i], v);
726f6388
JA
1447 }
1448 exit (0);
1449}
1450
1451int
1452builtin_error (format, arg1, arg2, arg3, arg4, arg5)
1453 char *format;
1454{
1455 fprintf (stderr, "expr: ");
1456 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
1457 fprintf (stderr, "\n");
1458 return 0;
1459}
1460
1461char *
1462itos (n)
7117c2d2 1463 intmax_t n;
726f6388
JA
1464{
1465 return ("42");
1466}
1467
1468#endif /* EXPR_TEST */