hush: shrink and make more versatile error-reporting machinery

function                                             old     new   delta
syntax_error_unterm_ch                                 -      31     +31
syntax_error_unterm_str                                -      14     +14
parse_stream                                        2356    2361      +5
syntax_error_at                                       12      14      +2
syntax_error                                          25      27      +2
syntax_error_unterminated                             28       -     -28
expand_variables                                    2063    2031     -32
------------------------------------------------------------------------------
(add/remove: 2/1 grow/shrink: 3/1 up/down: 54/-60)             Total: -6 bytes
   text    data     bss     dec     hex filename
  67278     197    3184   70659   11403 busybox_old
  67228     197    3184   70609   113d1 busybox_unstripped
This commit is contained in:
Denis Vlasenko 2009-04-09 20:41:34 +00:00
parent 05d3b7cc0d
commit d68ae08cde

View File

@ -663,23 +663,25 @@ static void xxfree(void *ptr)
* HUSH_DEBUG >= 2 prints line number in this file where it was detected. * HUSH_DEBUG >= 2 prints line number in this file where it was detected.
*/ */
#if HUSH_DEBUG < 2 #if HUSH_DEBUG < 2
# define die_if_script(lineno, fmt, msg) die_if_script(fmt, msg) # define die_if_script(lineno, fmt...) die_if_script(fmt)
# define syntax_error(lineno, msg) syntax_error(msg) # define syntax_error(lineno, msg) syntax_error(msg)
# define syntax_error_at(lineno, msg) syntax_error_at(msg) # define syntax_error_at(lineno, msg) syntax_error_at(msg)
# define syntax_error_unterminated(lineno, ch) syntax_error_unterminated(ch) # define syntax_error_unterm_ch(lineno, ch) syntax_error_unterm_ch(ch)
# define syntax_error_unterm_str(lineno, s) syntax_error_unterm_str(s)
#endif #endif
static void die_if_script(unsigned lineno, const char *fmt, const char *msg) static void die_if_script(unsigned lineno, const char *fmt, ...)
{ {
void FAST_FUNC (*fp)(const char *s, ...) = bb_error_msg_and_die; va_list p;
#if ENABLE_HUSH_INTERACTIVE
if (G_interactive_fd)
fp = bb_error_msg;
#endif
#if HUSH_DEBUG >= 2 #if HUSH_DEBUG >= 2
bb_error_msg("hush.c:%u", lineno); bb_error_msg("hush.c:%u", lineno);
#endif #endif
fp(fmt, msg); va_start(p, fmt);
bb_verror_msg(fmt, p, NULL);
va_end(p);
if (!G_interactive_fd)
xfunc_die();
} }
static void syntax_error(unsigned lineno, const char *msg) static void syntax_error(unsigned lineno, const char *msg)
@ -695,7 +697,7 @@ static void syntax_error_at(unsigned lineno, const char *msg)
die_if_script(lineno, "syntax error at '%s'", msg); die_if_script(lineno, "syntax error at '%s'", msg);
} }
static void syntax_error_unterminated(unsigned lineno, char ch) static void syntax_error_unterm_ch(unsigned lineno, char ch)
{ {
char msg[2]; char msg[2];
msg[0] = ch; msg[0] = ch;
@ -703,16 +705,23 @@ static void syntax_error_unterminated(unsigned lineno, char ch)
die_if_script(lineno, "syntax error: unterminated %s", msg); die_if_script(lineno, "syntax error: unterminated %s", msg);
} }
static void syntax_error_unterm_str(unsigned lineno, const char *s)
{
die_if_script(lineno, "syntax error: unterminated %s", s);
}
#if HUSH_DEBUG < 2 #if HUSH_DEBUG < 2
# undef die_if_script # undef die_if_script
# undef syntax_error # undef syntax_error
# undef syntax_error_at # undef syntax_error_at
# undef syntax_error_unterminated # undef syntax_error_unterm_ch
# undef syntax_error_unterm_str
#else #else
# define die_if_script(fmt, msg) die_if_script(__LINE__, fmt, msg) # define die_if_script(fmt...) die_if_script(__LINE__, fmt)
# define syntax_error(msg) syntax_error(__LINE__, msg) # define syntax_error(msg) syntax_error(__LINE__, msg)
# define syntax_error_at(msg) syntax_error_at(__LINE__, msg) # define syntax_error_at(msg) syntax_error_at(__LINE__, msg)
# define syntax_error_unterminated(ch) syntax_error_unterminated(__LINE__, ch) # define syntax_error_unterm_ch(ch) syntax_error_unterm_ch(__LINE__, ch)
# define syntax_error_unterm_str(s) syntax_error_unterm_str(__LINE__, s)
#endif #endif
@ -1957,7 +1966,7 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
msg = "expression recursion loop detected"; msg = "expression recursion loop detected";
break; break;
} }
die_if_script(msg, NULL); die_if_script(msg);
} }
debug_printf_subst("ARITH RES '"arith_t_fmt"'\n", res); debug_printf_subst("ARITH RES '"arith_t_fmt"'\n", res);
sprintf(arith_buf, arith_t_fmt, res); sprintf(arith_buf, arith_t_fmt, res);
@ -2036,20 +2045,18 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op, debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op,
exp_null ? "true" : "false", exp_test); exp_null ? "true" : "false", exp_test);
if (exp_test) { if (exp_test) {
if (exp_op == '?') if (exp_op == '?') {
//TODO: what does interactive bash //TODO: how interactive bash aborts expansion mid-command?
/* ${var?[error_msg_if_unset]} */ /* ${var?[error_msg_if_unset]} */
/* ${var:?[error_msg_if_unset_or_null]} */ /* ${var:?[error_msg_if_unset_or_null]} */
/* mimic bash message */ /* mimic bash message */
if (*exp_word) { die_if_script("%s: %s",
char *msg = xasprintf("%s: %s", var, exp_word); var,
die_if_script("%s", msg); exp_word[0] ? exp_word : "parameter null or not set"
free(msg); );
} else { } else {
die_if_script("%s: parameter null or not set", var);
}
else
val = exp_word; val = exp_word;
}
if (exp_op == '=') { if (exp_op == '=') {
/* ${var=[word]} or ${var:=[word]} */ /* ${var=[word]} or ${var:=[word]} */
@ -4487,7 +4494,7 @@ static int add_till_single_quote(o_string *dest, struct in_str *input)
while (1) { while (1) {
int ch = i_getch(input); int ch = i_getch(input);
if (ch == EOF) { if (ch == EOF) {
syntax_error_unterminated('\''); syntax_error_unterm_ch('\'');
return 1; return 1;
} }
if (ch == '\'') if (ch == '\'')
@ -4501,7 +4508,7 @@ static int add_till_double_quote(o_string *dest, struct in_str *input)
while (1) { while (1) {
int ch = i_getch(input); int ch = i_getch(input);
if (ch == EOF) { if (ch == EOF) {
syntax_error_unterminated('"'); syntax_error_unterm_ch('"');
return 1; return 1;
} }
if (ch == '"') if (ch == '"')
@ -4539,7 +4546,7 @@ static int add_till_backquote(o_string *dest, struct in_str *input)
while (1) { while (1) {
int ch = i_getch(input); int ch = i_getch(input);
if (ch == EOF) { if (ch == EOF) {
syntax_error_unterminated('`'); syntax_error_unterm_ch('`');
return 1; return 1;
} }
if (ch == '`') if (ch == '`')
@ -4548,7 +4555,7 @@ static int add_till_backquote(o_string *dest, struct in_str *input)
/* \x. Copy both chars unless it is \` */ /* \x. Copy both chars unless it is \` */
int ch2 = i_getch(input); int ch2 = i_getch(input);
if (ch2 == EOF) { if (ch2 == EOF) {
syntax_error_unterminated('`'); syntax_error_unterm_ch('`');
return 1; return 1;
} }
if (ch2 != '`' && ch2 != '$' && ch2 != '\\') if (ch2 != '`' && ch2 != '$' && ch2 != '\\')
@ -4576,7 +4583,7 @@ static int add_till_closing_paren(o_string *dest, struct in_str *input, bool dbl
while (1) { while (1) {
int ch = i_getch(input); int ch = i_getch(input);
if (ch == EOF) { if (ch == EOF) {
syntax_error_unterminated(')'); syntax_error_unterm_ch(')');
return 1; return 1;
} }
if (ch == '(') if (ch == '(')
@ -4608,7 +4615,7 @@ static int add_till_closing_paren(o_string *dest, struct in_str *input, bool dbl
/* \x. Copy verbatim. Important for \(, \) */ /* \x. Copy verbatim. Important for \(, \) */
ch = i_getch(input); ch = i_getch(input);
if (ch == EOF) { if (ch == EOF) {
syntax_error_unterminated(')'); syntax_error_unterm_ch(')');
return 1; return 1;
} }
o_addchr(dest, ch); o_addchr(dest, ch);
@ -4726,7 +4733,7 @@ static int handle_dollar(o_string *as_string,
break; break;
default: default:
case_default: case_default:
syntax_error("unterminated ${name}"); syntax_error_unterm_str("${name}");
debug_printf_parse("handle_dollar return 1: unterminated ${name}\n"); debug_printf_parse("handle_dollar return 1: unterminated ${name}\n");
return 1; return 1;
} }
@ -4831,7 +4838,7 @@ static int parse_stream_dquoted(o_string *as_string,
} }
/* note: can't move it above ch == dquote_end check! */ /* note: can't move it above ch == dquote_end check! */
if (ch == EOF) { if (ch == EOF) {
syntax_error_unterminated('"'); syntax_error_unterm_ch('"');
debug_printf_parse("parse_stream_dquoted return 1: unterminated \"\n"); debug_printf_parse("parse_stream_dquoted return 1: unterminated \"\n");
return 1; return 1;
} }
@ -4954,7 +4961,7 @@ static struct pipe *parse_stream(char **pstring,
struct pipe *pi; struct pipe *pi;
if (heredoc_cnt) { if (heredoc_cnt) {
syntax_error("unterminated here document"); syntax_error_unterm_str("here document");
goto parse_error; goto parse_error;
} }
if (done_word(&dest, &ctx)) { if (done_word(&dest, &ctx)) {
@ -5043,7 +5050,7 @@ static struct pipe *parse_stream(char **pstring,
* We require heredoc to be in enclosing {}/(), * We require heredoc to be in enclosing {}/(),
* if any. * if any.
*/ */
syntax_error("unterminated here document"); syntax_error_unterm_str("here document");
goto parse_error; goto parse_error;
} }
if (done_word(&dest, &ctx)) { if (done_word(&dest, &ctx)) {
@ -5123,7 +5130,7 @@ static struct pipe *parse_stream(char **pstring,
while (1) { while (1) {
ch = i_getch(input); ch = i_getch(input);
if (ch == EOF) { if (ch == EOF) {
syntax_error_unterminated('\''); syntax_error_unterm_ch('\'');
goto parse_error; goto parse_error;
} }
nommu_addchr(&ctx.as_string, ch); nommu_addchr(&ctx.as_string, ch);