aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-09 13:21:54 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-09 13:21:54 +0100
commit4a024c771992e274f46a8451647dc86f92a90999 (patch)
treea63f28dec034f1ea5bea10fdd6a7397ed5e3bbd6
parent3129f705fc630cf597abeaa97000f896d2813d52 (diff)
downloadbusybox-4a024c771992e274f46a8451647dc86f92a90999.tar.gz
bc: simplify string-tonumber conversion code
function old new delta bc_program_num 1108 983 -125 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-125) Total: -125 bytes text data bss dec hex filename 985831 477 7296 993604 f2944 busybox_old 985706 477 7296 993479 f28c7 busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/bc.c88
1 files changed, 43 insertions, 45 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 71b419d8f..c36486414 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -2199,49 +2199,45 @@ static BcStatus bc_num_binary(BcNum *a, BcNum *b, BcNum *c, size_t scale,
static bool bc_num_strValid(const char *val, size_t base)
{
BcDig b;
- bool small, radix = false;
- size_t i, len = strlen(val);
-
- if (!len) return true;
-
- small = base <= 10;
- b = (BcDig)(small ? base + '0' : base - 10 + 'A');
-
- for (i = 0; i < len; ++i) {
-
- BcDig c = val[i];
+ bool radix;
+ b = (BcDig)(base <= 10 ? base + '0' : base - 10 + 'A');
+ radix = false;
+ for (;;) {
+ BcDig c = *val++;
+ if (c == '\0')
+ break;
if (c == '.') {
-
if (radix) return false;
-
radix = true;
continue;
}
-
- if (c < '0' || (small && c >= b) || (c > '9' && (c < 'A' || c >= b)))
+ if (c < '0' || c >= b || (c > '9' && c < 'A'))
return false;
}
-
return true;
}
+// Note: n is already "bc_num_zero()"ed,
+// leading zeroes in "val" are removed
static void bc_num_parseDecimal(BcNum *n, const char *val)
{
size_t len, i;
const char *ptr;
- bool zero = true;
+ bool zero;
- for (i = 0; val[i] == '0'; ++i);
-
- val += i;
len = strlen(val);
- bc_num_zero(n);
+ if (len == 0)
+ return;
- if (len != 0) {
- for (i = 0; zero && i < len; ++i) zero = val[i] == '0' || val[i] == '.';
- bc_num_expand(n, len);
+ zero = true;
+ for (i = 0; val[i]; ++i) {
+ if (val[i] != '0' && val[i] != '.') {
+ zero = false;
+ break;
+ }
}
+ bc_num_expand(n, len);
ptr = strchr(val, '.');
@@ -2255,26 +2251,29 @@ static void bc_num_parseDecimal(BcNum *n, const char *val)
}
}
+// Note: n is already "bc_num_zero()"ed,
+// leading zeroes in "val" are removed
static void bc_num_parseBase(BcNum *n, const char *val, BcNum *base)
{
BcStatus s;
BcNum temp, mult, result;
BcDig c = '\0';
- bool zero = true;
unsigned long v;
- size_t i, digits, len = strlen(val);
+ size_t i, digits;
- bc_num_zero(n);
-
- for (i = 0; zero && i < len; ++i) zero = (val[i] == '.' || val[i] == '0');
- if (zero) return;
+ for (i = 0; ; ++i) {
+ if (val[i] == '\0')
+ return;
+ if (val[i] != '.' && val[i] != '0')
+ break;
+ }
bc_num_init_DEF_SIZE(&temp);
bc_num_init_DEF_SIZE(&mult);
- for (i = 0; i < len; ++i) {
-
- c = val[i];
+ for (;;) {
+ c = *val++;
+ if (c == '\0') goto int_err;
if (c == '.') break;
v = (unsigned long) (c <= '9' ? c - '0' : c - 'A' + 10);
@@ -2286,19 +2285,15 @@ static void bc_num_parseBase(BcNum *n, const char *val, BcNum *base)
if (s) goto int_err;
}
- if (i == len) {
- c = val[i];
- if (c == 0) goto int_err;
- }
-
bc_num_init(&result, base->len);
//bc_num_zero(&result); - already is
bc_num_one(&mult);
- for (i += 1, digits = 0; i < len; ++i, ++digits) {
-
- c = val[i];
- if (c == 0) break;
+ digits = 0;
+ for (;;) {
+ c = *val++;
+ if (c == '\0') break;
+ digits++;
v = (unsigned long) (c <= '9' ? c - '0' : c - 'A' + 10);
@@ -2318,8 +2313,7 @@ static void bc_num_parseBase(BcNum *n, const char *val, BcNum *base)
if (n->len != 0) {
if (n->rdx < digits) bc_num_extend(n, digits - n->rdx);
- }
- else
+ } else
bc_num_zero(n);
err:
@@ -2498,6 +2492,9 @@ static BcStatus bc_num_parse(BcNum *n, const char *val, BcNum *base,
if (!bc_num_strValid(val, base_t))
return bc_error("bad number string");
+ bc_num_zero(n);
+ while (*val == '0') val++;
+
if (base_t == 10)
bc_num_parseDecimal(n, val);
else
@@ -6387,7 +6384,7 @@ static BcStatus bc_program_asciify(void)
{
BcStatus s;
BcResult *r, res;
- BcNum *num = NULL, n;
+ BcNum *num, n;
char *str, *str2, c;
size_t len = G.prog.strs.len, idx;
unsigned long val;
@@ -6396,6 +6393,7 @@ static BcStatus bc_program_asciify(void)
return bc_error_stack_has_too_few_elements();
r = bc_vec_top(&G.prog.results);
+ num = NULL; // TODO: is this NULL needed?
s = bc_program_num(r, &num, false);
if (s) return s;