diff options
Diffstat (limited to 'miscutils')
-rw-r--r-- | miscutils/bc.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 07327af6f..cc15a8dd2 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -2591,7 +2591,7 @@ static void bc_num_parseDecimal(BcNum *n, const char *val) | |||
2591 | if (len == 0) | 2591 | if (len == 0) |
2592 | return; | 2592 | return; |
2593 | 2593 | ||
2594 | bc_num_expand(n, len); | 2594 | bc_num_expand(n, len + 1); // +1 for e.g. "A" converting into 10 |
2595 | 2595 | ||
2596 | ptr = strchr(val, '.'); | 2596 | ptr = strchr(val, '.'); |
2597 | 2597 | ||
@@ -2603,11 +2603,15 @@ static void bc_num_parseDecimal(BcNum *n, const char *val) | |||
2603 | if (val[i] != '0' && val[i] != '.') { | 2603 | if (val[i] != '0' && val[i] != '.') { |
2604 | // Not entirely zero value - convert it, and exit | 2604 | // Not entirely zero value - convert it, and exit |
2605 | if (len == 1) { | 2605 | if (len == 1) { |
2606 | char c = val[0] - '0'; | 2606 | unsigned c = val[0] - '0'; |
2607 | if (c > 9) // A-Z => 10-36 | 2607 | n->len = 1; |
2608 | if (c > 9) { // A-Z => 10-36 | ||
2609 | n->len = 2; | ||
2608 | c -= ('A' - '9' - 1); | 2610 | c -= ('A' - '9' - 1); |
2611 | n->num[1] = c/10; | ||
2612 | c = c%10; | ||
2613 | } | ||
2609 | n->num[0] = c; | 2614 | n->num[0] = c; |
2610 | n->len = 1; | ||
2611 | break; | 2615 | break; |
2612 | } | 2616 | } |
2613 | i = len - 1; | 2617 | i = len - 1; |
@@ -2817,17 +2821,20 @@ static BC_STATUS zxc_lex_number(char last) | |||
2817 | { | 2821 | { |
2818 | BcParse *p = &G.prs; | 2822 | BcParse *p = &G.prs; |
2819 | bool pt; | 2823 | bool pt; |
2824 | char last_valid_ch; | ||
2820 | 2825 | ||
2821 | bc_vec_pop_all(&p->lex_strnumbuf); | 2826 | bc_vec_pop_all(&p->lex_strnumbuf); |
2822 | bc_vec_pushByte(&p->lex_strnumbuf, last); | 2827 | bc_vec_pushByte(&p->lex_strnumbuf, last); |
2823 | 2828 | ||
2824 | // "Input numbers may contain the characters 0-9 and A-Z. | 2829 | // bc: "Input numbers may contain the characters 0-9 and A-Z. |
2825 | // (Note: They must be capitals. Lower case letters are variable names.) | 2830 | // (Note: They must be capitals. Lower case letters are variable names.) |
2826 | // Single digit numbers always have the value of the digit regardless of | 2831 | // Single digit numbers always have the value of the digit regardless of |
2827 | // the value of ibase. (i.e. A = 10.) For multi-digit numbers, bc changes | 2832 | // the value of ibase. (i.e. A = 10.) For multi-digit numbers, bc changes |
2828 | // all input digits greater or equal to ibase to the value of ibase-1. | 2833 | // all input digits greater or equal to ibase to the value of ibase-1. |
2829 | // This makes the number ZZZ always be the largest 3 digit number of the | 2834 | // This makes the number ZZZ always be the largest 3 digit number of the |
2830 | // input base." | 2835 | // input base." |
2836 | // dc only allows A-F, the rules about single-char and multi-char are the same. | ||
2837 | last_valid_ch = (IS_BC ? 'Z' : 'F'); | ||
2831 | pt = (last == '.'); | 2838 | pt = (last == '.'); |
2832 | p->lex = XC_LEX_NUMBER; | 2839 | p->lex = XC_LEX_NUMBER; |
2833 | for (;;) { | 2840 | for (;;) { |
@@ -2843,7 +2850,7 @@ static BC_STATUS zxc_lex_number(char last) | |||
2843 | c = peek_inbuf(); // force next line to be read | 2850 | c = peek_inbuf(); // force next line to be read |
2844 | goto check_c; | 2851 | goto check_c; |
2845 | } | 2852 | } |
2846 | if (!isdigit(c) && (c < 'A' || c > 'Z')) { | 2853 | if (!isdigit(c) && (c < 'A' || c > last_valid_ch)) { |
2847 | if (c != '.') break; | 2854 | if (c != '.') break; |
2848 | // if '.' was already seen, stop on second one: | 2855 | // if '.' was already seen, stop on second one: |
2849 | if (pt) break; | 2856 | if (pt) break; |