comparison cmd2.py @ 3:4520a1a073ff

require terminator for redirection
author catherine@cordelia
date Tue, 13 May 2008 08:29:18 -0400
parents 1ea887b51cad
children 78033fd1078d
comparison
equal deleted inserted replaced
2:1ea887b51cad 3:4520a1a073ff
61 """Lists single-key shortcuts available.""" 61 """Lists single-key shortcuts available."""
62 result = "\n".join('%s: %s' % (sc[0], sc[1]) for sc in self.shortcuts.items()) 62 result = "\n".join('%s: %s' % (sc[0], sc[1]) for sc in self.shortcuts.items())
63 self.stdout.write("Single-key shortcuts for other commands:\n%s\n" % (result)) 63 self.stdout.write("Single-key shortcuts for other commands:\n%s\n" % (result))
64 64
65 legalFileName = re.compile(r'''^[^"'\s]+$''') 65 legalFileName = re.compile(r'''^[^"'\s]+$''')
66 def parseRedirector(self, statement, symbol): 66 def parseRedirector(self, statement, symbol, mustBeTerminated=False):
67 parts = statement.split(symbol) 67 parts = statement.split(symbol)
68 if len(parts) < 2: 68 if (len(parts) < 2):
69 return statement, None 69 return statement, None
70 (newStatement, redirect) = (' '.join(parts[:-1]), parts[-1].strip()) 70 if mustBeTerminated and (parts[-2].strip()[-1] not in self.terminators):
71 return statement, None
72 (newStatement, redirect) = (symbol.join(parts[:-1]), parts[-1].strip())
71 if not self.legalFileName.search(redirect): 73 if not self.legalFileName.search(redirect):
72 return statement, None 74 return statement, None
73 return newStatement, redirect 75 return newStatement, redirect
74 76
77 def extractCommand(self, statement):
78 try:
79 (command, args) = statement.split(None,1)
80 except ValueError:
81 (command, args) = statement, ''
82 if self.caseInsensitive:
83 command = command.lower()
84 return command, args
85
75 def parseRedirectors(self, statement): 86 def parseRedirectors(self, statement):
76 newStatement, redirect = self.parseRedirector(statement, '>>') 87 mustBeTerminated = self.extractCommand(statement)[0] in self.multilineCommands
88 newStatement, redirect = self.parseRedirector(statement, '>>', mustBeTerminated)
77 if redirect: 89 if redirect:
78 return newStatement, redirect, 'a' 90 return newStatement, redirect, 'a'
79 newStatement, redirect = self.parseRedirector(statement, '>') 91 newStatement, redirect = self.parseRedirector(statement, '>', mustBeTerminated)
80 if redirect: 92 if redirect:
81 return newStatement, redirect, 'w' 93 return newStatement, redirect, 'w'
82 newStatement, redirect = self.parseRedirector(statement, '<') 94 newStatement, redirect = self.parseRedirector(statement, '<', mustBeTerminated)
83 if redirect: 95 if redirect:
84 return newStatement, redirect, 'r' 96 return newStatement, redirect, 'r'
85 return statement, '', '' 97 return statement, '', ''
86 98
87 def onecmd(self, line): 99 def onecmd(self, line):
91 This may be overridden, but should not normally need to be; 103 This may be overridden, but should not normally need to be;
92 see the precmd() and postcmd() methods for useful execution hooks. 104 see the precmd() and postcmd() methods for useful execution hooks.
93 The return value is a flag indicating whether interpretation of 105 The return value is a flag indicating whether interpretation of
94 commands by the interpreter should stop. 106 commands by the interpreter should stop.
95 107
96 """ 108 """
97 try: 109 command, args = self.extractCommand(line)
98 (command, args) = line.split(None,1)
99 except ValueError:
100 (command, args) = line, ''
101 if self.caseInsensitive:
102 command = command.lower()
103 statement = ' '.join([command, args]) 110 statement = ' '.join([command, args])
104 if command in self.multilineCommands: 111 if command in self.multilineCommands:
105 statement = self.finishStatement(statement) 112 statement = self.finishStatement(statement)
106 statekeeper = None 113 statekeeper = None
107 statement, redirect, mode = self.parseRedirectors(statement) 114 statement, redirect, mode = self.parseRedirectors(statement)
111 self.stdout = open(redirect, mode) 118 self.stdout = open(redirect, mode)
112 else: 119 else:
113 statement = '%s %s' % (statement, self.fileimport(statement=statement, source=redirect)) 120 statement = '%s %s' % (statement, self.fileimport(statement=statement, source=redirect))
114 stop = cmd.Cmd.onecmd(self, statement) 121 stop = cmd.Cmd.onecmd(self, statement)
115 try: 122 try:
123 # unnecessary to compute command again?
116 command = statement.split(None,1)[0].lower() 124 command = statement.split(None,1)[0].lower()
117 if command not in self.excludeFromHistory: 125 if command not in self.excludeFromHistory:
118 self.history.append(statement) 126 self.history.append(statement)
119 finally: 127 finally:
120 if statekeeper: 128 if statekeeper:
122 statekeeper.restore() 130 statekeeper.restore()
123 return stop 131 return stop
124 132
125 statementEndPattern = re.compile(r'[%s]\s*$' % terminators) 133 statementEndPattern = re.compile(r'[%s]\s*$' % terminators)
126 def statementHasEnded(self, lines): 134 def statementHasEnded(self, lines):
135 #import pdb; pdb.set_trace()
127 return bool(self.statementEndPattern.search(lines)) \ 136 return bool(self.statementEndPattern.search(lines)) \
128 or lines[-3:] == 'EOF' \ 137 or lines[-3:] == 'EOF' \
129 or self.parseRedirectors(lines)[1] 138 or self.parseRedirectors(lines)[1]
130 139
131 def finishStatement(self, firstline): 140 def finishStatement(self, firstline):