bc: change bc_read_line() and zbc_vm_stdin() to avoid double buffers
function old new delta bc_read_line 129 124 -5 bc_vm_run 523 433 -90 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-95) Total: -95 bytes text data bss dec hex filename 980445 485 7296 988226 f1442 busybox_old 980350 485 7296 988131 f13e3 busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
b7e61e3e4a
commit
82ea67fbfa
@ -1226,6 +1226,7 @@ static void bc_vec_string(BcVec *v, size_t len, const char *str)
|
|||||||
bc_vec_pushZeroByte(v);
|
bc_vec_pushZeroByte(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_FEATURE_BC_SIGNALS && ENABLE_FEATURE_EDITING
|
||||||
static void bc_vec_concat(BcVec *v, const char *str)
|
static void bc_vec_concat(BcVec *v, const char *str)
|
||||||
{
|
{
|
||||||
size_t len, slen;
|
size_t len, slen;
|
||||||
@ -1240,6 +1241,7 @@ static void bc_vec_concat(BcVec *v, const char *str)
|
|||||||
|
|
||||||
v->len = len;
|
v->len = len;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void *bc_vec_item(const BcVec *v, size_t idx)
|
static void *bc_vec_item(const BcVec *v, size_t idx)
|
||||||
{
|
{
|
||||||
@ -1326,29 +1328,21 @@ static size_t bc_map_index(const BcVec *v, const void *ptr)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int push_input_byte(BcVec *vec, char c)
|
static int bad_input_byte(char c)
|
||||||
{
|
{
|
||||||
if ((c < ' ' && c != '\t' && c != '\r' && c != '\n') // also allow '\v' '\f'?
|
if ((c < ' ' && c != '\t' && c != '\r' && c != '\n') // also allow '\v' '\f'?
|
||||||
|| c > 0x7e
|
|| c > 0x7e
|
||||||
) {
|
) {
|
||||||
// Bad chars on this line, ignore entire line
|
|
||||||
bc_error_fmt("illegal character 0x%02x", c);
|
bc_error_fmt("illegal character 0x%02x", c);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
bc_vec_pushByte(vec, (char)c);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: it _appends_ data from the stdin to vec.
|
||||||
static void bc_read_line(BcVec *vec)
|
static void bc_read_line(BcVec *vec)
|
||||||
{
|
{
|
||||||
bool bad_chars;
|
again:
|
||||||
|
|
||||||
do {
|
|
||||||
int c;
|
|
||||||
|
|
||||||
bad_chars = 0;
|
|
||||||
bc_vec_pop_all(vec);
|
|
||||||
|
|
||||||
fflush_and_check();
|
fflush_and_check();
|
||||||
|
|
||||||
#if ENABLE_FEATURE_BC_SIGNALS
|
#if ENABLE_FEATURE_BC_SIGNALS
|
||||||
@ -1359,6 +1353,7 @@ static void bc_read_line(BcVec *vec)
|
|||||||
// GNU dc says "Interrupt!"
|
// GNU dc says "Interrupt!"
|
||||||
fputs("\ninterrupted execution\n", stderr);
|
fputs("\ninterrupted execution\n", stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
# if ENABLE_FEATURE_EDITING
|
# if ENABLE_FEATURE_EDITING
|
||||||
if (G_ttyin) {
|
if (G_ttyin) {
|
||||||
int n, i;
|
int n, i;
|
||||||
@ -1371,15 +1366,20 @@ static void bc_read_line(BcVec *vec)
|
|||||||
}
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
c = line_buf[i++];
|
char c = line_buf[i++];
|
||||||
if (!c) break;
|
if (!c) break;
|
||||||
bad_chars |= push_input_byte(vec, c);
|
if (bad_input_byte(c)) goto again;
|
||||||
}
|
}
|
||||||
|
bc_vec_concat(vec, line_buf);
|
||||||
# undef line_buf
|
# undef line_buf
|
||||||
} else
|
} else
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
int c;
|
||||||
|
bool bad_chars = 0;
|
||||||
|
size_t len = vec->len;
|
||||||
|
|
||||||
IF_FEATURE_BC_SIGNALS(errno = 0;)
|
IF_FEATURE_BC_SIGNALS(errno = 0;)
|
||||||
do {
|
do {
|
||||||
c = fgetc(stdin);
|
c = fgetc(stdin);
|
||||||
@ -1399,10 +1399,15 @@ static void bc_read_line(BcVec *vec)
|
|||||||
// printf 'print 123' | bc - fails (syntax error)
|
// printf 'print 123' | bc - fails (syntax error)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bad_chars |= push_input_byte(vec, c);
|
bad_chars |= bad_input_byte(c);
|
||||||
|
bc_vec_pushByte(vec, (char)c);
|
||||||
} while (c != '\n');
|
} while (c != '\n');
|
||||||
|
if (bad_chars) {
|
||||||
|
// Bad chars on this line, ignore entire line
|
||||||
|
vec->len = len;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (bad_chars);
|
|
||||||
|
|
||||||
bc_vec_pushZeroByte(vec);
|
bc_vec_pushZeroByte(vec);
|
||||||
}
|
}
|
||||||
@ -5374,12 +5379,12 @@ static BC_STATUS zbc_program_read(void)
|
|||||||
|
|
||||||
f = bc_program_func(BC_PROG_READ);
|
f = bc_program_func(BC_PROG_READ);
|
||||||
bc_vec_pop_all(&f->code);
|
bc_vec_pop_all(&f->code);
|
||||||
bc_char_vec_init(&buf);
|
|
||||||
|
|
||||||
sv_file = G.prog.file;
|
sv_file = G.prog.file;
|
||||||
G.prog.file = NULL;
|
G.prog.file = NULL;
|
||||||
G.in_read = 1;
|
G.in_read = 1;
|
||||||
|
|
||||||
|
bc_char_vec_init(&buf);
|
||||||
bc_read_line(&buf);
|
bc_read_line(&buf);
|
||||||
|
|
||||||
bc_parse_create(&parse, BC_PROG_READ);
|
bc_parse_create(&parse, BC_PROG_READ);
|
||||||
@ -7039,7 +7044,7 @@ err:
|
|||||||
static BC_STATUS zbc_vm_stdin(void)
|
static BC_STATUS zbc_vm_stdin(void)
|
||||||
{
|
{
|
||||||
BcStatus s;
|
BcStatus s;
|
||||||
BcVec buf, buffer;
|
BcVec buffer;
|
||||||
size_t str;
|
size_t str;
|
||||||
bool comment;
|
bool comment;
|
||||||
|
|
||||||
@ -7047,8 +7052,6 @@ static BC_STATUS zbc_vm_stdin(void)
|
|||||||
bc_lex_file(&G.prs.l);
|
bc_lex_file(&G.prs.l);
|
||||||
|
|
||||||
bc_char_vec_init(&buffer);
|
bc_char_vec_init(&buffer);
|
||||||
bc_char_vec_init(&buf);
|
|
||||||
bc_vec_pushZeroByte(&buffer);
|
|
||||||
|
|
||||||
// This loop is complex because the vm tries not to send any lines that end
|
// This loop is complex because the vm tries not to send any lines that end
|
||||||
// with a backslash to the parser. The reason for that is because the parser
|
// with a backslash to the parser. The reason for that is because the parser
|
||||||
@ -7058,16 +7061,18 @@ static BC_STATUS zbc_vm_stdin(void)
|
|||||||
comment = false;
|
comment = false;
|
||||||
str = 0;
|
str = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
size_t prevlen = buffer.len;
|
||||||
char *string;
|
char *string;
|
||||||
|
|
||||||
bc_read_line(&buf);
|
bc_read_line(&buffer);
|
||||||
if (buf.len <= 1) // "" buf means EOF
|
// No more input means EOF
|
||||||
|
if (buffer.len <= prevlen + 1) // (we expect +1 for NUL byte)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
string = buf.v;
|
string = buffer.v + prevlen;
|
||||||
while (*string) {
|
while (*string) {
|
||||||
char c = *string;
|
char c = *string;
|
||||||
if (string == buf.v || string[-1] != '\\') {
|
if (string == buffer.v || string[-1] != '\\') {
|
||||||
// checking applet type is cheaper than accessing sbgn/send
|
// checking applet type is cheaper than accessing sbgn/send
|
||||||
if (IS_BC) // bc: sbgn = send = '"'
|
if (IS_BC) // bc: sbgn = send = '"'
|
||||||
str ^= (c == '"');
|
str ^= (c == '"');
|
||||||
@ -7089,17 +7094,20 @@ static BC_STATUS zbc_vm_stdin(void)
|
|||||||
string++;
|
string++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bc_vec_concat(&buffer, buf.v);
|
if (str || comment) {
|
||||||
if (str || comment)
|
buffer.len--; // backstep over the trailing NUL byte
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for backslash+newline.
|
// Check for backslash+newline.
|
||||||
// we do not check that last char is '\n' -
|
// we do not check that last char is '\n' -
|
||||||
// if it is not, then it's EOF, and looping back
|
// if it is not, then it's EOF, and looping back
|
||||||
// to bc_read_line() will detect it:
|
// to bc_read_line() will detect it:
|
||||||
string -= 2;
|
string -= 2;
|
||||||
if (string >= buf.v && *string == '\\')
|
if (string >= buffer.v && *string == '\\') {
|
||||||
|
buffer.len--;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
s = zbc_vm_process(buffer.v);
|
s = zbc_vm_process(buffer.v);
|
||||||
if (s) {
|
if (s) {
|
||||||
@ -7121,7 +7129,6 @@ static BC_STATUS zbc_vm_stdin(void)
|
|||||||
s = bc_error("comment end could not be found");
|
s = bc_error("comment end could not be found");
|
||||||
}
|
}
|
||||||
|
|
||||||
bc_vec_free(&buf);
|
|
||||||
bc_vec_free(&buffer);
|
bc_vec_free(&buffer);
|
||||||
RETURN_STATUS(s);
|
RETURN_STATUS(s);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user