]>
git.ipfire.org Git - thirdparty/bash.git/blob - expr.c
0930789d6a5631c078bc58e7e1dc76ef00af56d2
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)]
41 "=", "*=", "/=", "%=",
42 "+=", "-=", "<<=", ">>=",
45 (Note that most of these operators have special meaning to bash, and an
46 entire expression should be quoted, e.g. "a=$a+1" or "a=a+1" to ensure
47 that it is passed intact to the evaluator when using `let'. When using
48 the $[] or $(( )) forms, the text between the `[' and `]' or `((' and `))'
49 is treated as if in double quotes.)
51 Sub-expressions within parentheses have a precedence level greater than
52 all of the above levels and are evaluated first. Within a single prece-
53 dence group, evaluation is left-to-right, except for the arithmetic
54 assignment operator (`='), which is evaluated right-to-left (as in C).
56 The expression evaluator returns the value of the expression (assignment
57 statements have as a value what is returned by the RHS). The `let'
58 builtin, on the other hand, returns 0 if the last expression evaluates to
59 a non-zero, and 1 otherwise.
61 Implementation is a recursive-descent parser.
71 #if defined (HAVE_UNISTD_H)
77 /* Because of the $((...)) construct, expressions may include newlines.
78 Here is a macro which accepts newlines, tabs and spaces as whitespace. */
79 #define cr_whitespace(c) (whitespace(c) || ((c) == '\n'))
81 /* Size be which the expression stack grows when neccessary. */
82 #define EXPR_STACK_GROW_SIZE 10
84 /* Maximum amount of recursion allowed. This prevents a non-integer
85 variable such as "num=num+2" from infinitely adding to itself when
86 "let num=num+2" is given. */
87 #define MAX_EXPR_RECURSION_LEVEL 1024
89 /* The Tokens. Singing "The Lion Sleeps Tonight". */
91 #define EQEQ 1 /* "==" */
92 #define NEQ 2 /* "!=" */
93 #define LEQ 3 /* "<=" */
94 #define GEQ 4 /* ">=" */
95 #define STR 5 /* string */
96 #define NUM 6 /* number */
97 #define LAND 7 /* "&&" Logical AND */
98 #define LOR 8 /* "||" Logical OR */
99 #define LSH 9 /* "<<" Left SHift */
100 #define RSH 10 /* ">>" Right SHift */
101 #define OP_ASSIGN 11 /* op= expassign as in Posix.2 */
114 #define BAND '&' /* Bitwise AND */
115 #define BOR '|' /* Bitwise OR. */
116 #define BXOR '^' /* Bitwise eXclusive OR. */
117 #define BNOT '~' /* Bitwise NOT; Two's complement. */
121 static char *expression
; /* The current expression */
122 static char *tp
; /* token lexical position */
123 static char *lasttp
; /* pointer to last token position */
124 static int curtok
; /* the current token */
125 static int lasttok
; /* the previous token */
126 static int assigntok
; /* the OP in OP= */
127 static char *tokstr
; /* current token string */
128 static int tokval
; /* current token value */
129 static int noeval
; /* set to 1 if no assignment to be done */
130 static procenv_t evalbuf
;
132 static void readtok (); /* lexical analyzer */
133 static long subexpr (), expassign (), exp0 (), exp1 (), exp2 (), exp3 (),
134 exp4 (), exp5 (), expshift (), expland (), explor (),
135 expband (), expbor (), expbxor (), expcond ();
136 static long strlong ();
137 static void evalerror ();
139 /* A structure defining a single expression context. */
142 char *expression
, *tp
;
147 /* Global var which contains the stack of expression contexts. */
148 static EXPR_CONTEXT
**expr_stack
;
149 static int expr_depth
; /* Location in the stack. */
150 static int expr_stack_size
; /* Number of slots already allocated. */
152 extern char *this_command_name
;
154 /* Push and save away the contents of the globals describing the
155 current expression context. */
159 EXPR_CONTEXT
*context
;
161 if (expr_depth
>= MAX_EXPR_RECURSION_LEVEL
)
162 evalerror ("expression recursion level exceeded");
164 if (expr_depth
>= expr_stack_size
)
166 expr_stack
= (EXPR_CONTEXT
**)
167 xrealloc (expr_stack
, (expr_stack_size
+= EXPR_STACK_GROW_SIZE
)
168 * sizeof (EXPR_CONTEXT
*));
171 context
= (EXPR_CONTEXT
*)xmalloc (sizeof (EXPR_CONTEXT
));
173 context
->curtok
= curtok
;
174 context
->lasttok
= lasttok
;
175 context
->expression
= expression
;
177 context
->tokval
= tokval
;
178 context
->tokstr
= tokstr
;
179 expr_stack
[expr_depth
++] = context
;
182 /* Pop the the contents of the expression context stack into the
183 globals describing the current expression context. */
187 EXPR_CONTEXT
*context
;
190 evalerror ("recursion stack underflow");
192 context
= expr_stack
[--expr_depth
];
193 curtok
= context
->curtok
;
194 lasttok
= context
->lasttok
;
195 expression
= context
->expression
;
197 tokval
= context
->tokval
;
198 tokstr
= context
->tokstr
;
202 /* Evaluate EXPR, and return the arithmetic result. If VALIDP is
203 non-null, a zero is stored into the location to which it points
204 if the expression is invalid, non-zero otherwise. If a non-zero
205 value is returned in *VALIDP, the return value of evalexp() may
208 The `while' loop after the longjmp is caught relies on the above
209 implementation of pushexp and popexp leaving in expr_stack[0] the
210 values that the variables had when the program started. That is,
211 the first things saved are the initial values of the variables that
212 were assigned at program startup or by the compiler. Therefore, it is
213 safe to let the loop terminate when expr_depth == 0, without freeing up
214 any of the expr_depth[0] stuff. */
216 evalexp (expr
, validp
)
222 procenv_t old_evalbuf
;
228 /* Save the value of evalbuf to protect it around possible recursive
229 calls to evalexp (). */
230 COPY_PROCENV (evalbuf
, old_evalbuf
);
233 if (setjmp (evalbuf
))
237 tokstr
= expression
= (char *)NULL
;
239 while (--expr_depth
> 0)
241 if (expr_stack
[expr_depth
]->tokstr
)
242 free (expr_stack
[expr_depth
]->tokstr
);
244 if (expr_stack
[expr_depth
]->expression
)
245 free (expr_stack
[expr_depth
]->expression
);
247 free (expr_stack
[expr_depth
]);
249 free (expr_stack
[expr_depth
]); /* free the allocated EXPR_CONTEXT */
256 val
= subexpr (expr
);
259 /* Restore the value of evalbuf so that any subsequent longjmp calls
260 will have a valid location to jump to. */
261 COPY_PROCENV (old_evalbuf
, evalbuf
);
277 for (p
= expr
; p
&& *p
&& cr_whitespace (*p
); p
++)
280 if (p
== NULL
|| *p
== '\0')
284 curtok
= lasttok
= 0;
285 expression
= savestring (expr
);
288 tokstr
= (char *)NULL
;
296 evalerror ("syntax error in expression");
306 /* Bind/create a shell variable with the name LHS to the RHS.
307 This creates or modifies a variable such that it is an integer.
309 This should really be in variables.c, but it is here so that all of the
310 expression evaluation stuff is localized. Since we don't want any
311 recursive evaluation from bind_variable() (possible without this code,
312 since bind_variable() calls the evaluator for variables with the integer
313 attribute set), we temporarily turn off the integer attribute for each
314 variable we set here, then turn it back on after binding as necessary. */
317 bind_int_variable (lhs
, rhs
)
320 register SHELL_VAR
*v
;
323 v
= find_variable (lhs
);
326 isint
= integer_p (v
);
327 v
->attributes
&= ~att_integer
;
330 v
= bind_variable (lhs
, rhs
);
332 v
->attributes
|= att_integer
;
342 if (curtok
== EQ
|| curtok
== OP_ASSIGN
)
347 special
= curtok
== OP_ASSIGN
;
350 evalerror ("attempted assignment to non-variable");
354 op
= assigntok
; /* a OP= b */
358 lhs
= savestring (tokstr
);
360 value
= expassign ();
395 evalerror ("bug: bad expassign token");
403 bind_int_variable (lhs
, rhs
);
407 tokstr
= (char *)NULL
; /* For freeing on errors. */
412 /* Conditional expression (expr?expr:expr) */
416 long cval
, val1
, val2
, rval
;
420 rval
= cval
= explor ();
421 if (curtok
== QUES
) /* found conditional expr */
424 if (curtok
== 0 || curtok
== COL
)
425 evalerror ("expression expected");
439 evalerror ("`:' expected for conditional expression");
442 evalerror ("expression expected");
452 rval
= cval
? val1
: val2
;
462 register long val1
, val2
;
467 while (curtok
== LOR
)
490 register long val1
, val2
;
495 while (curtok
== LAND
)
518 register long val1
, val2
;
522 while (curtok
== BOR
)
536 register long val1
, val2
;
540 while (curtok
== BXOR
)
554 register long val1
, val2
;
558 while (curtok
== BAND
)
571 register long val1
, val2
;
575 while ((curtok
== EQEQ
) || (curtok
== NEQ
))
582 val1
= (val1
== val2
);
584 val1
= (val1
!= val2
);
592 register long val1
, val2
;
595 while ((curtok
== LEQ
) ||
611 else /* (op == GT) */
617 /* Left and right shifts. */
621 register long val1
, val2
;
625 while ((curtok
== LSH
) || (curtok
== RSH
))
644 register long val1
, val2
;
648 while ((curtok
== PLUS
) || (curtok
== MINUS
))
657 else if (op
== MINUS
)
666 register long val1
, val2
;
670 while ((curtok
== MUL
) ||
680 if (((op
== DIV
) || (op
== MOD
)) && (val2
== 0))
681 evalerror ("division by 0");
703 else if (curtok
== BNOT
)
717 register long val
= 0L;
724 else if (curtok
== PLUS
)
729 else if (curtok
== LPAR
)
735 evalerror ("missing `)'");
737 /* Skip over closing paren. */
740 else if ((curtok
== NUM
) || (curtok
== STR
))
746 evalerror ("syntax error: operand expected");
751 /* Lexical analyzer/token reader for the expression evaluator. Reads the
752 next token and puts its value into curtok, while advancing past it.
753 Updates value of tp. May also set tokval (for number) or tokstr (for
759 register int c
, c1
, e
;
761 /* Skip leading whitespace. */
764 while (cp
&& (c
= *cp
) && (cr_whitespace (c
)))
770 lasttp
= tp
= cp
- 1;
780 if (legal_variable_starter (c
))
782 /* Semi-bogus ksh compatibility feature -- variable names
783 not preceded with a dollar sign are shell variables. */
786 while (legal_variable_char (c
))
791 #if defined (ARRAY_VARS)
794 e
= skipsubscript (cp
, 0);
802 evalerror ("bad array subscript");
804 #endif /* ARRAY_VARS */
809 tokstr
= savestring (tp
);
811 #if defined (ARRAY_VARS)
812 value
= (e
== ']') ? get_array_value (tokstr
, 0) : get_string_value (tokstr
);
814 value
= get_string_value (tokstr
);
817 tokval
= (value
&& *value
) ? subexpr (value
) : 0;
819 #if defined (ARRAY_VARS)
821 FREE (value
); /* get_array_value returns newly-allocated memory */
830 while (digit (c
) || isletter (c
) || c
== '#' || c
== '@' || c
== '_')
836 tokval
= strlong (tp
);
844 if ((c
== EQ
) && (c1
== EQ
))
846 else if ((c
== NOT
) && (c1
== EQ
))
848 else if ((c
== GT
) && (c1
== EQ
))
850 else if ((c
== LT
) && (c1
== EQ
))
852 else if ((c
== LT
) && (c1
== LT
))
854 if (*cp
== '=') /* a <<= b */
863 else if ((c
== GT
) && (c1
== GT
))
867 assigntok
= RSH
; /* a >>= b */
874 else if ((c
== BAND
) && (c1
== BAND
))
876 else if ((c
== BOR
) && (c1
== BOR
))
878 else if (c1
== EQ
&& member(c
, "*/%+-&^|"))
880 assigntok
= c
; /* a OP= b */
884 cp
--; /* `unget' the character */
897 name
= this_command_name
;
898 for (t
= expression
; whitespace (*t
); t
++)
900 internal_error ("%s%s%s: %s (error token is \"%s\")",
901 name
? name
: "", name
? ": " : "", t
,
902 msg
, (lasttp
&& *lasttp
) ? lasttp
: "");
903 longjmp (evalbuf
, 1);
906 /* Convert a string to a long integer, with an arbitrary base.
909 Anything else: [base#]number (this is implemented to match ksh93)
911 Base may be >=2 and <=64. If base is <= 36, the numbers are drawn
912 from [0-9][a-zA-Z], and lowercase and uppercase letters may be used
913 interchangably. If base is > 36 and <= 64, the numbers are drawn
914 from [0-9][a-z][A-Z]_@ (a = 10, z = 35, A = 36, Z = 61, _ = 62, @ = 63 --
915 you get the picture). */
927 if (s
== NULL
|| *s
== '\0')
936 if (s
== NULL
|| *s
== '\0')
940 if (*s
== 'x' || *s
== 'X')
951 for (c
= *s
++; c
; c
= *s
++)
956 evalerror ("bad number");
960 /* Illegal base specifications raise an evaluation error. */
961 if (base
< 2 || base
> 64)
962 evalerror ("illegal arithmetic base");
967 else if (isletter(c
) || digit(c
) || (c
== '_') || (c
== '@'))
971 else if (c
>= 'a' && c
<= 'z')
973 else if (c
>= 'A' && c
<= 'Z')
974 c
-= 'A' - ((base
<= 36) ? 10 : 36);
981 evalerror ("value too great for base");
983 val
= (val
* base
) + c
;
991 #if defined (EXPR_TEST)
1004 return (realloc (s
, n
));
1007 SHELL_VAR
*find_variable () { return 0;}
1008 SHELL_VAR
*bind_variable () { return 0; }
1010 char *get_string_value () { return 0; }
1012 procenv_t top_level
;
1022 if (setjmp (top_level
))
1025 for (i
= 1; i
< argc
; i
++)
1027 v
= evalexp (argv
[i
], &expok
);
1029 fprintf (stderr
, "%s: expression error\n", argv
[i
]);
1031 printf ("'%s' -> %ld\n", argv
[i
], v
);
1037 builtin_error (format
, arg1
, arg2
, arg3
, arg4
, arg5
)
1040 fprintf (stderr
, "expr: ");
1041 fprintf (stderr
, format
, arg1
, arg2
, arg3
, arg4
, arg5
);
1042 fprintf (stderr
, "\n");
1053 #endif /* EXPR_TEST */