diff options
author | ridiculousfish <corydoras@ridiculousfish.com> | 2015-08-10 19:30:21 -0700 |
---|---|---|
committer | ridiculousfish <corydoras@ridiculousfish.com> | 2015-08-10 19:30:21 -0700 |
commit | aa76f64a94f9b8505e2093757ca2dbb3c8e44f88 (patch) | |
tree | 18e411fff5e09a5b50faeb441e7ea44a8bff97f9 | |
parent | e34a8da5d727ba26aeddd64e9b60a41c0c5312d3 (diff) |
Correct the caret position for unbalanced square brackets
-rw-r--r-- | src/fish_tests.cpp | 10 | ||||
-rw-r--r-- | src/parse_constants.h | 1 | ||||
-rw-r--r-- | src/parse_tree.cpp | 4 | ||||
-rw-r--r-- | src/tokenizer.cpp | 9 | ||||
-rw-r--r-- | src/tokenizer.h | 1 |
5 files changed, 23 insertions, 2 deletions
diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index 60de9fca..c507aca3 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -492,6 +492,16 @@ static void test_tok() do_test(token.error == TOK_UNTERMINATED_SUBSHELL); do_test(token.error_offset == 4); } + + { + tok_t token; + tokenizer_t t(L"abc defg[hij (klm)", 0); + do_test(t.next(&token)); + do_test(t.next(&token)); + do_test(token.type == TOK_ERROR); + do_test(token.error == TOK_UNTERMINATED_SLICE); + do_test(token.error_offset == 4); + } /* Test redirection_type_for_string */ if (redirection_type_for_string(L"<") != TOK_REDIRECT_IN) err(L"redirection_type_for_string failed on line %ld", (long)__LINE__); diff --git a/src/parse_constants.h b/src/parse_constants.h index 552085f8..40ccc636 100644 --- a/src/parse_constants.h +++ b/src/parse_constants.h @@ -134,6 +134,7 @@ enum parse_error_code_t //tokenizer errors parse_error_tokenizer_unterminated_quote, parse_error_tokenizer_unterminated_subshell, + parse_error_tokenizer_unterminated_slice, parse_error_tokenizer_unterminated_escape, parse_error_tokenizer_other, diff --git a/src/parse_tree.cpp b/src/parse_tree.cpp index b31a6503..6238ad06 100644 --- a/src/parse_tree.cpp +++ b/src/parse_tree.cpp @@ -908,6 +908,10 @@ void parse_ll_t::report_tokenizer_error(const tok_t &tok) case TOK_UNTERMINATED_SUBSHELL: parse_error_code = parse_error_tokenizer_unterminated_subshell; break; + + case TOK_UNTERMINATED_SLICE: + parse_error_code = parse_error_tokenizer_unterminated_slice; + break; case TOK_UNTERMINATED_ESCAPE: parse_error_code = parse_error_tokenizer_unterminated_escape; diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index e361f88b..b50673ea 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -163,6 +163,9 @@ void tokenizer_t::read_string() // up to 96 open parens, before we give up on good error reporting const size_t paran_offsets_max = 96; size_t paran_offsets[paran_offsets_max]; + + // where the open bracket is + size_t offset_of_bracket = 0; const wchar_t * const start = this->buff; bool is_first = true; @@ -219,7 +222,10 @@ void tokenizer_t::read_string() case L'[': { if (this->buff != start) + { mode = mode_array_brackets; + offset_of_bracket = this->buff - this->orig_buff; + } break; } @@ -361,8 +367,7 @@ void tokenizer_t::read_string() case mode_array_brackets: case mode_array_brackets_and_subshell: { - size_t offset_of_bracket = 0; - TOK_CALL_ERROR(this, TOK_UNTERMINATED_SUBSHELL, SQUARE_BRACKET_ERROR, this->orig_buff + offset_of_bracket); // TOK_UNTERMINATED_SUBSHELL is a lie but nobody actually looks at it + TOK_CALL_ERROR(this, TOK_UNTERMINATED_SLICE, SQUARE_BRACKET_ERROR, this->orig_buff + offset_of_bracket); break; } diff --git a/src/tokenizer.h b/src/tokenizer.h index dca8e5c2..d88feef6 100644 --- a/src/tokenizer.h +++ b/src/tokenizer.h @@ -39,6 +39,7 @@ enum tokenizer_error TOK_ERROR_NONE, TOK_UNTERMINATED_QUOTE, TOK_UNTERMINATED_SUBSHELL, + TOK_UNTERMINATED_SLICE, TOK_UNTERMINATED_ESCAPE, TOK_OTHER } |