diff options
Diffstat (limited to 'cmd2/parsing.py')
-rw-r--r-- | cmd2/parsing.py | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/cmd2/parsing.py b/cmd2/parsing.py index 7046b674..908e9272 100644 --- a/cmd2/parsing.py +++ b/cmd2/parsing.py @@ -7,6 +7,7 @@ import shlex from typing import List, Tuple from . import constants +from . import utils LINE_FEED = '\n' @@ -32,7 +33,11 @@ class Statement(str): :var args: the arguments to the command, not including any output redirection or terminators. quoted arguments remain quoted. - :type args: str + :type args: str or None + :var: argv: a list of arguments a la sys.argv. Quotes, if any, are removed + from the elements of the list, and aliases and shortcuts + are expanded + :type argv: list :var terminator: the charater which terminated the multiline command, if there was one :type terminator: str or None @@ -52,8 +57,8 @@ class Statement(str): self.raw = str(obj) self.command = None self.multiline_command = None - # has to be an empty string for compatibility with standard library cmd - self.args = '' + self.args = None + self.argv = None self.terminator = None self.suffix = None self.pipe_to = None @@ -66,7 +71,14 @@ class Statement(str): Quoted arguments remain quoted. """ - return '{} {}'.format('' if self.command is None else self.command, self.args).strip() + if self.command and self.args: + rtn = '{} {}'.format(self.command, self.args) + elif self.command: + # we are trusting that if we get here that self.args is None + rtn = self.command + else: + rtn = None + return rtn class StatementParser(): @@ -175,7 +187,8 @@ class StatementParser(): terminator = LINE_FEED command = None - args = '' + args = None + argv = None # lex the input into a list of tokens tokens = self.tokenize(rawinput) @@ -199,7 +212,8 @@ class StatementParser(): else: terminator_pos = tokens.index(terminator) # everything before the first terminator is the command and the args - (command, args) = self._command_and_args(tokens[:terminator_pos]) + argv = tokens[:terminator_pos] + (command, args) = self._command_and_args(argv) # we will set the suffix later # remove all the tokens before and including the terminator tokens = tokens[terminator_pos+1:] @@ -211,6 +225,7 @@ class StatementParser(): # because redirectors can only be after a terminator command = testcommand args = testargs + argv = tokens tokens = [] # check for output redirect @@ -254,7 +269,8 @@ class StatementParser(): suffix = None if not command: # command could already have been set, if so, don't set it again - (command, args) = self._command_and_args(tokens) + argv = tokens + (command, args) = self._command_and_args(argv) # set multiline if command in self.multiline_commands: @@ -263,10 +279,15 @@ class StatementParser(): multiline_command = None # build the statement - statement = Statement(args) + # string representation of args must be an empty string instead of + # None for compatibility with standard library cmd + statement = Statement('' if args is None else args) statement.raw = rawinput statement.command = command + # if there are no args we will use None since we don't have to worry + # about compatibility with standard library cmd statement.args = args + statement.argv = list(map(lambda x: utils.strip_quotes(x), argv)) statement.terminator = terminator statement.output = output statement.output_to = output_to @@ -288,10 +309,13 @@ class StatementParser(): (command, args) = self._command_and_args(tokens) # build the statement - statement = Statement(args) + # string representation of args must be an empty string instead of + # None for compatibility with standard library cmd + statement = Statement('' if args is None else args) statement.raw = rawinput statement.command = command statement.args = args + statement.argv = tokens return statement def _expand(self, line: str) -> str: @@ -331,11 +355,14 @@ class StatementParser(): @staticmethod def _command_and_args(tokens: List[str]) -> Tuple[str, str]: - """given a list of tokens, and return a tuple of the command + """Given a list of tokens, return a tuple of the command and the args as a string. + + The args string will be '' instead of None to retain backwards compatibility + with cmd in the standard library. """ command = None - args = '' + args = None if tokens: command = tokens[0] |