Improvements to error reporting. In particular, we now append a newline

in reader_shell_test, so that there's always a statement terminator.
Otherwise commands like 'echo |' would not be considered an error (just
incomplete).
This commit is contained in:
ridiculousfish 2014-01-08 18:20:55 -08:00
parent d69f408b14
commit 0e9d159bc2
2 changed files with 30 additions and 19 deletions

View File

@ -638,6 +638,9 @@ parse_execution_result_t parse_execution_context_t::run_while_statement(const pa
/* Reports an error. Always returns parse_execution_errored, so you can assign the result to an 'errored' variable */ /* Reports an error. Always returns parse_execution_errored, so you can assign the result to an 'errored' variable */
parse_execution_result_t parse_execution_context_t::report_error(const parse_node_t &node, const wchar_t *fmt, ...) parse_execution_result_t parse_execution_context_t::report_error(const parse_node_t &node, const wchar_t *fmt, ...)
{ {
if (parser->show_errors)
{
/* Create an error */
parse_error_t error; parse_error_t error;
error.source_start = node.source_start; error.source_start = node.source_start;
error.source_length = node.source_length; error.source_length = node.source_length;
@ -649,9 +652,12 @@ parse_execution_result_t parse_execution_context_t::report_error(const parse_nod
va_end(va); va_end(va);
/* Get a backtrace */ /* Get a backtrace */
wcstring backtrace; wcstring backtrace_and_desc;
const parse_error_list_t error_list = parse_error_list_t(1, error); const parse_error_list_t error_list = parse_error_list_t(1, error);
parser->get_backtrace(src, error_list, &backtrace); parser->get_backtrace(src, error_list, &backtrace_and_desc);
fprintf(stderr, "%ls", backtrace_and_desc.c_str());
}
return parse_execution_errored; return parse_execution_errored;
} }

View File

@ -2470,21 +2470,26 @@ void reader_run_command(parser_t &parser, const wcstring &cmd)
int reader_shell_test(const wchar_t *b) int reader_shell_test(const wchar_t *b)
{ {
assert(b != NULL);
wcstring bstr = b; wcstring bstr = b;
/* Append a newline, to act as a statement terminator */
bstr.push_back(L'\n');
parse_error_list_t errors; parse_error_list_t errors;
int res = parse_util_detect_errors(bstr, &errors); int res = parse_util_detect_errors(bstr, &errors);
if (res & PARSER_TEST_ERROR) if (res & PARSER_TEST_ERROR)
{ {
wcstring sb; wcstring error_desc;
parser_t::principal_parser().get_backtrace(bstr, errors, &sb); parser_t::principal_parser().get_backtrace(bstr, errors, &error_desc);
// ensure we end with a newline. Also add an initial newline, because it's likely the user just hit enter and so there's junk on the current line // ensure we end with a newline. Also add an initial newline, because it's likely the user just hit enter and so there's junk on the current line
if (! string_suffixes_string(L"\n", sb)) if (! string_suffixes_string(L"\n", error_desc))
{ {
sb.push_back(L'\n'); error_desc.push_back(L'\n');
} }
fwprintf(stderr, L"\n%ls", sb.c_str()); fwprintf(stderr, L"\n%ls", error_desc.c_str());
} }
return res; return res;
} }