diff options
| -rw-r--r-- | shell/hush.c | 85 | 
1 files changed, 46 insertions, 39 deletions
| diff --git a/shell/hush.c b/shell/hush.c index 41d65ff69..d6f765d6b 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -663,23 +663,25 @@ static void xxfree(void *ptr)   * HUSH_DEBUG >= 2 prints line number in this file where it was detected.   */  #if HUSH_DEBUG < 2 -# define die_if_script(lineno, fmt, msg)       die_if_script(fmt, msg) -# define syntax_error(lineno, msg)             syntax_error(msg) -# define syntax_error_at(lineno, msg)          syntax_error_at(msg) -# define syntax_error_unterminated(lineno, ch) syntax_error_unterminated(ch) +# define die_if_script(lineno, fmt...)      die_if_script(fmt) +# define syntax_error(lineno, msg)          syntax_error(msg) +# define syntax_error_at(lineno, msg)       syntax_error_at(msg) +# 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 -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; -#if ENABLE_HUSH_INTERACTIVE -	if (G_interactive_fd) -		fp = bb_error_msg; -#endif +	va_list p; +  #if HUSH_DEBUG >= 2  	bb_error_msg("hush.c:%u", lineno);  #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) @@ -695,7 +697,7 @@ static void syntax_error_at(unsigned lineno, const char *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];  	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);  } +static void syntax_error_unterm_str(unsigned lineno, const char *s) +{ +	die_if_script(lineno, "syntax error: unterminated %s", s); +} +  #if HUSH_DEBUG < 2  # undef die_if_script  # undef syntax_error  # undef syntax_error_at -# undef syntax_error_unterminated +# undef syntax_error_unterm_ch +# undef syntax_error_unterm_str  #else -# define die_if_script(fmt, msg)       die_if_script(__LINE__, fmt, msg) -# define syntax_error(msg)             syntax_error(__LINE__, msg) -# define syntax_error_at(msg)          syntax_error_at(__LINE__, msg) -# define syntax_error_unterminated(ch) syntax_error_unterminated(__LINE__, ch) +# define die_if_script(fmt...)      die_if_script(__LINE__, fmt) +# define syntax_error(msg)          syntax_error(__LINE__, msg) +# define syntax_error_at(msg)       syntax_error_at(__LINE__, msg) +# 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 @@ -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";  					break;  				} -				die_if_script(msg, NULL); +				die_if_script(msg);  			}  			debug_printf_subst("ARITH RES '"arith_t_fmt"'\n", 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,  						exp_null ? "true" : "false", exp_test);  					if (exp_test) { -						if (exp_op == '?') -//TODO: what does interactive bash +						if (exp_op == '?') { +//TODO: how interactive bash aborts expansion mid-command?  							/* ${var?[error_msg_if_unset]} */  							/* ${var:?[error_msg_if_unset_or_null]} */  							/* mimic bash message */ -							if (*exp_word) { -								char *msg = xasprintf("%s: %s", var, exp_word); -								die_if_script("%s", msg); -								free(msg); -							} else { -								die_if_script("%s: parameter null or not set", var); -							} -						else +							die_if_script("%s: %s", +								var, +								exp_word[0] ? exp_word : "parameter null or not set" +							); +						} else {  							val = exp_word; +						}  						if (exp_op == '=') {  							/* ${var=[word]} or ${var:=[word]} */ @@ -4487,7 +4494,7 @@ static int add_till_single_quote(o_string *dest, struct in_str *input)  	while (1) {  		int ch = i_getch(input);  		if (ch == EOF) { -			syntax_error_unterminated('\''); +			syntax_error_unterm_ch('\'');  			return 1;  		}  		if (ch == '\'') @@ -4501,7 +4508,7 @@ static int add_till_double_quote(o_string *dest, struct in_str *input)  	while (1) {  		int ch = i_getch(input);  		if (ch == EOF) { -			syntax_error_unterminated('"'); +			syntax_error_unterm_ch('"');  			return 1;  		}  		if (ch == '"') @@ -4539,7 +4546,7 @@ static int add_till_backquote(o_string *dest, struct in_str *input)  	while (1) {  		int ch = i_getch(input);  		if (ch == EOF) { -			syntax_error_unterminated('`'); +			syntax_error_unterm_ch('`');  			return 1;  		}  		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 \` */  			int ch2 = i_getch(input);  			if (ch2 == EOF) { -				syntax_error_unterminated('`'); +				syntax_error_unterm_ch('`');  				return 1;  			}  			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) {  		int ch = i_getch(input);  		if (ch == EOF) { -			syntax_error_unterminated(')'); +			syntax_error_unterm_ch(')');  			return 1;  		}  		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  \(, \) */  			ch = i_getch(input);  			if (ch == EOF) { -				syntax_error_unterminated(')'); +				syntax_error_unterm_ch(')');  				return 1;  			}  			o_addchr(dest, ch); @@ -4726,7 +4733,7 @@ static int handle_dollar(o_string *as_string,  					break;  				default:  				case_default: -					syntax_error("unterminated ${name}"); +					syntax_error_unterm_str("${name}");  					debug_printf_parse("handle_dollar return 1: unterminated ${name}\n");  					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! */  	if (ch == EOF) { -		syntax_error_unterminated('"'); +		syntax_error_unterm_ch('"');  		debug_printf_parse("parse_stream_dquoted return 1: unterminated \"\n");  		return 1;  	} @@ -4954,7 +4961,7 @@ static struct pipe *parse_stream(char **pstring,  			struct pipe *pi;  			if (heredoc_cnt) { -				syntax_error("unterminated here document"); +				syntax_error_unterm_str("here document");  				goto parse_error;  			}  			if (done_word(&dest, &ctx)) { @@ -5043,7 +5050,7 @@ static struct pipe *parse_stream(char **pstring,  				 * We require heredoc to be in enclosing {}/(),  				 * if any.  				 */ -				syntax_error("unterminated here document"); +				syntax_error_unterm_str("here document");  				goto parse_error;  			}  			if (done_word(&dest, &ctx)) { @@ -5123,7 +5130,7 @@ static struct pipe *parse_stream(char **pstring,  			while (1) {  				ch = i_getch(input);  				if (ch == EOF) { -					syntax_error_unterminated('\''); +					syntax_error_unterm_ch('\'');  					goto parse_error;  				}  				nommu_addchr(&ctx.as_string, ch); | 
