Skip to content

Commit

Permalink
Merge pull request sass#2543 from mgreter/bugfix/unicode-aware-error-…
Browse files Browse the repository at this point in the history
…indicator

Make error indicator Unicode aware
  • Loading branch information
mgreter committed Jan 20, 2018
2 parents a3b5d73 + 5c76806 commit e993a93
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 11 deletions.
9 changes: 9 additions & 0 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ namespace Sass {
// consume unicode BOM
read_bom();

// scan the input to find invalid utf8 sequences
const char* it = utf8::find_invalid(position, end);

// report invalid utf8
if (it != end) {
pstate += Offset::init(position, it);
throw Exception::InvalidSass(pstate, "Invalid UTF-8 sequence");
}

// create a block AST node to hold children
Block_Obj root = SASS_MEMORY_NEW(Block, pstate, 0, true);

Expand Down
33 changes: 22 additions & 11 deletions src/sass_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,24 +72,35 @@ namespace Sass {

// now create the code trace (ToDo: maybe have util functions?)
if (e.pstate.line != std::string::npos && e.pstate.column != std::string::npos) {
size_t line = e.pstate.line;
size_t lines = e.pstate.line;
const char* line_beg = e.pstate.src;
while (line_beg && *line_beg && line) {
if (*line_beg == '\n') --line;
++line_beg;
// scan through src until target line
// move line_beg pointer to line start
while (line_beg && *line_beg && lines != 0) {
if (*line_beg == '\n') --lines;
utf8::unchecked::next(line_beg);
}
const char* line_end = line_beg;
// move line_end before next newline character
while (line_end && *line_end && *line_end != '\n') {
if (*line_end == '\n') break;
if (*line_end == '\r') break;
line_end++;
utf8::unchecked::next(line_end);
}
size_t max_left = 42; size_t max_right = 78;
size_t move_in = e.pstate.column > max_left ? e.pstate.column - max_left : 0;
size_t shorten = (line_end - line_beg) - move_in > max_right ?
(line_end - line_beg) - move_in - max_right : 0;
msg_stream << ">> " << std::string(line_beg + move_in, line_end - shorten) << "\n";
msg_stream << " " << std::string(e.pstate.column - move_in, '-') << "^\n";
if (line_end && *line_end != 0) ++ line_end;
size_t line_len = line_end - line_beg;
size_t move_in = 0; size_t shorten = 0;
size_t left_chars = 42; size_t max_chars = 76;
// reported excerpt should not exceed `max_chars` chars
if (e.pstate.column > line_len) left_chars = e.pstate.column;
if (e.pstate.column > left_chars) move_in = e.pstate.column - left_chars;
if (line_len > max_chars + move_in) shorten = line_len - move_in - max_chars;
utf8::advance(line_beg, move_in, line_end);
utf8::retreat(line_end, shorten, line_beg);
std::string sanitized; std::string marker(e.pstate.column - move_in, '-');
utf8::replace_invalid(line_beg, line_end, std::back_inserter(sanitized));
msg_stream << ">> " << sanitized << "\n";
msg_stream << " " << marker << "^\n";
}

JsonNode* json_err = json_mkobject();
Expand Down
7 changes: 7 additions & 0 deletions src/utf8/checked.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,13 @@ namespace utf8
utf8::next(it, end);
}

template <typename octet_iterator, typename distance_type>
void retreat (octet_iterator& it, distance_type n, octet_iterator start)
{
for (distance_type i = 0; i < n; ++i)
utf8::prior(it, start);
}

template <typename octet_iterator>
typename std::iterator_traits<octet_iterator>::difference_type
distance (octet_iterator first, octet_iterator last)
Expand Down
7 changes: 7 additions & 0 deletions src/utf8/unchecked.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ namespace utf8
utf8::unchecked::next(it);
}

template <typename octet_iterator, typename distance_type>
void retreat (octet_iterator& it, distance_type n)
{
for (distance_type i = 0; i < n; ++i)
utf8::unchecked::prior(it);
}

template <typename octet_iterator>
typename std::iterator_traits<octet_iterator>::difference_type
distance (octet_iterator first, octet_iterator last)
Expand Down

0 comments on commit e993a93

Please sign in to comment.