diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-05 16:39:22 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-05 16:39:22 +0100 |
commit | 0409ad36a11ad51e47813b65a97e6ad68f42d381 (patch) | |
tree | b61128113f59b02e36b82847dbcdd24727842320 /miscutils/bc.c | |
parent | 0ad36c46c7a521760e5696ba9d6e9362a1a3777c (diff) |
bc: restore printing of script name on errors
Examples:
On stdin, no file name is available:
$ echo 'print "' | busybox bc
bc: string end could not be found
When the same error is in file:
$ busybox bc FILE
bc 1.30.0.git
Copyright (c) 2018 Gavin D. Howard and contributors
Report bugs at: https://github.com/gavinhoward/bc
This is free software with ABSOLUTELY NO WARRANTY
FILE: string end could not be found
ready for more input
>>>
Line number printing to be added later...
function old new delta
bc_error_fmt 38 70 +32
bc_posix_error_fmt 60 90 +30
bc_vm_run 1900 1919 +19
bc_program_read 338 355 +17
bc_lex_file 15 12 -3
bc_program_stdin_name 8 - -8
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 4/1 up/down: 98/-11) Total: 87 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils/bc.c')
-rw-r--r-- | miscutils/bc.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index fd9e31cc5..171bc8858 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -567,7 +567,6 @@ typedef struct BcLex { const char *buf; size_t i; size_t line; - const char *f; size_t len; bool newline; @@ -913,8 +912,6 @@ static const BcNumBinaryOp bc_program_ops[] = { bc_num_pow, bc_num_mul, bc_num_div, bc_num_mod, bc_num_add, bc_num_sub, }; -static const char bc_program_stdin_name[] = "<stdin>"; - static void fflush_and_check(void) { fflush_all(); @@ -933,11 +930,18 @@ static void quit(void) static NOINLINE int bc_error_fmt(const char *fmt, ...) { + const char *sv; va_list p; + sv = applet_name; + if (G.prog.file) + applet_name = G.prog.file; + va_start(p, fmt); bb_verror_msg(fmt, p, NULL); va_end(p); + applet_name = sv; + if (!G.ttyin) exit(1); return BC_STATUS_FAILURE; @@ -945,15 +949,21 @@ static NOINLINE int bc_error_fmt(const char *fmt, ...) static NOINLINE int bc_posix_error_fmt(const char *fmt, ...) { + const char *sv; va_list p; // Are non-POSIX constructs totally ok? if (!(option_mask32 & (BC_FLAG_S|BC_FLAG_W))) return BC_STATUS_SUCCESS; // yes + sv = applet_name; + if (G.prog.file) + applet_name = G.prog.file; + va_start(p, fmt); bb_verror_msg(fmt, p, NULL); va_end(p); + applet_name = sv; // Do we treat non-POSIX constructs as errors? if (!(option_mask32 & BC_FLAG_S)) @@ -2860,11 +2870,10 @@ static void bc_lex_free(BcLex *l) bc_vec_free(&l->t.v); } -static void bc_lex_file(BcLex *l, const char *file) +static void bc_lex_file(BcLex *l) { l->line = 1; l->newline = false; - l->f = file; } static BcStatus bc_lex_next(BcLex *l) @@ -5337,6 +5346,7 @@ err: static BcStatus bc_program_read(void) { + const char *sv_file; BcStatus s; BcParse parse; BcVec buf; @@ -5353,11 +5363,14 @@ static BcStatus bc_program_read(void) bc_vec_pop_all(&f->code); bc_char_vec_init(&buf); + sv_file = G.prog.file; + G.prog.file = NULL; + s = bc_read_line(&buf, "read> "); if (s) goto io_err; common_parse_init(&parse, BC_PROG_READ); - bc_lex_file(&parse.l, bc_program_stdin_name); + bc_lex_file(&parse.l); s = bc_parse_text(&parse, buf.v); if (s) goto exec_err; @@ -5380,6 +5393,7 @@ static BcStatus bc_program_read(void) bc_vec_push(&G.prog.stack, &ip); exec_err: + G.prog.file = sv_file; bc_parse_free(&parse); io_err: bc_vec_free(&buf); @@ -6862,16 +6876,18 @@ static BcStatus bc_vm_process(const char *text) static BcStatus bc_vm_file(const char *file) { - BcStatus s; + const char *sv_file; char *data; + BcStatus s; BcFunc *main_func; BcInstPtr *ip; - G.prog.file = file; data = bc_read_file(file); if (!data) return bc_error_fmt("file '%s' is not text", file); - bc_lex_file(&G.prs.l, file); + sv_file = G.prog.file; + G.prog.file = file; + bc_lex_file(&G.prs.l); s = bc_vm_process(data); if (s) goto err; @@ -6882,6 +6898,7 @@ static BcStatus bc_vm_file(const char *file) s = bc_error_fmt("file '%s' is not executable", file); err: + G.prog.file = sv_file; free(data); return s; } @@ -6893,8 +6910,8 @@ static BcStatus bc_vm_stdin(void) size_t len, i, str = 0; bool comment = false; - G.prog.file = bc_program_stdin_name; - bc_lex_file(&G.prs.l, bc_program_stdin_name); + G.prog.file = NULL; + bc_lex_file(&G.prs.l); bc_char_vec_init(&buffer); bc_char_vec_init(&buf); @@ -7156,7 +7173,7 @@ static BcStatus bc_vm_exec(void) // We know that internal library is not buggy, // thus error checking is normally disabled. # define DEBUG_LIB 0 - bc_lex_file(&G.prs.l, ""); + bc_lex_file(&G.prs.l); s = bc_parse_text(&G.prs, bc_lib); if (DEBUG_LIB && s) return s; |