diff options
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 |
commit | 8aa9e5714932b0e1a9f4b638e2d985faa7e4d911 (patch) | |
tree | 16966108ff04735932dfe87f0fd1a4ddb54a8fe0 | |
parent | 1e98a0705b4b6bc2120ae8bb87cabc218f0187fa (diff) | |
download | busybox-w32-8aa9e5714932b0e1a9f4b638e2d985faa7e4d911.tar.gz busybox-w32-8aa9e5714932b0e1a9f4b638e2d985faa7e4d911.tar.bz2 busybox-w32-8aa9e5714932b0e1a9f4b638e2d985faa7e4d911.zip |
support 64 arith. Close bug 136
-rw-r--r-- | coreutils/Config.in | 9 | ||||
-rw-r--r-- | coreutils/expr.c | 51 |
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 | ||
174 | config 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 | |||
174 | config CONFIG_FALSE | 183 | config 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 | }; |
53 | typedef enum valtype TYPE; | 55 | typedef enum valtype TYPE; |
54 | 56 | ||
57 | #if ENABLE_EXPR_MATH_SUPPORT_64 | ||
58 | typedef int64_t arith_t; | ||
59 | #define PF_REZ "ll" | ||
60 | #define STRTOL(s, e, b) strtoll(s, e, b) | ||
61 | #else | ||
62 | typedef 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.... */ |
56 | struct valinfo { | 68 | struct 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 | ||
68 | static VALUE *docolon (VALUE *sv, VALUE *pv); | 80 | static VALUE *docolon (VALUE *sv, VALUE *pv); |
69 | static VALUE *eval (void); | 81 | static VALUE *eval (void); |
70 | static VALUE *int_value (int i); | 82 | static VALUE *int_value (arith_t i); |
71 | static VALUE *str_value (char *s); | 83 | static VALUE *str_value (char *s); |
72 | static int nextarg (char *str); | 84 | static int nextarg (char *str); |
73 | static int null (VALUE *v); | 85 | static 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 | ||
102 | static VALUE *int_value (int i) | 114 | static 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) | |||
147 | static void tostring (VALUE *v) | 159 | static 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) | |||
157 | static int toarith (VALUE *v) | 169 | static 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 | ||
217 | static int arithmetic_common (VALUE *l, VALUE *r, int op) | 229 | static 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) | |||
400 | static VALUE *eval4 (void) | 412 | static 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) | |||
426 | static VALUE *eval3 (void) | 439 | static 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) | |||
450 | static VALUE *eval2 (void) | 464 | static 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) { |