diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-07 15:50:14 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-07 15:50:14 +0100 |
| commit | 64074a1767f69b186ce58cafb7eb95bc1aa0dda9 (patch) | |
| tree | 026187a294956fcab7b6c6b543fd1b10f57b5400 /miscutils | |
| parent | ffdcebdffe8a2b6261e3eb468d7c19fd0b454a87 (diff) | |
| download | busybox-w32-64074a1767f69b186ce58cafb7eb95bc1aa0dda9.tar.gz busybox-w32-64074a1767f69b186ce58cafb7eb95bc1aa0dda9.tar.bz2 busybox-w32-64074a1767f69b186ce58cafb7eb95bc1aa0dda9.zip | |
bc: do not perform domr limit checks when they can't work (e.g. on 32-bit arches)
Also, optimize printing of messages with fixed limit strings
by including limits as strings.
function old new delta
bc_num_ulong 103 95 -8
bc_lex_number 296 281 -15
dc_lex_token 701 684 -17
bc_lex_name 90 73 -17
bc_num_shift 72 54 -18
bc_lex_token 1299 1280 -19
bc_parse_stmt 1868 1768 -100
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/7 up/down: 0/-194) Total: -194 bytes
text data bss dec hex filename
985814 485 7296 993595 f293b busybox_old
985526 485 7296 993307 f281b busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils')
| -rw-r--r-- | miscutils/bc.c | 109 |
1 files changed, 76 insertions, 33 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 9eafa80e9..3da03b437 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
| @@ -725,14 +725,39 @@ typedef unsigned long (*BcProgramBuiltIn)(BcNum *); | |||
| 725 | #define BC_MAX(a, b) ((a) > (b) ? (a) : (b)) | 725 | #define BC_MAX(a, b) ((a) > (b) ? (a) : (b)) |
| 726 | #define BC_MIN(a, b) ((a) < (b) ? (a) : (b)) | 726 | #define BC_MIN(a, b) ((a) < (b) ? (a) : (b)) |
| 727 | 727 | ||
| 728 | #define BC_MAX_OBASE ((unsigned) 999) | 728 | #define BC_MAX_OBASE ((unsigned) 999) |
| 729 | #define BC_MAX_DIM ((unsigned) INT_MAX) | 729 | #define BC_MAX_DIM ((unsigned) INT_MAX) |
| 730 | #define BC_MAX_SCALE ((unsigned) UINT_MAX) | 730 | #define BC_MAX_SCALE ((unsigned) UINT_MAX) |
| 731 | #define BC_MAX_STRING ((unsigned) UINT_MAX - 1) | 731 | #define BC_MAX_STRING ((unsigned) UINT_MAX - 1) |
| 732 | #define BC_MAX_NAME BC_MAX_STRING | 732 | #define BC_MAX_NUM BC_MAX_STRING |
| 733 | #define BC_MAX_NUM BC_MAX_STRING | 733 | // Unused apart from "limits" message. Just show a "biggish number" there. |
| 734 | #define BC_MAX_EXP ((unsigned long) LONG_MAX) | 734 | //#define BC_MAX_NAME BC_MAX_STRING |
| 735 | #define BC_MAX_VARS ((unsigned long) SIZE_MAX - 1) | 735 | //#define BC_MAX_EXP ((unsigned long) LONG_MAX) |
| 736 | //#define BC_MAX_VARS ((unsigned long) SIZE_MAX - 1) | ||
| 737 | #define BC_MAX_NAME_STR "999999999" | ||
| 738 | #define BC_MAX_EXP_STR "999999999" | ||
| 739 | #define BC_MAX_VARS_STR "999999999" | ||
| 740 | |||
| 741 | #define BC_MAX_OBASE_STR "999" | ||
| 742 | |||
| 743 | #if INT_MAX == 2147483647 | ||
| 744 | # define BC_MAX_DIM_STR "2147483647" | ||
| 745 | #elif INT_MAX == 9223372036854775807 | ||
| 746 | # define BC_MAX_DIM_STR "9223372036854775807" | ||
| 747 | #else | ||
| 748 | # error Strange INT_MAX | ||
| 749 | #endif | ||
| 750 | |||
| 751 | #if UINT_MAX == 4294967295 | ||
| 752 | # define BC_MAX_SCALE_STR "4294967295" | ||
| 753 | # define BC_MAX_STRING_STR "4294967294" | ||
| 754 | #elif UINT_MAX == 18446744073709551615 | ||
| 755 | # define BC_MAX_SCALE_STR "18446744073709551615" | ||
| 756 | # define BC_MAX_STRING_STR "18446744073709551614" | ||
| 757 | #else | ||
| 758 | # error Strange UINT_MAX | ||
| 759 | #endif | ||
| 760 | #define BC_MAX_NUM_STR BC_MAX_STRING_STR | ||
| 736 | 761 | ||
| 737 | struct globals { | 762 | struct globals { |
| 738 | IF_FEATURE_BC_SIGNALS(smallint ttyin;) | 763 | IF_FEATURE_BC_SIGNALS(smallint ttyin;) |
| @@ -1590,8 +1615,12 @@ static void bc_num_split(BcNum *restrict n, size_t idx, BcNum *restrict a, | |||
| 1590 | static BcStatus bc_num_shift(BcNum *n, size_t places) | 1615 | static BcStatus bc_num_shift(BcNum *n, size_t places) |
| 1591 | { | 1616 | { |
| 1592 | if (places == 0 || n->len == 0) return BC_STATUS_SUCCESS; | 1617 | if (places == 0 || n->len == 0) return BC_STATUS_SUCCESS; |
| 1593 | if (places + n->len > BC_MAX_NUM) | 1618 | |
| 1594 | return bc_error("number too long: must be [1, BC_NUM_MAX]"); | 1619 | // This check makes sense only if size_t is (much) larger than BC_MAX_NUM. |
| 1620 | if (SIZE_MAX > (BC_MAX_NUM | 0xff)) { | ||
| 1621 | if (places + n->len > BC_MAX_NUM) | ||
| 1622 | return bc_error("number too long: must be [1,"BC_MAX_NUM_STR"]"); | ||
| 1623 | } | ||
| 1595 | 1624 | ||
| 1596 | if (n->rdx >= places) | 1625 | if (n->rdx >= places) |
| 1597 | n->rdx -= places; | 1626 | n->rdx -= places; |
| @@ -2891,8 +2920,11 @@ static BcStatus bc_lex_number(BcLex *l, char start) | |||
| 2891 | } | 2920 | } |
| 2892 | 2921 | ||
| 2893 | len = i + !last_pt - bslashes * 2; | 2922 | len = i + !last_pt - bslashes * 2; |
| 2894 | if (len > BC_MAX_NUM) | 2923 | // This check makes sense only if size_t is (much) larger than BC_MAX_NUM. |
| 2895 | return bc_error("number too long: must be [1, BC_NUM_MAX]"); | 2924 | if (SIZE_MAX > (BC_MAX_NUM | 0xff)) { |
| 2925 | if (len > BC_MAX_NUM) | ||
| 2926 | return bc_error("number too long: must be [1,"BC_MAX_NUM_STR"]"); | ||
| 2927 | } | ||
| 2896 | 2928 | ||
| 2897 | bc_vec_pop_all(&l->t.v); | 2929 | bc_vec_pop_all(&l->t.v); |
| 2898 | bc_vec_expand(&l->t.v, len + 1); | 2930 | bc_vec_expand(&l->t.v, len + 1); |
| @@ -2929,8 +2961,11 @@ static BcStatus bc_lex_name(BcLex *l) | |||
| 2929 | 2961 | ||
| 2930 | while ((c >= 'a' && c <= 'z') || isdigit(c) || c == '_') c = buf[++i]; | 2962 | while ((c >= 'a' && c <= 'z') || isdigit(c) || c == '_') c = buf[++i]; |
| 2931 | 2963 | ||
| 2932 | if (i > BC_MAX_STRING) | 2964 | // This check makes sense only if size_t is (much) larger than BC_MAX_STRING. |
| 2933 | return bc_error("name too long: must be [1, BC_NAME_MAX]"); | 2965 | if (SIZE_MAX > (BC_MAX_STRING | 0xff)) { |
| 2966 | if (i > BC_MAX_STRING) | ||
| 2967 | return bc_error("name too long: must be [1,"BC_MAX_STRING_STR"]"); | ||
| 2968 | } | ||
| 2934 | bc_vec_string(&l->t.v, i, buf); | 2969 | bc_vec_string(&l->t.v, i, buf); |
| 2935 | 2970 | ||
| 2936 | // Increment the index. We minus 1 because it has already been incremented. | 2971 | // Increment the index. We minus 1 because it has already been incremented. |
| @@ -3047,8 +3082,11 @@ static BcStatus bc_lex_string(BcLex *l) | |||
| 3047 | } | 3082 | } |
| 3048 | 3083 | ||
| 3049 | len = i - l->i; | 3084 | len = i - l->i; |
| 3050 | if (len > BC_MAX_STRING) | 3085 | // This check makes sense only if size_t is (much) larger than BC_MAX_STRING. |
| 3051 | return bc_error("string too long: must be [1, BC_STRING_MAX]"); | 3086 | if (SIZE_MAX > (BC_MAX_STRING | 0xff)) { |
| 3087 | if (len > BC_MAX_STRING) | ||
| 3088 | return bc_error("string too long: must be [1,"BC_MAX_STRING_STR"]"); | ||
| 3089 | } | ||
| 3052 | bc_vec_string(&l->t.v, len, l->buf + l->i); | 3090 | bc_vec_string(&l->t.v, len, l->buf + l->i); |
| 3053 | 3091 | ||
| 3054 | l->i = i + 1; | 3092 | l->i = i + 1; |
| @@ -3426,8 +3464,11 @@ static BcStatus dc_lex_string(BcLex *l) | |||
| 3426 | } | 3464 | } |
| 3427 | 3465 | ||
| 3428 | bc_vec_pushZeroByte(&l->t.v); | 3466 | bc_vec_pushZeroByte(&l->t.v); |
| 3429 | if (i - l->i > BC_MAX_STRING) | 3467 | // This check makes sense only if size_t is (much) larger than BC_MAX_STRING. |
| 3430 | return bc_error("string too long: must be [1, BC_STRING_MAX]"); | 3468 | if (SIZE_MAX > (BC_MAX_STRING | 0xff)) { |
| 3469 | if (i - l->i > BC_MAX_STRING) | ||
| 3470 | return bc_error("string too long: must be [1,"BC_MAX_STRING_STR"]"); | ||
| 3471 | } | ||
| 3431 | 3472 | ||
| 3432 | l->i = i; | 3473 | l->i = i; |
| 3433 | l->line += nls; | 3474 | l->line += nls; |
| @@ -4700,14 +4741,16 @@ static BcStatus bc_parse_stmt(BcParse *p) | |||
| 4700 | // the output is produced at _parse time_. | 4741 | // the output is produced at _parse time_. |
| 4701 | s = bc_lex_next(&p->l); | 4742 | s = bc_lex_next(&p->l); |
| 4702 | if (s) return s; | 4743 | if (s) return s; |
| 4703 | printf("BC_BASE_MAX = %u\n", BC_MAX_OBASE); | 4744 | printf( |
| 4704 | printf("BC_DIM_MAX = %u\n", BC_MAX_DIM); | 4745 | "BC_BASE_MAX = "BC_MAX_OBASE_STR "\n" |
| 4705 | printf("BC_SCALE_MAX = %u\n", BC_MAX_SCALE); | 4746 | "BC_DIM_MAX = "BC_MAX_DIM_STR "\n" |
| 4706 | printf("BC_STRING_MAX = %u\n", BC_MAX_STRING); | 4747 | "BC_SCALE_MAX = "BC_MAX_SCALE_STR "\n" |
| 4707 | printf("BC_NAME_MAX = %u\n", BC_MAX_NAME); | 4748 | "BC_STRING_MAX = "BC_MAX_STRING_STR"\n" |
| 4708 | printf("BC_NUM_MAX = %u\n", BC_MAX_NUM); | 4749 | "BC_NAME_MAX = "BC_MAX_NAME_STR "\n" |
| 4709 | printf("MAX Exponent = %lu\n", BC_MAX_EXP); | 4750 | "BC_NUM_MAX = "BC_MAX_NUM_STR "\n" |
| 4710 | printf("Number of vars = %lu\n", BC_MAX_VARS); | 4751 | "MAX Exponent = "BC_MAX_EXP_STR "\n" |
| 4752 | "Number of vars = "BC_MAX_VARS_STR "\n" | ||
| 4753 | ); | ||
| 4711 | break; | 4754 | break; |
| 4712 | } | 4755 | } |
| 4713 | 4756 | ||
| @@ -5903,12 +5946,12 @@ static BcStatus bc_program_assign(char inst) | |||
| 5903 | 5946 | ||
| 5904 | if (ib || sc || left->t == BC_RESULT_OBASE) { | 5947 | if (ib || sc || left->t == BC_RESULT_OBASE) { |
| 5905 | static const char *const msg[] = { | 5948 | static const char *const msg[] = { |
| 5906 | "bad ibase; must be [2, 16]", //BC_RESULT_IBASE | 5949 | "bad ibase; must be [2,16]", //BC_RESULT_IBASE |
| 5907 | "bad scale; must be [0, BC_SCALE_MAX]", //BC_RESULT_SCALE | 5950 | "bad scale; must be [0,"BC_MAX_SCALE_STR"]", //BC_RESULT_SCALE |
| 5908 | NULL, //can't happen //BC_RESULT_LAST | 5951 | NULL, //can't happen //BC_RESULT_LAST |
| 5909 | NULL, //can't happen //BC_RESULT_CONSTANT | 5952 | NULL, //can't happen //BC_RESULT_CONSTANT |
| 5910 | NULL, //can't happen //BC_RESULT_ONE | 5953 | NULL, //can't happen //BC_RESULT_ONE |
| 5911 | "bad obase; must be [2, BC_BASE_MAX]", //BC_RESULT_OBASE | 5954 | "bad obase; must be [2,"BC_MAX_OBASE_STR"]", //BC_RESULT_OBASE |
| 5912 | }; | 5955 | }; |
| 5913 | size_t *ptr; | 5956 | size_t *ptr; |
| 5914 | unsigned long val, max; | 5957 | unsigned long val, max; |
| @@ -6020,7 +6063,7 @@ static BcStatus bc_program_pushArray(char *code, size_t *bgn, | |||
| 6020 | if (s) goto err; | 6063 | if (s) goto err; |
| 6021 | 6064 | ||
| 6022 | if (temp > BC_MAX_DIM) { | 6065 | if (temp > BC_MAX_DIM) { |
| 6023 | s = bc_error("array too long; must be [1, BC_DIM_MAX]"); | 6066 | s = bc_error("array too long; must be [1,"BC_MAX_DIM_STR"]"); |
| 6024 | goto err; | 6067 | goto err; |
| 6025 | } | 6068 | } |
| 6026 | 6069 | ||
