Tweak error reporting in new parser to use fewer lines

This commit is contained in:
ridiculousfish 2014-02-17 14:51:51 -08:00
parent 2253c57628
commit 2e1024d275
4 changed files with 25 additions and 12 deletions

View File

@ -691,7 +691,7 @@ parse_execution_result_t parse_execution_context_t::report_error(const parse_nod
const parse_error_list_t error_list = parse_error_list_t(1, error);
parser->get_backtrace(src, error_list, &backtrace_and_desc);
fprintf(stderr, "<%ls>", backtrace_and_desc.c_str());
fprintf(stderr, "%ls", backtrace_and_desc.c_str());
}
return parse_execution_errored;

View File

@ -14,7 +14,7 @@ static bool production_is_empty(const production_t *production)
}
/** Returns a string description of this parse error */
wcstring parse_error_t::describe(const wcstring &src, bool skip_caret) const
wcstring parse_error_t::describe_with_prefix(const wcstring &src, const wcstring &prefix, bool skip_caret) const
{
wcstring result = text;
if (! skip_caret && source_start < src.size() && source_start + source_length <= src.size())
@ -53,15 +53,16 @@ wcstring parse_error_t::describe(const wcstring &src, bool skip_caret) const
{
result.push_back(L'\n');
}
result.append(prefix);
result.append(src, line_start, line_end - line_start);
// Append the caret line. The input source may include tabs; for that reason we construct a "caret line" that has tabs in corresponding positions
const wcstring line_to_measure = prefix + wcstring(src, line_start, source_start - line_start);
wcstring caret_space_line;
caret_space_line.reserve(source_start - line_start);
for (size_t i=line_start; i < source_start; i++)
for (size_t i=0; i < line_to_measure.size(); i++)
{
wchar_t wc = src.at(i);
wchar_t wc = line_to_measure.at(i);
if (wc == L'\t')
{
caret_space_line.push_back(L'\t');
@ -88,6 +89,11 @@ wcstring parse_error_t::describe(const wcstring &src, bool skip_caret) const
return result;
}
wcstring parse_error_t::describe(const wcstring &src) const
{
return this->describe_with_prefix(src, wcstring(), false);
}
wcstring parse_errors_description(const parse_error_list_t &errors, const wcstring &src, const wchar_t *prefix)
{
wcstring target;

View File

@ -34,7 +34,10 @@ struct parse_error_t
size_t source_length;
/** Return a string describing the error, suitable for presentation to the user. If skip_caret is false, the offending line with a caret is printed as well */
wcstring describe(const wcstring &src, bool skip_caret = false) const;
wcstring describe(const wcstring &src) const;
/** Return a string describing the error, suitable for presentation to the user, with the given prefix. If skip_caret is false, the offending line with a caret is printed as well */
wcstring describe_with_prefix(const wcstring &src, const wcstring &prefix, bool skip_caret) const;
};
typedef std::vector<parse_error_t> parse_error_list_t;

View File

@ -3002,20 +3002,24 @@ void parser_t::get_backtrace(const wcstring &src, const parse_error_list_t &erro
assert(err.source_start <= src.size());
size_t which_line = 1 + std::count(src.begin(), src.begin() + err.source_start, L'\n');
const wchar_t *filename = this->current_filename();
if (filename)
{
append_format(*output, _(L"fish: line %lu of %ls:\n"), which_line, user_presentable_path(filename).c_str());
}
else
{
output->append(L"fish: ");
}
// Don't include the caret if we're interactive, this is the first line of text, and our source is at its beginning, because then it's obvious
bool skip_caret = (get_is_interactive() && which_line == 1 && err.source_start == 0);
output->append(err.describe(src, skip_caret));
wcstring prefix;
const wchar_t *filename = this->current_filename();
if (filename)
{
prefix = format_string(_(L"%ls (line %lu): "), user_presentable_path(filename).c_str(), which_line);
//append_format(*output, _(L"%ls (line %lu):\n"), user_presentable_path(filename).c_str(), which_line);
}
else
{
prefix = L"fish: ";
//output->append(L"fish: ");
}
output->append(err.describe_with_prefix(src, prefix, skip_caret));
output->push_back(L'\n');
this->stack_trace(0, *output);