aboutsummaryrefslogtreecommitdiff
path: root/miscutils/bc.c
diff options
context:
space:
mode:
Diffstat (limited to 'miscutils/bc.c')
-rw-r--r--miscutils/bc.c64
1 files changed, 36 insertions, 28 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 59e18a8c1..02a61ac49 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -231,7 +231,7 @@ typedef struct BcNum {
#define BC_NUM_MAX_IBASE 36
// larger value might speed up BIGNUM calculations a bit:
#define BC_NUM_DEF_SIZE 16
-#define BC_NUM_PRINT_WIDTH 69
+#define BC_NUM_PRINT_WIDTH 70
#define BC_NUM_KARATSUBA_LEN 32
@@ -1827,7 +1827,7 @@ static FAST_FUNC BC_STATUS zbc_num_k(BcNum *restrict a, BcNum *restrict b,
#define zbc_num_k(...) (zbc_num_k(__VA_ARGS__) COMMA_SUCCESS)
{
BcStatus s;
- size_t max = BC_MAX(a->len, b->len), max2 = (max + 1) / 2;
+ size_t max, max2;
BcNum l1, h1, l2, h2, m2, m1, z0, z1, z2, temp;
bool aone;
@@ -1841,9 +1841,9 @@ static FAST_FUNC BC_STATUS zbc_num_k(BcNum *restrict a, BcNum *restrict b,
RETURN_STATUS(BC_STATUS_SUCCESS);
}
- if (a->len + b->len < BC_NUM_KARATSUBA_LEN
- || a->len < BC_NUM_KARATSUBA_LEN
+ if (a->len < BC_NUM_KARATSUBA_LEN
|| b->len < BC_NUM_KARATSUBA_LEN
+ /* || a->len + b->len < BC_NUM_KARATSUBA_LEN - redundant check */
) {
size_t i, j, len;
@@ -1877,6 +1877,7 @@ static FAST_FUNC BC_STATUS zbc_num_k(BcNum *restrict a, BcNum *restrict b,
RETURN_STATUS(BC_STATUS_SUCCESS);
}
+ max = BC_MAX(a->len, b->len);
bc_num_init(&l1, max);
bc_num_init(&h1, max);
bc_num_init(&l2, max);
@@ -1888,6 +1889,7 @@ static FAST_FUNC BC_STATUS zbc_num_k(BcNum *restrict a, BcNum *restrict b,
bc_num_init(&z2, max);
bc_num_init(&temp, max + max);
+ max2 = (max + 1) / 2;
bc_num_split(a, max2, &l1, &h1);
bc_num_split(b, max2, &l2, &h2);
@@ -2524,9 +2526,6 @@ static void xc_read_line(BcVec *vec, FILE *fp)
#if ENABLE_FEATURE_BC_INTERACTIVE
if (G_interrupt) { // ^C was pressed
-# if ENABLE_FEATURE_EDITING
- intr:
-# endif
if (fp != stdin) {
// ^C while running a script (bc SCRIPT): die.
// We do not return to interactive prompt:
@@ -2537,11 +2536,11 @@ static void xc_read_line(BcVec *vec, FILE *fp)
// the shell would be unexpected.
xfunc_die();
}
- // ^C while interactive input
+ // There was ^C while running calculations
G_interrupt = 0;
- // GNU bc says "interrupted execution."
+ // GNU bc says "interrupted execution." (to stdout, not stderr)
// GNU dc says "Interrupt!"
- fputs("\ninterrupted execution\n", stderr);
+ puts("\ninterrupted execution");
}
# if ENABLE_FEATURE_EDITING
@@ -2552,9 +2551,10 @@ static void xc_read_line(BcVec *vec, FILE *fp)
# define line_buf bb_common_bufsiz1
n = read_line_input(G.line_input_state, "", line_buf, COMMON_BUFSIZE);
if (n <= 0) { // read errors or EOF, or ^D, or ^C
- if (n == 0) // ^C
- goto intr;
- bc_vec_pushZeroByte(vec); // ^D or EOF (or error)
+ //GNU bc prints this on ^C:
+ //if (n == 0) // ^C
+ // puts("(interrupt) Exiting bc.");
+ bc_vec_pushZeroByte(vec);
return;
}
i = 0;
@@ -6448,7 +6448,7 @@ static BC_STATUS zdc_program_printStream(void)
char *str;
idx = (r->t == XC_RESULT_STR) ? r->d.id.idx : n->rdx;
str = *xc_program_str(idx);
- fputs(str, stdout);
+ fputs_stdout(str);
}
RETURN_STATUS(s);
@@ -7372,11 +7372,29 @@ static unsigned xc_vm_envLen(const char *var)
lenv = getenv(var);
len = BC_NUM_PRINT_WIDTH;
- if (!lenv) return len;
+ if (lenv) {
+ len = bb_strtou(lenv, NULL, 10);
+ if (len == 0 || len > INT_MAX)
+ len = INT_MAX;
+ if (errno)
+ len = BC_NUM_PRINT_WIDTH;
+ }
- len = bb_strtou(lenv, NULL, 10) - 1;
- if (errno || len < 2 || len >= INT_MAX)
- len = BC_NUM_PRINT_WIDTH;
+ // dc (GNU bc 1.07.1) 1.4.1 seems to use width
+ // 1 char wider than bc from the same package.
+ // Both default width, and xC_LINE_LENGTH=N are wider:
+ // "DC_LINE_LENGTH=5 dc -e'123456 p'" prints:
+ // |1234\ |
+ // |56 |
+ // "echo '123456' | BC_LINE_LENGTH=5 bc" prints:
+ // |123\ |
+ // |456 |
+ // Do the same, but it might be a bug in GNU package
+ if (IS_BC)
+ len--;
+
+ if (len < 2)
+ len = IS_BC ? BC_NUM_PRINT_WIDTH - 1 : BC_NUM_PRINT_WIDTH;
return len;
}
@@ -7467,16 +7485,6 @@ int dc_main(int argc UNUSED_PARAM, char **argv)
INIT_G();
- // TODO: dc (GNU bc 1.07.1) 1.4.1 seems to use width
- // 1 char wider than bc from the same package.
- // Both default width, and xC_LINE_LENGTH=N are wider:
- // "DC_LINE_LENGTH=5 dc -e'123456 p'" prints:
- // |1234\ |
- // |56 |
- // "echo '123456' | BC_LINE_LENGTH=5 bc" prints:
- // |123\ |
- // |456 |
- // Do the same, or it's a bug?
xc_vm_init("DC_LINE_LENGTH");
// Run -e'SCRIPT' and -fFILE in order of appearance, then handle FILEs