aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2015-08-10 19:30:21 -0700
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2015-08-10 19:30:21 -0700
commitaa76f64a94f9b8505e2093757ca2dbb3c8e44f88 (patch)
tree18e411fff5e09a5b50faeb441e7ea44a8bff97f9
parente34a8da5d727ba26aeddd64e9b60a41c0c5312d3 (diff)
Correct the caret position for unbalanced square brackets
-rw-r--r--src/fish_tests.cpp10
-rw-r--r--src/parse_constants.h1
-rw-r--r--src/parse_tree.cpp4
-rw-r--r--src/tokenizer.cpp9
-rw-r--r--src/tokenizer.h1
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
}