]>
git.ipfire.org Git - thirdparty/bash.git/blob - expr.c
3b7f80e5b2b8ebbdc80bc0bad06b3104d99db8c4
1 /* expr.c -- arithmetic expression evaluation. */
3 /* Copyright (C) 1990, 1991 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 All arithmetic is done as long 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 "-", "+" [(unary operators)]
30 "**" [(exponentiation)]
42 "=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", "&=", "^=", "|="
44 (Note that most of these operators have special meaning to bash, and an
45 entire expression should be quoted, e.g. "a=$a+1" or "a=a+1" to ensure
46 that it is passed intact to the evaluator when using `let'. When using
47 the $[] or $(( )) forms, the text between the `[' and `]' or `((' and `))'
48 is treated as if in double quotes.)
50 Sub-expressions within parentheses have a precedence level greater than
51 all of the above levels and are evaluated first. Within a single prece-
52 dence group, evaluation is left-to-right, except for the arithmetic
53 assignment operator (`='), which is evaluated right-to-left (as in C).
55 The expression evaluator returns the value of the expression (assignment
56 statements have as a value what is returned by the RHS). The `let'
57 builtin, on the other hand, returns 0 if the last expression evaluates to
58 a non-zero, and 1 otherwise.
60 Implementation is a recursive-descent parser.
71 #if defined (HAVE_UNISTD_H)
73 # include <sys/types.h>
80 /* Because of the $((...)) construct, expressions may include newlines.
81 Here is a macro which accepts newlines, tabs and spaces as whitespace. */
82 #define cr_whitespace(c) (whitespace(c) || ((c) == '\n'))
84 /* Size be which the expression stack grows when neccessary. */
85 #define EXPR_STACK_GROW_SIZE 10
87 /* Maximum amount of recursion allowed. This prevents a non-integer
88 variable such as "num=num+2" from infinitely adding to itself when
89 "let num=num+2" is given. */
90 #define MAX_EXPR_RECURSION_LEVEL 1024
92 /* The Tokens. Singing "The Lion Sleeps Tonight". */
94 #define EQEQ 1 /* "==" */
95 #define NEQ 2 /* "!=" */
96 #define LEQ 3 /* "<=" */
97 #define GEQ 4 /* ">=" */
98 #define STR 5 /* string */
99 #define NUM 6 /* number */
100 #define LAND 7 /* "&&" Logical AND */
101 #define LOR 8 /* "||" Logical OR */
102 #define LSH 9 /* "<<" Left SHift */
103 #define RSH 10 /* ">>" Right SHift */
104 #define OP_ASSIGN 11 /* op= expassign as in Posix.2 */
105 #define COND 12 /* exp1 ? exp2 : exp3 */
106 #define POWER 13 /* exp1**exp2 */
118 #define BAND '&' /* Bitwise AND */
119 #define BOR '|' /* Bitwise OR. */
120 #define BXOR '^' /* Bitwise eXclusive OR. */
121 #define BNOT '~' /* Bitwise NOT; Two's complement. */
125 static char *expression
; /* The current expression */
126 static char *tp
; /* token lexical position */
127 static char *lasttp
; /* pointer to last token position */
128 static int curtok
; /* the current token */
129 static int lasttok
; /* the previous token */
130 static int assigntok
; /* the OP in OP= */
131 static char *tokstr
; /* current token string */
132 static int tokval
; /* current token value */
133 static int noeval
; /* set to 1 if no assignment to be done */
134 static procenv_t evalbuf
;
136 static void readtok (); /* lexical analyzer */
137 static long subexpr (), expassign (), exp0 (), exp1 (), exp2 (), exp3 (),
138 exp4 (), exp5 (), expshift (), expland (), explor (),
139 expband (), expbor (), expbxor (), expcond (), exppower ();
140 static long strlong ();
141 static void evalerror ();
143 /* A structure defining a single expression context. */
146 char *expression
, *tp
;
151 /* Global var which contains the stack of expression contexts. */
152 static EXPR_CONTEXT
**expr_stack
;
153 static int expr_depth
; /* Location in the stack. */
154 static int expr_stack_size
; /* Number of slots already allocated. */
156 extern char *this_command_name
;
158 /* Push and save away the contents of the globals describing the
159 current expression context. */
163 EXPR_CONTEXT
*context
;
165 if (expr_depth
>= MAX_EXPR_RECURSION_LEVEL
)
166 evalerror ("expression recursion level exceeded");
168 if (expr_depth
>= expr_stack_size
)
170 expr_stack
= (EXPR_CONTEXT
**)
171 xrealloc (expr_stack
, (expr_stack_size
+= EXPR_STACK_GROW_SIZE
)
172 * sizeof (EXPR_CONTEXT
*));
175 context
= (EXPR_CONTEXT
*)xmalloc (sizeof (EXPR_CONTEXT
));
177 context
->curtok
= curtok
;
178 context
->lasttok
= lasttok
;
179 context
->expression
= expression
;
181 context
->tokval
= tokval
;
182 context
->tokstr
= tokstr
;
183 expr_stack
[expr_depth
++] = context
;
186 /* Pop the the contents of the expression context stack into the
187 globals describing the current expression context. */
191 EXPR_CONTEXT
*context
;
194 evalerror ("recursion stack underflow");
196 context
= expr_stack
[--expr_depth
];
197 curtok
= context
->curtok
;
198 lasttok
= context
->lasttok
;
199 expression
= context
->expression
;
201 tokval
= context
->tokval
;
202 tokstr
= context
->tokstr
;
206 /* Evaluate EXPR, and return the arithmetic result. If VALIDP is
207 non-null, a zero is stored into the location to which it points
208 if the expression is invalid, non-zero otherwise. If a non-zero
209 value is returned in *VALIDP, the return value of evalexp() may
212 The `while' loop after the longjmp is caught relies on the above
213 implementation of pushexp and popexp leaving in expr_stack[0] the
214 values that the variables had when the program started. That is,
215 the first things saved are the initial values of the variables that
216 were assigned at program startup or by the compiler. Therefore, it is
217 safe to let the loop terminate when expr_depth == 0, without freeing up
218 any of the expr_depth[0] stuff. */
220 evalexp (expr
, validp
)
226 procenv_t old_evalbuf
;
232 /* Save the value of evalbuf to protect it around possible recursive
233 calls to evalexp (). */
234 COPY_PROCENV (evalbuf
, old_evalbuf
);
237 if (setjmp (evalbuf
))
241 tokstr
= expression
= (char *)NULL
;
243 while (--expr_depth
> 0)
245 if (expr_stack
[expr_depth
]->tokstr
)
246 free (expr_stack
[expr_depth
]->tokstr
);
248 if (expr_stack
[expr_depth
]->expression
)
249 free (expr_stack
[expr_depth
]->expression
);
251 free (expr_stack
[expr_depth
]);
253 free (expr_stack
[expr_depth
]); /* free the allocated EXPR_CONTEXT */
260 val
= subexpr (expr
);
263 /* Restore the value of evalbuf so that any subsequent longjmp calls
264 will have a valid location to jump to. */
265 COPY_PROCENV (old_evalbuf
, evalbuf
);
281 for (p
= expr
; p
&& *p
&& cr_whitespace (*p
); p
++)
284 if (p
== NULL
|| *p
== '\0')
288 curtok
= lasttok
= 0;
289 expression
= savestring (expr
);
292 tokstr
= (char *)NULL
;
300 evalerror ("syntax error in expression");
310 /* Bind/create a shell variable with the name LHS to the RHS.
311 This creates or modifies a variable such that it is an integer.
313 This should really be in variables.c, but it is here so that all of the
314 expression evaluation stuff is localized. Since we don't want any
315 recursive evaluation from bind_variable() (possible without this code,
316 since bind_variable() calls the evaluator for variables with the integer
317 attribute set), we temporarily turn off the integer attribute for each
318 variable we set here, then turn it back on after binding as necessary. */
321 bind_int_variable (lhs
, rhs
)
324 register SHELL_VAR
*v
;
327 v
= find_variable (lhs
);
330 isint
= integer_p (v
);
331 v
->attributes
&= ~att_integer
;
334 v
= bind_variable (lhs
, rhs
);
336 v
->attributes
|= att_integer
;
346 if (curtok
== EQ
|| curtok
== OP_ASSIGN
)
351 special
= curtok
== OP_ASSIGN
;
354 evalerror ("attempted assignment to non-variable");
358 op
= assigntok
; /* a OP= b */
362 lhs
= savestring (tokstr
);
364 value
= expassign ();
399 evalerror ("bug: bad expassign token");
407 bind_int_variable (lhs
, rhs
);
411 tokstr
= (char *)NULL
; /* For freeing on errors. */
416 /* Conditional expression (expr?expr:expr) */
420 long cval
, val1
, val2
, rval
;
424 rval
= cval
= explor ();
425 if (curtok
== QUES
) /* found conditional expr */
428 if (curtok
== 0 || curtok
== COL
)
429 evalerror ("expression expected");
443 evalerror ("`:' expected for conditional expression");
446 evalerror ("expression expected");
456 rval
= cval
? val1
: val2
;
466 register long val1
, val2
;
471 while (curtok
== LOR
)
494 register long val1
, val2
;
499 while (curtok
== LAND
)
522 register long val1
, val2
;
526 while (curtok
== BOR
)
540 register long val1
, val2
;
544 while (curtok
== BXOR
)
558 register long val1
, val2
;
562 while (curtok
== BAND
)
575 register long val1
, val2
;
579 while ((curtok
== EQEQ
) || (curtok
== NEQ
))
586 val1
= (val1
== val2
);
588 val1
= (val1
!= val2
);
596 register long val1
, val2
;
599 while ((curtok
== LEQ
) ||
615 else /* (op == GT) */
621 /* Left and right shifts. */
625 register long val1
, val2
;
629 while ((curtok
== LSH
) || (curtok
== RSH
))
648 register long val1
, val2
;
652 while ((curtok
== PLUS
) || (curtok
== MINUS
))
661 else if (op
== MINUS
)
670 register long val1
, val2
;
674 while ((curtok
== MUL
) ||
684 if (((op
== DIV
) || (op
== MOD
)) && (val2
== 0))
685 evalerror ("division by 0");
700 register long val1
, val2
, c
;
709 for (c
= 1; val2
--; c
*= val1
)
726 else if (curtok
== BNOT
)
740 register long val
= 0L;
747 else if (curtok
== PLUS
)
752 else if (curtok
== LPAR
)
758 evalerror ("missing `)'");
760 /* Skip over closing paren. */
763 else if ((curtok
== NUM
) || (curtok
== STR
))
769 evalerror ("syntax error: operand expected");
774 /* Lexical analyzer/token reader for the expression evaluator. Reads the
775 next token and puts its value into curtok, while advancing past it.
776 Updates value of tp. May also set tokval (for number) or tokstr (for
782 register int c
, c1
, e
;
784 /* Skip leading whitespace. */
787 while (cp
&& (c
= *cp
) && (cr_whitespace (c
)))
793 lasttp
= tp
= cp
- 1;
803 if (legal_variable_starter (c
))
805 /* Semi-bogus ksh compatibility feature -- variable names
806 not preceded with a dollar sign are shell variables. */
809 while (legal_variable_char (c
))
814 #if defined (ARRAY_VARS)
817 e
= skipsubscript (cp
, 0);
825 evalerror ("bad array subscript");
827 #endif /* ARRAY_VARS */
832 tokstr
= savestring (tp
);
834 #if defined (ARRAY_VARS)
835 value
= (e
== ']') ? get_array_value (tokstr
, 0) : get_string_value (tokstr
);
837 value
= get_string_value (tokstr
);
840 tokval
= (value
&& *value
) ? subexpr (value
) : 0;
842 #if defined (ARRAY_VARS)
844 FREE (value
); /* get_array_value returns newly-allocated memory */
853 while (digit (c
) || isletter (c
) || c
== '#' || c
== '@' || c
== '_')
859 tokval
= strlong (tp
);
867 if ((c
== EQ
) && (c1
== EQ
))
869 else if ((c
== NOT
) && (c1
== EQ
))
871 else if ((c
== GT
) && (c1
== EQ
))
873 else if ((c
== LT
) && (c1
== EQ
))
875 else if ((c
== LT
) && (c1
== LT
))
877 if (*cp
== '=') /* a <<= b */
886 else if ((c
== GT
) && (c1
== GT
))
890 assigntok
= RSH
; /* a >>= b */
897 else if ((c
== BAND
) && (c1
== BAND
))
899 else if ((c
== BOR
) && (c1
== BOR
))
901 else if ((c
== '*') && (c1
== '*'))
903 else if (c1
== EQ
&& member(c
, "*/%+-&^|"))
905 assigntok
= c
; /* a OP= b */
909 cp
--; /* `unget' the character */
922 name
= this_command_name
;
923 for (t
= expression
; whitespace (*t
); t
++)
925 internal_error ("%s%s%s: %s (error token is \"%s\")",
926 name
? name
: "", name
? ": " : "", t
,
927 msg
, (lasttp
&& *lasttp
) ? lasttp
: "");
928 longjmp (evalbuf
, 1);
931 /* Convert a string to a long integer, with an arbitrary base.
934 Anything else: [base#]number (this is implemented to match ksh93)
936 Base may be >=2 and <=64. If base is <= 36, the numbers are drawn
937 from [0-9][a-zA-Z], and lowercase and uppercase letters may be used
938 interchangably. If base is > 36 and <= 64, the numbers are drawn
939 from [0-9][a-z][A-Z]_@ (a = 10, z = 35, A = 36, Z = 61, _ = 62, @ = 63 --
940 you get the picture). */
952 if (s
== NULL
|| *s
== '\0')
961 if (s
== NULL
|| *s
== '\0')
965 if (*s
== 'x' || *s
== 'X')
976 for (c
= *s
++; c
; c
= *s
++)
981 evalerror ("bad number");
985 /* Illegal base specifications raise an evaluation error. */
986 if (base
< 2 || base
> 64)
987 evalerror ("illegal arithmetic base");
992 else if (isletter(c
) || digit(c
) || (c
== '_') || (c
== '@'))
996 else if (c
>= 'a' && c
<= 'z')
998 else if (c
>= 'A' && c
<= 'Z')
999 c
-= 'A' - ((base
<= 36) ? 10 : 36);
1006 evalerror ("value too great for base");
1008 val
= (val
* base
) + c
;
1016 #if defined (EXPR_TEST)
1021 return (malloc (n
));
1029 return (realloc (s
, n
));
1032 SHELL_VAR
*find_variable () { return 0;}
1033 SHELL_VAR
*bind_variable () { return 0; }
1035 char *get_string_value () { return 0; }
1037 procenv_t top_level
;
1047 if (setjmp (top_level
))
1050 for (i
= 1; i
< argc
; i
++)
1052 v
= evalexp (argv
[i
], &expok
);
1054 fprintf (stderr
, "%s: expression error\n", argv
[i
]);
1056 printf ("'%s' -> %ld\n", argv
[i
], v
);
1062 builtin_error (format
, arg1
, arg2
, arg3
, arg4
, arg5
)
1065 fprintf (stderr
, "expr: ");
1066 fprintf (stderr
, format
, arg1
, arg2
, arg3
, arg4
, arg5
);
1067 fprintf (stderr
, "\n");
1078 #endif /* EXPR_TEST */