aboutsummaryrefslogtreecommitdiff
path: root/coreutils/expr.c
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2006-08-28 23:31:54 +0000
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2006-08-28 23:31:54 +0000
commit73561cc75ac31e63bcab4b4ebfaf738e4ca225e6 (patch)
tree2a57564b8917a983365c765d4daa83032d9f0a17 /coreutils/expr.c
parent6ce8dae1d5a201156a83201de6c49cdcc4c8df3e (diff)
downloadbusybox-w32-73561cc75ac31e63bcab4b4ebfaf738e4ca225e6.tar.gz
busybox-w32-73561cc75ac31e63bcab4b4ebfaf738e4ca225e6.tar.bz2
busybox-w32-73561cc75ac31e63bcab4b4ebfaf738e4ca225e6.zip
- pull from busybox_scratch: r15829:15850
Various fixes, cleanups and shrinkage: saves 952 Bytes: text data bss dec hex filename 1087742 15853 790632 1894227 1ce753 ../busybox/busybox.old 1086790 15853 790632 1893275 1ce39b busybox via: # scripts/bloat-o-meter ../busybox/busybox_unstripped.old busybox_unstripped function old new delta ipcrm_main 756 822 +66 getval - 61 +61 maybe_set_utc - 40 +40 udhcpc_main 2896 2912 +16 md5_hash_block 428 437 +9 opt 8 16 +8 qgravechar 106 110 +4 make_bitmap 292 295 +3 inflate_unzip 2056 2059 +3 add_partition 1412 1414 +2 __parsespent 156 158 +2 qrealloc 41 42 +1 format - 1 +1 catv_main 313 314 +1 watch_main 293 292 -1 varunset 81 80 -1 part 1 - -1 check_if_skip 837 836 -1 start_stop_daemon_main 840 837 -3 create_lost_and_found 175 172 -3 supress_non_delimited_lines 4 - -4 static.l 4 - -4 static.c 5 1 -4 bsd_sum_file 237 233 -4 eval2 338 332 -6 arithmetic_common 166 158 -8 cmpfunc 22 5 -17 cksum_main 294 275 -19 cmp_main 465 439 -26 dd_main 1535 1508 -27 rmmod_main 376 333 -43 cut_file 727 644 -83 ipcs_main 3809 3721 -88 cut_main 722 614 -108 date_main 1443 1263 -180 remove_ids 222 - -222 ------------------------------------------------------------------------------ (add/remove: 3/4 grow/shrink: 11/18 up/down: 217/-853) Total: -636 bytes
Diffstat (limited to 'coreutils/expr.c')
-rw-r--r--coreutils/expr.c406
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
39typedef int64_t arith_t; 39typedef 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
44typedef long arith_t; 45typedef 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.... */
51struct valinfo { 53struct 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. */
61static char **args; 63static char **args;
62 64
63static VALUE *docolon (VALUE *sv, VALUE *pv); 65static VALUE *docolon(VALUE * sv, VALUE * pv);
64static VALUE *eval (void); 66static VALUE *eval(void);
65static VALUE *int_value (arith_t i); 67static VALUE *int_value(arith_t i);
66static VALUE *str_value (char *s); 68static VALUE *str_value(char *s);
67static int nextarg (char *str); 69static int nextarg(char *str);
68static int null (VALUE *v); 70static int null(VALUE * v);
69static int toarith (VALUE *v); 71static int toarith(VALUE * v);
70static void freev (VALUE *v); 72static void freev(VALUE * v);
71static void tostring (VALUE *v); 73static void tostring(VALUE * v);
72 74
73int expr_main (int argc, char **argv) 75int 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
97static VALUE *int_value (arith_t i) 99static 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
109static VALUE *str_value (char *s) 111static 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
121static void freev (VALUE *v) 123static 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
130static int null (VALUE *v) 132static 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
142static void tostring (VALUE *v) 142static 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
152static int toarith (VALUE *v) 152static 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
173static int 173static int nextarg(char *str)
174nextarg (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
183static int cmp_common (VALUE *l, VALUE *r, int op) 182static 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
212static arith_t arithmetic_common (VALUE *l, VALUE *r, int op) 208static 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
240static VALUE *docolon (VALUE *sv, VALUE *pv) 234static 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, "\
252warning: unportable BRE: `%s': using `^' as the first character\n\ 246warning: unportable BRE: `%s': using `^' as the first character\n\
253of a basic regular expression is not portable; it is being ignored", 247of 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
286static VALUE *eval7 (void) 277static 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
310static VALUE *eval6 (void) 301static 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
377static VALUE *eval5 (void) 363static 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
395static VALUE *eval4 (void) 381static 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
422static VALUE *eval3 (void) 408static 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
447static VALUE *eval2 (void) 433static 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
482static VALUE *eval1 (void) 468static 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
503static VALUE *eval (void) 488static 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}