]>
git.ipfire.org Git - thirdparty/bash.git/blob - expr.c
1 /* expr.c -- arithmetic expression evaluation. */
3 /* Copyright (C) 1990-2002 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
7 Bash is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 Bash is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bash; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
22 All arithmetic is done as intmax_t integers with no checking for overflow
23 (though division by 0 is caught and flagged as an error).
25 The following operators are handled, grouped into a set of levels in
26 order of decreasing precedence.
28 "id++", "id--" [post-increment and post-decrement]
29 "++id", "--id" [pre-increment and pre-decrement]
30 "-", "+" [(unary operators)]
32 "**" [(exponentiation)]
44 "=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", "&=", "^=", "|="
46 (Note that most of these operators have special meaning to bash, and an
47 entire expression should be quoted, e.g. "a=$a+1" or "a=a+1" to ensure
48 that it is passed intact to the evaluator when using `let'. When using
49 the $[] or $(( )) forms, the text between the `[' and `]' or `((' and `))'
50 is treated as if in double quotes.)
52 Sub-expressions within parentheses have a precedence level greater than
53 all of the above levels and are evaluated first. Within a single prece-
54 dence group, evaluation is left-to-right, except for the arithmetic
55 assignment operator (`='), which is evaluated right-to-left (as in C).
57 The expression evaluator returns the value of the expression (assignment
58 statements have as a value what is returned by the RHS). The `let'
59 builtin, on the other hand, returns 0 if the last expression evaluates to
60 a non-zero, and 1 otherwise.
62 Implementation is a recursive-descent parser.
73 #if defined (HAVE_UNISTD_H)
75 # include <sys/types.h>
80 #include "chartypes.h"
84 /* Because of the $((...)) construct, expressions may include newlines.
85 Here is a macro which accepts newlines, tabs and spaces as whitespace. */
86 #define cr_whitespace(c) (whitespace(c) || ((c) == '\n'))
88 /* Size be which the expression stack grows when neccessary. */
89 #define EXPR_STACK_GROW_SIZE 10
91 /* Maximum amount of recursion allowed. This prevents a non-integer
92 variable such as "num=num+2" from infinitely adding to itself when
93 "let num=num+2" is given. */
94 #define MAX_EXPR_RECURSION_LEVEL 1024
96 /* The Tokens. Singing "The Lion Sleeps Tonight". */
98 #define EQEQ 1 /* "==" */
99 #define NEQ 2 /* "!=" */
100 #define LEQ 3 /* "<=" */
101 #define GEQ 4 /* ">=" */
102 #define STR 5 /* string */
103 #define NUM 6 /* number */
104 #define LAND 7 /* "&&" Logical AND */
105 #define LOR 8 /* "||" Logical OR */
106 #define LSH 9 /* "<<" Left SHift */
107 #define RSH 10 /* ">>" Right SHift */
108 #define OP_ASSIGN 11 /* op= expassign as in Posix.2 */
109 #define COND 12 /* exp1 ? exp2 : exp3 */
110 #define POWER 13 /* exp1**exp2 */
111 #define PREINC 14 /* ++var */
112 #define PREDEC 15 /* --var */
113 #define POSTINC 16 /* var++ */
114 #define POSTDEC 17 /* var-- */
126 #define BAND '&' /* Bitwise AND */
127 #define BOR '|' /* Bitwise OR. */
128 #define BXOR '^' /* Bitwise eXclusive OR. */
129 #define BNOT '~' /* Bitwise NOT; Two's complement. */
134 /* This should be the function corresponding to the operator with the
135 highest precedence. */
136 #define EXP_HIGHEST expcomma
138 static char *expression
; /* The current expression */
139 static char *tp
; /* token lexical position */
140 static char *lasttp
; /* pointer to last token position */
141 static int curtok
; /* the current token */
142 static int lasttok
; /* the previous token */
143 static int assigntok
; /* the OP in OP= */
144 static char *tokstr
; /* current token string */
145 static intmax_t tokval
; /* current token value */
146 static int noeval
; /* set to 1 if no assignment to be done */
147 static procenv_t evalbuf
;
149 static void readtok
__P((void)); /* lexical analyzer */
151 static intmax_t expr_streval
__P((char *, int));
152 static intmax_t strlong
__P((char *));
153 static void evalerror
__P((char *));
155 static void pushexp
__P((void));
156 static void popexp
__P((void));
157 static void expr_unwind
__P((void));
159 static intmax_t subexpr
__P((char *));
161 static intmax_t expcomma
__P((void));
162 static intmax_t expassign
__P((void));
163 static intmax_t expcond
__P((void));
164 static intmax_t explor
__P((void));
165 static intmax_t expland
__P((void));
166 static intmax_t expbor
__P((void));
167 static intmax_t expbxor
__P((void));
168 static intmax_t expband
__P((void));
169 static intmax_t exp5
__P((void));
170 static intmax_t exp4
__P((void));
171 static intmax_t expshift
__P((void));
172 static intmax_t exp3
__P((void));
173 static intmax_t exp2
__P((void));
174 static intmax_t exppower
__P((void));
175 static intmax_t exp1
__P((void));
176 static intmax_t exp0
__P((void));
178 /* A structure defining a single expression context. */
181 char *expression
, *tp
, *lasttp
;
187 #ifdef INCLUDE_UNUSED
195 /* Global var which contains the stack of expression contexts. */
196 static EXPR_CONTEXT
**expr_stack
;
197 static int expr_depth
; /* Location in the stack. */
198 static int expr_stack_size
; /* Number of slots already allocated. */
200 extern char *this_command_name
;
201 extern int unbound_vars_is_error
;
205 (X)->curtok = curtok; \
206 (X)->lasttok = lasttok; \
208 (X)->lasttp = lasttp; \
209 (X)->tokval = tokval; \
210 (X)->tokstr = tokstr; \
211 (X)->noeval = noeval; \
214 #define RESTORETOK(X) \
216 curtok = (X)->curtok; \
217 lasttok = (X)->lasttok; \
219 lasttp = (X)->lasttp; \
220 tokval = (X)->tokval; \
221 tokstr = (X)->tokstr; \
222 noeval = (X)->noeval; \
225 /* Push and save away the contents of the globals describing the
226 current expression context. */
230 EXPR_CONTEXT
*context
;
232 if (expr_depth
>= MAX_EXPR_RECURSION_LEVEL
)
233 evalerror ("expression recursion level exceeded");
235 if (expr_depth
>= expr_stack_size
)
237 expr_stack_size
+= EXPR_STACK_GROW_SIZE
;
238 expr_stack
= (EXPR_CONTEXT
**)xrealloc (expr_stack
, expr_stack_size
* sizeof (EXPR_CONTEXT
*));
241 context
= (EXPR_CONTEXT
*)xmalloc (sizeof (EXPR_CONTEXT
));
243 context
->expression
= expression
;
246 expr_stack
[expr_depth
++] = context
;
249 /* Pop the the contents of the expression context stack into the
250 globals describing the current expression context. */
254 EXPR_CONTEXT
*context
;
257 evalerror ("recursion stack underflow");
259 context
= expr_stack
[--expr_depth
];
261 expression
= context
->expression
;
262 RESTORETOK (context
);
270 while (--expr_depth
> 0)
272 if (expr_stack
[expr_depth
]->tokstr
)
273 free (expr_stack
[expr_depth
]->tokstr
);
275 if (expr_stack
[expr_depth
]->expression
)
276 free (expr_stack
[expr_depth
]->expression
);
278 free (expr_stack
[expr_depth
]);
280 free (expr_stack
[expr_depth
]); /* free the allocated EXPR_CONTEXT */
283 /* Evaluate EXPR, and return the arithmetic result. If VALIDP is
284 non-null, a zero is stored into the location to which it points
285 if the expression is invalid, non-zero otherwise. If a non-zero
286 value is returned in *VALIDP, the return value of evalexp() may
289 The `while' loop after the longjmp is caught relies on the above
290 implementation of pushexp and popexp leaving in expr_stack[0] the
291 values that the variables had when the program started. That is,
292 the first things saved are the initial values of the variables that
293 were assigned at program startup or by the compiler. Therefore, it is
294 safe to let the loop terminate when expr_depth == 0, without freeing up
295 any of the expr_depth[0] stuff. */
297 evalexp (expr
, validp
)
305 if (setjmp (evalbuf
))
309 tokstr
= expression
= (char *)NULL
;
318 val
= subexpr (expr
);
333 for (p
= expr
; p
&& *p
&& cr_whitespace (*p
); p
++)
336 if (p
== NULL
|| *p
== '\0')
340 curtok
= lasttok
= 0;
341 expression
= savestring (expr
);
344 tokstr
= (char *)NULL
;
349 val
= EXP_HIGHEST ();
352 evalerror ("syntax error in expression");
365 register intmax_t value
;
367 value
= expassign ();
368 while (curtok
== COMMA
)
371 value
= expassign ();
380 register intmax_t value
;
384 if (curtok
== EQ
|| curtok
== OP_ASSIGN
)
389 special
= curtok
== OP_ASSIGN
;
392 evalerror ("attempted assignment to non-variable");
396 op
= assigntok
; /* a OP= b */
400 lhs
= savestring (tokstr
);
402 value
= expassign ();
413 evalerror ("division by 0");
418 evalerror ("division by 0");
444 evalerror ("bug: bad expassign token");
452 (void)bind_int_variable (lhs
, rhs
);
456 tokstr
= (char *)NULL
; /* For freeing on errors. */
461 /* Conditional expression (expr?expr:expr) */
465 intmax_t cval
, val1
, val2
, rval
;
469 rval
= cval
= explor ();
470 if (curtok
== QUES
) /* found conditional expr */
473 if (curtok
== 0 || curtok
== COL
)
474 evalerror ("expression expected");
481 val1
= EXP_HIGHEST ();
486 evalerror ("`:' expected for conditional expression");
489 evalerror ("expression expected");
499 rval
= cval
? val1
: val2
;
509 register intmax_t val1
, val2
;
514 while (curtok
== LOR
)
537 register intmax_t val1
, val2
;
542 while (curtok
== LAND
)
565 register intmax_t val1
, val2
;
569 while (curtok
== BOR
)
583 register intmax_t val1
, val2
;
587 while (curtok
== BXOR
)
601 register intmax_t val1
, val2
;
605 while (curtok
== BAND
)
618 register intmax_t val1
, val2
;
622 while ((curtok
== EQEQ
) || (curtok
== NEQ
))
629 val1
= (val1
== val2
);
631 val1
= (val1
!= val2
);
639 register intmax_t val1
, val2
;
642 while ((curtok
== LEQ
) ||
658 else /* (op == GT) */
664 /* Left and right shifts. */
668 register intmax_t val1
, val2
;
672 while ((curtok
== LSH
) || (curtok
== RSH
))
691 register intmax_t val1
, val2
;
695 while ((curtok
== PLUS
) || (curtok
== MINUS
))
704 else if (op
== MINUS
)
713 register intmax_t val1
, val2
;
717 while ((curtok
== MUL
) ||
727 if (((op
== DIV
) || (op
== MOD
)) && (val2
== 0))
728 evalerror ("division by 0");
743 register intmax_t val1
, val2
, c
;
753 evalerror ("exponent less than 0");
754 for (c
= 1; val2
--; c
*= val1
)
764 register intmax_t val
;
771 else if (curtok
== BNOT
)
785 register intmax_t val
= 0, v2
;
789 /* XXX - might need additional logic here to decide whether or not
790 pre-increment or pre-decrement is legal at this point. */
791 if (curtok
== PREINC
|| curtok
== PREDEC
)
793 stok
= lasttok
= curtok
;
796 /* readtok() catches this */
797 evalerror ("identifier expected after pre-increment or pre-decrement");
799 v2
= tokval
+ ((stok
== PREINC
) ? 1 : -1);
802 (void)bind_int_variable (tokstr
, vincdec
);
806 curtok
= NUM
; /* make sure --x=7 is flagged as an error */
809 else if (curtok
== MINUS
)
814 else if (curtok
== PLUS
)
819 else if (curtok
== LPAR
)
822 val
= EXP_HIGHEST ();
825 evalerror ("missing `)'");
827 /* Skip over closing paren. */
830 else if ((curtok
== NUM
) || (curtok
== STR
))
833 if (curtok
== STR
&& (*tp
== '+' || *tp
== '-') && tp
[1] == *tp
&&
834 (tp
[2] == '\0' || (ISALNUM ((unsigned char)tp
[2]) == 0)))
836 /* post-increment or post-decrement */
837 v2
= val
+ ((*tp
== '+') ? 1 : -1);
840 (void)bind_int_variable (tokstr
, vincdec
);
843 curtok
= NUM
; /* make sure x++=7 is flagged as an error */
849 evalerror ("syntax error: operand expected");
855 expr_streval (tok
, e
)
864 #if defined (ARRAY_VARS)
865 v
= (e
== ']') ? array_variable_part (tok
, (char **)0, (int *)0) : find_variable (tok
);
867 v
= find_variable (tok
);
870 if ((v
== 0 || invisible_p (v
)) && unbound_vars_is_error
)
872 #if defined (ARRAY_VARS)
873 value
= (e
== ']') ? array_variable_name (tok
, (char **)0, (int *)0) : tok
;
878 err_unboundvar (value
);
880 #if defined (ARRAY_VARS)
882 FREE (value
); /* array_variable_name returns new memory */
885 if (interactive_shell
)
888 jump_to_top_level (DISCARD
);
891 jump_to_top_level (FORCE_EOF
);
894 #if defined (ARRAY_VARS)
895 /* Second argument of 0 to get_array_value means that we don't allow
896 references like array[@]. In this case, get_array_value is just
897 like get_variable_value in that it does not return newly-allocated
898 memory or quote the results. */
899 value
= (e
== ']') ? get_array_value (tok
, 0, (int *)NULL
) : get_variable_value (v
);
901 value
= get_variable_value (v
);
904 tval
= (value
&& *value
) ? subexpr (value
) : 0;
909 /* Lexical analyzer/token reader for the expression evaluator. Reads the
910 next token and puts its value into curtok, while advancing past it.
911 Updates value of tp. May also set tokval (for number) or tokstr (for
917 register unsigned char c
, c1
;
920 /* Skip leading whitespace. */
923 while (cp
&& (c
= *cp
) && (cr_whitespace (c
)))
929 lasttp
= tp
= cp
- 1;
939 if (legal_variable_starter (c
))
941 /* variable names not preceded with a dollar sign are shell variables. */
946 while (legal_variable_char (c
))
951 #if defined (ARRAY_VARS)
954 e
= skipsubscript (cp
, 0);
962 evalerror ("bad array subscript");
964 #endif /* ARRAY_VARS */
968 tokstr
= savestring (tp
);
972 tokstr
= (char *)NULL
; /* keep it from being freed */
977 if (peektok
== STR
) /* free new tokstr before old one is restored */
982 /* The tests for PREINC and PREDEC aren't strictly correct, but they
983 preserve old behavior if a construct like --x=9 is given. */
984 if (lasttok
== PREINC
|| lasttok
== PREDEC
|| peektok
!= EQ
)
985 tokval
= expr_streval (tokstr
, e
);
994 while (ISALNUM (c
) || c
== '#' || c
== '@' || c
== '_')
1000 tokval
= strlong (tp
);
1008 if ((c
== EQ
) && (c1
== EQ
))
1010 else if ((c
== NOT
) && (c1
== EQ
))
1012 else if ((c
== GT
) && (c1
== EQ
))
1014 else if ((c
== LT
) && (c1
== EQ
))
1016 else if ((c
== LT
) && (c1
== LT
))
1018 if (*cp
== '=') /* a <<= b */
1027 else if ((c
== GT
) && (c1
== GT
))
1031 assigntok
= RSH
; /* a >>= b */
1038 else if ((c
== BAND
) && (c1
== BAND
))
1040 else if ((c
== BOR
) && (c1
== BOR
))
1042 else if ((c
== '*') && (c1
== '*'))
1044 else if ((c
== '-') && (c1
== '-') && legal_variable_starter ((unsigned char)*cp
))
1046 else if ((c
== '+') && (c1
== '+') && legal_variable_starter ((unsigned char)*cp
))
1048 else if (c1
== EQ
&& member (c
, "*/%+-&^|"))
1050 assigntok
= c
; /* a OP= b */
1054 cp
--; /* `unget' the character */
1067 name
= this_command_name
;
1068 for (t
= expression
; whitespace (*t
); t
++)
1070 internal_error ("%s%s%s: %s (error token is \"%s\")",
1071 name
? name
: "", name
? ": " : "", t
,
1072 msg
, (lasttp
&& *lasttp
) ? lasttp
: "");
1073 longjmp (evalbuf
, 1);
1076 /* Convert a string to an intmax_t integer, with an arbitrary base.
1079 Anything else: [base#]number (this is implemented to match ksh93)
1081 Base may be >=2 and <=64. If base is <= 36, the numbers are drawn
1082 from [0-9][a-zA-Z], and lowercase and uppercase letters may be used
1083 interchangably. If base is > 36 and <= 64, the numbers are drawn
1084 from [0-9][a-z][A-Z]_@ (a = 10, z = 35, A = 36, Z = 61, _ = 62, @ = 63 --
1085 you get the picture). */
1092 register unsigned char c
;
1093 int base
, foundbase
;
1108 if (*s
== 'x' || *s
== 'X')
1119 for (c
= *s
++; c
; c
= *s
++)
1124 evalerror ("bad number");
1126 /* Illegal base specifications raise an evaluation error. */
1127 if (val
< 2 || val
> 64)
1128 evalerror ("illegal arithmetic base");
1134 else if (ISALNUM(c
) || (c
== '_') || (c
== '@'))
1138 else if (c
>= 'a' && c
<= 'z')
1140 else if (c
>= 'A' && c
<= 'Z')
1141 c
-= 'A' - ((base
<= 36) ? 10 : 36);
1148 evalerror ("value too great for base");
1150 val
= (val
* base
) + c
;
1158 #if defined (EXPR_TEST)
1163 return (malloc (n
));
1171 return (realloc (s
, n
));
1174 SHELL_VAR
*find_variable () { return 0;}
1175 SHELL_VAR
*bind_variable () { return 0; }
1177 char *get_string_value () { return 0; }
1179 procenv_t top_level
;
1189 if (setjmp (top_level
))
1192 for (i
= 1; i
< argc
; i
++)
1194 v
= evalexp (argv
[i
], &expok
);
1196 fprintf (stderr
, "%s: expression error\n", argv
[i
]);
1198 printf ("'%s' -> %ld\n", argv
[i
], v
);
1204 builtin_error (format
, arg1
, arg2
, arg3
, arg4
, arg5
)
1207 fprintf (stderr
, "expr: ");
1208 fprintf (stderr
, format
, arg1
, arg2
, arg3
, arg4
, arg5
);
1209 fprintf (stderr
, "\n");
1220 #endif /* EXPR_TEST */