Skip to content

Commit 9df22b9

Browse files
committed
Bug fix and unit tests for #474
1 parent 625aea0 commit 9df22b9

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

cmd2/parsing.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,25 +121,23 @@ def __init__(
121121
# double or single quotes.
122122
#
123123
# this big regular expression can be broken down into 3 regular
124-
# expressions that are OR'ed together.
124+
# expressions that are OR'ed together with a pipe character
125125
#
126-
# /\*.*?(\*/|$) matches C-style comments, with an optional
127-
# closing '*/'. The optional closing '*/' is
128-
# there to retain backward compatibility with
129-
# the pyparsing implementation of cmd2 < 0.9.0
130-
# \'(?:\\.|[^\\\'])*\' matches a single quoted string, allowing
126+
# /\*.*\*/ Matches C-style comments (i.e. /* comment */)
127+
# does not match unclosed comments.
128+
# \'(?:\\.|[^\\\'])*\' Matches a single quoted string, allowing
131129
# for embedded backslash escaped single quote
132-
# marks
133-
# "(?:\\.|[^\\"])*" matches a double quoted string, allowing
130+
# marks.
131+
# "(?:\\.|[^\\"])*" Matches a double quoted string, allowing
134132
# for embedded backslash escaped double quote
135-
# marks
133+
# marks.
136134
#
137135
# by way of reminder the (?:...) regular expression syntax is just
138136
# a non-capturing version of regular parenthesis. We need the non-
139137
# capturing syntax because _comment_replacer() looks at match
140138
# groups
141139
self.comment_pattern = re.compile(
142-
r'/\*.*?(\*/|$)|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
140+
r'/\*.*\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
143141
re.DOTALL | re.MULTILINE
144142
)
145143

tests/test_parsing.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,20 @@ def test_parse_c_comment_empty(parser):
142142
assert not statement.pipe_to
143143
assert not statement.argv
144144

145+
def test_parse_c_comment_no_closing(parser):
146+
statement = parser.parse('cat /tmp/*.txt')
147+
assert statement.command == 'cat'
148+
assert statement.args == '/tmp/*.txt'
149+
assert not statement.pipe_to
150+
assert statement.argv == ['cat', '/tmp/*.txt']
151+
152+
def test_parse_c_comment_multiple_opening(parser):
153+
statement = parser.parse('cat /tmp/*.txt /tmp/*.cfg')
154+
assert statement.command == 'cat'
155+
assert statement.args == '/tmp/*.txt /tmp/*.cfg'
156+
assert not statement.pipe_to
157+
assert statement.argv == ['cat', '/tmp/*.txt', '/tmp/*.cfg']
158+
145159
def test_parse_what_if_quoted_strings_seem_to_start_comments(parser):
146160
statement = parser.parse('what if "quoted strings /* seem to " start comments?')
147161
assert statement.command == 'what'
@@ -292,13 +306,13 @@ def test_parse_multiline_command_ignores_redirectors_within_it(parser, line, ter
292306
def test_parse_multiline_with_incomplete_comment(parser):
293307
"""A terminator within a comment will be ignored and won't terminate a multiline command.
294308
Un-closed comments effectively comment out everything after the start."""
295-
line = 'multiline command /* with comment in progress;'
309+
line = 'multiline command /* with unclosed comment;'
296310
statement = parser.parse(line)
297311
assert statement.multiline_command == 'multiline'
298312
assert statement.command == 'multiline'
299-
assert statement.args == 'command'
300-
assert statement.argv == ['multiline', 'command']
301-
assert not statement.terminator
313+
assert statement.args == 'command /* with unclosed comment'
314+
assert statement.argv == ['multiline', 'command', '/*', 'with', 'unclosed', 'comment']
315+
assert statement.terminator == ';'
302316

303317
def test_parse_multiline_with_complete_comment(parser):
304318
line = 'multiline command /* with comment complete */ is done;'

0 commit comments

Comments
 (0)