diff options
author | 2013-12-31 16:37:15 -0800 | |
---|---|---|
committer | 2013-12-31 16:37:15 -0800 | |
commit | 4402f73bf7a8db577cb6a61273a93b3c53969003 (patch) | |
tree | 63f8882d9d7acbb1c0ecef32247008b50d4bff8f | |
parent | 7356a0f6c86239de19195ae13c035544448eeca5 (diff) |
Improve error reporting for tokens ending with newlines
-rw-r--r-- | parse_tree.cpp | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/parse_tree.cpp b/parse_tree.cpp index ad825a11..b624cf37 100644 --- a/parse_tree.cpp +++ b/parse_tree.cpp @@ -20,27 +20,31 @@ wcstring parse_error_t::describe(const wcstring &src, bool skip_caret) const // Locate the beginning of this line of source size_t line_start = 0; - // Look for a newline prior to source_start. If we don't find one, start at the beginning of the string; otherwise start one past the newline - size_t newline = src.find_last_of(L'\n', source_start); - //fprintf(stderr, "newline: %lu, source_start %lu, source_length %lu\n", newline, source_start, source_length); - if (newline != wcstring::npos) + // Look for a newline prior to source_start. If we don't find one, start at the beginning of the string; otherwise start one past the newline. Note that source_start may itself point at a newline; we want to find the newline before it. + if (source_start > 0) { - line_start = newline + 1; + size_t newline = src.find_last_of(L'\n', source_start - 1); + if (newline != wcstring::npos) + { + line_start = newline + 1; + } } - size_t line_end = src.find(L'\n', source_start + source_length); + // Look for the newline after the source range. If the source range itself includes a newline, that's the one we want, so start just before the end of the range + size_t last_char_in_range = (source_length == 0 ? source_start : source_start + source_length - 1); + size_t line_end = src.find(L'\n', last_char_in_range); if (line_end == wcstring::npos) { line_end = src.size(); } + assert(line_end >= line_start); - //fprintf(stderr, "source start: %lu, source_length %lu, line start %lu, line end %lu\n", source_start, source_length, line_start, line_end); assert(source_start >= line_start); - // Append the line of text + // Append the line of text. result.push_back(L'\n'); 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 wcstring caret_space_line; caret_space_line.reserve(source_start - line_start); @@ -51,6 +55,11 @@ wcstring parse_error_t::describe(const wcstring &src, bool skip_caret) const { caret_space_line.push_back(L'\t'); } + else if (wc == L'\n') + { + /* It's possible that the source_start points at a newline itself. In that case, pretend it's a space. We only expect this to be at the end of the string. */ + caret_space_line.push_back(L' '); + } else { int width = fish_wcwidth(wc); |