Skip to content

Commit c1fc040

Browse files
authored
Merge branch 'master' into pyscript
2 parents ff89bad + 8125d45 commit c1fc040

File tree

2 files changed

+50
-12
lines changed

2 files changed

+50
-12
lines changed

cmd2/parsing.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -250,23 +250,27 @@ def parse(self, rawinput: str) -> Statement:
250250
tokens = self.tokenize(rawinput)
251251

252252
# of the valid terminators, find the first one to occur in the input
253-
terminator_pos = len(tokens)+1
254-
for test_terminator in self.terminators:
255-
try:
256-
pos = tokens.index(test_terminator)
257-
if pos < terminator_pos:
253+
terminator_pos = len(tokens) + 1
254+
for pos, cur_token in enumerate(tokens):
255+
for test_terminator in self.terminators:
256+
if cur_token.startswith(test_terminator):
258257
terminator_pos = pos
259258
terminator = test_terminator
259+
# break the inner loop, and we want to break the
260+
# outer loop too
260261
break
261-
except ValueError:
262-
# the terminator is not in the tokens
263-
pass
262+
else:
263+
# this else clause is only run if the inner loop
264+
# didn't execute a break. If it didn't, then
265+
# continue to the next iteration of the outer loop
266+
continue
267+
# inner loop was broken, break the outer
268+
break
264269

265270
if terminator:
266271
if terminator == LINE_FEED:
267272
terminator_pos = len(tokens)+1
268-
else:
269-
terminator_pos = tokens.index(terminator)
273+
270274
# everything before the first terminator is the command and the args
271275
argv = tokens[:terminator_pos]
272276
(command, args) = self._command_and_args(argv)

tests/test_parsing.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,23 @@ def test_parse_redirect_inside_terminator(parser):
250250
assert statement.argv == ['has', '>', 'inside']
251251
assert statement.terminator == ';'
252252

253+
@pytest.mark.parametrize('line,terminator',[
254+
('multiline with | inside;', ';'),
255+
('multiline with | inside ;', ';'),
256+
('multiline with | inside;;;', ';'),
257+
('multiline with | inside;; ;;', ';'),
258+
('multiline with | inside&', '&'),
259+
('multiline with | inside &;', '&'),
260+
('multiline with | inside&&;', '&'),
261+
('multiline with | inside &; &;', '&'),
262+
])
263+
def test_parse_multiple_terminators(parser, line, terminator):
264+
statement = parser.parse(line)
265+
assert statement.multiline_command == 'multiline'
266+
assert statement.args == 'with | inside'
267+
assert statement.argv == ['multiline', 'with', '|', 'inside']
268+
assert statement.terminator == terminator
269+
253270
def test_parse_unfinished_multiliine_command(parser):
254271
line = 'multiline has > inside an unfinished command'
255272
statement = parser.parse(line)
@@ -261,7 +278,10 @@ def test_parse_unfinished_multiliine_command(parser):
261278

262279
@pytest.mark.parametrize('line,terminator',[
263280
('multiline has > inside;', ';'),
281+
('multiline has > inside;;;', ';'),
282+
('multiline has > inside;; ;;', ';'),
264283
('multiline has > inside &', '&'),
284+
('multiline has > inside & &', '&'),
265285
])
266286
def test_parse_multiline_command_ignores_redirectors_within_it(parser, line, terminator):
267287
statement = parser.parse(line)
@@ -388,8 +408,15 @@ def test_parse_alias_pipe(parser, line):
388408
assert not statement.args
389409
assert statement.pipe_to == ['less']
390410

391-
def test_parse_alias_terminator_no_whitespace(parser):
392-
line = 'helpalias;'
411+
@pytest.mark.parametrize('line', [
412+
'helpalias;',
413+
'helpalias;;',
414+
'helpalias;; ;',
415+
'helpalias ;',
416+
'helpalias ; ;',
417+
'helpalias ;; ;',
418+
])
419+
def test_parse_alias_terminator_no_whitespace(parser, line):
393420
statement = parser.parse(line)
394421
assert statement.command == 'help'
395422
assert not statement.args
@@ -448,13 +475,20 @@ def test_parse_command_only_quoted_args(parser):
448475
'helpalias>>out.txt',
449476
'help|less',
450477
'helpalias;',
478+
'help ;;',
479+
'help; ;;',
451480
])
452481
def test_parse_command_only_specialchars(parser, line):
453482
statement = parser.parse_command_only(line)
454483
assert statement.command == 'help'
455484

456485
@pytest.mark.parametrize('line', [
457486
';',
487+
';;',
488+
';; ;',
489+
'&',
490+
'& &',
491+
' && &',
458492
'>',
459493
"'",
460494
'"',

0 commit comments

Comments
 (0)