comparison cmd2.py @ 166:a3414ac38677

so close - now problem with terminator in string
author catherine@dellzilla
date Mon, 08 Dec 2008 17:27:47 -0500
parents 3dc882a00e53
children a38303571916
comparison
equal deleted inserted replaced
165:3dc882a00e53 166:a3414ac38677
174 174
175 class Cmd(cmd.Cmd): 175 class Cmd(cmd.Cmd):
176 echo = False 176 echo = False
177 caseInsensitive = True 177 caseInsensitive = True
178 continuationPrompt = '> ' 178 continuationPrompt = '> '
179 legalChars = '!#$%.:?@_' # make sure your terminators are not in here! 179 legalChars = '!#$%.:?@_' + pyparsing.alphanums + pyparsing.alphas8bit # make sure your terminators are not in here!
180 shortcuts = {'?': 'help', '!': 'shell', '@': 'load' } 180 shortcuts = {'?': 'help', '!': 'shell', '@': 'load' }
181 excludeFromHistory = '''run r list l history hi ed edit li eof'''.split() 181 excludeFromHistory = '''run r list l history hi ed edit li eof'''.split()
182 noSpecialParse = 'set ed edit exit'.split() 182 noSpecialParse = 'set ed edit exit'.split()
183 defaultExtension = 'txt' 183 defaultExtension = 'txt'
184 defaultFileName = 'command.txt' 184 defaultFileName = 'command.txt'
373 ''' 373 '''
374 outputParser = pyparsing.oneOf(['>>','>'])('output') 374 outputParser = pyparsing.oneOf(['>>','>'])('output')
375 terminatorParser = pyparsing.oneOf(self.terminators)('terminator') 375 terminatorParser = pyparsing.oneOf(self.terminators)('terminator')
376 stringEnd = pyparsing.stringEnd ^ '\nEOF' 376 stringEnd = pyparsing.stringEnd ^ '\nEOF'
377 multilineCommand = pyparsing.Or([pyparsing.Keyword(c, caseless=self.caseInsensitive) for c in self.multilineCommands])('multilineCommand') 377 multilineCommand = pyparsing.Or([pyparsing.Keyword(c, caseless=self.caseInsensitive) for c in self.multilineCommands])('multilineCommand')
378 oneLineCommand = pyparsing.Word(self.legalChars + pyparsing.alphanums + pyparsing.alphas8bit)('command') 378 oneLineCommand = pyparsing.Word(self.legalChars)('command')
379 pipe = pyparsing.Keyword('|', identChars='|') 379 pipe = pyparsing.Keyword('|', identChars='|')
380 afterElements = \ 380 afterElements = \
381 pyparsing.Optional(pipe + pyparsing.SkipTo(outputParser ^ stringEnd)('pipeTo')) + \ 381 pyparsing.Optional(pipe + pyparsing.SkipTo(outputParser ^ stringEnd)('pipeTo')) + \
382 pyparsing.Optional(outputParser + pyparsing.SkipTo(stringEnd).setParseAction(lambda x: x[0].strip())('outputTo')) 382 pyparsing.Optional(outputParser + pyparsing.SkipTo(stringEnd).setParseAction(lambda x: x[0].strip())('outputTo'))
383 if self.caseInsensitive: 383 if self.caseInsensitive:
398 self.commentInProgress.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(pyparsing.cStyleComment) 398 self.commentInProgress.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(pyparsing.cStyleComment)
399 self.parser.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(self.commentGrammars).ignore(self.commentInProgress) 399 self.parser.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(self.commentGrammars).ignore(self.commentInProgress)
400 400
401 inputMark = pyparsing.Literal('<') 401 inputMark = pyparsing.Literal('<')
402 inputMark.setParseAction(lambda x: '') 402 inputMark.setParseAction(lambda x: '')
403 inputFrom = pyparsing.Word(self.legalChars)('inputFrom') 403 inputFrom = pyparsing.Word(self.legalChars + '/\\')('inputFrom')
404 inputFrom.setParseAction(lambda x: (x and open(x[0]).read()) or getPasteBuffer()) 404 inputFrom.setParseAction(lambda x: (x and open(x[0]).read()) or getPasteBuffer())
405 self.inputParser = inputMark + pyparsing.Optional(inputFrom) 405 self.inputParser = inputMark + pyparsing.Optional(inputFrom)
406 self.inputParser.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(self.commentGrammars).ignore(self.commentInProgress) 406 self.inputParser.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(self.commentGrammars).ignore(self.commentInProgress)
407 407
408 def parsed(self, raw, **kwargs): 408 def parsed(self, raw, **kwargs):
409 if isinstance(raw, ParsedString): 409 if isinstance(raw, ParsedString):
410 p = raw 410 p = raw
411 else: 411 else:
412 s = self.inputParser.transformString(raw.strip()) 412 s = self.inputParser.transformString(raw.strip()) # used to be raw.strip()
413 for (shortcut, expansion) in self.shortcuts.items(): 413 for (shortcut, expansion) in self.shortcuts.items():
414 if s.startswith(shortcut): 414 if s.startswith(shortcut):
415 s = s.replace(shortcut, expansion + ' ', 1) 415 s = s.replace(shortcut, expansion + ' ', 1)
416 break 416 break
417 result = self.parser.parseString(s) 417 result = self.parser.parseString(s)
418 result['command'] = result.multilineCommand or result.command 418 result['command'] = result.multilineCommand or result.command
419 result['raw'] = raw 419 result['raw'] = raw
420 result['clean'] = self.commentGrammars.transformString(result.args) 420 result['clean'] = self.commentGrammars.transformString(result.args)
421 result['expanded'] = s 421 result['expanded'] = s
422 p = ParsedString(result.args) 422 p = ParsedString(result.clean)
423 p.parsed = result 423 p.parsed = result
424 p.parser = self.parsed 424 p.parser = self.parsed
425 for (key, val) in kwargs.items(): 425 for (key, val) in kwargs.items():
426 p.parsed[key] = val 426 p.parsed[key] = val
427 return p 427 return p
428 428
429 def onecmd(self, line, assumeComplete=False): 429 def onecmd(self, line):
430 """Interpret the argument as though it had been typed in response 430 """Interpret the argument as though it had been typed in response
431 to the prompt. 431 to the prompt.
432 432
433 This may be overridden, but should not normally need to be; 433 This may be overridden, but should not normally need to be;
434 see the precmd() and postcmd() methods for useful execution hooks. 434 see the precmd() and postcmd() methods for useful execution hooks.
443 return self.emptyline() 443 return self.emptyline()
444 if not pyparsing.Or(self.commentGrammars).setParseAction(lambda x: '').transformString(line): 444 if not pyparsing.Or(self.commentGrammars).setParseAction(lambda x: '').transformString(line):
445 return 0 445 return 0
446 try: 446 try:
447 statement = self.parsed(line) 447 statement = self.parsed(line)
448 if assumeComplete: 448 while statement.parsed.multilineCommand and not statement.parsed.terminator:
449 if statement.parsed.multilineCommand and not statement.parsed.terminator: 449 statement = self.parsed('%s\n%s' % (statement.parsed.raw,
450 statement.parsed.terminator = self.terminators[0] 450 self.pseudo_raw_input(self.continuationPrompt)))
451 else:
452 while statement.parsed.multilineCommand and not statement.parsed.terminator:
453 statement = self.parsed('%s\n%s' % (statement.parsed.raw,
454 self.pseudo_raw_input(self.continuationPrompt)))
455 except Exception, e: 451 except Exception, e:
456 print e 452 print e
457 return 0 453 return 0
458 454
459 statekeeper = None 455 statekeeper = None
914 self.cmdapp = self.CmdApp() 910 self.cmdapp = self.CmdApp()
915 self.transcriptReader = TranscriptReader(self.cmdapp, self.transcriptFileName) 911 self.transcriptReader = TranscriptReader(self.cmdapp, self.transcriptFileName)
916 def testall(self): 912 def testall(self):
917 if self.CmdApp: 913 if self.CmdApp:
918 for (cmdInput, lineNum) in self.transcriptReader.inputGenerator(): 914 for (cmdInput, lineNum) in self.transcriptReader.inputGenerator():
919 self.cmdapp.onecmd(cmdInput, assumeComplete=True) 915 parsed = self.cmdapp.parsed(cmdInput)
916 if parsed.parsed.multilineCommand and not parsed.parsed.terminator:
917 cmdInput = cmdInput + self.cmdapp.terminators[0]
918 self.cmdapp.onecmd(cmdInput)
920 result = self.outputTrap.read() 919 result = self.outputTrap.read()
921 expected = self.transcriptReader.nextExpected() 920 expected = self.transcriptReader.nextExpected()
922 self.assertEqual(self.stripByLine(result), self.stripByLine(expected), 921 self.assertEqual(self.stripByLine(result), self.stripByLine(expected),
923 '\nFile %s, line %d\nCommand was:\n%s\nExpected:\n%s\nGot:\n%s\n' % 922 '\nFile %s, line %d\nCommand was:\n%s\nExpected:\n%s\nGot:\n%s\n' %
924 (self.transcriptFileName, lineNum, cmdInput, expected, result)) 923 (self.transcriptFileName, lineNum, cmdInput, expected, result))
924 #self.assertEqual(self.stripByLine(result), self.stripByLine(expected),
925 # '\nFile %s, line %d\nCommand was:\n%s\nExpected:\n%s\nGot:\n%s\n' %
926 # (self.transcriptFileName, lineNum, cmdInput, expected, result))
925 def stripByLine(self, s): 927 def stripByLine(self, s):
926 bareprompt = self.cmdapp.continuationPrompt.strip() 928 bareprompt = self.cmdapp.continuationPrompt.strip()
927 lines = [] 929 lines = []
928 for line in s.splitlines(): 930 for line in s.splitlines():
929 line = line.rstrip() 931 line = line.rstrip()