Mercurial > python-cmd2
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() |