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>
This commit is contained in:
parent
3129f705fc
commit
4a024c7719
@ -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)
|
static bool bc_num_strValid(const char *val, size_t base)
|
||||||
{
|
{
|
||||||
BcDig b;
|
BcDig b;
|
||||||
bool small, radix = false;
|
bool radix;
|
||||||
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];
|
|
||||||
|
|
||||||
|
b = (BcDig)(base <= 10 ? base + '0' : base - 10 + 'A');
|
||||||
|
radix = false;
|
||||||
|
for (;;) {
|
||||||
|
BcDig c = *val++;
|
||||||
|
if (c == '\0')
|
||||||
|
break;
|
||||||
if (c == '.') {
|
if (c == '.') {
|
||||||
|
|
||||||
if (radix) return false;
|
if (radix) return false;
|
||||||
|
|
||||||
radix = true;
|
radix = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (c < '0' || c >= b || (c > '9' && c < 'A'))
|
||||||
if (c < '0' || (small && c >= b) || (c > '9' && (c < 'A' || c >= b)))
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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)
|
static void bc_num_parseDecimal(BcNum *n, const char *val)
|
||||||
{
|
{
|
||||||
size_t len, i;
|
size_t len, i;
|
||||||
const char *ptr;
|
const char *ptr;
|
||||||
bool zero = true;
|
bool zero;
|
||||||
|
|
||||||
for (i = 0; val[i] == '0'; ++i);
|
|
||||||
|
|
||||||
val += i;
|
|
||||||
len = strlen(val);
|
len = strlen(val);
|
||||||
bc_num_zero(n);
|
if (len == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (len != 0) {
|
zero = true;
|
||||||
for (i = 0; zero && i < len; ++i) zero = val[i] == '0' || val[i] == '.';
|
for (i = 0; val[i]; ++i) {
|
||||||
bc_num_expand(n, len);
|
if (val[i] != '0' && val[i] != '.') {
|
||||||
|
zero = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
bc_num_expand(n, len);
|
||||||
|
|
||||||
ptr = strchr(val, '.');
|
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)
|
static void bc_num_parseBase(BcNum *n, const char *val, BcNum *base)
|
||||||
{
|
{
|
||||||
BcStatus s;
|
BcStatus s;
|
||||||
BcNum temp, mult, result;
|
BcNum temp, mult, result;
|
||||||
BcDig c = '\0';
|
BcDig c = '\0';
|
||||||
bool zero = true;
|
|
||||||
unsigned long v;
|
unsigned long v;
|
||||||
size_t i, digits, len = strlen(val);
|
size_t i, digits;
|
||||||
|
|
||||||
bc_num_zero(n);
|
for (i = 0; ; ++i) {
|
||||||
|
if (val[i] == '\0')
|
||||||
for (i = 0; zero && i < len; ++i) zero = (val[i] == '.' || val[i] == '0');
|
return;
|
||||||
if (zero) return;
|
if (val[i] != '.' && val[i] != '0')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
bc_num_init_DEF_SIZE(&temp);
|
bc_num_init_DEF_SIZE(&temp);
|
||||||
bc_num_init_DEF_SIZE(&mult);
|
bc_num_init_DEF_SIZE(&mult);
|
||||||
|
|
||||||
for (i = 0; i < len; ++i) {
|
for (;;) {
|
||||||
|
c = *val++;
|
||||||
c = val[i];
|
if (c == '\0') goto int_err;
|
||||||
if (c == '.') break;
|
if (c == '.') break;
|
||||||
|
|
||||||
v = (unsigned long) (c <= '9' ? c - '0' : c - 'A' + 10);
|
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 (s) goto int_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == len) {
|
|
||||||
c = val[i];
|
|
||||||
if (c == 0) goto int_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
bc_num_init(&result, base->len);
|
bc_num_init(&result, base->len);
|
||||||
//bc_num_zero(&result); - already is
|
//bc_num_zero(&result); - already is
|
||||||
bc_num_one(&mult);
|
bc_num_one(&mult);
|
||||||
|
|
||||||
for (i += 1, digits = 0; i < len; ++i, ++digits) {
|
digits = 0;
|
||||||
|
for (;;) {
|
||||||
c = val[i];
|
c = *val++;
|
||||||
if (c == 0) break;
|
if (c == '\0') break;
|
||||||
|
digits++;
|
||||||
|
|
||||||
v = (unsigned long) (c <= '9' ? c - '0' : c - 'A' + 10);
|
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->len != 0) {
|
||||||
if (n->rdx < digits) bc_num_extend(n, digits - n->rdx);
|
if (n->rdx < digits) bc_num_extend(n, digits - n->rdx);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
bc_num_zero(n);
|
bc_num_zero(n);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@ -2498,6 +2492,9 @@ static BcStatus bc_num_parse(BcNum *n, const char *val, BcNum *base,
|
|||||||
if (!bc_num_strValid(val, base_t))
|
if (!bc_num_strValid(val, base_t))
|
||||||
return bc_error("bad number string");
|
return bc_error("bad number string");
|
||||||
|
|
||||||
|
bc_num_zero(n);
|
||||||
|
while (*val == '0') val++;
|
||||||
|
|
||||||
if (base_t == 10)
|
if (base_t == 10)
|
||||||
bc_num_parseDecimal(n, val);
|
bc_num_parseDecimal(n, val);
|
||||||
else
|
else
|
||||||
@ -6387,7 +6384,7 @@ static BcStatus bc_program_asciify(void)
|
|||||||
{
|
{
|
||||||
BcStatus s;
|
BcStatus s;
|
||||||
BcResult *r, res;
|
BcResult *r, res;
|
||||||
BcNum *num = NULL, n;
|
BcNum *num, n;
|
||||||
char *str, *str2, c;
|
char *str, *str2, c;
|
||||||
size_t len = G.prog.strs.len, idx;
|
size_t len = G.prog.strs.len, idx;
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
@ -6396,6 +6393,7 @@ static BcStatus bc_program_asciify(void)
|
|||||||
return bc_error_stack_has_too_few_elements();
|
return bc_error_stack_has_too_few_elements();
|
||||||
r = bc_vec_top(&G.prog.results);
|
r = bc_vec_top(&G.prog.results);
|
||||||
|
|
||||||
|
num = NULL; // TODO: is this NULL needed?
|
||||||
s = bc_program_num(r, &num, false);
|
s = bc_program_num(r, &num, false);
|
||||||
if (s) return s;
|
if (s) return s;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user