diff options
author | Denis Vlasenko | 2007-05-23 15:22:50 +0000 |
---|---|---|
committer | Denis Vlasenko | 2007-05-23 15:22:50 +0000 |
commit | 90e485ce79b8a0cd345bc5be76100291ec589579 (patch) | |
tree | b994e960b598f802820ddd5cf712678903c404de /shell | |
parent | 1744cb18610aece474ba080f43aa5dc89177388e (diff) | |
download | busybox-90e485ce79b8a0cd345bc5be76100291ec589579.zip busybox-90e485ce79b8a0cd345bc5be76100291ec589579.tar.gz |
hush: make syntax error messages a bit more useful
Diffstat (limited to 'shell')
-rw-r--r-- | shell/hush.c | 66 | ||||
-rw-r--r-- | shell/hush_test/hush-parsing/noeol3.right (renamed from shell/hush_test/hush-bugs/noeol3.right) | 0 | ||||
-rwxr-xr-x | shell/hush_test/hush-parsing/noeol3.tests (renamed from shell/hush_test/hush-bugs/noeol3.tests) | 0 |
3 files changed, 37 insertions, 29 deletions
diff --git a/shell/hush.c b/shell/hush.c index 1545b04..579950f 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -423,11 +423,20 @@ enum { run_list_level = 0 }; #define B_NOSPAC 1 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" -static void __syntax(int line) +#if 1 +/* Normal */ +static void syntax(const char *msg) +{ + bb_error_msg(msg ? "%s: %s" : "syntax error", "syntax error", msg); +} +#else +/* Debug */ +static void syntax_lineno(int line) { bb_error_msg("syntax error hush.c:%d", line); } -#define syntax() __syntax(__LINE__) +#define syntax(str) syntax_lineno(__LINE__) +#endif /* Index of subroutines: */ /* function prototypes for builtins */ @@ -1981,7 +1990,7 @@ static int run_list_real(struct pipe *pi) if ((rpipe->res_word == RES_IN || rpipe->res_word == RES_FOR) && (rpipe->next == NULL) ) { - syntax(); /* unterminated FOR (no IN or no commands after IN) */ + syntax("malformed for"); /* no IN or no commands after IN */ debug_printf_exec("run_list_real lvl %d return 1\n", run_list_level); return 1; } @@ -1989,7 +1998,7 @@ static int run_list_real(struct pipe *pi) || (rpipe->res_word == RES_FOR && rpipe->next->res_word != RES_IN) ) { /* TODO: what is tested in the first condition? */ - syntax(); /* 2nd: malformed FOR (not followed by IN) */ + syntax("malformed for"); /* 2nd condition: not followed by IN */ debug_printf_exec("run_list_real lvl %d return 1\n", run_list_level); return 1; } @@ -2914,7 +2923,7 @@ static int reserved_word(o_string *dest, struct p_context *ctx) debug_printf("push stack\n"); #if ENABLE_HUSH_LOOPS if (ctx->res_w == RES_IN || ctx->res_w == RES_FOR) { - syntax(); + syntax("malformed for"); /* example: 'for if' */ ctx->res_w = RES_SNTX; b_reset(dest); return 1; @@ -2925,7 +2934,7 @@ static int reserved_word(o_string *dest, struct p_context *ctx) initialize_context(ctx); ctx->stack = new; } else if (ctx->res_w == RES_NONE || !(ctx->old_flag & (1 << r->code))) { - syntax(); + syntax(NULL); ctx->res_w = RES_SNTX; b_reset(dest); return 1; @@ -2968,7 +2977,7 @@ static int done_word(o_string *dest, struct p_context *ctx) glob_target = &ctx->pending_redirect->word; } else { if (child->group) { - syntax(); + syntax(NULL); debug_printf_parse("done_word return 1: syntax error, groups and arglists don't mix\n"); return 1; } @@ -3224,21 +3233,15 @@ static int parse_group(o_string *dest, struct p_context *ctx, debug_printf_parse("parse_group entered\n"); if (child->argv) { - syntax(); + syntax(NULL); debug_printf_parse("parse_group return 1: syntax error, groups and arglists don't mix\n"); return 1; } initialize_context(&sub); - switch (ch) { - case '(': + endch = "}"; + if (ch == '(') { endch = ")"; child->subshell = 1; - break; - case '{': - endch = "}"; - break; - default: - syntax(); /* really logic error */ } rcode = parse_stream(dest, &sub, input, endch); done_word(dest, &sub); /* finish off the final word in the subcontext */ @@ -3307,7 +3310,7 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i while (1) { ch = b_getch(input); if (ch == EOF) { - syntax(); + syntax("unterminated ${name}"); debug_printf_parse("handle_dollar return 1: unterminated ${name}\n"); return 1; } @@ -3368,7 +3371,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx, || (m != CHAR_SPECIAL && dest->quote) ) { if (ch == EOF) { - syntax(); + syntax("unterminated \""); debug_printf_parse("parse_stream return 1: unterminated \"\n"); return 1; } @@ -3412,7 +3415,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx, break; case '\\': if (next == EOF) { - syntax(); + syntax("\\<eof>"); debug_printf_parse("parse_stream return 1: \\<eof>\n"); return 1; } @@ -3434,7 +3437,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx, b_addchr(dest, ch); } if (ch == EOF) { - syntax(); + syntax("unterminated '"); debug_printf_parse("parse_stream return 1: unterminated '\n"); return 1; } @@ -3455,11 +3458,14 @@ static int parse_stream(o_string *dest, struct p_context *ctx, if (next == '>') { redir_style = REDIRECT_APPEND; b_getch(input); - } else if (next == '(') { - syntax(); /* until we support >(list) Process Substitution */ + } +#if 0 + else if (next == '(') { + syntax(">(process) not supported"); debug_printf_parse("parse_stream return 1: >(process) not supported\n"); return 1; } +#endif setup_redirect(ctx, redir_fd, redir_style, input); break; case '<': @@ -3472,11 +3478,14 @@ static int parse_stream(o_string *dest, struct p_context *ctx, } else if (next == '>') { redir_style = REDIRECT_IO; b_getch(input); - } else if (next == '(') { - syntax(); /* until we support <(list) Process Substitution */ + } +#if 0 + else if (next == '(') { + syntax("<(process) not supported"); debug_printf_parse("parse_stream return 1: <(process) not supported\n"); return 1; } +#endif setup_redirect(ctx, redir_fd, redir_style, input); break; case ';': @@ -3513,13 +3522,12 @@ static int parse_stream(o_string *dest, struct p_context *ctx, break; case ')': case '}': - syntax(); /* Proper use of this character is caught by end_trigger */ + syntax("unexpected }"); /* Proper use of this character is caught by end_trigger */ debug_printf_parse("parse_stream return 1: unexpected '}'\n"); return 1; default: - syntax(); /* this is really an internal logic error */ - debug_printf_parse("parse_stream return 1: internal logic error\n"); - return 1; + if (ENABLE_HUSH_DEBUG) + bb_error_msg_and_die("BUG: unexpected %c\n", ch); } } /* Complain if quote? No, maybe we just finished a command substitution @@ -3585,7 +3593,7 @@ static int parse_and_run_stream(struct in_str *inp, int parse_flag) * TEST should be printed */ rcode = parse_stream(&temp, &ctx, inp, ";\n"); if (rcode != 1 && ctx.old_flag != 0) { - syntax(); + syntax(NULL); } if (rcode != 1 && ctx.old_flag == 0) { done_word(&temp, &ctx); diff --git a/shell/hush_test/hush-bugs/noeol3.right b/shell/hush_test/hush-parsing/noeol3.right index 56f8515..56f8515 100644 --- a/shell/hush_test/hush-bugs/noeol3.right +++ b/shell/hush_test/hush-parsing/noeol3.right diff --git a/shell/hush_test/hush-bugs/noeol3.tests b/shell/hush_test/hush-parsing/noeol3.tests index ec958ed..ec958ed 100755 --- a/shell/hush_test/hush-bugs/noeol3.tests +++ b/shell/hush_test/hush-parsing/noeol3.tests |