Skip to content

Commit ad634b2

Browse files
committed
Add argv to Statement object
1 parent 802000b commit ad634b2

File tree

3 files changed

+93
-18
lines changed

3 files changed

+93
-18
lines changed

cmd2/parsing.py

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from typing import List, Tuple
88

99
from . import constants
10+
from . import utils
1011

1112
LINE_FEED = '\n'
1213

@@ -33,6 +34,10 @@ class Statement(str):
3334
redirection or terminators. quoted arguments remain
3435
quoted.
3536
:type args: str or None
37+
:var: argv: a list of arguments a la sys.argv. Quotes, if any, are removed
38+
from the elements of the list, and aliases and shortcuts
39+
are expanded
40+
:type argv: list
3641
:var terminator: the charater which terminated the multiline command, if
3742
there was one
3843
:type terminator: str or None
@@ -53,6 +58,7 @@ def __init__(self, obj):
5358
self.command = None
5459
self.multiline_command = None
5560
self.args = None
61+
self.argv = None
5662
self.terminator = None
5763
self.suffix = None
5864
self.pipe_to = None
@@ -65,7 +71,14 @@ def command_and_args(self):
6571
6672
Quoted arguments remain quoted.
6773
"""
68-
return '{} {}'.format('' if self.command is None else self.command, self.args).strip()
74+
if self.command and self.args:
75+
rtn = '{} {}'.format(self.command, self.args)
76+
elif self.command:
77+
# we are trusting that if we get here that self.args is None
78+
rtn = self.command
79+
else:
80+
rtn = None
81+
return rtn
6982

7083

7184
class StatementParser():
@@ -175,6 +188,7 @@ def parse(self, rawinput: str) -> Statement:
175188

176189
command = None
177190
args = None
191+
argv = None
178192

179193
# lex the input into a list of tokens
180194
tokens = self.tokenize(rawinput)
@@ -198,7 +212,8 @@ def parse(self, rawinput: str) -> Statement:
198212
else:
199213
terminator_pos = tokens.index(terminator)
200214
# everything before the first terminator is the command and the args
201-
(command, args) = self._command_and_args(tokens[:terminator_pos])
215+
argv = tokens[:terminator_pos]
216+
(command, args) = self._command_and_args(argv)
202217
# we will set the suffix later
203218
# remove all the tokens before and including the terminator
204219
tokens = tokens[terminator_pos+1:]
@@ -210,6 +225,7 @@ def parse(self, rawinput: str) -> Statement:
210225
# because redirectors can only be after a terminator
211226
command = testcommand
212227
args = testargs
228+
argv = tokens
213229
tokens = []
214230

215231
# check for output redirect
@@ -253,7 +269,8 @@ def parse(self, rawinput: str) -> Statement:
253269
suffix = None
254270
if not command:
255271
# command could already have been set, if so, don't set it again
256-
(command, args) = self._command_and_args(tokens)
272+
argv = tokens
273+
(command, args) = self._command_and_args(argv)
257274

258275
# set multiline
259276
if command in self.multiline_commands:
@@ -268,8 +285,9 @@ def parse(self, rawinput: str) -> Statement:
268285
statement.raw = rawinput
269286
statement.command = command
270287
# if there are no args we will use None since we don't have to worry
271-
# about compatibility wiht standard library cmd
288+
# about compatibility with standard library cmd
272289
statement.args = args
290+
statement.argv = list(map(lambda x: utils.strip_quotes(x), argv))
273291
statement.terminator = terminator
274292
statement.output = output
275293
statement.output_to = output_to
@@ -291,10 +309,13 @@ def parse_command_only(self, rawinput: str) -> Statement:
291309
(command, args) = self._command_and_args(tokens)
292310

293311
# build the statement
294-
statement = Statement(args)
312+
# string representation of args must be an empty string instead of
313+
# None for compatibility with standard library cmd
314+
statement = Statement('' if args is None else args)
295315
statement.raw = rawinput
296316
statement.command = command
297317
statement.args = args
318+
statement.argv = tokens
298319
return statement
299320

300321
def _expand(self, line: str) -> str:
@@ -341,7 +362,7 @@ def _command_and_args(tokens: List[str]) -> Tuple[str, str]:
341362
with cmd in the standard library.
342363
"""
343364
command = None
344-
args = ''
365+
args = None
345366

346367
if tokens:
347368
command = tokens[0]

docs/unfreefeatures.rst

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,28 @@ input:
2929
command
3030
Name of the command called
3131

32+
args
33+
The arguments to the command with output redirection
34+
or piping to shell commands removed
35+
36+
command_and_args
37+
A string of just the command and the arguments, with
38+
output redirection or piping to shell commands removed
39+
40+
argv
41+
A list of arguments a-la ``sys.argv``, including
42+
the command as ``argv[0]`` and the subsequent
43+
arguments as additional items in the list.
44+
Quotes around arguments will be stripped as will
45+
any output redirection or piping portions of the command
46+
3247
raw
3348
Full input exactly as typed.
3449

3550
terminator
3651
Character used to end a multiline command
3752

38-
command_and_args
39-
A string of just the command and the arguments, with
40-
output redirection or piping to shell commands removed
53+
4154

4255
If ``Statement`` does not contain an attribute,
4356
querying for it will return ``None``.

0 commit comments

Comments
 (0)