comparison cmd2.py @ 81:a3b0ef23146f

trying to parseResults
author catherine@Elli.myhome.westell.com
date Fri, 04 Jul 2008 14:02:54 -0400
parents 1e4ba836539e
children bbf0afc6868b
comparison
equal deleted inserted replaced
80:1e4ba836539e 81:a3b0ef23146f
124 raise OSError, pastebufferr % ('xclip', 'On Debian/Ubuntu, install with "sudo apt-get install xclip"') 124 raise OSError, pastebufferr % ('xclip', 'On Debian/Ubuntu, install with "sudo apt-get install xclip"')
125 setPasteBuffer = getPasteBuffer 125 setPasteBuffer = getPasteBuffer
126 126
127 pyparsing.ParserElement.setDefaultWhitespaceChars(' \t') 127 pyparsing.ParserElement.setDefaultWhitespaceChars(' \t')
128 def parseSearchResults(pattern, s): 128 def parseSearchResults(pattern, s):
129 generator = pattern.scanString(s)
129 try: 130 try:
130 return pattern.searchString(s)[0] 131 result, start, stop = generator.next()
131 except IndexError: 132 result['before'], result['after'] = s[:start], s[stop:]
132 return pyparsing.ParseResults('') 133 except StopIteration:
134 result = pyparsing.ParseResults('')
135 result['before'] = s
136 return result
133 137
134 class Cmd(cmd.Cmd): 138 class Cmd(cmd.Cmd):
135 caseInsensitive = True 139 caseInsensitive = True
136 multilineCommands = [] 140 multilineCommands = []
137 continuationPrompt = '> ' 141 continuationPrompt = '> '
148 for editor in ['gedit', 'kate', 'vim', 'emacs', 'nano', 'pico']: 152 for editor in ['gedit', 'kate', 'vim', 'emacs', 'nano', 'pico']:
149 if not os.system('which %s' % (editor)): 153 if not os.system('which %s' % (editor)):
150 break 154 break
151 155
152 settable = ['prompt', 'continuationPrompt', 'defaultFileName', 'editor', 'caseInsensitive'] 156 settable = ['prompt', 'continuationPrompt', 'defaultFileName', 'editor', 'caseInsensitive']
153 terminators = ';\n' 157 terminators = ';\n' #TODO: strip this
154 _TO_PASTE_BUFFER = 1 158 _TO_PASTE_BUFFER = 1
155 def do_cmdenvironment(self, args): 159 def do_cmdenvironment(self, args):
156 self.stdout.write(""" 160 self.stdout.write("""
157 Commands are %(casesensitive)scase-sensitive. 161 Commands are %(casesensitive)scase-sensitive.
158 Commands may be terminated with: %(terminators)s 162 Commands may be terminated with: %(terminators)s
179 def do_shortcuts(self, args): 183 def do_shortcuts(self, args):
180 """Lists single-key shortcuts available.""" 184 """Lists single-key shortcuts available."""
181 result = "\n".join('%s: %s' % (sc[0], sc[1]) for sc in self.shortcuts.items()) 185 result = "\n".join('%s: %s' % (sc[0], sc[1]) for sc in self.shortcuts.items())
182 self.stdout.write("Single-key shortcuts for other commands:\n%s\n" % (result)) 186 self.stdout.write("Single-key shortcuts for other commands:\n%s\n" % (result))
183 187
184 terminators = (pyparsing.Literal(';') ^ pyparsing.Literal('\n\n')) \ 188 terminatorPattern = (pyparsing.Literal(';') ^ pyparsing.Literal('\n\n')) \
185 ('terminator') 189 ('terminator')
186 argSeparatorPattern = pyparsing.Word(pyparsing.printables)('command') \ 190 argSeparatorPattern = pyparsing.Word(pyparsing.printables)('command') \
187 + pyparsing.SkipTo(pyparsing.StringEnd())('args') 191 + pyparsing.SkipTo(pyparsing.StringEnd())('args')
188 filenamePattern = pyparsing.Word(pyparsing.alphanums + '#$-_~{},.!') 192 filenamePattern = pyparsing.Word(pyparsing.alphanums + '#$-_~{},.!')
189 integerPattern = pyparsing.Word(pyparsing.nums).setParseAction( lambda s,l,t: [ int(t[0]) ] ) 193 integerPattern = pyparsing.Word(pyparsing.nums).setParseAction( lambda s,l,t: [ int(t[0]) ] )
190 pipePattern = pyparsing.Literal('|')('pipe') + pyparsing.restOfLine('pipeTo') 194 pipePattern = pyparsing.Literal('|')('pipe') + pyparsing.restOfLine('pipeTo')
191 redirectOutPattern = (pyparsing.Literal('>>') ^ '>')('output') \ 195 redirectOutPattern = (pyparsing.Literal('>>') ^ '>')('output') \
192 + pyparsing.Optional(filenamePattern)('outputTo') 196 + pyparsing.Optional(filenamePattern)('outputTo')
193 redirectInPattern = pyparsing.Literal('<')('input') \ 197 redirectInPattern = pyparsing.Literal('<')('input') \
194 + pyparsing.Optional(filenamePattern)('inputFrom') 198 + pyparsing.Optional(filenamePattern)('inputFrom')
195 punctuationPattern = pipePattern ^ redirectInPattern ^ redirectOutPattern 199 punctuationPattern = pipePattern ^ redirectInPattern ^ redirectOutPattern
196 for p in (terminators, pipePattern, redirectInPattern, redirectOutPattern, punctuationPattern): 200 for p in (terminatorPattern, pipePattern, redirectInPattern, redirectOutPattern, punctuationPattern):
197 p.ignore(pyparsing.sglQuotedString) 201 p.ignore(pyparsing.sglQuotedString)
198 p.ignore(pyparsing.dblQuotedString) 202 p.ignore(pyparsing.dblQuotedString)
199 203
200 def parsed(self, s): 204 def parsed(self, s):
201 ''' 205 '''
202 >>> c = Cmd() 206 >>> c = Cmd()
203 >>> c.parsed('quotes "are > ignored" < inp.txt').asDict() 207 >>> c.parsed('quotes "are > ignored" < inp.txt').asDict()
204 {'args': '"are > ignored"', 'inputFrom': 'inp.txt', 'command': 'quotes', 'statement': 'quotes "are > ignored"', 'input': '<', 'fullStatement': 'quotes "are > ignored" < inp.txt'} 208 {'args': '"are > ignored"', 'inputFrom': 'inp.txt', 'command': 'quotes', 'statement': 'quotes "are > ignored"', 'input': '<', 'fullStatement': 'quotes "are > ignored" < inp.txt'}
205 >>> c.parsed('very complex; < from.txt >> to.txt etc.').asDict() 209 >>> c.parsed('very complex; < from.txt >> to.txt etc.').asDict()
206 {'args': 'complex;', 'inputFrom': 'from.txt', 'command': 'very', 'statement': 'very complex;', 'input': '<', 'output': '>>', 'outputTo': 'to.txt', 'fullStatement': 'very complex; < from.txt >> to.txt etc.'} 210 {'args': 'complex;', 'inputFrom': 'from.txt', 'command': 'very', 'terminator': ';', 'statement': 'very complex;', 'input': '<', 'output': '>>', 'outputTo': 'to.txt', 'fullStatement': 'very complex; < from.txt >> to.txt etc.'}
207 >>> c.parsed('nothing to parse').asDict() 211 >>> c.parsed('nothing to parse').asDict()
208 {'args': 'to parse', 'command': 'nothing', 'statement': 'nothing to parse', 'fullStatement': 'nothing to parse'} 212 {'args': 'to parse', 'command': 'nothing', 'statement': 'nothing to parse', 'fullStatement': 'nothing to parse'}
209 >>> c.parsed('send it to | sort | wc').asDict() 213 >>> c.parsed('send it to | sort | wc').asDict()
210 {'args': 'it to', 'pipe': '|', 'pipeTo': ' sort | wc', 'command': 'send', 'statement': 'send it to', 'fullStatement': 'send it to | sort | wc'} 214 {'args': 'it to', 'pipe': '|', 'pipeTo': ' sort | wc', 'command': 'send', 'statement': 'send it to', 'fullStatement': 'send it to | sort | wc'}
211 >>> r = c.parsed('got from < thisfile.txt plus blah blah') 215 >>> r = c.parsed('got from < thisfile.txt plus blah blah')
216 ''' 220 '''
217 if isinstance(s, pyparsing.ParseResults): 221 if isinstance(s, pyparsing.ParseResults):
218 return s 222 return s
219 result = (pyparsing.SkipTo(pyparsing.StringEnd()))('fullStatement').parseString(s) 223 result = (pyparsing.SkipTo(pyparsing.StringEnd()))('fullStatement').parseString(s)
220 result['statement'] = result.fullStatement 224 result['statement'] = result.fullStatement
221 try: 225 result['parseable'] = result.fullStatement
222 result += (pyparsing.SkipTo(self.punctuationPattern)('statement') \ 226 result += parseSearchResults(
223 + self.punctuationPattern).parseString(s) 227 pyparsing.SkipTo(self.terminatorPattern, include=True)('statement') +
224 result += parseSearchResults(self.pipePattern, s) 228 pyparsing.SkipTo(pyparsing.StringEnd())('parseable'), s)
225 result += parseSearchResults(self.redirectInPattern, s) 229 if result.terminator:
226 result += parseSearchResults(self.redirectOutPattern, s) 230 result['statement'] = ''.join(result.statement)
227 except pyparsing.ParseException: 231 else:
228 pass
229 finally:
230 try: 232 try:
231 result += self.argSeparatorPattern.parseString(result.statement) 233 result += pyparsing.SkipTo(self.punctuationPattern)('statement').parseString(s)
232 except pyparsing.ParseException: 234 except pyparsing.ParseException:
233 return result 235 pass
234 if self.caseInsensitive: 236 result += parseSearchResults(self.pipePattern, result.parseable)
235 result['command'] = result.command.lower() 237 result += parseSearchResults(self.redirectInPattern, result.parseable)
236 result['statement'] = '%s %s' % (result.command, result.args) 238 result += parseSearchResults(self.redirectOutPattern, result.parseable)
237 return result 239 result += parseSearchResults(self.argSeparatorPattern, result.statement)
240 if self.caseInsensitive:
241 result['command'] = result.command.lower()
242 result['statement'] = '%s %s' % (result.command, result.args)
243 return result
238 244
239 def extractCommand(self, statement): 245 def extractCommand(self, statement):
240 try: 246 try:
241 (command, args) = statement.split(None,1) 247 (command, args) = statement.split(None,1)
242 except ValueError: 248 except ValueError: