Commit b193de59 authored by Christoph Biedl's avatar Christoph Biedl

Import upstream version 1.30.1

parent 0d4be2ff
From 2747f6195b94db6c1adf2eae243df5c0a01d39f2 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Mon, 31 Dec 2018 18:48:10 +0100
Subject: [PATCH 04/84] bc: fold xc_lex_more_input() into peek_inbuf()
function old new delta
peek_inbuf 69 56 -13
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
miscutils/bc.c | 31 +++++++++----------------------
1 file changed, 9 insertions(+), 22 deletions(-)
diff --git a/miscutils/bc.c b/miscutils/bc.c
index de6f9aab8..72c23542c 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -2727,20 +2727,6 @@ static BC_STATUS zxc_num_parse(BcNum *n, const char *val, unsigned base_t)
}
#define zxc_num_parse(...) (zxc_num_parse(__VA_ARGS__) COMMA_SUCCESS)
-static bool xc_lex_more_input(void)
-{
- BcParse *p = &G.prs;
-
- bc_vec_pop_all(&G.input_buffer);
-
- xc_read_line(&G.input_buffer, G.prs.lex_input_fp);
-
- p->lex_inbuf = G.input_buffer.v;
-// bb_error_msg("G.input_buffer.len:%d '%s'", G.input_buffer.len, G.input_buffer.v);
-
- return G.input_buffer.len > 1;
-}
-
// p->lex_inbuf points to the current string to be parsed.
// if p->lex_inbuf points to '\0', it's either EOF or it points after
// last processed line's terminating '\n' (and more reading needs to be done
@@ -2774,10 +2760,13 @@ static bool xc_lex_more_input(void)
// end" - ...prints "str#\<newline>end"
static char peek_inbuf(void)
{
- if (*G.prs.lex_inbuf == '\0') {
- if (G.prs.lex_input_fp)
- if (!xc_lex_more_input())
- G.prs.lex_input_fp = NULL;
+ if (*G.prs.lex_inbuf == '\0'
+ && G.prs.lex_input_fp
+ ) {
+ xc_read_line(&G.input_buffer, G.prs.lex_input_fp);
+ G.prs.lex_inbuf = G.input_buffer.v;
+ if (G.input_buffer.len <= 1) // on EOF, len is 1 (NUL byte)
+ G.prs.lex_input_fp = NULL;
}
return *G.prs.lex_inbuf;
}
@@ -2796,7 +2785,7 @@ static void xc_lex_lineComment(void)
// Try: echo -n '#foo' | bc
p->lex = XC_LEX_WHITESPACE;
- // We depend here on input being done in whole lines:
+ // Not peek_inbuf(): we depend on input being done in whole lines:
// '\0' which isn't the EOF can only be seen after '\n'.
while ((c = *p->lex_inbuf) != '\n' && c != '\0')
p->lex_inbuf++;
@@ -5281,17 +5270,15 @@ static BC_STATUS zxc_program_read(void)
IF_DC(s = zdc_parse_exprs_until_eof());
}
if (s) goto exec_err;
-
if (G.prs.lex != XC_LEX_NLINE && G.prs.lex != XC_LEX_EOF) {
s = bc_error("bad read() expression");
goto exec_err;
}
+ xc_parse_push(XC_INST_RET);
ip.func = BC_PROG_READ;
ip.inst_idx = 0;
IF_BC(ip.results_len_before_call = G.prog.results.len;)
-
- xc_parse_push(XC_INST_RET);
bc_vec_push(&G.prog.exestack, &ip);
exec_err:
--
2.16.2
From 680ccd357395ad081afe821ffbeef1ff338fe41d Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Mon, 31 Dec 2018 19:42:13 +0100
Subject: [PATCH 05/84] bc: support ibase up to 36 (GNU compat)
function old new delta
zxc_program_num 995 1018 +23
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
miscutils/bc.c | 50 +++++++++++++++++++++++++++++++-------------------
testsuite/bc.tests | 5 +++++
2 files changed, 36 insertions(+), 19 deletions(-)
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 72c23542c..798bc0a3e 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -5,7 +5,6 @@
* Original code copyright (c) 2018 Gavin D. Howard and contributors.
*/
//TODO: GNU extensions:
-// support ibase up to 36
// support "define void f()..."
// support "define f(*param[])" - "pass array by reference" syntax
@@ -231,7 +230,7 @@ typedef struct BcNum {
bool neg;
} BcNum;
-#define BC_NUM_MAX_IBASE ((unsigned long) 16)
+#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
@@ -2638,32 +2637,33 @@ static void bc_num_parseDecimal(BcNum *n, const char *val)
static void bc_num_parseBase(BcNum *n, const char *val, unsigned base_t)
{
BcStatus s;
- BcNum temp, mult, result;
+ BcNum mult, result;
+ BcNum temp;
BcNum base;
+ BcDig temp_digs[ULONG_NUM_BUFSIZE];
BcDig base_digs[ULONG_NUM_BUFSIZE];
BcDig c = '\0';
- unsigned long v;
- size_t i, digits;
-
- for (i = 0; ; ++i) {
- if (val[i] == '\0')
- return;
- if (val[i] != '.' && val[i] != '0')
- break;
- }
+ size_t digits;
- bc_num_init_DEF_SIZE(&temp);
bc_num_init_DEF_SIZE(&mult);
+
+ temp.cap = ARRAY_SIZE(temp_digs);
+ temp.num = temp_digs;
+
base.cap = ARRAY_SIZE(base_digs);
base.num = base_digs;
bc_num_ulong2num(&base, base_t);
+ base_t--;
for (;;) {
+ unsigned v;
+
c = *val++;
if (c == '\0') goto int_err;
if (c == '.') break;
- v = (unsigned long) (c <= '9' ? c - '0' : c - 'A' + 10);
+ v = (unsigned)(c <= '9' ? c - '0' : c - 'A' + 10);
+ if (v > base_t) v = base_t;
s = zbc_num_mul(n, &base, &mult, 0);
if (s) goto int_err;
@@ -2678,11 +2678,14 @@ static void bc_num_parseBase(BcNum *n, const char *val, unsigned base_t)
digits = 0;
for (;;) {
+ unsigned v;
+
c = *val++;
if (c == '\0') break;
digits++;
- v = (unsigned long) (c <= '9' ? c - '0' : c - 'A' + 10);
+ v = (unsigned)(c <= '9' ? c - '0' : c - 'A' + 10);
+ if (v > base_t) v = base_t;
s = zbc_num_mul(&result, &base, &result, 0);
if (s) goto err;
@@ -2707,18 +2710,27 @@ static void bc_num_parseBase(BcNum *n, const char *val, unsigned base_t)
bc_num_free(&result);
int_err:
bc_num_free(&mult);
- bc_num_free(&temp);
}
static BC_STATUS zxc_num_parse(BcNum *n, const char *val, unsigned base_t)
{
+ size_t i;
+
if (!xc_num_strValid(val))
RETURN_STATUS(bc_error("bad number string"));
bc_num_zero(n);
- while (*val == '0') val++;
+ while (*val == '0')
+ val++;
+ for (i = 0; ; ++i) {
+ if (val[i] == '\0')
+ RETURN_STATUS(BC_STATUS_SUCCESS);
+ if (val[i] != '.' && val[i] != '0')
+ break;
+ }
- if (base_t == 10)
+ if (base_t == 10 || val[1] == '\0')
+ // Decimal, or single-digit number
bc_num_parseDecimal(n, val);
else
bc_num_parseBase(n, val, base_t);
@@ -5526,7 +5538,7 @@ static BC_STATUS zxc_num_printBase(BcNum *n)
n->neg = false;
- if (G.prog.ob_t <= BC_NUM_MAX_IBASE) {
+ if (G.prog.ob_t <= 16) {
width = 1;
print = bc_num_printHex;
} else {
diff --git a/testsuite/bc.tests b/testsuite/bc.tests
index 3fbb49996..1d4545559 100755
--- a/testsuite/bc.tests
+++ b/testsuite/bc.tests
@@ -218,6 +218,11 @@ for(i=1; i<3; i++) {
99
"
+testing "bc ibase" \
+ "bc" \
+ "99\n1295\n1224\n" \
+ "" "a=ZZ;a;ibase=36;a=ZZ;a;ibase=Z;a=ZZ;a"
+
tar xJf bc_large.tar.xz
for f in bc*.bc; do
--
2.16.2
From 8797adc1c6e84789c261ee24afe5a1cbfaddba6b Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Mon, 31 Dec 2018 19:50:06 +0100
Subject: [PATCH 06/84] bc: remove superfluous assigment
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
miscutils/bc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 798bc0a3e..febf51cfd 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -2642,7 +2642,6 @@ static void bc_num_parseBase(BcNum *n, const char *val, unsigned base_t)
BcNum base;
BcDig temp_digs[ULONG_NUM_BUFSIZE];
BcDig base_digs[ULONG_NUM_BUFSIZE];
- BcDig c = '\0';
size_t digits;
bc_num_init_DEF_SIZE(&mult);
@@ -2657,6 +2656,7 @@ static void bc_num_parseBase(BcNum *n, const char *val, unsigned base_t)
for (;;) {
unsigned v;
+ char c;
c = *val++;
if (c == '\0') goto int_err;
@@ -2679,6 +2679,7 @@ static void bc_num_parseBase(BcNum *n, const char *val, unsigned base_t)
digits = 0;
for (;;) {
unsigned v;
+ char c;
c = *val++;
if (c == '\0') break;
--
2.16.2
From 51b510a480b99d480bcf6919b8bae16eb1c61718 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Tue, 1 Jan 2019 02:19:02 +0100
Subject: [PATCH 07/84] bc: in xc_read_line(), check ^C on NUL input bytes too
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
miscutils/bc.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/miscutils/bc.c b/miscutils/bc.c
index febf51cfd..23b3521d4 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -2509,7 +2509,7 @@ static void xc_read_line(BcVec *vec, FILE *fp)
i = 0;
for (;;) {
char c = line_buf[i++];
- if (!c) break;
+ if (c == '\0') break;
if (bad_input_byte(c)) goto again;
}
bc_vec_string(vec, n, line_buf);
@@ -2522,14 +2522,16 @@ static void xc_read_line(BcVec *vec, FILE *fp)
bool bad_chars = 0;
do {
+ get_char:
#if ENABLE_FEATURE_BC_INTERACTIVE
if (G_interrupt) {
// ^C was pressed: ignore entire line, get another one
- bc_vec_pop_all(vec);
- goto intr;
+ goto again;
}
#endif
- do c = fgetc(fp); while (c == '\0');
+ c = fgetc(fp);
+ if (c == '\0')
+ goto get_char;
if (c == EOF) {
if (ferror(fp))
bb_perror_msg_and_die("input error");
--
2.16.2
This diff is collapsed.
From 266bec8ba76898c5602e54fb3460c4af42f38af0 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Wed, 2 Jan 2019 05:03:53 +0100
Subject: [PATCH 11/84] bc: speed up string printing, fix print ""
function old new delta
static.esc - 9 +9
zxc_program_print 681 683 +2
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/0 up/down: 11/0) Total: 11 bytes
text data bss dec hex filename
979144 485 7296 986925 f0f2d busybox_old
979062 485 7296 986843 f0edb busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
miscutils/bc.c | 66 ++++++++++++++++++------------------------------------
testsuite/bc.tests | 6 +++++
2 files changed, 28 insertions(+), 44 deletions(-)
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 1b9cdce5e..bb91216c2 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -5359,7 +5359,7 @@ static char *xc_program_name(char *code, size_t *bgn)
static void xc_program_printString(const char *str)
{
#if ENABLE_DC
- if (!str[0]) {
+ if (!str[0] && IS_DC) {
// Example: echo '[]ap' | dc
// should print two bytes: 0x00, 0x0A
bb_putchar('\0');
@@ -5367,46 +5367,25 @@ static void xc_program_printString(const char *str)
}
#endif
while (*str) {
- int c = *str++;
- if (c != '\\' || !*str)
- bb_putchar(c);
- else {
+ char c = *str++;
+ if (c == '\\') {
+ static const char esc[] ALIGN1 = "nabfrt""e\\";
+ char *n;
+
c = *str++;
- switch (c) {
- case 'a':
- bb_putchar('\a');
- break;
- case 'b':
- bb_putchar('\b');
- break;
- case '\\':
- case 'e':
- bb_putchar('\\');
- break;
- case 'f':
- bb_putchar('\f');
- break;
- case 'n':
- bb_putchar('\n');
- G.prog.nchars = SIZE_MAX;
- break;
- case 'r':
- bb_putchar('\r');
- break;
- case 'q':
- bb_putchar('"');
- break;
- case 't':
- bb_putchar('\t');
- break;
- default:
- // Just print the backslash and following character.
+ n = strchr(esc, c); // note: c can be NUL
+ if (!n) {
+ // Just print the backslash and following character
bb_putchar('\\');
++G.prog.nchars;
- bb_putchar(c);
- break;
+ } else {
+ if (n - esc == 0) // "\n" ?
+ G.prog.nchars = SIZE_MAX;
+ c = "\n\a\b\f\r\t""\\\\""\\"[n - esc];
+ // n a b f r t e \ \<end of line>
}
}
+ putchar(c);
++G.prog.nchars;
}
}
@@ -5631,16 +5610,15 @@ static BC_STATUS zxc_program_print(char inst, size_t idx)
str = *xc_program_str(idx);
if (inst == XC_INST_PRINT_STR) {
- for (;;) {
- char c = *str++;
- if (c == '\0') break;
- bb_putchar(c);
- ++G.prog.nchars;
- if (c == '\n') G.prog.nchars = 0;
- }
+ char *nl;
+ G.prog.nchars += printf("%s", str);
+ nl = strrchr(str, '\n');
+ if (nl)
+ G.prog.nchars = strlen(nl + 1);
} else {
xc_program_printString(str);
- if (inst == XC_INST_PRINT) bb_putchar('\n');
+ if (inst == XC_INST_PRINT)
+ bb_putchar('\n');
}
}
diff --git a/testsuite/bc.tests b/testsuite/bc.tests
index 13525ea52..fbcfff2e4 100755
--- a/testsuite/bc.tests
+++ b/testsuite/bc.tests
@@ -149,6 +149,12 @@ testing "bc (!a&&b)" \
"0\n" \
"" "(!a&&b)"