blob: c25160051ec6d1782e9dd1a7145530afee981ef6 [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001/* expr.c -- arithmetic expression evaluation. */
2
Jari Aalto31859422009-01-12 13:36:28 +00003/* Copyright (C) 1990-2009 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00004
5 This file is part of GNU Bash, the Bourne Again SHell.
6
Jari Aalto31859422009-01-12 13:36:28 +00007 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.
Jari Aalto726f6381996-08-26 18:22:31 +000011
Jari Aalto31859422009-01-12 13:36:28 +000012 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.
Jari Aalto726f6381996-08-26 18:22:31 +000016
17 You should have received a copy of the GNU General Public License
Jari Aalto31859422009-01-12 13:36:28 +000018 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19*/
Jari Aalto726f6381996-08-26 18:22:31 +000020
21/*
Jari Aalto7117c2d2002-07-17 14:10:11 +000022 All arithmetic is done as intmax_t integers with no checking for overflow
Jari Aalto726f6381996-08-26 18:22:31 +000023 (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
Jari Aaltobb706242000-03-17 21:46:59 +000028 "id++", "id--" [post-increment and post-decrement]
29 "++id", "--id" [pre-increment and pre-decrement]
Jari Aalto726f6381996-08-26 18:22:31 +000030 "-", "+" [(unary operators)]
31 "!", "~"
Jari Aaltocce855b1998-04-17 19:52:44 +000032 "**" [(exponentiation)]
Jari Aalto726f6381996-08-26 18:22:31 +000033 "*", "/", "%"
34 "+", "-"
35 "<<", ">>"
36 "<=", ">=", "<", ">"
37 "==", "!="
38 "&"
39 "^"
40 "|"
41 "&&"
42 "||"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000043 "expr ? expr : expr"
Jari Aaltocce855b1998-04-17 19:52:44 +000044 "=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", "&=", "^=", "|="
Jari Aaltob80f6442004-07-27 13:29:18 +000045 , [comma]
Jari Aalto726f6381996-08-26 18:22:31 +000046
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
Jari Aaltoccc6cda1996-12-23 17:02:34 +000069#include "config.h"
70
Jari Aalto726f6381996-08-26 18:22:31 +000071#include <stdio.h>
72#include "bashansi.h"
Jari Aaltocce855b1998-04-17 19:52:44 +000073
Jari Aaltoccc6cda1996-12-23 17:02:34 +000074#if defined (HAVE_UNISTD_H)
Jari Aaltocce855b1998-04-17 19:52:44 +000075# ifdef _MINIX
76# include <sys/types.h>
77# endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +000078# include <unistd.h>
79#endif
Jari Aalto726f6381996-08-26 18:22:31 +000080
Jari Aaltof73dda02001-11-13 17:56:06 +000081#include "chartypes.h"
Jari Aaltob80f6442004-07-27 13:29:18 +000082#include "bashintl.h"
Jari Aaltobb706242000-03-17 21:46:59 +000083
Jari Aaltoccc6cda1996-12-23 17:02:34 +000084#include "shell.h"
Jari Aalto726f6381996-08-26 18:22:31 +000085
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
Jari Aalto726f6381996-08-26 18:22:31 +000090/* 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
Jari Aaltoccc6cda1996-12-23 17:02:34 +000095 "let num=num+2" is given. */
Jari Aalto726f6381996-08-26 18:22:31 +000096#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 */
Jari Aaltocce855b1998-04-17 19:52:44 +0000111#define COND 12 /* exp1 ? exp2 : exp3 */
112#define POWER 13 /* exp1**exp2 */
Jari Aaltobb706242000-03-17 21:46:59 +0000113#define PREINC 14 /* ++var */
114#define PREDEC 15 /* --var */
115#define POSTINC 16 /* var++ */
116#define POSTDEC 17 /* var-- */
Jari Aalto726f6381996-08-26 18:22:31 +0000117#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 */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000129#define BOR '|' /* Bitwise OR. */
Jari Aalto726f6381996-08-26 18:22:31 +0000130#define BXOR '^' /* Bitwise eXclusive OR. */
131#define BNOT '~' /* Bitwise NOT; Two's complement. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000132#define QUES '?'
133#define COL ':'
Jari Aaltobb706242000-03-17 21:46:59 +0000134#define COMMA ','
135
136/* This should be the function corresponding to the operator with the
137 highest precedence. */
138#define EXP_HIGHEST expcomma
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000139
140static char *expression; /* The current expression */
141static char *tp; /* token lexical position */
142static char *lasttp; /* pointer to last token position */
143static int curtok; /* the current token */
144static int lasttok; /* the previous token */
145static int assigntok; /* the OP in OP= */
146static char *tokstr; /* current token string */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000147static intmax_t tokval; /* current token value */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000148static int noeval; /* set to 1 if no assignment to be done */
149static procenv_t evalbuf;
150
Jari Aalto06285672006-10-10 14:15:34 +0000151static int _is_arithop __P((int));
Jari Aaltof73dda02001-11-13 17:56:06 +0000152static void readtok __P((void)); /* lexical analyzer */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000153
154static intmax_t expr_streval __P((char *, int));
155static intmax_t strlong __P((char *));
Jari Aalto31859422009-01-12 13:36:28 +0000156static void evalerror __P((const char *));
Jari Aaltof73dda02001-11-13 17:56:06 +0000157
158static void pushexp __P((void));
159static void popexp __P((void));
Jari Aalto7117c2d2002-07-17 14:10:11 +0000160static void expr_unwind __P((void));
Jari Aaltob80f6442004-07-27 13:29:18 +0000161static void expr_bind_variable __P((char *, char *));
Jari Aaltof73dda02001-11-13 17:56:06 +0000162
Jari Aalto7117c2d2002-07-17 14:10:11 +0000163static intmax_t subexpr __P((char *));
Jari Aaltof73dda02001-11-13 17:56:06 +0000164
Jari Aalto7117c2d2002-07-17 14:10:11 +0000165static intmax_t expcomma __P((void));
166static intmax_t expassign __P((void));
167static intmax_t expcond __P((void));
168static intmax_t explor __P((void));
169static intmax_t expland __P((void));
170static intmax_t expbor __P((void));
171static intmax_t expbxor __P((void));
172static intmax_t expband __P((void));
173static intmax_t exp5 __P((void));
174static intmax_t exp4 __P((void));
175static intmax_t expshift __P((void));
176static intmax_t exp3 __P((void));
177static intmax_t exp2 __P((void));
178static intmax_t exppower __P((void));
179static intmax_t exp1 __P((void));
180static intmax_t exp0 __P((void));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000181
182/* A structure defining a single expression context. */
183typedef struct {
184 int curtok, lasttok;
Jari Aaltobb706242000-03-17 21:46:59 +0000185 char *expression, *tp, *lasttp;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000186 intmax_t tokval;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000187 char *tokstr;
Jari Aaltobb706242000-03-17 21:46:59 +0000188 int noeval;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000189} EXPR_CONTEXT;
190
Jari Aaltof73dda02001-11-13 17:56:06 +0000191#ifdef INCLUDE_UNUSED
192/* Not used yet. */
Jari Aaltobb706242000-03-17 21:46:59 +0000193typedef struct {
194 char *tokstr;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000195 intmax_t tokval;
Jari Aaltobb706242000-03-17 21:46:59 +0000196} LVALUE;
Jari Aaltof73dda02001-11-13 17:56:06 +0000197#endif
Jari Aaltobb706242000-03-17 21:46:59 +0000198
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000199/* Global var which contains the stack of expression contexts. */
200static EXPR_CONTEXT **expr_stack;
201static int expr_depth; /* Location in the stack. */
202static int expr_stack_size; /* Number of slots already allocated. */
203
204extern char *this_command_name;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000205extern int unbound_vars_is_error;
Jari Aalto726f6381996-08-26 18:22:31 +0000206
Jari Aaltob80f6442004-07-27 13:29:18 +0000207#if defined (ARRAY_VARS)
Jari Aalto31859422009-01-12 13:36:28 +0000208extern const char * const bash_badsub_errmsg;
Jari Aaltob80f6442004-07-27 13:29:18 +0000209#endif
210
Jari Aaltobb706242000-03-17 21:46:59 +0000211#define SAVETOK(X) \
212 do { \
213 (X)->curtok = curtok; \
214 (X)->lasttok = lasttok; \
215 (X)->tp = tp; \
216 (X)->lasttp = lasttp; \
217 (X)->tokval = tokval; \
218 (X)->tokstr = tokstr; \
219 (X)->noeval = noeval; \
220 } while (0)
221
222#define RESTORETOK(X) \
223 do { \
224 curtok = (X)->curtok; \
225 lasttok = (X)->lasttok; \
226 tp = (X)->tp; \
227 lasttp = (X)->lasttp; \
228 tokval = (X)->tokval; \
229 tokstr = (X)->tokstr; \
230 noeval = (X)->noeval; \
231 } while (0)
232
Jari Aalto726f6381996-08-26 18:22:31 +0000233/* Push and save away the contents of the globals describing the
234 current expression context. */
235static void
236pushexp ()
237{
238 EXPR_CONTEXT *context;
239
Jari Aalto726f6381996-08-26 18:22:31 +0000240 if (expr_depth >= MAX_EXPR_RECURSION_LEVEL)
Jari Aaltob80f6442004-07-27 13:29:18 +0000241 evalerror (_("expression recursion level exceeded"));
Jari Aalto726f6381996-08-26 18:22:31 +0000242
243 if (expr_depth >= expr_stack_size)
244 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000245 expr_stack_size += EXPR_STACK_GROW_SIZE;
246 expr_stack = (EXPR_CONTEXT **)xrealloc (expr_stack, expr_stack_size * sizeof (EXPR_CONTEXT *));
Jari Aalto726f6381996-08-26 18:22:31 +0000247 }
248
Jari Aaltod166f041997-06-05 14:59:13 +0000249 context = (EXPR_CONTEXT *)xmalloc (sizeof (EXPR_CONTEXT));
250
Jari Aalto726f6381996-08-26 18:22:31 +0000251 context->expression = expression;
Jari Aaltobb706242000-03-17 21:46:59 +0000252 SAVETOK(context);
253
Jari Aalto726f6381996-08-26 18:22:31 +0000254 expr_stack[expr_depth++] = context;
255}
256
257/* Pop the the contents of the expression context stack into the
258 globals describing the current expression context. */
259static void
260popexp ()
261{
262 EXPR_CONTEXT *context;
263
264 if (expr_depth == 0)
Jari Aaltob80f6442004-07-27 13:29:18 +0000265 evalerror (_("recursion stack underflow"));
Jari Aalto726f6381996-08-26 18:22:31 +0000266
267 context = expr_stack[--expr_depth];
Jari Aaltobb706242000-03-17 21:46:59 +0000268
Jari Aalto726f6381996-08-26 18:22:31 +0000269 expression = context->expression;
Jari Aaltobb706242000-03-17 21:46:59 +0000270 RESTORETOK (context);
271
Jari Aalto726f6381996-08-26 18:22:31 +0000272 free (context);
273}
274
Jari Aalto7117c2d2002-07-17 14:10:11 +0000275static void
276expr_unwind ()
277{
278 while (--expr_depth > 0)
279 {
280 if (expr_stack[expr_depth]->tokstr)
281 free (expr_stack[expr_depth]->tokstr);
282
283 if (expr_stack[expr_depth]->expression)
284 free (expr_stack[expr_depth]->expression);
285
286 free (expr_stack[expr_depth]);
287 }
288 free (expr_stack[expr_depth]); /* free the allocated EXPR_CONTEXT */
Jari Aaltof1be6662008-11-18 13:15:12 +0000289
290 noeval = 0; /* XXX */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000291}
292
Jari Aaltob80f6442004-07-27 13:29:18 +0000293static void
294expr_bind_variable (lhs, rhs)
295 char *lhs, *rhs;
296{
297 (void)bind_int_variable (lhs, rhs);
298 stupidly_hack_special_variables (lhs);
299}
300
Jari Aaltod166f041997-06-05 14:59:13 +0000301/* Evaluate EXPR, and return the arithmetic result. If VALIDP is
302 non-null, a zero is stored into the location to which it points
303 if the expression is invalid, non-zero otherwise. If a non-zero
304 value is returned in *VALIDP, the return value of evalexp() may
305 be used.
Jari Aalto726f6381996-08-26 18:22:31 +0000306
307 The `while' loop after the longjmp is caught relies on the above
308 implementation of pushexp and popexp leaving in expr_stack[0] the
309 values that the variables had when the program started. That is,
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000310 the first things saved are the initial values of the variables that
Jari Aalto726f6381996-08-26 18:22:31 +0000311 were assigned at program startup or by the compiler. Therefore, it is
312 safe to let the loop terminate when expr_depth == 0, without freeing up
313 any of the expr_depth[0] stuff. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000314intmax_t
Jari Aaltod166f041997-06-05 14:59:13 +0000315evalexp (expr, validp)
Jari Aalto726f6381996-08-26 18:22:31 +0000316 char *expr;
Jari Aaltod166f041997-06-05 14:59:13 +0000317 int *validp;
Jari Aalto726f6381996-08-26 18:22:31 +0000318{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000319 intmax_t val;
Jari Aaltob80f6442004-07-27 13:29:18 +0000320 int c;
321 procenv_t oevalbuf;
Jari Aalto726f6381996-08-26 18:22:31 +0000322
Jari Aaltof73dda02001-11-13 17:56:06 +0000323 val = 0;
Jari Aaltof1be6662008-11-18 13:15:12 +0000324 noeval = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000325
Jari Aaltob80f6442004-07-27 13:29:18 +0000326 FASTCOPY (evalbuf, oevalbuf, sizeof (evalbuf));
327
328 c = setjmp (evalbuf);
329
330 if (c)
Jari Aalto726f6381996-08-26 18:22:31 +0000331 {
Jari Aaltod166f041997-06-05 14:59:13 +0000332 FREE (tokstr);
333 FREE (expression);
334 tokstr = expression = (char *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +0000335
Jari Aalto7117c2d2002-07-17 14:10:11 +0000336 expr_unwind ();
Jari Aaltod166f041997-06-05 14:59:13 +0000337
338 if (validp)
339 *validp = 0;
Jari Aaltof73dda02001-11-13 17:56:06 +0000340 return (0);
Jari Aalto726f6381996-08-26 18:22:31 +0000341 }
342
Jari Aaltod166f041997-06-05 14:59:13 +0000343 val = subexpr (expr);
344
Jari Aaltod166f041997-06-05 14:59:13 +0000345 if (validp)
346 *validp = 1;
347
Jari Aaltob80f6442004-07-27 13:29:18 +0000348 FASTCOPY (oevalbuf, evalbuf, sizeof (evalbuf));
349
Jari Aaltod166f041997-06-05 14:59:13 +0000350 return (val);
351}
352
Jari Aalto7117c2d2002-07-17 14:10:11 +0000353static intmax_t
Jari Aaltod166f041997-06-05 14:59:13 +0000354subexpr (expr)
355 char *expr;
356{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000357 intmax_t val;
Jari Aaltod166f041997-06-05 14:59:13 +0000358 char *p;
359
360 for (p = expr; p && *p && cr_whitespace (*p); p++)
361 ;
362
363 if (p == NULL || *p == '\0')
Jari Aaltof73dda02001-11-13 17:56:06 +0000364 return (0);
Jari Aaltod166f041997-06-05 14:59:13 +0000365
Jari Aalto726f6381996-08-26 18:22:31 +0000366 pushexp ();
367 curtok = lasttok = 0;
368 expression = savestring (expr);
369 tp = expression;
370
371 tokstr = (char *)NULL;
Jari Aaltof73dda02001-11-13 17:56:06 +0000372 tokval = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000373
374 readtok ();
375
Jari Aaltobb706242000-03-17 21:46:59 +0000376 val = EXP_HIGHEST ();
Jari Aalto726f6381996-08-26 18:22:31 +0000377
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000378 if (curtok != 0)
Jari Aaltob80f6442004-07-27 13:29:18 +0000379 evalerror (_("syntax error in expression"));
Jari Aalto726f6381996-08-26 18:22:31 +0000380
Jari Aaltod166f041997-06-05 14:59:13 +0000381 FREE (tokstr);
382 FREE (expression);
Jari Aalto726f6381996-08-26 18:22:31 +0000383
384 popexp ();
385
Jari Aaltod166f041997-06-05 14:59:13 +0000386 return val;
Jari Aalto726f6381996-08-26 18:22:31 +0000387}
388
Jari Aalto7117c2d2002-07-17 14:10:11 +0000389static intmax_t
Jari Aaltobb706242000-03-17 21:46:59 +0000390expcomma ()
Jari Aalto726f6381996-08-26 18:22:31 +0000391{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000392 register intmax_t value;
Jari Aalto726f6381996-08-26 18:22:31 +0000393
Jari Aaltobb706242000-03-17 21:46:59 +0000394 value = expassign ();
395 while (curtok == COMMA)
Jari Aalto726f6381996-08-26 18:22:31 +0000396 {
Jari Aaltobb706242000-03-17 21:46:59 +0000397 readtok ();
398 value = expassign ();
Jari Aalto726f6381996-08-26 18:22:31 +0000399 }
400
Jari Aaltobb706242000-03-17 21:46:59 +0000401 return value;
Jari Aalto726f6381996-08-26 18:22:31 +0000402}
Jari Aaltobb706242000-03-17 21:46:59 +0000403
Jari Aalto7117c2d2002-07-17 14:10:11 +0000404static intmax_t
Jari Aalto726f6381996-08-26 18:22:31 +0000405expassign ()
406{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000407 register intmax_t value;
Jari Aalto726f6381996-08-26 18:22:31 +0000408 char *lhs, *rhs;
409
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000410 value = expcond ();
Jari Aalto726f6381996-08-26 18:22:31 +0000411 if (curtok == EQ || curtok == OP_ASSIGN)
412 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000413 int special, op;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000414 intmax_t lvalue;
Jari Aalto726f6381996-08-26 18:22:31 +0000415
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000416 special = curtok == OP_ASSIGN;
417
Jari Aalto726f6381996-08-26 18:22:31 +0000418 if (lasttok != STR)
Jari Aaltob80f6442004-07-27 13:29:18 +0000419 evalerror (_("attempted assignment to non-variable"));
Jari Aalto726f6381996-08-26 18:22:31 +0000420
421 if (special)
422 {
423 op = assigntok; /* a OP= b */
424 lvalue = value;
425 }
426
427 lhs = savestring (tokstr);
428 readtok ();
429 value = expassign ();
430
431 if (special)
432 {
433 switch (op)
434 {
435 case MUL:
436 lvalue *= value;
437 break;
438 case DIV:
Jari Aalto7117c2d2002-07-17 14:10:11 +0000439 if (value == 0)
Jari Aaltob80f6442004-07-27 13:29:18 +0000440 evalerror (_("division by 0"));
Jari Aalto726f6381996-08-26 18:22:31 +0000441 lvalue /= value;
442 break;
443 case MOD:
Jari Aalto7117c2d2002-07-17 14:10:11 +0000444 if (value == 0)
Jari Aaltob80f6442004-07-27 13:29:18 +0000445 evalerror (_("division by 0"));
Jari Aalto726f6381996-08-26 18:22:31 +0000446 lvalue %= value;
447 break;
448 case PLUS:
449 lvalue += value;
450 break;
451 case MINUS:
452 lvalue -= value;
453 break;
454 case LSH:
455 lvalue <<= value;
456 break;
457 case RSH:
458 lvalue >>= value;
459 break;
460 case BAND:
461 lvalue &= value;
462 break;
463 case BOR:
464 lvalue |= value;
465 break;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000466 case BXOR:
467 lvalue ^= value;
468 break;
Jari Aalto726f6381996-08-26 18:22:31 +0000469 default:
Jari Aaltod166f041997-06-05 14:59:13 +0000470 free (lhs);
Jari Aaltob80f6442004-07-27 13:29:18 +0000471 evalerror (_("bug: bad expassign token"));
Jari Aalto726f6381996-08-26 18:22:31 +0000472 break;
473 }
474 value = lvalue;
475 }
476
477 rhs = itos (value);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000478 if (noeval == 0)
Jari Aaltob80f6442004-07-27 13:29:18 +0000479 expr_bind_variable (lhs, rhs);
Jari Aalto726f6381996-08-26 18:22:31 +0000480 free (rhs);
481 free (lhs);
Jari Aaltod166f041997-06-05 14:59:13 +0000482 FREE (tokstr);
Jari Aalto726f6381996-08-26 18:22:31 +0000483 tokstr = (char *)NULL; /* For freeing on errors. */
484 }
485 return (value);
486}
487
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000488/* Conditional expression (expr?expr:expr) */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000489static intmax_t
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000490expcond ()
491{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000492 intmax_t cval, val1, val2, rval;
Jari Aaltod166f041997-06-05 14:59:13 +0000493 int set_noeval;
494
495 set_noeval = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000496 rval = cval = explor ();
497 if (curtok == QUES) /* found conditional expr */
498 {
499 readtok ();
500 if (curtok == 0 || curtok == COL)
Jari Aaltob80f6442004-07-27 13:29:18 +0000501 evalerror (_("expression expected"));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000502 if (cval == 0)
Jari Aaltod166f041997-06-05 14:59:13 +0000503 {
504 set_noeval = 1;
505 noeval++;
506 }
Jari Aaltof73dda02001-11-13 17:56:06 +0000507
Jari Aaltobb706242000-03-17 21:46:59 +0000508 val1 = EXP_HIGHEST ();
Jari Aaltof73dda02001-11-13 17:56:06 +0000509
Jari Aaltod166f041997-06-05 14:59:13 +0000510 if (set_noeval)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000511 noeval--;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000512 if (curtok != COL)
Jari Aaltob80f6442004-07-27 13:29:18 +0000513 evalerror (_("`:' expected for conditional expression"));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000514 readtok ();
515 if (curtok == 0)
Jari Aaltob80f6442004-07-27 13:29:18 +0000516 evalerror (_("expression expected"));
Jari Aaltod166f041997-06-05 14:59:13 +0000517 set_noeval = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000518 if (cval)
Jari Aaltod166f041997-06-05 14:59:13 +0000519 {
520 set_noeval = 1;
521 noeval++;
522 }
Jari Aaltof1be6662008-11-18 13:15:12 +0000523
524 val2 = expcond ();
Jari Aaltod166f041997-06-05 14:59:13 +0000525 if (set_noeval)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000526 noeval--;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000527 rval = cval ? val1 : val2;
528 lasttok = COND;
529 }
530 return rval;
531}
532
Jari Aalto726f6381996-08-26 18:22:31 +0000533/* Logical OR. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000534static intmax_t
Jari Aalto726f6381996-08-26 18:22:31 +0000535explor ()
536{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000537 register intmax_t val1, val2;
Jari Aaltod166f041997-06-05 14:59:13 +0000538 int set_noeval;
Jari Aalto726f6381996-08-26 18:22:31 +0000539
540 val1 = expland ();
541
542 while (curtok == LOR)
543 {
Jari Aaltod166f041997-06-05 14:59:13 +0000544 set_noeval = 0;
545 if (val1 != 0)
546 {
547 noeval++;
548 set_noeval = 1;
549 }
Jari Aalto726f6381996-08-26 18:22:31 +0000550 readtok ();
551 val2 = expland ();
Jari Aaltod166f041997-06-05 14:59:13 +0000552 if (set_noeval)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000553 noeval--;
Jari Aalto726f6381996-08-26 18:22:31 +0000554 val1 = val1 || val2;
Jari Aaltod166f041997-06-05 14:59:13 +0000555 lasttok = LOR;
Jari Aalto726f6381996-08-26 18:22:31 +0000556 }
557
558 return (val1);
559}
560
561/* Logical AND. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000562static intmax_t
Jari Aalto726f6381996-08-26 18:22:31 +0000563expland ()
564{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000565 register intmax_t val1, val2;
Jari Aaltod166f041997-06-05 14:59:13 +0000566 int set_noeval;
Jari Aalto726f6381996-08-26 18:22:31 +0000567
568 val1 = expbor ();
569
570 while (curtok == LAND)
571 {
Jari Aaltod166f041997-06-05 14:59:13 +0000572 set_noeval = 0;
573 if (val1 == 0)
574 {
575 set_noeval = 1;
576 noeval++;
577 }
Jari Aalto726f6381996-08-26 18:22:31 +0000578 readtok ();
579 val2 = expbor ();
Jari Aaltod166f041997-06-05 14:59:13 +0000580 if (set_noeval)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000581 noeval--;
Jari Aalto726f6381996-08-26 18:22:31 +0000582 val1 = val1 && val2;
Jari Aaltod166f041997-06-05 14:59:13 +0000583 lasttok = LAND;
Jari Aalto726f6381996-08-26 18:22:31 +0000584 }
585
586 return (val1);
587}
588
589/* Bitwise OR. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000590static intmax_t
Jari Aalto726f6381996-08-26 18:22:31 +0000591expbor ()
592{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000593 register intmax_t val1, val2;
Jari Aalto726f6381996-08-26 18:22:31 +0000594
595 val1 = expbxor ();
596
597 while (curtok == BOR)
598 {
599 readtok ();
600 val2 = expbxor ();
601 val1 = val1 | val2;
602 }
603
604 return (val1);
605}
606
607/* Bitwise XOR. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000608static intmax_t
Jari Aalto726f6381996-08-26 18:22:31 +0000609expbxor ()
610{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000611 register intmax_t val1, val2;
Jari Aalto726f6381996-08-26 18:22:31 +0000612
613 val1 = expband ();
614
615 while (curtok == BXOR)
616 {
617 readtok ();
618 val2 = expband ();
619 val1 = val1 ^ val2;
620 }
621
622 return (val1);
623}
624
625/* Bitwise AND. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000626static intmax_t
Jari Aalto726f6381996-08-26 18:22:31 +0000627expband ()
628{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000629 register intmax_t val1, val2;
Jari Aalto726f6381996-08-26 18:22:31 +0000630
631 val1 = exp5 ();
632
633 while (curtok == BAND)
634 {
635 readtok ();
636 val2 = exp5 ();
637 val1 = val1 & val2;
638 }
639
640 return (val1);
641}
642
Jari Aalto7117c2d2002-07-17 14:10:11 +0000643static intmax_t
Jari Aalto726f6381996-08-26 18:22:31 +0000644exp5 ()
645{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000646 register intmax_t val1, val2;
Jari Aalto726f6381996-08-26 18:22:31 +0000647
648 val1 = exp4 ();
649
650 while ((curtok == EQEQ) || (curtok == NEQ))
651 {
652 int op = curtok;
653
654 readtok ();
655 val2 = exp4 ();
656 if (op == EQEQ)
657 val1 = (val1 == val2);
658 else if (op == NEQ)
659 val1 = (val1 != val2);
660 }
661 return (val1);
662}
663
Jari Aalto7117c2d2002-07-17 14:10:11 +0000664static intmax_t
Jari Aalto726f6381996-08-26 18:22:31 +0000665exp4 ()
666{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000667 register intmax_t val1, val2;
Jari Aalto726f6381996-08-26 18:22:31 +0000668
669 val1 = expshift ();
670 while ((curtok == LEQ) ||
671 (curtok == GEQ) ||
672 (curtok == LT) ||
673 (curtok == GT))
674 {
675 int op = curtok;
676
677 readtok ();
678 val2 = expshift ();
679
680 if (op == LEQ)
681 val1 = val1 <= val2;
682 else if (op == GEQ)
683 val1 = val1 >= val2;
684 else if (op == LT)
685 val1 = val1 < val2;
Jari Aaltod166f041997-06-05 14:59:13 +0000686 else /* (op == GT) */
Jari Aalto726f6381996-08-26 18:22:31 +0000687 val1 = val1 > val2;
688 }
689 return (val1);
690}
691
692/* Left and right shifts. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000693static intmax_t
Jari Aalto726f6381996-08-26 18:22:31 +0000694expshift ()
695{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000696 register intmax_t val1, val2;
Jari Aalto726f6381996-08-26 18:22:31 +0000697
698 val1 = exp3 ();
699
700 while ((curtok == LSH) || (curtok == RSH))
701 {
702 int op = curtok;
703
704 readtok ();
705 val2 = exp3 ();
706
707 if (op == LSH)
708 val1 = val1 << val2;
709 else
710 val1 = val1 >> val2;
711 }
712
713 return (val1);
714}
715
Jari Aalto7117c2d2002-07-17 14:10:11 +0000716static intmax_t
Jari Aalto726f6381996-08-26 18:22:31 +0000717exp3 ()
718{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000719 register intmax_t val1, val2;
Jari Aalto726f6381996-08-26 18:22:31 +0000720
721 val1 = exp2 ();
722
723 while ((curtok == PLUS) || (curtok == MINUS))
724 {
725 int op = curtok;
726
727 readtok ();
728 val2 = exp2 ();
729
730 if (op == PLUS)
731 val1 += val2;
732 else if (op == MINUS)
733 val1 -= val2;
734 }
735 return (val1);
736}
737
Jari Aalto7117c2d2002-07-17 14:10:11 +0000738static intmax_t
Jari Aalto726f6381996-08-26 18:22:31 +0000739exp2 ()
740{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000741 register intmax_t val1, val2;
Jari Aalto726f6381996-08-26 18:22:31 +0000742
Jari Aaltocce855b1998-04-17 19:52:44 +0000743 val1 = exppower ();
Jari Aalto726f6381996-08-26 18:22:31 +0000744
745 while ((curtok == MUL) ||
Jari Aalto28ef6c32001-04-06 19:14:31 +0000746 (curtok == DIV) ||
747 (curtok == MOD))
Jari Aalto726f6381996-08-26 18:22:31 +0000748 {
749 int op = curtok;
750
751 readtok ();
752
Jari Aaltocce855b1998-04-17 19:52:44 +0000753 val2 = exppower ();
Jari Aalto726f6381996-08-26 18:22:31 +0000754
755 if (((op == DIV) || (op == MOD)) && (val2 == 0))
Jari Aaltob80f6442004-07-27 13:29:18 +0000756 evalerror (_("division by 0"));
Jari Aalto726f6381996-08-26 18:22:31 +0000757
758 if (op == MUL)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000759 val1 *= val2;
Jari Aalto726f6381996-08-26 18:22:31 +0000760 else if (op == DIV)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000761 val1 /= val2;
Jari Aalto726f6381996-08-26 18:22:31 +0000762 else if (op == MOD)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000763 val1 %= val2;
Jari Aalto726f6381996-08-26 18:22:31 +0000764 }
765 return (val1);
766}
767
Jari Aalto7117c2d2002-07-17 14:10:11 +0000768static intmax_t
Jari Aaltocce855b1998-04-17 19:52:44 +0000769exppower ()
770{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000771 register intmax_t val1, val2, c;
Jari Aaltocce855b1998-04-17 19:52:44 +0000772
773 val1 = exp1 ();
Jari Aaltob80f6442004-07-27 13:29:18 +0000774 while (curtok == POWER)
Jari Aaltocce855b1998-04-17 19:52:44 +0000775 {
776 readtok ();
Jari Aalto95732b42005-12-07 14:08:12 +0000777 val2 = exppower (); /* exponentiation is right-associative */
Jari Aaltocce855b1998-04-17 19:52:44 +0000778 if (val2 == 0)
Jari Aaltof73dda02001-11-13 17:56:06 +0000779 return (1);
Jari Aaltobb706242000-03-17 21:46:59 +0000780 if (val2 < 0)
Jari Aaltob80f6442004-07-27 13:29:18 +0000781 evalerror (_("exponent less than 0"));
Jari Aaltocce855b1998-04-17 19:52:44 +0000782 for (c = 1; val2--; c *= val1)
783 ;
784 val1 = c;
785 }
786 return (val1);
787}
788
Jari Aalto7117c2d2002-07-17 14:10:11 +0000789static intmax_t
Jari Aalto726f6381996-08-26 18:22:31 +0000790exp1 ()
791{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000792 register intmax_t val;
Jari Aalto726f6381996-08-26 18:22:31 +0000793
794 if (curtok == NOT)
795 {
796 readtok ();
797 val = !exp1 ();
798 }
799 else if (curtok == BNOT)
800 {
801 readtok ();
802 val = ~exp1 ();
803 }
804 else
805 val = exp0 ();
806
807 return (val);
808}
809
Jari Aalto7117c2d2002-07-17 14:10:11 +0000810static intmax_t
Jari Aalto726f6381996-08-26 18:22:31 +0000811exp0 ()
812{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000813 register intmax_t val = 0, v2;
Jari Aaltobb706242000-03-17 21:46:59 +0000814 char *vincdec;
815 int stok;
Jari Aaltob80f6442004-07-27 13:29:18 +0000816 EXPR_CONTEXT ec;
Jari Aalto726f6381996-08-26 18:22:31 +0000817
Jari Aaltobb706242000-03-17 21:46:59 +0000818 /* XXX - might need additional logic here to decide whether or not
819 pre-increment or pre-decrement is legal at this point. */
820 if (curtok == PREINC || curtok == PREDEC)
821 {
822 stok = lasttok = curtok;
823 readtok ();
824 if (curtok != STR)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000825 /* readtok() catches this */
Jari Aaltob80f6442004-07-27 13:29:18 +0000826 evalerror (_("identifier expected after pre-increment or pre-decrement"));
Jari Aaltobb706242000-03-17 21:46:59 +0000827
828 v2 = tokval + ((stok == PREINC) ? 1 : -1);
829 vincdec = itos (v2);
830 if (noeval == 0)
Jari Aaltob80f6442004-07-27 13:29:18 +0000831 expr_bind_variable (tokstr, vincdec);
Jari Aaltobb706242000-03-17 21:46:59 +0000832 free (vincdec);
833 val = v2;
834
835 curtok = NUM; /* make sure --x=7 is flagged as an error */
836 readtok ();
837 }
838 else if (curtok == MINUS)
Jari Aalto726f6381996-08-26 18:22:31 +0000839 {
840 readtok ();
841 val = - exp0 ();
842 }
843 else if (curtok == PLUS)
844 {
845 readtok ();
846 val = exp0 ();
847 }
848 else if (curtok == LPAR)
849 {
850 readtok ();
Jari Aaltobb706242000-03-17 21:46:59 +0000851 val = EXP_HIGHEST ();
Jari Aalto726f6381996-08-26 18:22:31 +0000852
Jari Aaltob80f6442004-07-27 13:29:18 +0000853 if (curtok != RPAR) /* ( */
854 evalerror (_("missing `)'"));
Jari Aalto726f6381996-08-26 18:22:31 +0000855
856 /* Skip over closing paren. */
857 readtok ();
858 }
859 else if ((curtok == NUM) || (curtok == STR))
860 {
861 val = tokval;
Jari Aaltob80f6442004-07-27 13:29:18 +0000862 if (curtok == STR)
Jari Aaltobb706242000-03-17 21:46:59 +0000863 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000864 SAVETOK (&ec);
865 tokstr = (char *)NULL; /* keep it from being freed */
866 noeval = 1;
867 readtok ();
868 stok = curtok;
869
Jari Aaltobb706242000-03-17 21:46:59 +0000870 /* post-increment or post-decrement */
Jari Aaltob80f6442004-07-27 13:29:18 +0000871 if (stok == POSTINC || stok == POSTDEC)
872 {
873 /* restore certain portions of EC */
874 tokstr = ec.tokstr;
875 noeval = ec.noeval;
876 lasttok = STR; /* ec.curtok */
877
878 v2 = val + ((stok == POSTINC) ? 1 : -1);
879 vincdec = itos (v2);
880 if (noeval == 0)
881 expr_bind_variable (tokstr, vincdec);
882 free (vincdec);
883 curtok = NUM; /* make sure x++=7 is flagged as an error */
884 }
885 else
886 {
887 if (stok == STR) /* free new tokstr before old one is restored */
888 FREE (tokstr);
889 RESTORETOK (&ec);
890 }
891
Jari Aaltobb706242000-03-17 21:46:59 +0000892 }
893
Jari Aalto726f6381996-08-26 18:22:31 +0000894 readtok ();
895 }
896 else
Jari Aaltob80f6442004-07-27 13:29:18 +0000897 evalerror (_("syntax error: operand expected"));
Jari Aalto726f6381996-08-26 18:22:31 +0000898
899 return (val);
900}
901
Jari Aalto7117c2d2002-07-17 14:10:11 +0000902static intmax_t
903expr_streval (tok, e)
904 char *tok;
905 int e;
906{
907 SHELL_VAR *v;
908 char *value;
909 intmax_t tval;
910
911 /* [[[[[ */
912#if defined (ARRAY_VARS)
913 v = (e == ']') ? array_variable_part (tok, (char **)0, (int *)0) : find_variable (tok);
914#else
915 v = find_variable (tok);
916#endif
917
918 if ((v == 0 || invisible_p (v)) && unbound_vars_is_error)
919 {
920#if defined (ARRAY_VARS)
921 value = (e == ']') ? array_variable_name (tok, (char **)0, (int *)0) : tok;
922#else
923 value = tok;
924#endif
925
926 err_unboundvar (value);
927
928#if defined (ARRAY_VARS)
929 if (e == ']')
930 FREE (value); /* array_variable_name returns new memory */
931#endif
932
933 if (interactive_shell)
934 {
935 expr_unwind ();
Jari Aaltof1be6662008-11-18 13:15:12 +0000936 top_level_cleanup ();
Jari Aalto7117c2d2002-07-17 14:10:11 +0000937 jump_to_top_level (DISCARD);
938 }
939 else
940 jump_to_top_level (FORCE_EOF);
941 }
942
943#if defined (ARRAY_VARS)
944 /* Second argument of 0 to get_array_value means that we don't allow
945 references like array[@]. In this case, get_array_value is just
946 like get_variable_value in that it does not return newly-allocated
947 memory or quote the results. */
948 value = (e == ']') ? get_array_value (tok, 0, (int *)NULL) : get_variable_value (v);
949#else
950 value = get_variable_value (v);
951#endif
952
953 tval = (value && *value) ? subexpr (value) : 0;
954
955 return (tval);
956}
957
Jari Aalto06285672006-10-10 14:15:34 +0000958static int
959_is_multiop (c)
960 int c;
961{
962 switch (c)
963 {
964 case EQEQ:
965 case NEQ:
966 case LEQ:
967 case GEQ:
968 case LAND:
969 case LOR:
970 case LSH:
971 case RSH:
972 case OP_ASSIGN:
973 case COND:
974 case POWER:
975 case PREINC:
976 case PREDEC:
977 case POSTINC:
978 case POSTDEC:
979 return 1;
980 default:
981 return 0;
982 }
983}
984
985static int
986_is_arithop (c)
987 int c;
988{
989 switch (c)
990 {
991 case EQ:
992 case GT:
993 case LT:
994 case PLUS:
995 case MINUS:
996 case MUL:
997 case DIV:
998 case MOD:
999 case NOT:
1000 case LPAR:
1001 case RPAR:
1002 case BAND:
1003 case BOR:
1004 case BXOR:
1005 case BNOT:
1006 return 1; /* operator tokens */
1007 case QUES:
1008 case COL:
1009 case COMMA:
1010 return 1; /* questionable */
1011 default:
1012 return 0; /* anything else is invalid */
1013 }
1014}
1015
Jari Aalto726f6381996-08-26 18:22:31 +00001016/* Lexical analyzer/token reader for the expression evaluator. Reads the
1017 next token and puts its value into curtok, while advancing past it.
1018 Updates value of tp. May also set tokval (for number) or tokstr (for
1019 string). */
1020static void
1021readtok ()
1022{
Jari Aaltob80f6442004-07-27 13:29:18 +00001023 register char *cp, *xp;
Jari Aaltof73dda02001-11-13 17:56:06 +00001024 register unsigned char c, c1;
1025 register int e;
Jari Aalto726f6381996-08-26 18:22:31 +00001026
1027 /* Skip leading whitespace. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001028 cp = tp;
1029 c = e = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00001030 while (cp && (c = *cp) && (cr_whitespace (c)))
1031 cp++;
1032
1033 if (c)
1034 cp++;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001035
Jari Aalto726f6381996-08-26 18:22:31 +00001036 if (c == '\0')
1037 {
1038 lasttok = curtok;
1039 curtok = 0;
1040 tp = cp;
1041 return;
1042 }
Jari Aalto31859422009-01-12 13:36:28 +00001043 lasttp = tp = cp - 1;
Jari Aalto726f6381996-08-26 18:22:31 +00001044
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001045 if (legal_variable_starter (c))
Jari Aalto726f6381996-08-26 18:22:31 +00001046 {
Jari Aaltobb706242000-03-17 21:46:59 +00001047 /* variable names not preceded with a dollar sign are shell variables. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001048 char *savecp;
Jari Aaltobb706242000-03-17 21:46:59 +00001049 EXPR_CONTEXT ec;
1050 int peektok;
Jari Aalto726f6381996-08-26 18:22:31 +00001051
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001052 while (legal_variable_char (c))
Jari Aalto726f6381996-08-26 18:22:31 +00001053 c = *cp++;
1054
1055 c = *--cp;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001056
1057#if defined (ARRAY_VARS)
1058 if (c == '[')
1059 {
1060 e = skipsubscript (cp, 0);
1061 if (cp[e] == ']')
1062 {
1063 cp += e + 1;
1064 c = *cp;
1065 e = ']';
1066 }
1067 else
Jari Aaltob80f6442004-07-27 13:29:18 +00001068 evalerror (bash_badsub_errmsg);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001069 }
1070#endif /* ARRAY_VARS */
1071
Jari Aalto726f6381996-08-26 18:22:31 +00001072 *cp = '\0';
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001073 FREE (tokstr);
Jari Aalto726f6381996-08-26 18:22:31 +00001074 tokstr = savestring (tp);
Jari Aalto726f6381996-08-26 18:22:31 +00001075 *cp = c;
Jari Aaltobb706242000-03-17 21:46:59 +00001076
1077 SAVETOK (&ec);
1078 tokstr = (char *)NULL; /* keep it from being freed */
1079 tp = savecp = cp;
1080 noeval = 1;
Jari Aaltob80f6442004-07-27 13:29:18 +00001081 curtok = STR;
Jari Aaltobb706242000-03-17 21:46:59 +00001082 readtok ();
1083 peektok = curtok;
1084 if (peektok == STR) /* free new tokstr before old one is restored */
1085 FREE (tokstr);
1086 RESTORETOK (&ec);
1087 cp = savecp;
1088
1089 /* The tests for PREINC and PREDEC aren't strictly correct, but they
1090 preserve old behavior if a construct like --x=9 is given. */
1091 if (lasttok == PREINC || lasttok == PREDEC || peektok != EQ)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001092 tokval = expr_streval (tokstr, e);
Jari Aaltobb706242000-03-17 21:46:59 +00001093 else
Jari Aalto28ef6c32001-04-06 19:14:31 +00001094 tokval = 0;
Jari Aaltobb706242000-03-17 21:46:59 +00001095
Jari Aalto726f6381996-08-26 18:22:31 +00001096 lasttok = curtok;
1097 curtok = STR;
1098 }
Jari Aaltof73dda02001-11-13 17:56:06 +00001099 else if (DIGIT(c))
Jari Aalto726f6381996-08-26 18:22:31 +00001100 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001101 while (ISALNUM (c) || c == '#' || c == '@' || c == '_')
Jari Aalto726f6381996-08-26 18:22:31 +00001102 c = *cp++;
1103
1104 c = *--cp;
1105 *cp = '\0';
1106
1107 tokval = strlong (tp);
1108 *cp = c;
1109 lasttok = curtok;
1110 curtok = NUM;
1111 }
1112 else
1113 {
1114 c1 = *cp++;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001115 if ((c == EQ) && (c1 == EQ))
Jari Aalto726f6381996-08-26 18:22:31 +00001116 c = EQEQ;
1117 else if ((c == NOT) && (c1 == EQ))
1118 c = NEQ;
1119 else if ((c == GT) && (c1 == EQ))
1120 c = GEQ;
1121 else if ((c == LT) && (c1 == EQ))
1122 c = LEQ;
1123 else if ((c == LT) && (c1 == LT))
1124 {
1125 if (*cp == '=') /* a <<= b */
1126 {
1127 assigntok = LSH;
1128 c = OP_ASSIGN;
1129 cp++;
1130 }
1131 else
1132 c = LSH;
1133 }
1134 else if ((c == GT) && (c1 == GT))
1135 {
1136 if (*cp == '=')
1137 {
1138 assigntok = RSH; /* a >>= b */
1139 c = OP_ASSIGN;
1140 cp++;
1141 }
1142 else
1143 c = RSH;
1144 }
1145 else if ((c == BAND) && (c1 == BAND))
1146 c = LAND;
1147 else if ((c == BOR) && (c1 == BOR))
1148 c = LOR;
Jari Aaltocce855b1998-04-17 19:52:44 +00001149 else if ((c == '*') && (c1 == '*'))
Jari Aalto28ef6c32001-04-06 19:14:31 +00001150 c = POWER;
Jari Aaltob80f6442004-07-27 13:29:18 +00001151 else if ((c == '-' || c == '+') && c1 == c && curtok == STR)
1152 c = (c == '-') ? POSTDEC : POSTINC;
1153 else if ((c == '-' || c == '+') && c1 == c)
1154 {
1155 /* Quickly scan forward to see if this is followed by optional
1156 whitespace and an identifier. */
1157 xp = cp;
1158 while (xp && *xp && cr_whitespace (*xp))
1159 xp++;
1160 if (legal_variable_starter ((unsigned char)*xp))
1161 c = (c == '-') ? PREDEC : PREINC;
1162 else
1163 cp--; /* not preinc or predec, so unget the character */
1164 }
Jari Aalto28ef6c32001-04-06 19:14:31 +00001165 else if (c1 == EQ && member (c, "*/%+-&^|"))
Jari Aalto726f6381996-08-26 18:22:31 +00001166 {
1167 assigntok = c; /* a OP= b */
1168 c = OP_ASSIGN;
1169 }
Jari Aalto06285672006-10-10 14:15:34 +00001170 else if (_is_arithop (c) == 0)
1171 {
1172 cp--;
1173 /* use curtok, since it hasn't been copied to lasttok yet */
1174 if (curtok == 0 || _is_arithop (curtok) || _is_multiop (curtok))
1175 evalerror (_("syntax error: operand expected"));
1176 else
1177 evalerror (_("syntax error: invalid arithmetic operator"));
1178 }
Jari Aalto726f6381996-08-26 18:22:31 +00001179 else
1180 cp--; /* `unget' the character */
Jari Aalto06285672006-10-10 14:15:34 +00001181
1182 /* Should check here to make sure that the current character is one
1183 of the recognized operators and flag an error if not. Could create
1184 a character map the first time through and check it on subsequent
1185 calls. */
Jari Aalto726f6381996-08-26 18:22:31 +00001186 lasttok = curtok;
1187 curtok = c;
1188 }
1189 tp = cp;
1190}
1191
1192static void
1193evalerror (msg)
Jari Aalto31859422009-01-12 13:36:28 +00001194 const char *msg;
Jari Aalto726f6381996-08-26 18:22:31 +00001195{
1196 char *name, *t;
1197
1198 name = this_command_name;
Jari Aalto726f6381996-08-26 18:22:31 +00001199 for (t = expression; whitespace (*t); t++)
1200 ;
Jari Aalto31859422009-01-12 13:36:28 +00001201 internal_error (_("%s%s%s: %s (error token is \"%s\")"),
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001202 name ? name : "", name ? ": " : "", t,
1203 msg, (lasttp && *lasttp) ? lasttp : "");
Jari Aalto726f6381996-08-26 18:22:31 +00001204 longjmp (evalbuf, 1);
1205}
1206
Jari Aalto7117c2d2002-07-17 14:10:11 +00001207/* Convert a string to an intmax_t integer, with an arbitrary base.
Jari Aalto726f6381996-08-26 18:22:31 +00001208 0nnn -> base 8
Jari Aaltocce855b1998-04-17 19:52:44 +00001209 0[Xx]nn -> base 16
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001210 Anything else: [base#]number (this is implemented to match ksh93)
1211
1212 Base may be >=2 and <=64. If base is <= 36, the numbers are drawn
1213 from [0-9][a-zA-Z], and lowercase and uppercase letters may be used
1214 interchangably. If base is > 36 and <= 64, the numbers are drawn
Jari Aalto95732b42005-12-07 14:08:12 +00001215 from [0-9][a-z][A-Z]_@ (a = 10, z = 35, A = 36, Z = 61, @ = 62, _ = 63 --
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001216 you get the picture). */
1217
Jari Aalto7117c2d2002-07-17 14:10:11 +00001218static intmax_t
Jari Aalto726f6381996-08-26 18:22:31 +00001219strlong (num)
1220 char *num;
1221{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001222 register char *s;
Jari Aaltof73dda02001-11-13 17:56:06 +00001223 register unsigned char c;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001224 int base, foundbase;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001225 intmax_t val;
Jari Aalto726f6381996-08-26 18:22:31 +00001226
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001227 s = num;
Jari Aalto726f6381996-08-26 18:22:31 +00001228
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001229 base = 10;
1230 foundbase = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00001231 if (*s == '0')
1232 {
1233 s++;
1234
Jari Aaltof73dda02001-11-13 17:56:06 +00001235 if (*s == '\0')
1236 return 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001237
Jari Aalto726f6381996-08-26 18:22:31 +00001238 /* Base 16? */
1239 if (*s == 'x' || *s == 'X')
1240 {
1241 base = 16;
1242 s++;
1243 }
1244 else
1245 base = 8;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001246 foundbase++;
Jari Aalto726f6381996-08-26 18:22:31 +00001247 }
1248
Jari Aaltof73dda02001-11-13 17:56:06 +00001249 val = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00001250 for (c = *s++; c; c = *s++)
1251 {
1252 if (c == '#')
1253 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001254 if (foundbase)
Jari Aaltob80f6442004-07-27 13:29:18 +00001255 evalerror (_("invalid number"));
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001256
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001257 /* Illegal base specifications raise an evaluation error. */
Jari Aaltof73dda02001-11-13 17:56:06 +00001258 if (val < 2 || val > 64)
Jari Aaltob80f6442004-07-27 13:29:18 +00001259 evalerror (_("invalid arithmetic base"));
Jari Aalto726f6381996-08-26 18:22:31 +00001260
Jari Aaltof73dda02001-11-13 17:56:06 +00001261 base = val;
1262 val = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001263 foundbase++;
1264 }
Jari Aaltof73dda02001-11-13 17:56:06 +00001265 else if (ISALNUM(c) || (c == '_') || (c == '@'))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001266 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001267 if (DIGIT(c))
1268 c = TODIGIT(c);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001269 else if (c >= 'a' && c <= 'z')
1270 c -= 'a' - 10;
1271 else if (c >= 'A' && c <= 'Z')
1272 c -= 'A' - ((base <= 36) ? 10 : 36);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001273 else if (c == '@')
Jari Aaltof73dda02001-11-13 17:56:06 +00001274 c = 62;
1275 else if (c == '_')
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001276 c = 63;
1277
1278 if (c >= base)
Jari Aaltob80f6442004-07-27 13:29:18 +00001279 evalerror (_("value too great for base"));
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001280
1281 val = (val * base) + c;
Jari Aalto726f6381996-08-26 18:22:31 +00001282 }
1283 else
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001284 break;
Jari Aalto726f6381996-08-26 18:22:31 +00001285 }
Jari Aalto95732b42005-12-07 14:08:12 +00001286
Jari Aalto726f6381996-08-26 18:22:31 +00001287 return (val);
1288}
1289
1290#if defined (EXPR_TEST)
Jari Aaltof73dda02001-11-13 17:56:06 +00001291void *
Jari Aalto726f6381996-08-26 18:22:31 +00001292xmalloc (n)
1293 int n;
1294{
1295 return (malloc (n));
1296}
1297
Jari Aaltof73dda02001-11-13 17:56:06 +00001298void *
Jari Aalto726f6381996-08-26 18:22:31 +00001299xrealloc (s, n)
1300 char *s;
1301 int n;
1302{
1303 return (realloc (s, n));
1304}
1305
1306SHELL_VAR *find_variable () { return 0;}
1307SHELL_VAR *bind_variable () { return 0; }
1308
1309char *get_string_value () { return 0; }
1310
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001311procenv_t top_level;
Jari Aalto726f6381996-08-26 18:22:31 +00001312
1313main (argc, argv)
1314 int argc;
1315 char **argv;
1316{
1317 register int i;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001318 intmax_t v;
Jari Aaltod166f041997-06-05 14:59:13 +00001319 int expok;
Jari Aalto726f6381996-08-26 18:22:31 +00001320
1321 if (setjmp (top_level))
1322 exit (0);
1323
1324 for (i = 1; i < argc; i++)
1325 {
Jari Aaltod166f041997-06-05 14:59:13 +00001326 v = evalexp (argv[i], &expok);
1327 if (expok == 0)
Jari Aalto31859422009-01-12 13:36:28 +00001328 fprintf (stderr, _("%s: expression error\n"), argv[i]);
Jari Aaltod166f041997-06-05 14:59:13 +00001329 else
Jari Aalto28ef6c32001-04-06 19:14:31 +00001330 printf ("'%s' -> %ld\n", argv[i], v);
Jari Aalto726f6381996-08-26 18:22:31 +00001331 }
1332 exit (0);
1333}
1334
1335int
1336builtin_error (format, arg1, arg2, arg3, arg4, arg5)
1337 char *format;
1338{
1339 fprintf (stderr, "expr: ");
1340 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
1341 fprintf (stderr, "\n");
1342 return 0;
1343}
1344
1345char *
1346itos (n)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001347 intmax_t n;
Jari Aalto726f6381996-08-26 18:22:31 +00001348{
1349 return ("42");
1350}
1351
1352#endif /* EXPR_TEST */