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