aboutsummaryrefslogtreecommitdiff
path: root/coreutils/expr.c
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2003-08-29 07:29:30 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2003-08-29 07:29:30 +0000
commit7b8765c808641d74edd1f0a4f22c092ea21421fa (patch)
treef15b6c928209cc41ad172054caa8831e618066b4 /coreutils/expr.c
parent23365976f8e0265adc2f21d8e330ce58e270041a (diff)
downloadbusybox-w32-7b8765c808641d74edd1f0a4f22c092ea21421fa.tar.gz
busybox-w32-7b8765c808641d74edd1f0a4f22c092ea21421fa.tar.bz2
busybox-w32-7b8765c808641d74edd1f0a4f22c092ea21421fa.zip
vodz, last patch 103
Diffstat (limited to 'coreutils/expr.c')
-rw-r--r--coreutils/expr.c141
1 files changed, 69 insertions, 72 deletions
diff --git a/coreutils/expr.c b/coreutils/expr.c
index ecba825d5..f58f4b062 100644
--- a/coreutils/expr.c
+++ b/coreutils/expr.c
@@ -7,6 +7,7 @@
7 * 7 *
8 * Busybox modifications 8 * Busybox modifications
9 * Copyright (c) 2000 Edward Betts <edward@debian.org>. 9 * Copyright (c) 2000 Edward Betts <edward@debian.org>.
10 * Aug 2003 Vladimir Oleynik - reduced 464 bytes.
10 * 11 *
11 * this program is free software; you can redistribute it and/or modify 12 * this program is free software; you can redistribute it and/or modify
12 * it under the terms of the gnu general public license as published by 13 * it under the terms of the gnu general public license as published by
@@ -40,6 +41,7 @@
40#include <stdlib.h> 41#include <stdlib.h>
41#include <regex.h> 42#include <regex.h>
42#include <sys/types.h> 43#include <sys/types.h>
44#include <errno.h>
43#include "busybox.h" 45#include "busybox.h"
44 46
45 47
@@ -135,10 +137,8 @@ static int null (VALUE *v)
135 switch (v->type) { 137 switch (v->type) {
136 case integer: 138 case integer:
137 return v->u.i == 0; 139 return v->u.i == 0;
138 case string: 140 default: /* string: */
139 return v->u.s[0] == '\0' || strcmp (v->u.s, "0") == 0; 141 return v->u.s[0] == '\0' || strcmp (v->u.s, "0") == 0;
140 default:
141 abort ();
142 } 142 }
143} 143}
144 144
@@ -156,13 +156,9 @@ static void tostring (VALUE *v)
156 156
157static int toarith (VALUE *v) 157static int toarith (VALUE *v)
158{ 158{
159 if(v->type == string) {
159 int i; 160 int i;
160 161
161 switch (v->type) {
162 case integer:
163 return 1;
164 case string:
165 i = 0;
166 /* Don't interpret the empty string as an integer. */ 162 /* Don't interpret the empty string as an integer. */
167 if (v->u.s == 0) 163 if (v->u.s == 0)
168 return 0; 164 return 0;
@@ -170,10 +166,8 @@ static int toarith (VALUE *v)
170 free (v->u.s); 166 free (v->u.s);
171 v->u.i = i; 167 v->u.i = i;
172 v->type = integer; 168 v->type = integer;
173 return 1;
174 default:
175 abort ();
176 } 169 }
170 return 1;
177} 171}
178 172
179/* Return nonzero if the next token matches STR exactly. 173/* Return nonzero if the next token matches STR exactly.
@@ -189,56 +183,59 @@ nextarg (char *str)
189 183
190/* The comparison operator handling functions. */ 184/* The comparison operator handling functions. */
191 185
192#define cmpf(name, rel) \ 186static int cmp_common (VALUE *l, VALUE *r, int op)
193static int name (VALUE *l, VALUE *r) \ 187{
194{ \ 188 int cmpval;
195 if (l->type == string || r->type == string) { \
196 tostring (l); \
197 tostring (r); \
198 return strcmp (l->u.s, r->u.s) rel 0; \
199 } \
200 else \
201 return l->u.i rel r->u.i; \
202}
203 cmpf (less_than, <)
204 cmpf (less_equal, <=)
205 cmpf (equal, ==)
206 cmpf (not_equal, !=)
207 cmpf (greater_equal, >=)
208 cmpf (greater_than, >)
209 189
210#undef cmpf 190 if (l->type == string || r->type == string) {
191 tostring (l);
192 tostring (r);
193 cmpval = strcmp (l->u.s, r->u.s);
194 }
195 else
196 cmpval = l->u.i - r->u.i;
197 switch(op) {
198 case '<':
199 return cmpval < 0;
200 case ('L'+'E'):
201 return cmpval <= 0;
202 case '=':
203 return cmpval == 0;
204 case '!':
205 return cmpval != 0;
206 case '>':
207 return cmpval > 0;
208 default: /* >= */
209 return cmpval >= 0;
210 }
211}
211 212
212/* The arithmetic operator handling functions. */ 213/* The arithmetic operator handling functions. */
213 214
214#define arithf(name, op) \ 215static int arithmetic_common (VALUE *l, VALUE *r, int op)
215static \ 216{
216int name (VALUE *l, VALUE *r) \ 217 int li, ri;
217{ \ 218
218 if (!toarith (l) || !toarith (r)) \ 219 if (!toarith (l) || !toarith (r))
219 bb_error_msg_and_die ("non-numeric argument"); \ 220 bb_error_msg_and_die ("non-numeric argument");
220 return l->u.i op r->u.i; \ 221 li = l->u.i;
221} 222 ri = r->u.i;
222 223 if((op == '/' || op == '%') && ri == 0)
223#define arithdivf(name, op) \ 224 bb_error_msg_and_die ( "division by zero");
224static int name (VALUE *l, VALUE *r) \ 225 switch(op) {
225{ \ 226 case '+':
226 if (!toarith (l) || !toarith (r)) \ 227 return li + ri;
227 bb_error_msg_and_die ( "non-numeric argument"); \ 228 case '-':
228 if (r->u.i == 0) \ 229 return li - ri;
229 bb_error_msg_and_die ( "division by zero"); \ 230 case '*':
230 return l->u.i op r->u.i; \ 231 return li * ri;
232 case '/':
233 return li / ri;
234 default:
235 return li % ri;
236 }
231} 237}
232 238
233 arithf (plus, +)
234 arithf (minus, -)
235 arithf (multiply, *)
236 arithdivf (divide, /)
237 arithdivf (mod, %)
238
239#undef arithf
240#undef arithdivf
241
242/* Do the : operator. 239/* Do the : operator.
243 SV is the VALUE for the lhs (the string), 240 SV is the VALUE for the lhs (the string),
244 PV is the VALUE for the rhs (the pattern). */ 241 PV is the VALUE for the rhs (the pattern). */
@@ -408,21 +405,21 @@ static VALUE *eval5 (void)
408static VALUE *eval4 (void) 405static VALUE *eval4 (void)
409{ 406{
410 VALUE *l, *r; 407 VALUE *l, *r;
411 int (*fxn) (VALUE *, VALUE *), val; 408 int op, val;
412 409
413 l = eval5 (); 410 l = eval5 ();
414 while (1) { 411 while (1) {
415 if (nextarg ("*")) 412 if (nextarg ("*"))
416 fxn = multiply; 413 op = '*';
417 else if (nextarg ("/")) 414 else if (nextarg ("/"))
418 fxn = divide; 415 op = '/';
419 else if (nextarg ("%")) 416 else if (nextarg ("%"))
420 fxn = mod; 417 op = '%';
421 else 418 else
422 return l; 419 return l;
423 args++; 420 args++;
424 r = eval5 (); 421 r = eval5 ();
425 val = (*fxn) (l, r); 422 val = arithmetic_common (l, r, op);
426 freev (l); 423 freev (l);
427 freev (r); 424 freev (r);
428 l = int_value (val); 425 l = int_value (val);
@@ -434,19 +431,19 @@ static VALUE *eval4 (void)
434static VALUE *eval3 (void) 431static VALUE *eval3 (void)
435{ 432{
436 VALUE *l, *r; 433 VALUE *l, *r;
437 int (*fxn) (VALUE *, VALUE *), val; 434 int op, val;
438 435
439 l = eval4 (); 436 l = eval4 ();
440 while (1) { 437 while (1) {
441 if (nextarg ("+")) 438 if (nextarg ("+"))
442 fxn = plus; 439 op = '+';
443 else if (nextarg ("-")) 440 else if (nextarg ("-"))
444 fxn = minus; 441 op = '+';
445 else 442 else
446 return l; 443 return l;
447 args++; 444 args++;
448 r = eval4 (); 445 r = eval4 ();
449 val = (*fxn) (l, r); 446 val = arithmetic_common (l, r, op);
450 freev (l); 447 freev (l);
451 freev (r); 448 freev (r);
452 l = int_value (val); 449 l = int_value (val);
@@ -458,29 +455,29 @@ static VALUE *eval3 (void)
458static VALUE *eval2 (void) 455static VALUE *eval2 (void)
459{ 456{
460 VALUE *l, *r; 457 VALUE *l, *r;
461 int (*fxn) (VALUE *, VALUE *), val; 458 int op, val;
462 459
463 l = eval3 (); 460 l = eval3 ();
464 while (1) { 461 while (1) {
465 if (nextarg ("<")) 462 if (nextarg ("<"))
466 fxn = less_than; 463 op = '<';
467 else if (nextarg ("<=")) 464 else if (nextarg ("<="))
468 fxn = less_equal; 465 op = 'L'+'E';
469 else if (nextarg ("=") || nextarg ("==")) 466 else if (nextarg ("=") || nextarg ("=="))
470 fxn = equal; 467 op = '=';
471 else if (nextarg ("!=")) 468 else if (nextarg ("!="))
472 fxn = not_equal; 469 op = '!';
473 else if (nextarg (">=")) 470 else if (nextarg (">="))
474 fxn = greater_equal; 471 op = 'G'+'E';
475 else if (nextarg (">")) 472 else if (nextarg (">"))
476 fxn = greater_than; 473 op = '>';
477 else 474 else
478 return l; 475 return l;
479 args++; 476 args++;
480 r = eval3 (); 477 r = eval3 ();
481 toarith (l); 478 toarith (l);
482 toarith (r); 479 toarith (r);
483 val = (*fxn) (l, r); 480 val = cmp_common (l, r, op);
484 freev (l); 481 freev (l);
485 freev (r); 482 freev (r);
486 l = int_value (val); 483 l = int_value (val);