diff options
Diffstat (limited to 'coreutils/expr.c')
-rw-r--r-- | coreutils/expr.c | 406 |
1 files changed, 195 insertions, 211 deletions
diff --git a/coreutils/expr.c b/coreutils/expr.c index 0a1baa19d..e7fdc5f1e 100644 --- a/coreutils/expr.c +++ b/coreutils/expr.c | |||
@@ -37,11 +37,13 @@ typedef enum valtype TYPE; | |||
37 | 37 | ||
38 | #if ENABLE_EXPR_MATH_SUPPORT_64 | 38 | #if ENABLE_EXPR_MATH_SUPPORT_64 |
39 | typedef int64_t arith_t; | 39 | typedef int64_t arith_t; |
40 | |||
40 | #define PF_REZ "ll" | 41 | #define PF_REZ "ll" |
41 | #define PF_REZ_TYPE (long long) | 42 | #define PF_REZ_TYPE (long long) |
42 | #define STRTOL(s, e, b) strtoll(s, e, b) | 43 | #define STRTOL(s, e, b) strtoll(s, e, b) |
43 | #else | 44 | #else |
44 | typedef long arith_t; | 45 | typedef long arith_t; |
46 | |||
45 | #define PF_REZ "l" | 47 | #define PF_REZ "l" |
46 | #define PF_REZ_TYPE (long) | 48 | #define PF_REZ_TYPE (long) |
47 | #define STRTOL(s, e, b) strtol(s, e, b) | 49 | #define STRTOL(s, e, b) strtol(s, e, b) |
@@ -49,8 +51,8 @@ typedef long arith_t; | |||
49 | 51 | ||
50 | /* A value is.... */ | 52 | /* A value is.... */ |
51 | struct valinfo { | 53 | struct valinfo { |
52 | TYPE type; /* Which kind. */ | 54 | TYPE type; /* Which kind. */ |
53 | union { /* The value itself. */ | 55 | union { /* The value itself. */ |
54 | arith_t i; | 56 | arith_t i; |
55 | char *s; | 57 | char *s; |
56 | } u; | 58 | } u; |
@@ -60,17 +62,17 @@ typedef struct valinfo VALUE; | |||
60 | /* The arguments given to the program, minus the program name. */ | 62 | /* The arguments given to the program, minus the program name. */ |
61 | static char **args; | 63 | static char **args; |
62 | 64 | ||
63 | static VALUE *docolon (VALUE *sv, VALUE *pv); | 65 | static VALUE *docolon(VALUE * sv, VALUE * pv); |
64 | static VALUE *eval (void); | 66 | static VALUE *eval(void); |
65 | static VALUE *int_value (arith_t i); | 67 | static VALUE *int_value(arith_t i); |
66 | static VALUE *str_value (char *s); | 68 | static VALUE *str_value(char *s); |
67 | static int nextarg (char *str); | 69 | static int nextarg(char *str); |
68 | static int null (VALUE *v); | 70 | static int null(VALUE * v); |
69 | static int toarith (VALUE *v); | 71 | static int toarith(VALUE * v); |
70 | static void freev (VALUE *v); | 72 | static void freev(VALUE * v); |
71 | static void tostring (VALUE *v); | 73 | static void tostring(VALUE * v); |
72 | 74 | ||
73 | int expr_main (int argc, char **argv) | 75 | int expr_main(int argc, char **argv) |
74 | { | 76 | { |
75 | VALUE *v; | 77 | VALUE *v; |
76 | 78 | ||
@@ -80,25 +82,25 @@ int expr_main (int argc, char **argv) | |||
80 | 82 | ||
81 | args = argv + 1; | 83 | args = argv + 1; |
82 | 84 | ||
83 | v = eval (); | 85 | v = eval(); |
84 | if (*args) | 86 | if (*args) |
85 | bb_error_msg_and_die ("syntax error"); | 87 | bb_error_msg_and_die("syntax error"); |
86 | 88 | ||
87 | if (v->type == integer) | 89 | if (v->type == integer) |
88 | printf ("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i); | 90 | bb_printf("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i); |
89 | else | 91 | else |
90 | puts (v->u.s); | 92 | puts(v->u.s); |
91 | 93 | ||
92 | exit (null (v)); | 94 | exit(null(v)); |
93 | } | 95 | } |
94 | 96 | ||
95 | /* Return a VALUE for I. */ | 97 | /* Return a VALUE for I. */ |
96 | 98 | ||
97 | static VALUE *int_value (arith_t i) | 99 | static VALUE *int_value(arith_t i) |
98 | { | 100 | { |
99 | VALUE *v; | 101 | VALUE *v; |
100 | 102 | ||
101 | v = xmalloc (sizeof(VALUE)); | 103 | v = xmalloc(sizeof(VALUE)); |
102 | v->type = integer; | 104 | v->type = integer; |
103 | v->u.i = i; | 105 | v->u.i = i; |
104 | return v; | 106 | return v; |
@@ -106,7 +108,7 @@ static VALUE *int_value (arith_t i) | |||
106 | 108 | ||
107 | /* Return a VALUE for S. */ | 109 | /* Return a VALUE for S. */ |
108 | 110 | ||
109 | static VALUE *str_value (char *s) | 111 | static VALUE *str_value(char *s) |
110 | { | 112 | { |
111 | VALUE *v; | 113 | VALUE *v; |
112 | 114 | ||
@@ -118,28 +120,26 @@ static VALUE *str_value (char *s) | |||
118 | 120 | ||
119 | /* Free VALUE V, including structure components. */ | 121 | /* Free VALUE V, including structure components. */ |
120 | 122 | ||
121 | static void freev (VALUE *v) | 123 | static void freev(VALUE * v) |
122 | { | 124 | { |
123 | if (v->type == string) | 125 | if (v->type == string) |
124 | free (v->u.s); | 126 | free(v->u.s); |
125 | free (v); | 127 | free(v); |
126 | } | 128 | } |
127 | 129 | ||
128 | /* Return nonzero if V is a null-string or zero-number. */ | 130 | /* Return nonzero if V is a null-string or zero-number. */ |
129 | 131 | ||
130 | static int null (VALUE *v) | 132 | static int null(VALUE * v) |
131 | { | 133 | { |
132 | switch (v->type) { | 134 | if (v->type == integer) |
133 | case integer: | 135 | return v->u.i == 0; |
134 | return v->u.i == 0; | 136 | else /* string: */ |
135 | default: /* string: */ | 137 | return v->u.s[0] == '\0' || strcmp(v->u.s, "0") == 0; |
136 | return v->u.s[0] == '\0' || strcmp (v->u.s, "0") == 0; | ||
137 | } | ||
138 | } | 138 | } |
139 | 139 | ||
140 | /* Coerce V to a string value (can't fail). */ | 140 | /* Coerce V to a string value (can't fail). */ |
141 | 141 | ||
142 | static void tostring (VALUE *v) | 142 | static void tostring(VALUE * v) |
143 | { | 143 | { |
144 | if (v->type == integer) { | 144 | if (v->type == integer) { |
145 | v->u.s = xasprintf("%" PF_REZ "d", PF_REZ_TYPE v->u.i); | 145 | v->u.s = xasprintf("%" PF_REZ "d", PF_REZ_TYPE v->u.i); |
@@ -149,9 +149,9 @@ static void tostring (VALUE *v) | |||
149 | 149 | ||
150 | /* Coerce V to an integer value. Return 1 on success, 0 on failure. */ | 150 | /* Coerce V to an integer value. Return 1 on success, 0 on failure. */ |
151 | 151 | ||
152 | static int toarith (VALUE *v) | 152 | static int toarith(VALUE * v) |
153 | { | 153 | { |
154 | if(v->type == string) { | 154 | if (v->type == string) { |
155 | arith_t i; | 155 | arith_t i; |
156 | char *e; | 156 | char *e; |
157 | 157 | ||
@@ -160,7 +160,7 @@ static int toarith (VALUE *v) | |||
160 | i = STRTOL(v->u.s, &e, 10); | 160 | i = STRTOL(v->u.s, &e, 10); |
161 | if ((v->u.s == e) || *e) | 161 | if ((v->u.s == e) || *e) |
162 | return 0; | 162 | return 0; |
163 | free (v->u.s); | 163 | free(v->u.s); |
164 | v->u.i = i; | 164 | v->u.i = i; |
165 | v->type = integer; | 165 | v->type = integer; |
166 | } | 166 | } |
@@ -170,221 +170,207 @@ static int toarith (VALUE *v) | |||
170 | /* Return nonzero if the next token matches STR exactly. | 170 | /* Return nonzero if the next token matches STR exactly. |
171 | STR must not be NULL. */ | 171 | STR must not be NULL. */ |
172 | 172 | ||
173 | static int | 173 | static int nextarg(char *str) |
174 | nextarg (char *str) | ||
175 | { | 174 | { |
176 | if (*args == NULL) | 175 | if (*args == NULL) |
177 | return 0; | 176 | return 0; |
178 | return strcmp (*args, str) == 0; | 177 | return strcmp(*args, str) == 0; |
179 | } | 178 | } |
180 | 179 | ||
181 | /* The comparison operator handling functions. */ | 180 | /* The comparison operator handling functions. */ |
182 | 181 | ||
183 | static int cmp_common (VALUE *l, VALUE *r, int op) | 182 | static int cmp_common(VALUE * l, VALUE * r, int op) |
184 | { | 183 | { |
185 | int cmpval; | 184 | int cmpval; |
186 | 185 | ||
187 | if (l->type == string || r->type == string) { | 186 | if (l->type == string || r->type == string) { |
188 | tostring (l); | 187 | tostring(l); |
189 | tostring (r); | 188 | tostring(r); |
190 | cmpval = strcmp (l->u.s, r->u.s); | 189 | cmpval = strcmp(l->u.s, r->u.s); |
191 | } | 190 | } else |
192 | else | ||
193 | cmpval = l->u.i - r->u.i; | 191 | cmpval = l->u.i - r->u.i; |
194 | switch(op) { | 192 | if (op == '<') |
195 | case '<': | 193 | return cmpval < 0; |
196 | return cmpval < 0; | 194 | else if (op == ('L' + 'E')) |
197 | case ('L'+'E'): | 195 | return cmpval <= 0; |
198 | return cmpval <= 0; | 196 | else if (op == '=') |
199 | case '=': | 197 | return cmpval == 0; |
200 | return cmpval == 0; | 198 | else if (op == '!') |
201 | case '!': | 199 | return cmpval != 0; |
202 | return cmpval != 0; | 200 | else if (op == '>') |
203 | case '>': | 201 | return cmpval > 0; |
204 | return cmpval > 0; | 202 | else /* >= */ |
205 | default: /* >= */ | 203 | return cmpval >= 0; |
206 | return cmpval >= 0; | ||
207 | } | ||
208 | } | 204 | } |
209 | 205 | ||
210 | /* The arithmetic operator handling functions. */ | 206 | /* The arithmetic operator handling functions. */ |
211 | 207 | ||
212 | static arith_t arithmetic_common (VALUE *l, VALUE *r, int op) | 208 | static arith_t arithmetic_common(VALUE * l, VALUE * r, int op) |
213 | { | 209 | { |
214 | arith_t li, ri; | 210 | arith_t li, ri; |
215 | 211 | ||
216 | if (!toarith (l) || !toarith (r)) | 212 | if (!toarith(l) || !toarith(r)) |
217 | bb_error_msg_and_die ("non-numeric argument"); | 213 | bb_error_msg_and_die("non-numeric argument"); |
218 | li = l->u.i; | 214 | li = l->u.i; |
219 | ri = r->u.i; | 215 | ri = r->u.i; |
220 | if((op == '/' || op == '%') && ri == 0) | 216 | if ((op == '/' || op == '%') && ri == 0) |
221 | bb_error_msg_and_die ( "division by zero"); | 217 | bb_error_msg_and_die("division by zero"); |
222 | switch(op) { | 218 | if (op == '+') |
223 | case '+': | ||
224 | return li + ri; | 219 | return li + ri; |
225 | case '-': | 220 | else if (op == '-') |
226 | return li - ri; | 221 | return li - ri; |
227 | case '*': | 222 | else if (op == '*') |
228 | return li * ri; | 223 | return li * ri; |
229 | case '/': | 224 | else if (op == '/') |
230 | return li / ri; | 225 | return li / ri; |
231 | default: | 226 | else |
232 | return li % ri; | 227 | return li % ri; |
233 | } | ||
234 | } | 228 | } |
235 | 229 | ||
236 | /* Do the : operator. | 230 | /* Do the : operator. |
237 | SV is the VALUE for the lhs (the string), | 231 | SV is the VALUE for the lhs (the string), |
238 | PV is the VALUE for the rhs (the pattern). */ | 232 | PV is the VALUE for the rhs (the pattern). */ |
239 | 233 | ||
240 | static VALUE *docolon (VALUE *sv, VALUE *pv) | 234 | static VALUE *docolon(VALUE * sv, VALUE * pv) |
241 | { | 235 | { |
242 | VALUE *v; | 236 | VALUE *v; |
243 | regex_t re_buffer; | 237 | regex_t re_buffer; |
244 | const int NMATCH = 2; | 238 | const int NMATCH = 2; |
245 | regmatch_t re_regs[NMATCH]; | 239 | regmatch_t re_regs[NMATCH]; |
246 | 240 | ||
247 | tostring (sv); | 241 | tostring(sv); |
248 | tostring (pv); | 242 | tostring(pv); |
249 | 243 | ||
250 | if (pv->u.s[0] == '^') { | 244 | if (pv->u.s[0] == '^') { |
251 | fprintf (stderr, "\ | 245 | fprintf(stderr, "\ |
252 | warning: unportable BRE: `%s': using `^' as the first character\n\ | 246 | warning: unportable BRE: `%s': using `^' as the first character\n\ |
253 | of a basic regular expression is not portable; it is being ignored", | 247 | of a basic regular expression is not portable; it is being ignored", pv->u.s); |
254 | pv->u.s); | ||
255 | } | 248 | } |
256 | 249 | ||
257 | memset (&re_buffer, 0, sizeof (re_buffer)); | 250 | memset(&re_buffer, 0, sizeof(re_buffer)); |
258 | memset (re_regs, 0, sizeof (*re_regs)); | 251 | memset(re_regs, 0, sizeof(*re_regs)); |
259 | if( regcomp (&re_buffer, pv->u.s, 0) != 0 ) | 252 | if (regcomp(&re_buffer, pv->u.s, 0) != 0) |
260 | bb_error_msg_and_die("Invalid regular expression"); | 253 | bb_error_msg_and_die("Invalid regular expression"); |
261 | 254 | ||
262 | /* expr uses an anchored pattern match, so check that there was a | 255 | /* expr uses an anchored pattern match, so check that there was a |
263 | * match and that the match starts at offset 0. */ | 256 | * match and that the match starts at offset 0. */ |
264 | if (regexec (&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH && | 257 | if (regexec(&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH && |
265 | re_regs[0].rm_so == 0) { | 258 | re_regs[0].rm_so == 0) { |
266 | /* Were \(...\) used? */ | 259 | /* Were \(...\) used? */ |
267 | if (re_buffer.re_nsub > 0) { | 260 | if (re_buffer.re_nsub > 0) { |
268 | sv->u.s[re_regs[1].rm_eo] = '\0'; | 261 | sv->u.s[re_regs[1].rm_eo] = '\0'; |
269 | v = str_value (sv->u.s + re_regs[1].rm_so); | 262 | v = str_value(sv->u.s + re_regs[1].rm_so); |
270 | } | 263 | } else |
271 | else | 264 | v = int_value(re_regs[0].rm_eo); |
272 | v = int_value (re_regs[0].rm_eo); | 265 | } else { |
273 | } | ||
274 | else { | ||
275 | /* Match failed -- return the right kind of null. */ | 266 | /* Match failed -- return the right kind of null. */ |
276 | if (re_buffer.re_nsub > 0) | 267 | if (re_buffer.re_nsub > 0) |
277 | v = str_value (""); | 268 | v = str_value(""); |
278 | else | 269 | else |
279 | v = int_value (0); | 270 | v = int_value(0); |
280 | } | 271 | } |
281 | return v; | 272 | return v; |
282 | } | 273 | } |
283 | 274 | ||
284 | /* Handle bare operands and ( expr ) syntax. */ | 275 | /* Handle bare operands and ( expr ) syntax. */ |
285 | 276 | ||
286 | static VALUE *eval7 (void) | 277 | static VALUE *eval7(void) |
287 | { | 278 | { |
288 | VALUE *v; | 279 | VALUE *v; |
289 | 280 | ||
290 | if (!*args) | 281 | if (!*args) |
291 | bb_error_msg_and_die ( "syntax error"); | 282 | bb_error_msg_and_die("syntax error"); |
292 | 283 | ||
293 | if (nextarg ("(")) { | 284 | if (nextarg("(")) { |
294 | args++; | 285 | args++; |
295 | v = eval (); | 286 | v = eval(); |
296 | if (!nextarg (")")) | 287 | if (!nextarg(")")) |
297 | bb_error_msg_and_die ( "syntax error"); | 288 | bb_error_msg_and_die("syntax error"); |
298 | args++; | 289 | args++; |
299 | return v; | 290 | return v; |
300 | } | 291 | } |
301 | 292 | ||
302 | if (nextarg (")")) | 293 | if (nextarg(")")) |
303 | bb_error_msg_and_die ( "syntax error"); | 294 | bb_error_msg_and_die("syntax error"); |
304 | 295 | ||
305 | return str_value (*args++); | 296 | return str_value(*args++); |
306 | } | 297 | } |
307 | 298 | ||
308 | /* Handle match, substr, index, length, and quote keywords. */ | 299 | /* Handle match, substr, index, length, and quote keywords. */ |
309 | 300 | ||
310 | static VALUE *eval6 (void) | 301 | static VALUE *eval6(void) |
311 | { | 302 | { |
312 | VALUE *l, *r, *v, *i1, *i2; | 303 | VALUE *l, *r, *v, *i1, *i2; |
313 | 304 | ||
314 | if (nextarg ("quote")) { | 305 | if (nextarg("quote")) { |
315 | args++; | 306 | args++; |
316 | if (!*args) | 307 | if (!*args) |
317 | bb_error_msg_and_die ( "syntax error"); | 308 | bb_error_msg_and_die("syntax error"); |
318 | return str_value (*args++); | 309 | return str_value(*args++); |
319 | } | 310 | } else if (nextarg("length")) { |
320 | else if (nextarg ("length")) { | ||
321 | args++; | 311 | args++; |
322 | r = eval6 (); | 312 | r = eval6(); |
323 | tostring (r); | 313 | tostring(r); |
324 | v = int_value (strlen (r->u.s)); | 314 | v = int_value(strlen(r->u.s)); |
325 | freev (r); | 315 | freev(r); |
326 | return v; | 316 | return v; |
327 | } | 317 | } else if (nextarg("match")) { |
328 | else if (nextarg ("match")) { | ||
329 | args++; | 318 | args++; |
330 | l = eval6 (); | 319 | l = eval6(); |
331 | r = eval6 (); | 320 | r = eval6(); |
332 | v = docolon (l, r); | 321 | v = docolon(l, r); |
333 | freev (l); | 322 | freev(l); |
334 | freev (r); | 323 | freev(r); |
335 | return v; | 324 | return v; |
336 | } | 325 | } else if (nextarg("index")) { |
337 | else if (nextarg ("index")) { | ||
338 | args++; | 326 | args++; |
339 | l = eval6 (); | 327 | l = eval6(); |
340 | r = eval6 (); | 328 | r = eval6(); |
341 | tostring (l); | 329 | tostring(l); |
342 | tostring (r); | 330 | tostring(r); |
343 | v = int_value (strcspn (l->u.s, r->u.s) + 1); | 331 | v = int_value(strcspn(l->u.s, r->u.s) + 1); |
344 | if (v->u.i == (arith_t) strlen (l->u.s) + 1) | 332 | if (v->u.i == (arith_t) strlen(l->u.s) + 1) |
345 | v->u.i = 0; | 333 | v->u.i = 0; |
346 | freev (l); | 334 | freev(l); |
347 | freev (r); | 335 | freev(r); |
348 | return v; | 336 | return v; |
349 | } | 337 | } else if (nextarg("substr")) { |
350 | else if (nextarg ("substr")) { | ||
351 | args++; | 338 | args++; |
352 | l = eval6 (); | 339 | l = eval6(); |
353 | i1 = eval6 (); | 340 | i1 = eval6(); |
354 | i2 = eval6 (); | 341 | i2 = eval6(); |
355 | tostring (l); | 342 | tostring(l); |
356 | if (!toarith (i1) || !toarith (i2) | 343 | if (!toarith(i1) || !toarith(i2) |
357 | || i1->u.i > (arith_t) strlen (l->u.s) | 344 | || i1->u.i > (arith_t) strlen(l->u.s) |
358 | || i1->u.i <= 0 || i2->u.i <= 0) | 345 | || i1->u.i <= 0 || i2->u.i <= 0) |
359 | v = str_value (""); | 346 | v = str_value(""); |
360 | else { | 347 | else { |
361 | v = xmalloc (sizeof(VALUE)); | 348 | v = xmalloc(sizeof(VALUE)); |
362 | v->type = string; | 349 | v->type = string; |
363 | v->u.s = xstrndup(l->u.s + i1->u.i - 1, i2->u.i); | 350 | v->u.s = xstrndup(l->u.s + i1->u.i - 1, i2->u.i); |
364 | } | 351 | } |
365 | freev (l); | 352 | freev(l); |
366 | freev (i1); | 353 | freev(i1); |
367 | freev (i2); | 354 | freev(i2); |
368 | return v; | 355 | return v; |
369 | } | 356 | } else |
370 | else | 357 | return eval7(); |
371 | return eval7 (); | ||
372 | } | 358 | } |
373 | 359 | ||
374 | /* Handle : operator (pattern matching). | 360 | /* Handle : operator (pattern matching). |
375 | Calls docolon to do the real work. */ | 361 | Calls docolon to do the real work. */ |
376 | 362 | ||
377 | static VALUE *eval5 (void) | 363 | static VALUE *eval5(void) |
378 | { | 364 | { |
379 | VALUE *l, *r, *v; | 365 | VALUE *l, *r, *v; |
380 | 366 | ||
381 | l = eval6 (); | 367 | l = eval6(); |
382 | while (nextarg (":")) { | 368 | while (nextarg(":")) { |
383 | args++; | 369 | args++; |
384 | r = eval6 (); | 370 | r = eval6(); |
385 | v = docolon (l, r); | 371 | v = docolon(l, r); |
386 | freev (l); | 372 | freev(l); |
387 | freev (r); | 373 | freev(r); |
388 | l = v; | 374 | l = v; |
389 | } | 375 | } |
390 | return l; | 376 | return l; |
@@ -392,128 +378,126 @@ static VALUE *eval5 (void) | |||
392 | 378 | ||
393 | /* Handle *, /, % operators. */ | 379 | /* Handle *, /, % operators. */ |
394 | 380 | ||
395 | static VALUE *eval4 (void) | 381 | static VALUE *eval4(void) |
396 | { | 382 | { |
397 | VALUE *l, *r; | 383 | VALUE *l, *r; |
398 | int op; | 384 | int op; |
399 | arith_t val; | 385 | arith_t val; |
400 | 386 | ||
401 | l = eval5 (); | 387 | l = eval5(); |
402 | while (1) { | 388 | while (1) { |
403 | if (nextarg ("*")) | 389 | if (nextarg("*")) |
404 | op = '*'; | 390 | op = '*'; |
405 | else if (nextarg ("/")) | 391 | else if (nextarg("/")) |
406 | op = '/'; | 392 | op = '/'; |
407 | else if (nextarg ("%")) | 393 | else if (nextarg("%")) |
408 | op = '%'; | 394 | op = '%'; |
409 | else | 395 | else |
410 | return l; | 396 | return l; |
411 | args++; | 397 | args++; |
412 | r = eval5 (); | 398 | r = eval5(); |
413 | val = arithmetic_common (l, r, op); | 399 | val = arithmetic_common(l, r, op); |
414 | freev (l); | 400 | freev(l); |
415 | freev (r); | 401 | freev(r); |
416 | l = int_value (val); | 402 | l = int_value(val); |
417 | } | 403 | } |
418 | } | 404 | } |
419 | 405 | ||
420 | /* Handle +, - operators. */ | 406 | /* Handle +, - operators. */ |
421 | 407 | ||
422 | static VALUE *eval3 (void) | 408 | static VALUE *eval3(void) |
423 | { | 409 | { |
424 | VALUE *l, *r; | 410 | VALUE *l, *r; |
425 | int op; | 411 | int op; |
426 | arith_t val; | 412 | arith_t val; |
427 | 413 | ||
428 | l = eval4 (); | 414 | l = eval4(); |
429 | while (1) { | 415 | while (1) { |
430 | if (nextarg ("+")) | 416 | if (nextarg("+")) |
431 | op = '+'; | 417 | op = '+'; |
432 | else if (nextarg ("-")) | 418 | else if (nextarg("-")) |
433 | op = '-'; | 419 | op = '-'; |
434 | else | 420 | else |
435 | return l; | 421 | return l; |
436 | args++; | 422 | args++; |
437 | r = eval4 (); | 423 | r = eval4(); |
438 | val = arithmetic_common (l, r, op); | 424 | val = arithmetic_common(l, r, op); |
439 | freev (l); | 425 | freev(l); |
440 | freev (r); | 426 | freev(r); |
441 | l = int_value (val); | 427 | l = int_value(val); |
442 | } | 428 | } |
443 | } | 429 | } |
444 | 430 | ||
445 | /* Handle comparisons. */ | 431 | /* Handle comparisons. */ |
446 | 432 | ||
447 | static VALUE *eval2 (void) | 433 | static VALUE *eval2(void) |
448 | { | 434 | { |
449 | VALUE *l, *r; | 435 | VALUE *l, *r; |
450 | int op; | 436 | int op; |
451 | arith_t val; | 437 | arith_t val; |
452 | 438 | ||
453 | l = eval3 (); | 439 | l = eval3(); |
454 | while (1) { | 440 | while (1) { |
455 | if (nextarg ("<")) | 441 | if (nextarg("<")) |
456 | op = '<'; | 442 | op = '<'; |
457 | else if (nextarg ("<=")) | 443 | else if (nextarg("<=")) |
458 | op = 'L'+'E'; | 444 | op = 'L' + 'E'; |
459 | else if (nextarg ("=") || nextarg ("==")) | 445 | else if (nextarg("=") || nextarg("==")) |
460 | op = '='; | 446 | op = '='; |
461 | else if (nextarg ("!=")) | 447 | else if (nextarg("!=")) |
462 | op = '!'; | 448 | op = '!'; |
463 | else if (nextarg (">=")) | 449 | else if (nextarg(">=")) |
464 | op = 'G'+'E'; | 450 | op = 'G' + 'E'; |
465 | else if (nextarg (">")) | 451 | else if (nextarg(">")) |
466 | op = '>'; | 452 | op = '>'; |
467 | else | 453 | else |
468 | return l; | 454 | return l; |
469 | args++; | 455 | args++; |
470 | r = eval3 (); | 456 | r = eval3(); |
471 | toarith (l); | 457 | toarith(l); |
472 | toarith (r); | 458 | toarith(r); |
473 | val = cmp_common (l, r, op); | 459 | val = cmp_common(l, r, op); |
474 | freev (l); | 460 | freev(l); |
475 | freev (r); | 461 | freev(r); |
476 | l = int_value (val); | 462 | l = int_value(val); |
477 | } | 463 | } |
478 | } | 464 | } |
479 | 465 | ||
480 | /* Handle &. */ | 466 | /* Handle &. */ |
481 | 467 | ||
482 | static VALUE *eval1 (void) | 468 | static VALUE *eval1(void) |
483 | { | 469 | { |
484 | VALUE *l, *r; | 470 | VALUE *l, *r; |
485 | 471 | ||
486 | l = eval2 (); | 472 | l = eval2(); |
487 | while (nextarg ("&")) { | 473 | while (nextarg("&")) { |
488 | args++; | 474 | args++; |
489 | r = eval2 (); | 475 | r = eval2(); |
490 | if (null (l) || null (r)) { | 476 | if (null(l) || null(r)) { |
491 | freev (l); | 477 | freev(l); |
492 | freev (r); | 478 | freev(r); |
493 | l = int_value (0); | 479 | l = int_value(0); |
494 | } | 480 | } else |
495 | else | 481 | freev(r); |
496 | freev (r); | ||
497 | } | 482 | } |
498 | return l; | 483 | return l; |
499 | } | 484 | } |
500 | 485 | ||
501 | /* Handle |. */ | 486 | /* Handle |. */ |
502 | 487 | ||
503 | static VALUE *eval (void) | 488 | static VALUE *eval(void) |
504 | { | 489 | { |
505 | VALUE *l, *r; | 490 | VALUE *l, *r; |
506 | 491 | ||
507 | l = eval1 (); | 492 | l = eval1(); |
508 | while (nextarg ("|")) { | 493 | while (nextarg("|")) { |
509 | args++; | 494 | args++; |
510 | r = eval1 (); | 495 | r = eval1(); |
511 | if (null (l)) { | 496 | if (null(l)) { |
512 | freev (l); | 497 | freev(l); |
513 | l = r; | 498 | l = r; |
514 | } | 499 | } else |
515 | else | 500 | freev(r); |
516 | freev (r); | ||
517 | } | 501 | } |
518 | return l; | 502 | return l; |
519 | } | 503 | } |