#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 */
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;
}
|| (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;
}
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;
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;
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;
}
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 */
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;
}
|| (m != CHAR_SPECIAL && dest->quote)
) {
if (ch == EOF) {
- syntax();
+ syntax("unterminated \"");
debug_printf_parse("parse_stream return 1: unterminated \"\n");
return 1;
}
break;
case '\\':
if (next == EOF) {
- syntax();
+ syntax("\\<eof>");
debug_printf_parse("parse_stream return 1: \\<eof>\n");
return 1;
}
b_addchr(dest, ch);
}
if (ch == EOF) {
- syntax();
+ syntax("unterminated '");
debug_printf_parse("parse_stream return 1: unterminated '\n");
return 1;
}
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 '<':
} 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 ';':
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
* 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);