aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author"Vladimir N. Oleynik" <dzo@simtreas.ru>2006-01-25 13:56:03 +0000
committer"Vladimir N. Oleynik" <dzo@simtreas.ru>2006-01-25 13:56:03 +0000
commit8aa9e5714932b0e1a9f4b638e2d985faa7e4d911 (patch)
tree16966108ff04735932dfe87f0fd1a4ddb54a8fe0
parent1e98a0705b4b6bc2120ae8bb87cabc218f0187fa (diff)
downloadbusybox-w32-8aa9e5714932b0e1a9f4b638e2d985faa7e4d911.tar.gz
busybox-w32-8aa9e5714932b0e1a9f4b638e2d985faa7e4d911.tar.bz2
busybox-w32-8aa9e5714932b0e1a9f4b638e2d985faa7e4d911.zip
support 64 arith. Close bug 136
-rw-r--r--coreutils/Config.in9
-rw-r--r--coreutils/expr.c51
2 files changed, 42 insertions, 18 deletions
diff --git a/coreutils/Config.in b/coreutils/Config.in
index 29f73adea..0ee5e9dbd 100644
--- a/coreutils/Config.in
+++ b/coreutils/Config.in
@@ -171,6 +171,15 @@ config CONFIG_EXPR
171 expr is used to calculate numbers and print the result 171 expr is used to calculate numbers and print the result
172 to standard output. 172 to standard output.
173 173
174config CONFIG_EXPR_MATH_SUPPORT_64
175 bool " Extend Posix numbers support to 64 bit"
176 default n
177 depends on CONFIG_EXPR
178 help
179 Enable 64-bit math support in the expr applet. This will make
180 the applet slightly larger, but will allow computation with very
181 large numbers.
182
174config CONFIG_FALSE 183config CONFIG_FALSE
175 bool "false" 184 bool "false"
176 default n 185 default n
diff --git a/coreutils/expr.c b/coreutils/expr.c
index a243e75af..e0eb4ec8c 100644
--- a/coreutils/expr.c
+++ b/coreutils/expr.c
@@ -7,7 +7,9 @@
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 * Copyright (C) 2003-2005 Vladimir Oleynik <dzo@simtreas.ru>
11 * - reduced 464 bytes.
12 * - 64 math support
11 * 13 *
12 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
@@ -52,11 +54,21 @@ enum valtype {
52}; 54};
53typedef enum valtype TYPE; 55typedef enum valtype TYPE;
54 56
57#if ENABLE_EXPR_MATH_SUPPORT_64
58typedef int64_t arith_t;
59#define PF_REZ "ll"
60#define STRTOL(s, e, b) strtoll(s, e, b)
61#else
62typedef long arith_t;
63#define PF_REZ "l"
64#define STRTOL(s, e, b) strtol(s, e, b)
65#endif
66
55/* A value is.... */ 67/* A value is.... */
56struct valinfo { 68struct valinfo {
57 TYPE type; /* Which kind. */ 69 TYPE type; /* Which kind. */
58 union { /* The value itself. */ 70 union { /* The value itself. */
59 int i; 71 arith_t i;
60 char *s; 72 char *s;
61 } u; 73 } u;
62}; 74};
@@ -67,7 +79,7 @@ static char **args;
67 79
68static VALUE *docolon (VALUE *sv, VALUE *pv); 80static VALUE *docolon (VALUE *sv, VALUE *pv);
69static VALUE *eval (void); 81static VALUE *eval (void);
70static VALUE *int_value (int i); 82static VALUE *int_value (arith_t i);
71static VALUE *str_value (char *s); 83static VALUE *str_value (char *s);
72static int nextarg (char *str); 84static int nextarg (char *str);
73static int null (VALUE *v); 85static int null (VALUE *v);
@@ -90,7 +102,7 @@ int expr_main (int argc, char **argv)
90 bb_error_msg_and_die ("syntax error"); 102 bb_error_msg_and_die ("syntax error");
91 103
92 if (v->type == integer) 104 if (v->type == integer)
93 printf ("%d\n", v->u.i); 105 printf ("%" PF_REZ "d\n", v->u.i);
94 else 106 else
95 puts (v->u.s); 107 puts (v->u.s);
96 108
@@ -99,7 +111,7 @@ int expr_main (int argc, char **argv)
99 111
100/* Return a VALUE for I. */ 112/* Return a VALUE for I. */
101 113
102static VALUE *int_value (int i) 114static VALUE *int_value (arith_t i)
103{ 115{
104 VALUE *v; 116 VALUE *v;
105 117
@@ -147,7 +159,7 @@ static int null (VALUE *v)
147static void tostring (VALUE *v) 159static void tostring (VALUE *v)
148{ 160{
149 if (v->type == integer) { 161 if (v->type == integer) {
150 v->u.s = bb_xasprintf ("%d", v->u.i); 162 v->u.s = bb_xasprintf ("%" PF_REZ "d", v->u.i);
151 v->type = string; 163 v->type = string;
152 } 164 }
153} 165}
@@ -157,12 +169,12 @@ static void tostring (VALUE *v)
157static int toarith (VALUE *v) 169static int toarith (VALUE *v)
158{ 170{
159 if(v->type == string) { 171 if(v->type == string) {
160 int i; 172 arith_t i;
161 char *e; 173 char *e;
162 174
163 /* Don't interpret the empty string as an integer. */ 175 /* Don't interpret the empty string as an integer. */
164 /* Currently does not worry about overflow or int/long differences. */ 176 /* Currently does not worry about overflow or int/long differences. */
165 i = (int) strtol(v->u.s, &e, 10); 177 i = STRTOL(v->u.s, &e, 10);
166 if ((v->u.s == e) || *e) 178 if ((v->u.s == e) || *e)
167 return 0; 179 return 0;
168 free (v->u.s); 180 free (v->u.s);
@@ -214,9 +226,9 @@ static int cmp_common (VALUE *l, VALUE *r, int op)
214 226
215/* The arithmetic operator handling functions. */ 227/* The arithmetic operator handling functions. */
216 228
217static int arithmetic_common (VALUE *l, VALUE *r, int op) 229static arith_t arithmetic_common (VALUE *l, VALUE *r, int op)
218{ 230{
219 int li, ri; 231 arith_t li, ri;
220 232
221 if (!toarith (l) || !toarith (r)) 233 if (!toarith (l) || !toarith (r))
222 bb_error_msg_and_die ("non-numeric argument"); 234 bb_error_msg_and_die ("non-numeric argument");
@@ -346,7 +358,7 @@ static VALUE *eval6 (void)
346 tostring (l); 358 tostring (l);
347 tostring (r); 359 tostring (r);
348 v = int_value (strcspn (l->u.s, r->u.s) + 1); 360 v = int_value (strcspn (l->u.s, r->u.s) + 1);
349 if (v->u.i == (int) strlen (l->u.s) + 1) 361 if (v->u.i == (arith_t) strlen (l->u.s) + 1)
350 v->u.i = 0; 362 v->u.i = 0;
351 freev (l); 363 freev (l);
352 freev (r); 364 freev (r);
@@ -359,13 +371,13 @@ static VALUE *eval6 (void)
359 i2 = eval6 (); 371 i2 = eval6 ();
360 tostring (l); 372 tostring (l);
361 if (!toarith (i1) || !toarith (i2) 373 if (!toarith (i1) || !toarith (i2)
362 || i1->u.i > (int) strlen (l->u.s) 374 || i1->u.i > (arith_t) strlen (l->u.s)
363 || i1->u.i <= 0 || i2->u.i <= 0) 375 || i1->u.i <= 0 || i2->u.i <= 0)
364 v = str_value (""); 376 v = str_value ("");
365 else { 377 else {
366 v = xmalloc (sizeof(VALUE)); 378 v = xmalloc (sizeof(VALUE));
367 v->type = string; 379 v->type = string;
368 v->u.s = bb_xstrndup(l->u.s + i1->u.i - 1, i2->u.i); 380 v->u.s = bb_xstrndup(l->u.s + i1->u.i - 1, i2->u.i);
369 } 381 }
370 freev (l); 382 freev (l);
371 freev (i1); 383 freev (i1);
@@ -400,7 +412,8 @@ static VALUE *eval5 (void)
400static VALUE *eval4 (void) 412static VALUE *eval4 (void)
401{ 413{
402 VALUE *l, *r; 414 VALUE *l, *r;
403 int op, val; 415 int op;
416 arith_t val;
404 417
405 l = eval5 (); 418 l = eval5 ();
406 while (1) { 419 while (1) {
@@ -426,7 +439,8 @@ static VALUE *eval4 (void)
426static VALUE *eval3 (void) 439static VALUE *eval3 (void)
427{ 440{
428 VALUE *l, *r; 441 VALUE *l, *r;
429 int op, val; 442 int op;
443 arith_t val;
430 444
431 l = eval4 (); 445 l = eval4 ();
432 while (1) { 446 while (1) {
@@ -450,7 +464,8 @@ static VALUE *eval3 (void)
450static VALUE *eval2 (void) 464static VALUE *eval2 (void)
451{ 465{
452 VALUE *l, *r; 466 VALUE *l, *r;
453 int op, val; 467 int op;
468 arith_t val;
454 469
455 l = eval3 (); 470 l = eval3 ();
456 while (1) { 471 while (1) {