comparison cmd2.py @ 170:310ebf4baa7a

\n endings still squirrely; watch blank spaces in saved files
author catherine@dellzilla
date Wed, 10 Dec 2008 16:33:05 -0500
parents 429c8e984df4
children 0b93f1a4076c
comparison
equal deleted inserted replaced
169:429c8e984df4 170:310ebf4baa7a
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'
185 singleQuotedStrings = True 185 settable = ['prompt', 'continuationPrompt', 'defaultFileName', 'editor', 'caseInsensitive', 'echo']
186 doubleQuotedStrings = True
187 186
188 editor = os.environ.get('EDITOR') 187 editor = os.environ.get('EDITOR')
189 _STOP_AND_EXIT = 2 188 _STOP_AND_EXIT = 2
190 if not editor: 189 if not editor:
191 if sys.platform[:3] == 'win': 190 if sys.platform[:3] == 'win':
193 else: 192 else:
194 for editor in ['gedit', 'kate', 'vim', 'emacs', 'nano', 'pico']: 193 for editor in ['gedit', 'kate', 'vim', 'emacs', 'nano', 'pico']:
195 if not os.system('which %s' % (editor)): 194 if not os.system('which %s' % (editor)):
196 break 195 break
197 196
198 settable = ['prompt', 'continuationPrompt', 'defaultFileName', 'editor', 'caseInsensitive', 'echo']
199 def do_cmdenvironment(self, args): 197 def do_cmdenvironment(self, args):
200 self.stdout.write(""" 198 self.stdout.write("""
201 Commands are %(casesensitive)scase-sensitive. 199 Commands are %(casesensitive)scase-sensitive.
202 Commands may be terminated with: %(terminators)s 200 Commands may be terminated with: %(terminators)s
203 Settable parameters: %(settable)s 201 Settable parameters: %(settable)s
227 self.stdout.write("Single-key shortcuts for other commands:\n%s\n" % (result)) 225 self.stdout.write("Single-key shortcuts for other commands:\n%s\n" % (result))
228 226
229 commentGrammars = pyparsing.Or([pyparsing.pythonStyleComment, pyparsing.cStyleComment]) 227 commentGrammars = pyparsing.Or([pyparsing.pythonStyleComment, pyparsing.cStyleComment])
230 commentGrammars.addParseAction(lambda x: '') 228 commentGrammars.addParseAction(lambda x: '')
231 commentInProgress = pyparsing.Literal('/*') + pyparsing.SkipTo(pyparsing.stringEnd) 229 commentInProgress = pyparsing.Literal('/*') + pyparsing.SkipTo(pyparsing.stringEnd)
232 #quotedStringInProgress = pyparsing.Literal('"') ^ pyparsing.Literal("'") + pyparsing.SkipTo(pyparsing.lineEnd)
233 terminators = [';', '\n\n'] 230 terminators = [';', '\n\n']
234 multilineCommands = [] 231 multilineCommands = []
235 232
236 def _init_parser(self): 233 def _init_parser(self):
237 ''' 234 '''
381 multilineCommand = pyparsing.Or([pyparsing.Keyword(c, caseless=self.caseInsensitive) for c in self.multilineCommands])('multilineCommand') 378 multilineCommand = pyparsing.Or([pyparsing.Keyword(c, caseless=self.caseInsensitive) for c in self.multilineCommands])('multilineCommand')
382 oneLineCommand = pyparsing.Word(self.legalChars)('command') 379 oneLineCommand = pyparsing.Word(self.legalChars)('command')
383 pipe = pyparsing.Keyword('|', identChars='|') 380 pipe = pyparsing.Keyword('|', identChars='|')
384 self.commentGrammars.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).setParseAction(lambda x: '') 381 self.commentGrammars.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).setParseAction(lambda x: '')
385 self.commentInProgress.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(pyparsing.cStyleComment) 382 self.commentInProgress.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(pyparsing.cStyleComment)
386 #self.quotedStringInProgress.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString)
387 afterElements = \ 383 afterElements = \
388 pyparsing.Optional(pipe + pyparsing.SkipTo(outputParser ^ stringEnd)('pipeTo')) + \ 384 pyparsing.Optional(pipe + pyparsing.SkipTo(outputParser ^ stringEnd)('pipeTo')) + \
389 pyparsing.Optional(outputParser + pyparsing.SkipTo(stringEnd).setParseAction(lambda x: x[0].strip())('outputTo')) 385 pyparsing.Optional(outputParser + pyparsing.SkipTo(stringEnd).setParseAction(lambda x: x[0].strip())('outputTo'))
390 if self.caseInsensitive: 386 if self.caseInsensitive:
391 multilineCommand.setParseAction(lambda x: x[0].lower()) 387 multilineCommand.setParseAction(lambda x: x[0].lower())
392 oneLineCommand.setParseAction(lambda x: x[0].lower()) 388 oneLineCommand.setParseAction(lambda x: x[0].lower())
389 subparser1 = (((multilineCommand ^ oneLineCommand) + pyparsing.SkipTo(terminatorParser).setParseAction(lambda x: x[0].strip())('args') + terminatorParser)('statement') +
390 pyparsing.SkipTo(outputParser ^ pipe ^ stringEnd).setParseAction(lambda x: x[0].strip())('suffix') + afterElements)
391 subparser2 = ((oneLineCommand + pyparsing.SkipTo(terminatorParser ^ stringEnd ^ pipe ^ outputParser).setParseAction(lambda x:x[0].strip())('args'))('statement') +
392 pyparsing.Optional(terminatorParser) + afterElements)
393 self.parser = ( 393 self.parser = (
394 pyparsing.stringEnd 394 pyparsing.stringEnd
395 ^ 395 |
396 (((multilineCommand ^ oneLineCommand) + pyparsing.SkipTo(terminatorParser).setParseAction(lambda x: x[0].strip())('args') + terminatorParser)('statement') + 396 subparser1
397 pyparsing.SkipTo(outputParser ^ pipe ^ stringEnd).setParseAction(lambda x: x[0].strip())('suffix') + afterElements) 397 |
398 ^
399 multilineCommand + pyparsing.SkipTo(pyparsing.stringEnd) 398 multilineCommand + pyparsing.SkipTo(pyparsing.stringEnd)
400 ^ 399 |
401 ((oneLineCommand + pyparsing.SkipTo(terminatorParser ^ stringEnd ^ pipe ^ outputParser).setParseAction(lambda x:x[0].strip())('args'))('statement') + 400 subparser2
402 pyparsing.Optional(terminatorParser) + afterElements)
403 ) 401 )
404 self.parser.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(self.commentGrammars).ignore(self.commentInProgress) 402 self.parser.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(self.commentGrammars).ignore(self.commentInProgress)
405 403
406 inputMark = pyparsing.Literal('<') 404 inputMark = pyparsing.Literal('<')
407 inputMark.setParseAction(lambda x: '') 405 inputMark.setParseAction(lambda x: '')
412 410
413 def parsed(self, raw, **kwargs): 411 def parsed(self, raw, **kwargs):
414 if isinstance(raw, ParsedString): 412 if isinstance(raw, ParsedString):
415 p = raw 413 p = raw
416 else: 414 else:
417 s = self.inputParser.transformString(raw.strip()) # used to be raw.strip() 415 s = self.inputParser.transformString(raw) # used to be raw.strip()
418 for (shortcut, expansion) in self.shortcuts.items(): 416 for (shortcut, expansion) in self.shortcuts.items():
419 if s.startswith(shortcut): 417 if s.startswith(shortcut):
420 s = s.replace(shortcut, expansion + ' ', 1) 418 s = s.replace(shortcut, expansion + ' ', 1)
421 break 419 break
422 result = self.parser.parseString(s) 420 result = self.parser.parseString(s)
441 commands by the interpreter should stop. 439 commands by the interpreter should stop.
442 440
443 This (`cmd2`) version of `onecmd` already override's `cmd`'s `onecmd`. 441 This (`cmd2`) version of `onecmd` already override's `cmd`'s `onecmd`.
444 442
445 """ 443 """
446 line = line.strip() 444 #line = line.strip() # trying to allow proper \n\n endings
447 if not line: 445 if not line:
448 return self.emptyline() 446 return self.emptyline()
449 if not pyparsing.Or(self.commentGrammars).setParseAction(lambda x: '').transformString(line): 447 if not pyparsing.Or(self.commentGrammars).setParseAction(lambda x: '').transformString(line):
450 return 0 448 return 0
451 try: 449 try:
452 statement = self.parsed(line) 450 statement = self.parsed(line)
453 while statement.parsed.multilineCommand and not statement.parsed.terminator: 451 while statement.parsed.multilineCommand and (statement.parsed.terminator == ''):
454 statement = self.parsed('%s\n%s' % (statement.parsed.raw, 452 statement = self.parsed('%s\n%s' % (statement.parsed.raw,
455 self.pseudo_raw_input(self.continuationPrompt))) 453 self.pseudo_raw_input(self.continuationPrompt)))
456 except Exception, e: 454 except Exception, e:
457 print e 455 print e
458 return 0 456 return 0
916 self.transcriptReader = TranscriptReader(self.cmdapp, self.transcriptFileName) 914 self.transcriptReader = TranscriptReader(self.cmdapp, self.transcriptFileName)
917 def testall(self): 915 def testall(self):
918 if self.CmdApp: 916 if self.CmdApp:
919 for (cmdInput, lineNum) in self.transcriptReader.inputGenerator(): 917 for (cmdInput, lineNum) in self.transcriptReader.inputGenerator():
920 parsed = self.cmdapp.parsed(cmdInput) 918 parsed = self.cmdapp.parsed(cmdInput)
921 if parsed.parsed.multilineCommand and not parsed.parsed.terminator: 919 if parsed.parsed.multilineCommand and (parsed.parsed.terminator != ''):
922 cmdInput = cmdInput + self.cmdapp.terminators[0] 920 cmdInput = cmdInput + self.cmdapp.terminators[0]
923 self.cmdapp.onecmd(cmdInput) 921 self.cmdapp.onecmd(cmdInput)
924 result = self.outputTrap.read() 922 result = self.outputTrap.read()
925 expected = self.transcriptReader.nextExpected() 923 expected = self.transcriptReader.nextExpected()
926 self.assertEqual(self.stripByLine(result), self.stripByLine(expected), 924 self.assertEqual(self.stripByLine(result), self.stripByLine(expected),