changeset 76:dcd5d13e5603

fixed problem with interpreting terminators
author catherine@Elli.myhome.westell.com
date Sat, 28 Jun 2008 10:31:12 -0400
parents 8b2603d1acc1
children bb44928c3856
files cmd2.py
diffstat 1 files changed, 27 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/cmd2.py	Fri Jun 27 15:36:03 2008 -0400
+++ b/cmd2.py	Sat Jun 28 10:31:12 2008 -0400
@@ -129,13 +129,23 @@
         setPasteBuffer = getPasteBuffer
 
 pyparsing.ParserElement.setDefaultWhitespaceChars(' \t')    # see http://pyparsing.wikispaces.com/message/view/home/1352689    
-       
+     
+class Arguments(str):
+    def __new__(cls, s, parent):
+        result = str.__new__(cls, s)
+        result.parent = parent
+        return result
+    
 class UserCommand(str):
     def __new__(cls, s, app):
         return str.__new__(cls, s)
     def __init__(self, s, app):
         self.terminator = None
         self.terminator_suffix = None
+        s = s.strip()
+        shortcut = app.shortcuts.get(s[0])
+        if shortcut and hasattr(app, 'do_%s' % shortcut):
+            s = '%s %s' % (shortcut, s[1:])
         self.searchable = self.asEntered = s
         self.app = app
         self.output_destination_pattern = self.punctuationPattern(['>>', '>'])
@@ -150,7 +160,7 @@
         processed.ignore(pyparsing.dblQuotedString)
         pattern = pyparsing.SkipTo(processed) + processed + pyparsing.restOfLine
         return pattern
-    def find_punctuation(self):
+    def parse(self):
         punctuators = ['|','>','>>','<']
         punctuators.extend(self.app.terminators)          
         punctuated = self.punctuationPattern(punctuators).searchString(self.asEntered)
@@ -158,6 +168,13 @@
             self.executable, self.searchable = punctuated[0][0], self.asEntered[len(punctuated[0][0]):]
         else:
             self.executable, self.searchable = self.asEntered, ''
+        self.executable = self.executable.strip()
+        try:
+            self.cmd, self.arg = (pyparsing.Word(self.app.identchars)+pyparsing.restOfLine).parseString(self.executable)
+            self.arg = Arguments(self.arg, self)
+        except pyparsing.ParseException:
+            self.cmd, self.arg = None, None         
+            
     def complete(self):
         terminator_finder = self.punctuationPattern(self.app.terminators)
         result = terminator_finder.searchString(self.asEntered)
@@ -165,11 +182,10 @@
             inp = self.app.pseudo_raw_input(self.app.continuationPrompt)
             self.asEntered = '%s\n%s' % (self.asEntered, inp)
             result = terminator_finder.searchString(self.asEntered)
-        try:
-            self.terminator = result[0][1][0]
-            self.terminator_suffix = result[0][1][1]
-        except IndexError:
-            self.terminator = result[0][1]
+        self.terminator = result[0][1]
+        if len(result[0]) > 3:
+            self.terminator_suffix = result[0][2]
+        else:
             self.terminator_suffix = None
     def redirectedInput(self):
         inputFrom = self.input_source_pattern.searchString(self.searchable)
@@ -195,27 +211,6 @@
                 mode = 'w'
             return dest, mode
         return None, None
-
-                
-            
-        """
-        Produces a string parser based on a list of targets to search for.
-        Output is a parser function.
-        Parser's output is a tuple: (before the target, [elements of the target], after the target)
-        >>> p = punctuationParser([';', 'EOF'])
-        >>> p('is terminated;')
-        ('is terminated', [';'], '')
-        >>> p('is terminated EOF after the end')    
-        ('is terminated', ['EOF'], 'after the end')
-        >>> p('is not terminated')
-        >>> pattern1 = pyparsing.Literal(';') + pyparsing.Optional(pyparsing.Word(pyparsing.nums))
-        >>> p2 = punctuationParser([pattern1, 'EOF'])
-        >>> p2('the quick brown fox;4')
-        ('the quick brown fox', [';', '4'], '')
-        >>> p2('the quick brown foxEOF')
-        ('the quick brown fox', ['EOF'], '')
-        >>> p2('nothing')
-        """
     
 class Cmd(cmd.Cmd):
     caseInsensitive = True
@@ -300,7 +295,7 @@
         statement = UserCommand(originalStatement, self)
         if (not assumeComplete) and (command in self.multilineCommands):
             statement.complete()
-        statement.find_punctuation()
+        statement.parse()
         statement.redirectedInput()
         pipeTo = statement.pipeDestination()
         if pipeTo:
@@ -318,7 +313,7 @@
                     if outputMode == 'a':
                         self.stdout.write(getPasteBuffer())
 
-        stop = cmd.Cmd.onecmd(self, statement.executable)
+        stop = cmd.Cmd.onecmd(self, statement)
         try:
             if command not in self.excludeFromHistory:
                 self.history.append(originalStatement)
@@ -411,17 +406,9 @@
         the arguments.  Returns a tuple containing (command, args, line).
         'command' and 'args' may be None if the line couldn't be parsed.
         """
-        line = line.strip()
-        if not line:
+        if not line.executable:
             return None, None, line
-        shortcut = self.shortcuts.get(line[0])
-        if shortcut and hasattr(self, 'do_%s' % shortcut):
-            line = '%s %s' % (shortcut, line[1:])
-        i, n = 0, len(line)
-        while i < n and line[i] in self.identchars: i = i+1
-        cmd, arg = line[:i], line[i:].strip()
-        return cmd, arg, line
-    
+        return line.cmd, line.arg, line.executable    
     def showParam(self, param):
         param = self.clean(param)
         if param in self.settable: