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