summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Leonhardt <todd.leonhardt@gmail.com>2018-05-17 12:29:47 -0400
committerGitHub <noreply@github.com>2018-05-17 12:29:47 -0400
commit8125d45412cce07b1316ef19fdcbc98deeb0a57a (patch)
treeed2a665bcda8b583f21b953dc0eadc7945b517fe
parenta9b712108e5af49937b0af3aa51db2ebe5c159e4 (diff)
parent490c8424c9be872538a5130734f120d0a34fdcaf (diff)
downloadcmd2-git-8125d45412cce07b1316ef19fdcbc98deeb0a57a.tar.gz
Merge pull request #403 from python-cmd2/terminator_run
Added check to support a continuous run of a terminator to end a line
-rw-r--r--cmd2/parsing.py24
-rw-r--r--tests/test_parsing.py38
2 files changed, 50 insertions, 12 deletions
diff --git a/cmd2/parsing.py b/cmd2/parsing.py
index ce15bd38..655e0c58 100644
--- a/cmd2/parsing.py
+++ b/cmd2/parsing.py
@@ -250,23 +250,27 @@ class StatementParser:
tokens = self.tokenize(rawinput)
# of the valid terminators, find the first one to occur in the input
- terminator_pos = len(tokens)+1
- for test_terminator in self.terminators:
- try:
- pos = tokens.index(test_terminator)
- if pos < terminator_pos:
+ terminator_pos = len(tokens) + 1
+ for pos, cur_token in enumerate(tokens):
+ for test_terminator in self.terminators:
+ if cur_token.startswith(test_terminator):
terminator_pos = pos
terminator = test_terminator
+ # break the inner loop, and we want to break the
+ # outer loop too
break
- except ValueError:
- # the terminator is not in the tokens
- pass
+ else:
+ # this else clause is only run if the inner loop
+ # didn't execute a break. If it didn't, then
+ # continue to the next iteration of the outer loop
+ continue
+ # inner loop was broken, break the outer
+ break
if terminator:
if terminator == LINE_FEED:
terminator_pos = len(tokens)+1
- else:
- terminator_pos = tokens.index(terminator)
+
# everything before the first terminator is the command and the args
argv = tokens[:terminator_pos]
(command, args) = self._command_and_args(argv)
diff --git a/tests/test_parsing.py b/tests/test_parsing.py
index 41966c71..7b361b7e 100644
--- a/tests/test_parsing.py
+++ b/tests/test_parsing.py
@@ -250,6 +250,23 @@ def test_parse_redirect_inside_terminator(parser):
assert statement.argv == ['has', '>', 'inside']
assert statement.terminator == ';'
+@pytest.mark.parametrize('line,terminator',[
+ ('multiline with | inside;', ';'),
+ ('multiline with | inside ;', ';'),
+ ('multiline with | inside;;;', ';'),
+ ('multiline with | inside;; ;;', ';'),
+ ('multiline with | inside&', '&'),
+ ('multiline with | inside &;', '&'),
+ ('multiline with | inside&&;', '&'),
+ ('multiline with | inside &; &;', '&'),
+])
+def test_parse_multiple_terminators(parser, line, terminator):
+ statement = parser.parse(line)
+ assert statement.multiline_command == 'multiline'
+ assert statement.args == 'with | inside'
+ assert statement.argv == ['multiline', 'with', '|', 'inside']
+ assert statement.terminator == terminator
+
def test_parse_unfinished_multiliine_command(parser):
line = 'multiline has > inside an unfinished command'
statement = parser.parse(line)
@@ -261,7 +278,10 @@ def test_parse_unfinished_multiliine_command(parser):
@pytest.mark.parametrize('line,terminator',[
('multiline has > inside;', ';'),
+ ('multiline has > inside;;;', ';'),
+ ('multiline has > inside;; ;;', ';'),
('multiline has > inside &', '&'),
+ ('multiline has > inside & &', '&'),
])
def test_parse_multiline_command_ignores_redirectors_within_it(parser, line, terminator):
statement = parser.parse(line)
@@ -388,8 +408,15 @@ def test_parse_alias_pipe(parser, line):
assert not statement.args
assert statement.pipe_to == ['less']
-def test_parse_alias_terminator_no_whitespace(parser):
- line = 'helpalias;'
+@pytest.mark.parametrize('line', [
+ 'helpalias;',
+ 'helpalias;;',
+ 'helpalias;; ;',
+ 'helpalias ;',
+ 'helpalias ; ;',
+ 'helpalias ;; ;',
+])
+def test_parse_alias_terminator_no_whitespace(parser, line):
statement = parser.parse(line)
assert statement.command == 'help'
assert not statement.args
@@ -448,6 +475,8 @@ def test_parse_command_only_quoted_args(parser):
'helpalias>>out.txt',
'help|less',
'helpalias;',
+ 'help ;;',
+ 'help; ;;',
])
def test_parse_command_only_specialchars(parser, line):
statement = parser.parse_command_only(line)
@@ -455,6 +484,11 @@ def test_parse_command_only_specialchars(parser, line):
@pytest.mark.parametrize('line', [
';',
+ ';;',
+ ';; ;',
+ '&',
+ '& &',
+ ' && &',
'>',
"'",
'"',