From 04cdcb0feb369ac4c60e10ccdc139c57e8b52e62 Mon Sep 17 00:00:00 2001 From: Zearin Date: Fri, 7 Oct 2011 10:34:23 -0400 Subject: Removed leftovers from installing with pip. Oops! I noticed there was a bunch of extra crap left over from when I installed this module onto my own system. I thought it wouldn't have modified itself at the time (just the Python module library on my system), but I was wrong. Begone, useless cruft! --- doxygen/html/cmd2_8py_source.html | 1721 ------------------------------------- 1 file changed, 1721 deletions(-) delete mode 100644 doxygen/html/cmd2_8py_source.html (limited to 'doxygen/html/cmd2_8py_source.html') diff --git a/doxygen/html/cmd2_8py_source.html b/doxygen/html/cmd2_8py_source.html deleted file mode 100644 index ab7ea18..0000000 --- a/doxygen/html/cmd2_8py_source.html +++ /dev/null @@ -1,1721 +0,0 @@ - - - - -Cmd2: /Users/amrogers/Developer/Projects/cmd2/cmd2.py Source File - - - - - - - - - - - - - - -
- - -
- - - - - - - - - - - -
-
Cmd2 - -
- -
-
- - - - - -
-
- -
-
-
- -
-
-
-
cmd2.py
-
-
-Go to the documentation of this file.
00001 """Variant on standard library's cmd with extra features.
-00002 
-00003 To use, simply import cmd2.Cmd instead of cmd.Cmd; use precisely as though you
-00004 were using the standard library's cmd, while enjoying the extra features.
-00005 
-00006 Searchable command history (commands: "hi", "li", "run")
-00007 Load commands from file, save to file, edit commands in file
-00008 Multi-line commands
-00009 Case-insensitive commands
-00010 Special-character shortcut commands (beyond cmd's "@" and "!")
-00011 Settable environment parameters
-00012 Optional _onchange_{paramname} called when environment parameter changes
-00013 Parsing commands with `optparse` options (flags)
-00014 Redirection to file with >, >>; input from file with <
-00015 Easy transcript-based testing of applications (see example/example.py)
-00016 Bash-style ``select`` available
-00017 
-00018 Note that redirection with > and | will only work if `self.stdout.write()`
-00019 is used in place of `print`.  The standard library's `cmd` module is 
-00020 written to use `self.stdout.write()`, 
-00021 
-00022 - Catherine Devlin, Jan 03 2008 - catherinedevlin.blogspot.com
-00023 
-00024 mercurial repository at http://www.assembla.com/wiki/show/python-cmd2
-00025 """
-00026 import cmd
-00027 import re
-00028 import os
-00029 import sys
-00030 import optparse
-00031 import subprocess
-00032 import tempfile
-00033 import doctest
-00034 import unittest
-00035 import datetime
-00036 import urllib
-00037 import glob
-00038 import traceback
-00039 import platform
-00040 import copy
-00041 from code import InteractiveConsole, InteractiveInterpreter
-00042 from optparse import make_option
-00043 import pyparsing
-00044 
-00045 __version__ = '0.6.4'
-00046 
-00047 if sys.version_info[0] == 2:
-00048     pyparsing.ParserElement.enablePackrat()
-00049 
-00050 """
-00051 Packrat is causing Python3 errors that I don't understand.
-00052 
-00053 > /usr/local/Cellar/python3/3.2/lib/python3.2/site-packages/pyparsing-1.5.6-py3.2.egg/pyparsing.py(999)scanString()
-00054 -> nextLoc,tokens = parseFn( instring, preloc, callPreParse=False )
-00055 (Pdb) n
-00056 NameError: global name 'exc' is not defined
-00057 
-00058 (Pdb) parseFn
-00059 <bound method Or._parseCache of {Python style comment ^ C style comment}>
-00060 
-00061 Bug report filed: https://sourceforge.net/tracker/?func=detail&atid=617311&aid=3381439&group_id=97203
-00062 """
-00063 
-00064 class OptionParser(optparse.OptionParser):
-00065     def exit(self, status=0, msg=None):
-00066         self.values._exit = True
-00067         if msg:
-00068             print (msg)
-00069             
-00070     def print_help(self, *args, **kwargs):
-00071         try:
-00072             print (self._func.__doc__)
-00073         except AttributeError:
-00074             pass
-00075         optparse.OptionParser.print_help(self, *args, **kwargs)
-00076 
-00077     def error(self, msg):
-00078         """error(msg : string)
-00079 
-00080         Print a usage message incorporating 'msg' to stderr and exit.
-00081         If you override this in a subclass, it should not return -- it
-00082         should either exit or raise an exception.
-00083         """
-00084         raise optparse.OptParseError(msg)
-00085         
-00086 def remaining_args(oldArgs, newArgList):
-00087     '''
-00088     Preserves the spacing originally in the argument after
-00089     the removal of options.
-00090     
-00091     >>> remaining_args('-f bar   bar   cow', ['bar', 'cow'])
-00092     'bar   cow'
-00093     '''
-00094     pattern = '\s+'.join(re.escape(a) for a in newArgList) + '\s*$'
-00095     matchObj = re.search(pattern, oldArgs)
-00096     return oldArgs[matchObj.start():]
-00097    
-00098 def _attr_get_(obj, attr):
-00099     '''Returns an attribute's value, or None (no error) if undefined.
-00100        Analagous to .get() for dictionaries.  Useful when checking for
-00101        value of options that may not have been defined on a given
-00102        method.'''
-00103     try:
-00104         return getattr(obj, attr)
-00105     except AttributeError:
-00106         return None
-00107     
-00108 optparse.Values.get = _attr_get_
-00109     
-00110 options_defined = [] # used to distinguish --options from SQL-style --comments
-00111 
-00112 def options(option_list, arg_desc="arg"):
-00113     '''Used as a decorator and passed a list of optparse-style options,
-00114        alters a cmd2 method to populate its ``opts`` argument from its
-00115        raw text argument.
-00116 
-00117        Example: transform
-00118        def do_something(self, arg):
-00119 
-00120        into
-00121        @options([make_option('-q', '--quick', action="store_true",
-00122                  help="Makes things fast")],
-00123                  "source dest")
-00124        def do_something(self, arg, opts):
-00125            if opts.quick:
-00126                self.fast_button = True
-00127        '''
-00128     if not isinstance(option_list, list):
-00129         option_list = [option_list]
-00130     for opt in option_list:
-00131         options_defined.append(pyparsing.Literal(opt.get_opt_string()))
-00132     def option_setup(func):
-00133         optionParser = OptionParser()
-00134         for opt in option_list:
-00135             optionParser.add_option(opt)
-00136         optionParser.set_usage("%s [options] %s" % (func.__name__[3:], arg_desc))
-00137         optionParser._func = func
-00138         def new_func(instance, arg):
-00139             try:
-00140                 opts, newArgList = optionParser.parse_args(arg.split())
-00141                 # Must find the remaining args in the original argument list, but 
-00142                 # mustn't include the command itself
-00143                 #if hasattr(arg, 'parsed') and newArgList[0] == arg.parsed.command:
-00144                 #    newArgList = newArgList[1:]
-00145                 newArgs = remaining_args(arg, newArgList)
-00146                 if isinstance(arg, ParsedString):
-00147                     arg = arg.with_args_replaced(newArgs)
-00148                 else:
-00149                     arg = newArgs
-00150             except optparse.OptParseError, e:
-00151                 print (e)
-00152                 optionParser.print_help()
-00153                 return
-00154             if hasattr(opts, '_exit'):
-00155                 return None
-00156             result = func(instance, arg, opts)                            
-00157             return result        
-00158         new_func.__doc__ = '%s\n%s' % (func.__doc__, optionParser.format_help())
-00159         return new_func
-00160     return option_setup
-00161 
-00162 class PasteBufferError(EnvironmentError):
-00163     if sys.platform[:3] == 'win':
-00164         errmsg = """Redirecting to or from paste buffer requires pywin32
-00165 to be installed on operating system.
-00166 Download from http://sourceforge.net/projects/pywin32/"""
-00167     elif sys.platform[:3] == 'dar':
-00168         # Use built in pbcopy on Mac OSX
-00169         pass
-00170     else:
-00171         errmsg = """Redirecting to or from paste buffer requires xclip 
-00172 to be installed on operating system.
-00173 On Debian/Ubuntu, 'sudo apt-get install xclip' will install it."""        
-00174     def __init__(self):
-00175         Exception.__init__(self, self.errmsg)
-00176 
-00177 pastebufferr = """Redirecting to or from paste buffer requires %s
-00178 to be installed on operating system.
-00179 %s"""
-00180 
-00181 if subprocess.mswindows:
-00182     try:
-00183         import win32clipboard
-00184         def get_paste_buffer():
-00185             win32clipboard.OpenClipboard(0)
-00186             try:
-00187                 result = win32clipboard.GetClipboardData()
-00188             except TypeError:
-00189                 result = ''  #non-text
-00190             win32clipboard.CloseClipboard()
-00191             return result            
-00192         def write_to_paste_buffer(txt):
-00193             win32clipboard.OpenClipboard(0)
-00194             win32clipboard.EmptyClipboard()
-00195             win32clipboard.SetClipboardText(txt)
-00196             win32clipboard.CloseClipboard()        
-00197     except ImportError:
-00198         def get_paste_buffer(*args):
-00199             raise OSError, pastebufferr % ('pywin32', 'Download from http://sourceforge.net/projects/pywin32/')
-00200         write_to_paste_buffer = get_paste_buffer
-00201 elif sys.platform == 'darwin':
-00202     can_clip = False
-00203     try:
-00204         # test for pbcopy - AFAIK, should always be installed on MacOS
-00205         subprocess.check_call('pbcopy -help', shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
-00206         can_clip = True
-00207     except (subprocess.CalledProcessError, OSError, IOError):
-00208         pass
-00209     if can_clip:
-00210         def get_paste_buffer():
-00211             pbcopyproc = subprocess.Popen('pbcopy -help', shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
-00212             return pbcopyproc.stdout.read()
-00213         def write_to_paste_buffer(txt):
-00214             pbcopyproc = subprocess.Popen('pbcopy', shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
-00215             pbcopyproc.communicate(txt.encode())
-00216     else:
-00217         def get_paste_buffer(*args):
-00218             raise OSError, pastebufferr % ('pbcopy', 'On MacOS X - error should not occur - part of the default installation')
-00219         write_to_paste_buffer = get_paste_buffer
-00220 else:
-00221     can_clip = False
-00222     try:
-00223         subprocess.check_call('xclip -o -sel clip', shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
-00224         can_clip = True
-00225     except AttributeError:  # check_call not defined, Python < 2.5
-00226         try:
-00227             teststring = 'Testing for presence of xclip.'
-00228             xclipproc = subprocess.Popen('xclip -sel clip', shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
-00229             xclipproc.stdin.write(teststring)
-00230             xclipproc.stdin.close()
-00231             xclipproc = subprocess.Popen('xclip -o -sel clip', shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)        
-00232             if xclipproc.stdout.read() == teststring:
-00233                 can_clip = True
-00234         except Exception: # hate a bare Exception call, but exception classes vary too much b/t stdlib versions
-00235             pass
-00236     except Exception:
-00237         pass # something went wrong with xclip and we cannot use it
-00238     if can_clip:    
-00239         def get_paste_buffer():
-00240             xclipproc = subprocess.Popen('xclip -o -sel clip', shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
-00241             return xclipproc.stdout.read()
-00242         def write_to_paste_buffer(txt):
-00243             xclipproc = subprocess.Popen('xclip -sel clip', shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
-00244             xclipproc.stdin.write(txt.encode())
-00245             xclipproc.stdin.close()
-00246             # but we want it in both the "primary" and "mouse" clipboards
-00247             xclipproc = subprocess.Popen('xclip', shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
-00248             xclipproc.stdin.write(txt.encode())
-00249             xclipproc.stdin.close()
-00250     else:
-00251         def get_paste_buffer(*args):
-00252             raise OSError, pastebufferr % ('xclip', 'On Debian/Ubuntu, install with "sudo apt-get install xclip"')
-00253         write_to_paste_buffer = get_paste_buffer
-00254           
-00255 pyparsing.ParserElement.setDefaultWhitespaceChars(' \t')
-00256 
-00257 class ParsedString(str):
-00258     def full_parsed_statement(self):
-00259         new = ParsedString('%s %s' % (self.parsed.command, self.parsed.args))
-00260         new.parsed = self.parsed
-00261         new.parser = self.parser
-00262         return new       
-00263     def with_args_replaced(self, newargs):
-00264         new = ParsedString(newargs)
-00265         new.parsed = self.parsed
-00266         new.parser = self.parser
-00267         new.parsed['args'] = newargs
-00268         new.parsed.statement['args'] = newargs
-00269         return new
-00270         
-00271 class StubbornDict(dict):
-00272     '''Dictionary that tolerates many input formats.
-00273     Create it with stubbornDict(arg) factory function.
-00274     
-00275     >>> d = StubbornDict(large='gross', small='klein')
-00276     >>> sorted(d.items())
-00277     [('large', 'gross'), ('small', 'klein')]
-00278     >>> d.append(['plain', '  plaid'])
-00279     >>> sorted(d.items())
-00280     [('large', 'gross'), ('plaid', ''), ('plain', ''), ('small', 'klein')]
-00281     >>> d += '   girl Frauelein, Maedchen\\n\\n shoe schuh'
-00282     >>> sorted(d.items())
-00283     [('girl', 'Frauelein, Maedchen'), ('large', 'gross'), ('plaid', ''), ('plain', ''), ('shoe', 'schuh'), ('small', 'klein')]
-00284     '''    
-00285     def update(self, arg):
-00286         dict.update(self, StubbornDict.to_dict(arg))
-00287     append = update
-00288     def __iadd__(self, arg):
-00289         self.update(arg)
-00290         return self
-00291     def __add__(self, arg):
-00292         selfcopy = copy.copy(self)
-00293         selfcopy.update(stubbornDict(arg))
-00294         return selfcopy
-00295     def __radd__(self, arg):
-00296         selfcopy = copy.copy(self)
-00297         selfcopy.update(stubbornDict(arg))
-00298         return selfcopy    
-00299         
-00300     @classmethod
-00301     def to_dict(cls, arg):
-00302         'Generates dictionary from string or list of strings'
-00303         if hasattr(arg, 'splitlines'):
-00304             arg = arg.splitlines()
-00305         if hasattr(arg, '__reversed__'):
-00306             result = {}    
-00307             for a in arg:
-00308                 a = a.strip()
-00309                 if a:
-00310                     key_val = a.split(None, 1)
-00311                     key = key_val[0]
-00312                     if len(key_val) > 1:
-00313                         val = key_val[1]
-00314                     else:
-00315                         val = ''
-00316                     result[key] = val
-00317         else:
-00318             result = arg
-00319         return result
-00320 
-00321 def stubbornDict(*arg, **kwarg):
-00322     '''
-00323     >>> sorted(stubbornDict('cow a bovine\\nhorse an equine').items())
-00324     [('cow', 'a bovine'), ('horse', 'an equine')]
-00325     >>> sorted(stubbornDict(['badger', 'porcupine a poky creature']).items())
-00326     [('badger', ''), ('porcupine', 'a poky creature')]
-00327     >>> sorted(stubbornDict(turtle='has shell', frog='jumpy').items())
-00328     [('frog', 'jumpy'), ('turtle', 'has shell')]
-00329     '''
-00330     result = {}
-00331     for a in arg:
-00332         result.update(StubbornDict.to_dict(a))
-00333     result.update(kwarg)                      
-00334     return StubbornDict(result)
-00335         
-00336 def replace_with_file_contents(fname):
-00337     if fname:
-00338         try:
-00339             result = open(os.path.expanduser(fname[0])).read()
-00340         except IOError:
-00341             result = '< %s' % fname[0]  # wasn't a file after all
-00342     else:
-00343         result = get_paste_buffer()
-00344     return result      
-00345 
-00346 class EmbeddedConsoleExit(SystemExit):
-00347     pass
-00348 
-00349 class EmptyStatement(Exception):
-00350     pass
-00351 
-00352 def ljust(x, width, fillchar=' '):
-00353     'analogous to str.ljust, but works for lists'
-00354     if hasattr(x, 'ljust'):
-00355         return x.ljust(width, fillchar)
-00356     else:
-00357         if len(x) < width:
-00358             x = (x + [fillchar] * width)[:width]
-00359         return x
-00360     
-00361 class Cmd(cmd.Cmd):
-00362     echo = False
-00363     case_insensitive = True     # Commands recognized regardless of case
-00364     continuation_prompt = '> '  
-00365     timing = False              # Prints elapsed time for each command
-00366     # make sure your terminators are not in legalChars!
-00367     legalChars = u'!#$%.:?@_' + pyparsing.alphanums + pyparsing.alphas8bit
-00368     shortcuts = {'?': 'help', '!': 'shell', '@': 'load', '@@': '_relative_load'}
-00369     excludeFromHistory = '''run r list l history hi ed edit li eof'''.split()
-00370     default_to_shell = False
-00371     noSpecialParse = 'set ed edit exit'.split()
-00372     defaultExtension = 'txt'            # For ``save``, ``load``, etc.
-00373     default_file_name = 'command.txt'   # For ``save``, ``load``, etc.
-00374     abbrev = True                       # Abbreviated commands recognized
-00375     current_script_dir = None
-00376     reserved_words = []
-00377     feedback_to_output = False          # Do include nonessentials in >, | output
-00378     quiet = False                       # Do not suppress nonessential output
-00379     debug = False
-00380     locals_in_py = True
-00381     kept_state = None
-00382     redirector = '>'                    # for sending output to file
-00383     settable = stubbornDict('''
-00384         prompt
-00385         colors                Colorized output (*nix only)
-00386         continuation_prompt   On 2nd+ line of input
-00387         debug                 Show full error stack on error
-00388         default_file_name     for ``save``, ``load``, etc.
-00389         editor                Program used by ``edit``  
-00390         case_insensitive      upper- and lower-case both OK
-00391         feedback_to_output    include nonessentials in `|`, `>` results 
-00392         quiet                 Don't print nonessential feedback
-00393         echo                  Echo command issued into output
-00394         timing                Report execution times
-00395         abbrev                Accept abbreviated commands
-00396         ''')
-00397     
-00398     def poutput(self, msg):
-00399         '''Convenient shortcut for self.stdout.write(); adds newline if necessary.'''
-00400         if msg:
-00401             self.stdout.write(msg)
-00402             if msg[-1] != '\n':
-00403                 self.stdout.write('\n')
-00404     def perror(self, errmsg, statement=None):
-00405         if self.debug:
-00406             traceback.print_exc()
-00407         print (str(errmsg))
-00408     def pfeedback(self, msg):
-00409         """For printing nonessential feedback.  Can be silenced with `quiet`.
-00410            Inclusion in redirected output is controlled by `feedback_to_output`."""
-00411         if not self.quiet:
-00412             if self.feedback_to_output:
-00413                 self.poutput(msg)
-00414             else:
-00415                 print (msg)
-00416     _STOP_AND_EXIT = True  # distinguish end of script file from actual exit
-00417     _STOP_SCRIPT_NO_EXIT = -999
-00418     editor = os.environ.get('EDITOR')
-00419     if not editor:
-00420         if sys.platform[:3] == 'win':
-00421             editor = 'notepad'
-00422         else:
-00423             for editor in ['gedit', 'kate', 'vim', 'emacs', 'nano', 'pico']:
-00424                 if subprocess.Popen(['which', editor], stdout=subprocess.PIPE).communicate()[0]:
-00425                     break
-00426 
-00427     colorcodes =    {'bold':{True:'\x1b[1m',False:'\x1b[22m'},
-00428                   'cyan':{True:'\x1b[36m',False:'\x1b[39m'},
-00429                   'blue':{True:'\x1b[34m',False:'\x1b[39m'},
-00430                   'red':{True:'\x1b[31m',False:'\x1b[39m'},
-00431                   'magenta':{True:'\x1b[35m',False:'\x1b[39m'},
-00432                   'green':{True:'\x1b[32m',False:'\x1b[39m'},
-00433                   'underline':{True:'\x1b[4m',False:'\x1b[24m'}}
-00434     colors = (platform.system() != 'Windows')
-00435     def colorize(self, val, color):
-00436         '''Given a string (``val``), returns that string wrapped in UNIX-style 
-00437            special characters that turn on (and then off) text color and style.
-00438            If the ``colors`` environment paramter is ``False``, or the application
-00439            is running on Windows, will return ``val`` unchanged.
-00440            ``color`` should be one of the supported strings (or styles):
-00441            red/blue/green/cyan/magenta, bold, underline'''
-00442         if self.colors and (self.stdout == self.initial_stdout):
-00443             return self.colorcodes[color][True] + val + self.colorcodes[color][False]
-00444         return val
-00445 
-00446     def do_cmdenvironment(self, args):
-00447         '''Summary report of interactive parameters.'''
-00448         self.stdout.write("""
-00449         Commands are %(casesensitive)scase-sensitive.
-00450         Commands may be terminated with: %(terminators)s
-00451         Settable parameters: %(settable)s\n""" % \
-00452         { 'casesensitive': (self.case_insensitive and 'not ') or '',
-00453           'terminators': str(self.terminators),
-00454           'settable': ' '.join(self.settable)
-00455         })
-00456         
-00457     def do_help(self, arg):
-00458         if arg:
-00459             funcname = self.func_named(arg)
-00460             if funcname:
-00461                 fn = getattr(self, funcname)
-00462                 try:
-00463                     fn.optionParser.print_help(file=self.stdout)
-00464                 except AttributeError:
-00465                     cmd.Cmd.do_help(self, funcname[3:])
-00466         else:
-00467             cmd.Cmd.do_help(self, arg)
-00468         
-00469     def __init__(self, *args, **kwargs):        
-00470         cmd.Cmd.__init__(self, *args, **kwargs)
-00471         self.initial_stdout = sys.stdout
-00472         self.history = History()
-00473         self.pystate = {}
-00474         self.shortcuts = sorted(self.shortcuts.items(), reverse=True)
-00475         self.keywords = self.reserved_words + [fname[3:] for fname in dir(self) 
-00476                                                if fname.startswith('do_')]            
-00477         self._init_parser()
-00478             
-00479     def do_shortcuts(self, args):
-00480         """Lists single-key shortcuts available."""
-00481         result = "\n".join('%s: %s' % (sc[0], sc[1]) for sc in sorted(self.shortcuts))
-00482         self.stdout.write("Single-key shortcuts for other commands:\n%s\n" % (result))
-00483 
-00484     prefixParser = pyparsing.Empty()
-00485     commentGrammars = pyparsing.Or([pyparsing.pythonStyleComment, pyparsing.cStyleComment])
-00486     commentGrammars.addParseAction(lambda x: '')
-00487     commentInProgress  = pyparsing.Literal('/*') + pyparsing.SkipTo(
-00488         pyparsing.stringEnd ^ '*/')
-00489     terminators = [';']
-00490     blankLinesAllowed = False
-00491     multilineCommands = []
-00492     
-00493     def _init_parser(self):
-00494         r'''
-00495         >>> c = Cmd()
-00496         >>> c.multilineCommands = ['multiline']
-00497         >>> c.case_insensitive = True
-00498         >>> c._init_parser()
-00499         >>> print (c.parser.parseString('').dump())
-00500         []
-00501         >>> print (c.parser.parseString('').dump())
-00502         []        
-00503         >>> print (c.parser.parseString('/* empty command */').dump())
-00504         []        
-00505         >>> print (c.parser.parseString('plainword').dump())
-00506         ['plainword', '']
-00507         - command: plainword
-00508         - statement: ['plainword', '']
-00509           - command: plainword        
-00510         >>> print (c.parser.parseString('termbare;').dump())
-00511         ['termbare', '', ';', '']
-00512         - command: termbare
-00513         - statement: ['termbare', '', ';']
-00514           - command: termbare
-00515           - terminator: ;
-00516         - terminator: ;        
-00517         >>> print (c.parser.parseString('termbare; suffx').dump())
-00518         ['termbare', '', ';', 'suffx']
-00519         - command: termbare
-00520         - statement: ['termbare', '', ';']
-00521           - command: termbare
-00522           - terminator: ;
-00523         - suffix: suffx
-00524         - terminator: ;        
-00525         >>> print (c.parser.parseString('barecommand').dump())
-00526         ['barecommand', '']
-00527         - command: barecommand
-00528         - statement: ['barecommand', '']
-00529           - command: barecommand
-00530         >>> print (c.parser.parseString('COMmand with args').dump())
-00531         ['command', 'with args']
-00532         - args: with args
-00533         - command: command
-00534         - statement: ['command', 'with args']
-00535           - args: with args
-00536           - command: command
-00537         >>> print (c.parser.parseString('command with args and terminator; and suffix').dump())
-00538         ['command', 'with args and terminator', ';', 'and suffix']
-00539         - args: with args and terminator
-00540         - command: command
-00541         - statement: ['command', 'with args and terminator', ';']
-00542           - args: with args and terminator
-00543           - command: command
-00544           - terminator: ;
-00545         - suffix: and suffix
-00546         - terminator: ;
-00547         >>> print (c.parser.parseString('simple | piped').dump())
-00548         ['simple', '', '|', ' piped']
-00549         - command: simple
-00550         - pipeTo:  piped
-00551         - statement: ['simple', '']
-00552           - command: simple
-00553         >>> print (c.parser.parseString('double-pipe || is not a pipe').dump())
-00554         ['double', '-pipe || is not a pipe']
-00555         - args: -pipe || is not a pipe
-00556         - command: double
-00557         - statement: ['double', '-pipe || is not a pipe']
-00558           - args: -pipe || is not a pipe
-00559           - command: double
-00560         >>> print (c.parser.parseString('command with args, terminator;sufx | piped').dump())
-00561         ['command', 'with args, terminator', ';', 'sufx', '|', ' piped']
-00562         - args: with args, terminator
-00563         - command: command
-00564         - pipeTo:  piped
-00565         - statement: ['command', 'with args, terminator', ';']
-00566           - args: with args, terminator
-00567           - command: command
-00568           - terminator: ;
-00569         - suffix: sufx
-00570         - terminator: ;
-00571         >>> print (c.parser.parseString('output into > afile.txt').dump())
-00572         ['output', 'into', '>', 'afile.txt']
-00573         - args: into
-00574         - command: output
-00575         - output: >
-00576         - outputTo: afile.txt
-00577         - statement: ['output', 'into']
-00578           - args: into
-00579           - command: output   
-00580         >>> print (c.parser.parseString('output into;sufx | pipethrume plz > afile.txt').dump())
-00581         ['output', 'into', ';', 'sufx', '|', ' pipethrume plz', '>', 'afile.txt']
-00582         - args: into
-00583         - command: output
-00584         - output: >
-00585         - outputTo: afile.txt
-00586         - pipeTo:  pipethrume plz
-00587         - statement: ['output', 'into', ';']
-00588           - args: into
-00589           - command: output
-00590           - terminator: ;
-00591         - suffix: sufx
-00592         - terminator: ;
-00593         >>> print (c.parser.parseString('output to paste buffer >> ').dump())
-00594         ['output', 'to paste buffer', '>>', '']
-00595         - args: to paste buffer
-00596         - command: output
-00597         - output: >>
-00598         - statement: ['output', 'to paste buffer']
-00599           - args: to paste buffer
-00600           - command: output
-00601         >>> print (c.parser.parseString('ignore the /* commented | > */ stuff;').dump())
-00602         ['ignore', 'the /* commented | > */ stuff', ';', '']
-00603         - args: the /* commented | > */ stuff
-00604         - command: ignore
-00605         - statement: ['ignore', 'the /* commented | > */ stuff', ';']
-00606           - args: the /* commented | > */ stuff
-00607           - command: ignore
-00608           - terminator: ;
-00609         - terminator: ;
-00610         >>> print (c.parser.parseString('has > inside;').dump())
-00611         ['has', '> inside', ';', '']
-00612         - args: > inside
-00613         - command: has
-00614         - statement: ['has', '> inside', ';']
-00615           - args: > inside
-00616           - command: has
-00617           - terminator: ;
-00618         - terminator: ;        
-00619         >>> print (c.parser.parseString('multiline has > inside an unfinished command').dump())
-00620         ['multiline', ' has > inside an unfinished command']
-00621         - multilineCommand: multiline        
-00622         >>> print (c.parser.parseString('multiline has > inside;').dump())
-00623         ['multiline', 'has > inside', ';', '']
-00624         - args: has > inside
-00625         - multilineCommand: multiline
-00626         - statement: ['multiline', 'has > inside', ';']
-00627           - args: has > inside
-00628           - multilineCommand: multiline
-00629           - terminator: ;
-00630         - terminator: ;        
-00631         >>> print (c.parser.parseString('multiline command /* with comment in progress;').dump())
-00632         ['multiline', ' command /* with comment in progress;']
-00633         - multilineCommand: multiline
-00634         >>> print (c.parser.parseString('multiline command /* with comment complete */ is done;').dump())
-00635         ['multiline', 'command /* with comment complete */ is done', ';', '']
-00636         - args: command /* with comment complete */ is done
-00637         - multilineCommand: multiline
-00638         - statement: ['multiline', 'command /* with comment complete */ is done', ';']
-00639           - args: command /* with comment complete */ is done
-00640           - multilineCommand: multiline
-00641           - terminator: ;
-00642         - terminator: ;
-00643         >>> print (c.parser.parseString('multiline command ends\n\n').dump())
-00644         ['multiline', 'command ends', '\n', '\n']
-00645         - args: command ends
-00646         - multilineCommand: multiline
-00647         - statement: ['multiline', 'command ends', '\n', '\n']
-00648           - args: command ends
-00649           - multilineCommand: multiline
-00650           - terminator: ['\n', '\n']
-00651         - terminator: ['\n', '\n']
-00652         >>> print (c.parser.parseString('multiline command "with term; ends" now\n\n').dump())
-00653         ['multiline', 'command "with term; ends" now', '\n', '\n']
-00654         - args: command "with term; ends" now
-00655         - multilineCommand: multiline
-00656         - statement: ['multiline', 'command "with term; ends" now', '\n', '\n']
-00657           - args: command "with term; ends" now
-00658           - multilineCommand: multiline
-00659           - terminator: ['\n', '\n']
-00660         - terminator: ['\n', '\n']
-00661         >>> print (c.parser.parseString('what if "quoted strings /* seem to " start comments?').dump())
-00662         ['what', 'if "quoted strings /* seem to " start comments?']
-00663         - args: if "quoted strings /* seem to " start comments?
-00664         - command: what
-00665         - statement: ['what', 'if "quoted strings /* seem to " start comments?']
-00666           - args: if "quoted strings /* seem to " start comments?
-00667           - command: what
-00668         '''
-00669         #outputParser = (pyparsing.Literal('>>') | (pyparsing.WordStart() + '>') | pyparsing.Regex('[^=]>'))('output')
-00670         outputParser = (pyparsing.Literal(self.redirector *2) | \
-00671                        (pyparsing.WordStart() + self.redirector) | \
-00672                         pyparsing.Regex('[^=]' + self.redirector))('output')
-00673         
-00674         terminatorParser = pyparsing.Or([(hasattr(t, 'parseString') and t) or pyparsing.Literal(t) for t in self.terminators])('terminator')
-00675         stringEnd = pyparsing.stringEnd ^ '\nEOF'
-00676         self.multilineCommand = pyparsing.Or([pyparsing.Keyword(c, caseless=self.case_insensitive) for c in self.multilineCommands])('multilineCommand')
-00677         oneLineCommand = (~self.multilineCommand + pyparsing.Word(self.legalChars))('command')
-00678         pipe = pyparsing.Keyword('|', identChars='|')
-00679         self.commentGrammars.ignore(pyparsing.quotedString).setParseAction(lambda x: '')
-00680         doNotParse = self.commentGrammars | self.commentInProgress | pyparsing.quotedString
-00681         afterElements = \
-00682             pyparsing.Optional(pipe + pyparsing.SkipTo(outputParser ^ stringEnd, ignore=doNotParse)('pipeTo')) + \
-00683             pyparsing.Optional(outputParser + pyparsing.SkipTo(stringEnd, ignore=doNotParse).setParseAction(lambda x: x[0].strip())('outputTo'))
-00684         if self.case_insensitive:
-00685             self.multilineCommand.setParseAction(lambda x: x[0].lower())
-00686             oneLineCommand.setParseAction(lambda x: x[0].lower())
-00687         if self.blankLinesAllowed:
-00688             self.blankLineTerminationParser = pyparsing.NoMatch
-00689         else:
-00690             self.blankLineTerminator = (pyparsing.lineEnd + pyparsing.lineEnd)('terminator')
-00691             self.blankLineTerminator.setResultsName('terminator')
-00692             self.blankLineTerminationParser = ((self.multilineCommand ^ oneLineCommand) + pyparsing.SkipTo(self.blankLineTerminator, ignore=doNotParse).setParseAction(lambda x: x[0].strip())('args') + self.blankLineTerminator)('statement')
-00693         self.multilineParser = (((self.multilineCommand ^ oneLineCommand) + pyparsing.SkipTo(terminatorParser, ignore=doNotParse).setParseAction(lambda x: x[0].strip())('args') + terminatorParser)('statement') +
-00694                                 pyparsing.SkipTo(outputParser ^ pipe ^ stringEnd, ignore=doNotParse).setParseAction(lambda x: x[0].strip())('suffix') + afterElements)
-00695         self.multilineParser.ignore(self.commentInProgress)
-00696         self.singleLineParser = ((oneLineCommand + pyparsing.SkipTo(terminatorParser ^ stringEnd ^ pipe ^ outputParser, ignore=doNotParse).setParseAction(lambda x:x[0].strip())('args'))('statement') +
-00697                                  pyparsing.Optional(terminatorParser) + afterElements)
-00698         #self.multilineParser = self.multilineParser.setResultsName('multilineParser')
-00699         #self.singleLineParser = self.singleLineParser.setResultsName('singleLineParser')
-00700         self.blankLineTerminationParser = self.blankLineTerminationParser.setResultsName('statement')
-00701         self.parser = self.prefixParser + (
-00702             stringEnd |
-00703             self.multilineParser |
-00704             self.singleLineParser |
-00705             self.blankLineTerminationParser | 
-00706             self.multilineCommand + pyparsing.SkipTo(stringEnd, ignore=doNotParse)
-00707             )
-00708         self.parser.ignore(self.commentGrammars)
-00709         
-00710         inputMark = pyparsing.Literal('<')
-00711         inputMark.setParseAction(lambda x: '')
-00712         fileName = pyparsing.Word(self.legalChars + '/\\')
-00713         inputFrom = fileName('inputFrom')
-00714         inputFrom.setParseAction(replace_with_file_contents)
-00715         # a not-entirely-satisfactory way of distinguishing < as in "import from" from <
-00716         # as in "lesser than"
-00717         self.inputParser = inputMark + pyparsing.Optional(inputFrom) + pyparsing.Optional('>') + \
-00718                            pyparsing.Optional(fileName) + (pyparsing.stringEnd | '|')
-00719         self.inputParser.ignore(self.commentInProgress)               
-00720     
-00721     def preparse(self, raw, **kwargs):
-00722         return raw
-00723     def postparse(self, parseResult):
-00724         return parseResult
-00725    
-00726     def parsed(self, raw, **kwargs):
-00727         if isinstance(raw, ParsedString):
-00728             p = raw
-00729         else:
-00730             # preparse is an overridable hook; default makes no changes
-00731             s = self.preparse(raw, **kwargs)
-00732             s = self.inputParser.transformString(s.lstrip())
-00733             s = self.commentGrammars.transformString(s)
-00734             for (shortcut, expansion) in self.shortcuts:
-00735                 if s.lower().startswith(shortcut):
-00736                     s = s.replace(shortcut, expansion + ' ', 1)
-00737                     break
-00738             result = self.parser.parseString(s)
-00739             result['raw'] = raw            
-00740             result['command'] = result.multilineCommand or result.command        
-00741             result = self.postparse(result)
-00742             p = ParsedString(result.args)
-00743             p.parsed = result
-00744             p.parser = self.parsed
-00745         for (key, val) in kwargs.items():
-00746             p.parsed[key] = val
-00747         return p
-00748               
-00749     def postparsing_precmd(self, statement):
-00750         stop = 0
-00751         return stop, statement
-00752     def postparsing_postcmd(self, stop):
-00753         return stop
-00754     
-00755     def func_named(self, arg):
-00756         result = None
-00757         target = 'do_' + arg
-00758         if target in dir(self):
-00759             result = target
-00760         else:
-00761             if self.abbrev:   # accept shortened versions of commands
-00762                 funcs = [fname for fname in self.keywords if fname.startswith(arg)]
-00763                 if len(funcs) == 1:
-00764                     result = 'do_' + funcs[0]
-00765         return result
-00766     def onecmd_plus_hooks(self, line):
-00767         # The outermost level of try/finally nesting can be condensed once
-00768         # Python 2.4 support can be dropped.
-00769         stop = 0
-00770         try:
-00771             try:
-00772                 statement = self.complete_statement(line)
-00773                 (stop, statement) = self.postparsing_precmd(statement)
-00774                 if stop:
-00775                     return self.postparsing_postcmd(stop)
-00776                 if statement.parsed.command not in self.excludeFromHistory:
-00777                     self.history.append(statement.parsed.raw)      
-00778                 try:
-00779                     self.redirect_output(statement)
-00780                     timestart = datetime.datetime.now()
-00781                     statement = self.precmd(statement)
-00782                     stop = self.onecmd(statement)
-00783                     stop = self.postcmd(stop, statement)
-00784                     if self.timing:
-00785                         self.pfeedback('Elapsed: %s' % str(datetime.datetime.now() - timestart))
-00786                 finally:
-00787                     self.restore_output(statement)
-00788             except EmptyStatement:
-00789                 return 0
-00790             except Exception, e:
-00791                 self.perror(str(e), statement)            
-00792         finally:
-00793             return self.postparsing_postcmd(stop)        
-00794     def complete_statement(self, line):
-00795         """Keep accepting lines of input until the command is complete."""
-00796         if (not line) or (
-00797             not pyparsing.Or(self.commentGrammars).
-00798                 setParseAction(lambda x: '').transformString(line)):
-00799             raise EmptyStatement
-00800         statement = self.parsed(line)
-00801         while statement.parsed.multilineCommand and (statement.parsed.terminator == ''):
-00802             statement = '%s\n%s' % (statement.parsed.raw, 
-00803                                     self.pseudo_raw_input(self.continuation_prompt))                
-00804             statement = self.parsed(statement)
-00805         if not statement.parsed.command:
-00806             raise EmptyStatement
-00807         return statement
-00808     
-00809     def redirect_output(self, statement):
-00810         if statement.parsed.pipeTo:
-00811             self.kept_state = Statekeeper(self, ('stdout',))
-00812             self.kept_sys = Statekeeper(sys, ('stdout',))
-00813             self.redirect = subprocess.Popen(statement.parsed.pipeTo, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
-00814             sys.stdout = self.stdout = self.redirect.stdin
-00815         elif statement.parsed.output:
-00816             if (not statement.parsed.outputTo) and (not can_clip):
-00817                 raise EnvironmentError('Cannot redirect to paste buffer; install ``xclip`` and re-run to enable')
-00818             self.kept_state = Statekeeper(self, ('stdout',))            
-00819             self.kept_sys = Statekeeper(sys, ('stdout',))
-00820             if statement.parsed.outputTo:
-00821                 mode = 'w'
-00822                 if statement.parsed.output == 2 * self.redirector:
-00823                     mode = 'a'
-00824                 sys.stdout = self.stdout = open(os.path.expanduser(statement.parsed.outputTo), mode)                            
-00825             else:
-00826                 sys.stdout = self.stdout = tempfile.TemporaryFile(mode="w+")
-00827                 if statement.parsed.output == '>>':
-00828                     self.stdout.write(get_paste_buffer())
-00829                     
-00830     def restore_output(self, statement):
-00831         if self.kept_state:
-00832             if statement.parsed.output:
-00833                 if not statement.parsed.outputTo:
-00834                     self.stdout.seek(0)
-00835                     write_to_paste_buffer(self.stdout.read())
-00836             elif statement.parsed.pipeTo:
-00837                 for result in self.redirect.communicate():              
-00838                     self.kept_state.stdout.write(result or '')                        
-00839             self.stdout.close()
-00840             self.kept_state.restore()  
-00841             self.kept_sys.restore()
-00842             self.kept_state = None                        
-00843                         
-00844     def onecmd(self, line):
-00845         """Interpret the argument as though it had been typed in response
-00846         to the prompt.
-00847 
-00848         This may be overridden, but should not normally need to be;
-00849         see the precmd() and postcmd() methods for useful execution hooks.
-00850         The return value is a flag indicating whether interpretation of
-00851         commands by the interpreter should stop.
-00852         
-00853         This (`cmd2`) version of `onecmd` already override's `cmd`'s `onecmd`.
-00854 
-00855         """
-00856         statement = self.parsed(line)
-00857         self.lastcmd = statement.parsed.raw   
-00858         funcname = self.func_named(statement.parsed.command)
-00859         if not funcname:
-00860             return self._default(statement)
-00861         try:
-00862             func = getattr(self, funcname)
-00863         except AttributeError:
-00864             return self._default(statement)
-00865         stop = func(statement) 
-00866         return stop                
-00867         
-00868     def _default(self, statement):
-00869         arg = statement.full_parsed_statement()
-00870         if self.default_to_shell:
-00871             result = os.system(arg)
-00872             if not result:
-00873                 return self.postparsing_postcmd(None)
-00874         return self.postparsing_postcmd(self.default(arg))
-00875 
-00876     def pseudo_raw_input(self, prompt):
-00877         """copied from cmd's cmdloop; like raw_input, but accounts for changed stdin, stdout"""
-00878         
-00879         if self.use_rawinput:
-00880             try:
-00881                 line = raw_input(prompt)
-00882             except EOFError:
-00883                 line = 'EOF'
-00884         else:
-00885             self.stdout.write(prompt)
-00886             self.stdout.flush()
-00887             line = self.stdin.readline()
-00888             if not len(line):
-00889                 line = 'EOF'
-00890             else:
-00891                 if line[-1] == '\n': # this was always true in Cmd
-00892                     line = line[:-1] 
-00893         return line
-00894     
-00895     def _cmdloop(self, intro=None):
-00896         """Repeatedly issue a prompt, accept input, parse an initial prefix
-00897         off the received input, and dispatch to action methods, passing them
-00898         the remainder of the line as argument.
-00899         """
-00900 
-00901         # An almost perfect copy from Cmd; however, the pseudo_raw_input portion
-00902         # has been split out so that it can be called separately
-00903         
-00904         self.preloop()
-00905         if self.use_rawinput and self.completekey:
-00906             try:
-00907                 import readline
-00908                 self.old_completer = readline.get_completer()
-00909                 readline.set_completer(self.complete)
-00910                 readline.parse_and_bind(self.completekey+": complete")
-00911             except ImportError:
-00912                 pass
-00913         try:
-00914             if intro is not None:
-00915                 self.intro = intro
-00916             if self.intro:
-00917                 self.stdout.write(str(self.intro)+"\n")
-00918             stop = None
-00919             while not stop:
-00920                 if self.cmdqueue:
-00921                     line = self.cmdqueue.pop(0)
-00922                 else:
-00923                     line = self.pseudo_raw_input(self.prompt)
-00924                 if (self.echo) and (isinstance(self.stdin, file)):
-00925                     self.stdout.write(line + '\n')
-00926                 stop = self.onecmd_plus_hooks(line)
-00927             self.postloop()
-00928         finally:
-00929             if self.use_rawinput and self.completekey:
-00930                 try:
-00931                     import readline
-00932                     readline.set_completer(self.old_completer)
-00933                 except ImportError:
-00934                     pass    
-00935             return stop
-00936 
-00937     def do_EOF(self, arg):
-00938         return self._STOP_SCRIPT_NO_EXIT # End of script; should not exit app
-00939     do_eof = do_EOF
-00940                            
-00941     def do_quit(self, arg):
-00942         return self._STOP_AND_EXIT
-00943     do_exit = do_quit
-00944     do_q = do_quit
-00945     
-00946     def select(self, options, prompt='Your choice? '):
-00947         '''Presents a numbered menu to the user.  Modelled after
-00948            the bash shell's SELECT.  Returns the item chosen.
-00949            
-00950            Argument ``options`` can be:
-00951 
-00952              | a single string -> will be split into one-word options
-00953              | a list of strings -> will be offered as options
-00954              | a list of tuples -> interpreted as (value, text), so 
-00955                                    that the return value can differ from
-00956                                    the text advertised to the user '''
-00957         if isinstance(options, basestring):
-00958             options = zip(options.split(), options.split())
-00959         fulloptions = []
-00960         for opt in options:
-00961             if isinstance(opt, basestring):
-00962                 fulloptions.append((opt, opt))
-00963             else:
-00964                 try:
-00965                     fulloptions.append((opt[0], opt[1]))
-00966                 except IndexError:
-00967                     fulloptions.append((opt[0], opt[0]))
-00968         for (idx, (value, text)) in enumerate(fulloptions):
-00969             self.poutput('  %2d. %s\n' % (idx+1, text))
-00970         while True:
-00971             response = raw_input(prompt)
-00972             try:
-00973                 response = int(response)
-00974                 result = fulloptions[response - 1][0]
-00975                 break
-00976             except ValueError:
-00977                 pass # loop and ask again
-00978         return result
-00979     
-00980     @options([make_option('-l', '--long', action="store_true",
-00981                  help="describe function of parameter")])    
-00982     def do_show(self, arg, opts):
-00983         '''Shows value of a parameter.'''
-00984         param = arg.strip().lower()
-00985         result = {}
-00986         maxlen = 0
-00987         for p in self.settable:
-00988             if (not param) or p.startswith(param):
-00989                 result[p] = '%s: %s' % (p, str(getattr(self, p)))
-00990                 maxlen = max(maxlen, len(result[p]))
-00991         if result:
-00992             for p in sorted(result):
-00993                 if opts.long:
-00994                     self.poutput('%s # %s' % (result[p].ljust(maxlen), self.settable[p]))
-00995                 else:
-00996                     self.poutput(result[p])
-00997         else:
-00998             raise NotImplementedError("Parameter '%s' not supported (type 'show' for list of parameters)." % param)
-00999     
-01000     def do_set(self, arg):
-01001         '''
-01002         Sets a cmd2 parameter.  Accepts abbreviated parameter names so long
-01003         as there is no ambiguity.  Call without arguments for a list of 
-01004         settable parameters with their values.'''
-01005         try:
-01006             statement, paramName, val = arg.parsed.raw.split(None, 2)
-01007             val = val.strip()
-01008             paramName = paramName.strip().lower()
-01009             if paramName not in self.settable:
-01010                 hits = [p for p in self.settable if p.startswith(paramName)]
-01011                 if len(hits) == 1:
-01012                     paramName = hits[0]
-01013                 else:
-01014                     return self.do_show(paramName)
-01015             currentVal = getattr(self, paramName)
-01016             if (val[0] == val[-1]) and val[0] in ("'", '"'):
-01017                 val = val[1:-1]
-01018             else:                
-01019                 val = cast(currentVal, val)
-01020             setattr(self, paramName, val)
-01021             self.stdout.write('%s - was: %s\nnow: %s\n' % (paramName, currentVal, val))
-01022             if currentVal != val:
-01023                 try:
-01024                     onchange_hook = getattr(self, '_onchange_%s' % paramName)
-01025                     onchange_hook(old=currentVal, new=val)
-01026                 except AttributeError:
-01027                     pass
-01028         except (ValueError, AttributeError, NotSettableError), e:
-01029             self.do_show(arg)
-01030                 
-01031     def do_pause(self, arg):
-01032         'Displays the specified text then waits for the user to press RETURN.'
-01033         raw_input(arg + '\n')
-01034         
-01035     def do_shell(self, arg):
-01036         'execute a command as if at the OS prompt.'
-01037         os.system(arg)
-01038                 
-01039     def do_py(self, arg):  
-01040         '''
-01041         py <command>: Executes a Python command.
-01042         py: Enters interactive Python mode.
-01043         End with ``Ctrl-D`` (Unix) / ``Ctrl-Z`` (Windows), ``quit()``, '`exit()``.
-01044         Non-python commands can be issued with ``cmd("your command")``.
-01045         Run python code from external files with ``run("filename.py")``
-01046         '''
-01047         self.pystate['self'] = self
-01048         arg = arg.parsed.raw[2:].strip()
-01049         localvars = (self.locals_in_py and self.pystate) or {}
-01050         interp = InteractiveConsole(locals=localvars)
-01051         interp.runcode('import sys, os;sys.path.insert(0, os.getcwd())')
-01052         if arg.strip():
-01053             interp.runcode(arg)
-01054         else:
-01055             def quit():
-01056                 raise EmbeddedConsoleExit
-01057             def onecmd_plus_hooks(arg):
-01058                 return self.onecmd_plus_hooks(arg + '\n')
-01059             def run(arg):
-01060                 try:
-01061                     file = open(arg)
-01062                     interp.runcode(file.read())
-01063                     file.close()
-01064                 except IOError, e:
-01065                     self.perror(e)
-01066             self.pystate['quit'] = quit
-01067             self.pystate['exit'] = quit
-01068             self.pystate['cmd'] = onecmd_plus_hooks
-01069             self.pystate['run'] = run
-01070             try:
-01071                 cprt = 'Type "help", "copyright", "credits" or "license" for more information.'        
-01072                 keepstate = Statekeeper(sys, ('stdin','stdout'))
-01073                 sys.stdout = self.stdout
-01074                 sys.stdin = self.stdin
-01075                 interp.interact(banner= "Python %s on %s\n%s\n(%s)\n%s" %
-01076                        (sys.version, sys.platform, cprt, self.__class__.__name__, self.do_py.__doc__))
-01077             except EmbeddedConsoleExit:
-01078                 pass
-01079             keepstate.restore()
-01080             
-01081     @options([make_option('-s', '--script', action="store_true", help="Script format; no separation lines"),
-01082              ], arg_desc = '(limit on which commands to include)')
-01083     def do_history(self, arg, opts):
-01084         """history [arg]: lists past commands issued
-01085         
-01086         | no arg:         list all
-01087         | arg is integer: list one history item, by index
-01088         | arg is string:  string search
-01089         | arg is /enclosed in forward-slashes/: regular expression search
-01090         """
-01091         if arg:
-01092             history = self.history.get(arg)
-01093         else:
-01094             history = self.history
-01095         for hi in history:
-01096             if opts.script:
-01097                 self.poutput(hi)
-01098             else:
-01099                 self.stdout.write(hi.pr())
-01100     def last_matching(self, arg):
-01101         try:
-01102             if arg:
-01103                 return self.history.get(arg)[-1]
-01104             else:
-01105                 return self.history[-1]
-01106         except IndexError:
-01107             return None        
-01108     def do_list(self, arg):
-01109         """list [arg]: lists last command issued
-01110         
-01111         no arg -> list most recent command
-01112         arg is integer -> list one history item, by index
-01113         a..b, a:b, a:, ..b -> list spans from a (or start) to b (or end)
-01114         arg is string -> list all commands matching string search
-01115         arg is /enclosed in forward-slashes/ -> regular expression search
-01116         """
-01117         try:
-01118             history = self.history.span(arg or '-1')
-01119         except IndexError:
-01120             history = self.history.search(arg)
-01121         for hi in history:
-01122             self.poutput(hi.pr())
-01123 
-01124     do_hi = do_history
-01125     do_l = do_list
-01126     do_li = do_list
-01127         
-01128     def do_ed(self, arg):
-01129         """ed: edit most recent command in text editor
-01130         ed [N]: edit numbered command from history
-01131         ed [filename]: edit specified file name
-01132         
-01133         commands are run after editor is closed.
-01134         "set edit (program-name)" or set  EDITOR environment variable
-01135         to control which editing program is used."""
-01136         if not self.editor:
-01137             raise EnvironmentError("Please use 'set editor' to specify your text editing program of choice.")
-01138         filename = self.default_file_name
-01139         if arg:
-01140             try:
-01141                 buffer = self.last_matching(int(arg))
-01142             except ValueError:
-01143                 filename = arg
-01144                 buffer = ''
-01145         else:
-01146             buffer = self.history[-1]
-01147 
-01148         if buffer:
-01149             f = open(os.path.expanduser(filename), 'w')
-01150             f.write(buffer or '')
-01151             f.close()        
-01152                 
-01153         os.system('%s %s' % (self.editor, filename))
-01154         self.do__load(filename)
-01155     do_edit = do_ed
-01156     
-01157     saveparser = (pyparsing.Optional(pyparsing.Word(pyparsing.nums)^'*')("idx") + 
-01158                   pyparsing.Optional(pyparsing.Word(legalChars + '/\\'))("fname") +
-01159                   pyparsing.stringEnd)    
-01160     def do_save(self, arg):
-01161         """`save [N] [filename.ext]`
-01162 
-01163         Saves command from history to file.
-01164 
-01165         | N => Number of command (from history), or `*`; 
-01166         |      most recent command if omitted"""
-01167 
-01168         try:
-01169             args = self.saveparser.parseString(arg)
-01170         except pyparsing.ParseException:
-01171             self.perror('Could not understand save target %s' % arg)
-01172             raise SyntaxError(self.do_save.__doc__)
-01173         fname = args.fname or self.default_file_name
-01174         if args.idx == '*':
-01175             saveme = '\n\n'.join(self.history[:])
-01176         elif args.idx:
-01177             saveme = self.history[int(args.idx)-1]
-01178         else:
-01179             saveme = self.history[-1]
-01180         try:
-01181             f = open(os.path.expanduser(fname), 'w')
-01182             f.write(saveme)
-01183             f.close()
-01184             self.pfeedback('Saved to %s' % (fname))
-01185         except Exception, e:
-01186             self.perror('Error saving %s' % (fname))
-01187             raise
-01188             
-01189     def read_file_or_url(self, fname):
-01190         # TODO: not working on localhost
-01191         if isinstance(fname, file):
-01192             result = open(fname, 'r')
-01193         else:
-01194             match = self.urlre.match(fname)
-01195             if match:
-01196                 result = urllib.urlopen(match.group(1))
-01197             else:
-01198                 fname = os.path.expanduser(fname)
-01199                 try:
-01200                     result = open(os.path.expanduser(fname), 'r')
-01201                 except IOError:                    
-01202                     result = open('%s.%s' % (os.path.expanduser(fname), 
-01203                                              self.defaultExtension), 'r')
-01204         return result
-01205         
-01206     def do__relative_load(self, arg=None):
-01207         '''
-01208         Runs commands in script at file or URL; if this is called from within an
-01209         already-running script, the filename will be interpreted relative to the 
-01210         already-running script's directory.'''
-01211         if arg:
-01212             arg = arg.split(None, 1)
-01213             targetname, args = arg[0], (arg[1:] or [''])[0]
-01214             targetname = os.path.join(self.current_script_dir or '', targetname)
-01215             self.do__load('%s %s' % (targetname, args))
-01216     
-01217     urlre = re.compile('(https?://[-\\w\\./]+)')
-01218     def do_load(self, arg=None):           
-01219         """Runs script of command(s) from a file or URL."""
-01220         if arg is None:
-01221             targetname = self.default_file_name
-01222         else:
-01223             arg = arg.split(None, 1)
-01224             targetname, args = arg[0], (arg[1:] or [''])[0].strip()
-01225         try:
-01226             target = self.read_file_or_url(targetname)
-01227         except IOError, e:
-01228             self.perror('Problem accessing script from %s: \n%s' % (targetname, e))
-01229             return
-01230         keepstate = Statekeeper(self, ('stdin','use_rawinput','prompt',
-01231                                        'continuation_prompt','current_script_dir'))
-01232         self.stdin = target    
-01233         self.use_rawinput = False
-01234         self.prompt = self.continuation_prompt = ''
-01235         self.current_script_dir = os.path.split(targetname)[0]
-01236         stop = self._cmdloop()
-01237         self.stdin.close()
-01238         keepstate.restore()
-01239         self.lastcmd = ''
-01240         return stop and (stop != self._STOP_SCRIPT_NO_EXIT)    
-01241     do__load = do_load  # avoid an unfortunate legacy use of do_load from sqlpython
-01242     
-01243     def do_run(self, arg):
-01244         """run [arg]: re-runs an earlier command
-01245         
-01246         no arg -> run most recent command
-01247         arg is integer -> run one history item, by index
-01248         arg is string -> run most recent command by string search
-01249         arg is /enclosed in forward-slashes/ -> run most recent by regex
-01250         """        
-01251         'run [N]: runs the SQL that was run N commands ago'
-01252         runme = self.last_matching(arg)
-01253         self.pfeedback(runme)
-01254         if runme:
-01255             stop = self.onecmd_plus_hooks(runme)
-01256     do_r = do_run        
-01257             
-01258     def fileimport(self, statement, source):
-01259         try:
-01260             f = open(os.path.expanduser(source))
-01261         except IOError:
-01262             self.stdout.write("Couldn't read from file %s\n" % source)
-01263             return ''
-01264         data = f.read()
-01265         f.close()
-01266         return data
-01267 
-01268     def runTranscriptTests(self, callargs):
-01269         class TestMyAppCase(Cmd2TestCase):
-01270             CmdApp = self.__class__        
-01271         self.__class__.testfiles = callargs
-01272         sys.argv = [sys.argv[0]] # the --test argument upsets unittest.main()
-01273         testcase = TestMyAppCase()
-01274         runner = unittest.TextTestRunner()
-01275         result = runner.run(testcase)
-01276         result.printErrors()
-01277 
-01278     def run_commands_at_invocation(self, callargs):
-01279         for initial_command in callargs:
-01280             if self.onecmd_plus_hooks(initial_command + '\n'):
-01281                 return self._STOP_AND_EXIT
-01282 
-01283     def cmdloop(self):
-01284         parser = optparse.OptionParser()
-01285         parser.add_option('-t', '--test', dest='test',
-01286                action="store_true", 
-01287                help='Test against transcript(s) in FILE (wildcards OK)')
-01288         (callopts, callargs) = parser.parse_args()
-01289         if callopts.test:
-01290             self.runTranscriptTests(callargs)
-01291         else:
-01292             if not self.run_commands_at_invocation(callargs):
-01293                 self._cmdloop()   
-01294             
-01295 class HistoryItem(str):
-01296     listformat = '-------------------------[%d]\n%s\n'
-01297     def __init__(self, instr):
-01298         str.__init__(self)
-01299         self.lowercase = self.lower()
-01300         self.idx = None
-01301     def pr(self):
-01302         return self.listformat % (self.idx, str(self))
-01303         
-01304 class History(list):
-01305     '''A list of HistoryItems that knows how to respond to user requests.
-01306     >>> h = History([HistoryItem('first'), HistoryItem('second'), HistoryItem('third'), HistoryItem('fourth')])
-01307     >>> h.span('-2..')
-01308     ['third', 'fourth']
-01309     >>> h.span('2..3')
-01310     ['second', 'third']
-01311     >>> h.span('3')
-01312     ['third']    
-01313     >>> h.span(':')
-01314     ['first', 'second', 'third', 'fourth']
-01315     >>> h.span('2..')
-01316     ['second', 'third', 'fourth']
-01317     >>> h.span('-1')
-01318     ['fourth']    
-01319     >>> h.span('-2..-3')
-01320     ['third', 'second']      
-01321     >>> h.search('o')
-01322     ['second', 'fourth']
-01323     >>> h.search('/IR/')
-01324     ['first', 'third']
-01325     '''
-01326     def zero_based_index(self, onebased):
-01327         result = onebased
-01328         if result > 0:
-01329             result -= 1
-01330         return result
-01331     def to_index(self, raw):
-01332         if raw:
-01333             result = self.zero_based_index(int(raw))
-01334         else:
-01335             result = None
-01336         return result
-01337     def search(self, target):
-01338         target = target.strip()
-01339         if target[0] == target[-1] == '/' and len(target) > 1:
-01340             target = target[1:-1]
-01341         else:
-01342             target = re.escape(target)
-01343         pattern = re.compile(target, re.IGNORECASE)
-01344         return [s for s in self if pattern.search(s)]
-01345     spanpattern = re.compile(r'^\s*(?P<start>\-?\d+)?\s*(?P<separator>:|(\.{2,}))?\s*(?P<end>\-?\d+)?\s*$')
-01346     def span(self, raw):
-01347         if raw.lower() in ('*', '-', 'all'):
-01348             raw = ':'
-01349         results = self.spanpattern.search(raw)
-01350         if not results:
-01351             raise IndexError
-01352         if not results.group('separator'):
-01353             return [self[self.to_index(results.group('start'))]]
-01354         start = self.to_index(results.group('start'))
-01355         end = self.to_index(results.group('end'))
-01356         reverse = False
-01357         if end is not None:
-01358             if end < start:
-01359                 (start, end) = (end, start)
-01360                 reverse = True
-01361             end += 1
-01362         result = self[start:end]
-01363         if reverse:
-01364             result.reverse()
-01365         return result
-01366                 
-01367     rangePattern = re.compile(r'^\s*(?P<start>[\d]+)?\s*\-\s*(?P<end>[\d]+)?\s*$')
-01368     def append(self, new):
-01369         new = HistoryItem(new)
-01370         list.append(self, new)
-01371         new.idx = len(self)
-01372     def extend(self, new):
-01373         for n in new:
-01374             self.append(n)
-01375         
-01376     def get(self, getme=None, fromEnd=False):
-01377         if not getme:
-01378             return self
-01379         try:
-01380             getme = int(getme)
-01381             if getme < 0:
-01382                 return self[:(-1 * getme)]
-01383             else:
-01384                 return [self[getme-1]]
-01385         except IndexError:
-01386             return []
-01387         except ValueError:
-01388             rangeResult = self.rangePattern.search(getme)
-01389             if rangeResult:
-01390                 start = rangeResult.group('start') or None
-01391                 end = rangeResult.group('start') or None
-01392                 if start:
-01393                     start = int(start) - 1
-01394                 if end:
-01395                     end = int(end)
-01396                 return self[start:end]
-01397                 
-01398             getme = getme.strip()
-01399 
-01400             if getme.startswith(r'/') and getme.endswith(r'/'):
-01401                 finder = re.compile(getme[1:-1], re.DOTALL | re.MULTILINE | re.IGNORECASE)
-01402                 def isin(hi):
-01403                     return finder.search(hi)
-01404             else:
-01405                 def isin(hi):
-01406                     return (getme.lower() in hi.lowercase)
-01407             return [itm for itm in self if isin(itm)]
-01408 
-01409 class NotSettableError(Exception):
-01410     pass
-01411         
-01412 def cast(current, new):
-01413     """Tries to force a new value into the same type as the current."""
-01414     typ = type(current)
-01415     if typ == bool:
-01416         try:
-01417             return bool(int(new))
-01418         except (ValueError, TypeError):
-01419             pass
-01420         try:
-01421             new = new.lower()    
-01422         except:
-01423             pass
-01424         if (new=='on') or (new[0] in ('y','t')):
-01425             return True
-01426         if (new=='off') or (new[0] in ('n','f')):
-01427             return False
-01428     else:
-01429         try:
-01430             return typ(new)
-01431         except:
-01432             pass
-01433     print ("Problem setting parameter (now %s) to %s; incorrect type?" % (current, new))
-01434     return current
-01435         
-01436 class Statekeeper(object):
-01437     def __init__(self, obj, attribs):
-01438         self.obj = obj
-01439         self.attribs = attribs
-01440         if self.obj:
-01441             self.save()
-01442     def save(self):
-01443         for attrib in self.attribs:
-01444             setattr(self, attrib, getattr(self.obj, attrib))
-01445     def restore(self):
-01446         if self.obj:
-01447             for attrib in self.attribs:
-01448                 setattr(self.obj, attrib, getattr(self, attrib))        
-01449 
-01450 class Borg(object):
-01451     '''All instances of any Borg subclass will share state.
-01452     from Python Cookbook, 2nd Ed., recipe 6.16'''
-01453     _shared_state = {}
-01454     def __new__(cls, *a, **k):
-01455         obj = object.__new__(cls, *a, **k)
-01456         obj.__dict__ = cls._shared_state
-01457         return obj
-01458     
-01459 class OutputTrap(Borg):
-01460     '''Instantiate  an OutputTrap to divert/capture ALL stdout output.  For use in unit testing.
-01461     Call `tearDown()` to return to normal output.'''
-01462     def __init__(self):
-01463         self.contents = ''
-01464         self.old_stdout = sys.stdout
-01465         sys.stdout = self
-01466     def write(self, txt):
-01467         self.contents += txt
-01468     def read(self):
-01469         result = self.contents
-01470         self.contents = ''
-01471         return result
-01472     def tearDown(self):
-01473         sys.stdout = self.old_stdout
-01474         self.contents = ''
-01475         
-01476 class Cmd2TestCase(unittest.TestCase):
-01477     '''Subclass this, setting CmdApp, to make a unittest.TestCase class
-01478        that will execute the commands in a transcript file and expect the results shown.
-01479        See example.py'''
-01480     CmdApp = None
-01481     def fetchTranscripts(self):
-01482         self.transcripts = {}
-01483         for fileset in self.CmdApp.testfiles:
-01484             for fname in glob.glob(fileset):
-01485                 tfile = open(fname)
-01486                 self.transcripts[fname] = iter(tfile.readlines())
-01487                 tfile.close()
-01488         if not len(self.transcripts):
-01489             raise (StandardError,), "No test files found - nothing to test."
-01490     def setUp(self):
-01491         if self.CmdApp:
-01492             self.outputTrap = OutputTrap()
-01493             self.cmdapp = self.CmdApp()
-01494             self.fetchTranscripts()
-01495     def runTest(self): # was testall
-01496         if self.CmdApp:
-01497             its = sorted(self.transcripts.items())
-01498             for (fname, transcript) in its:
-01499                 self._test_transcript(fname, transcript)
-01500     regexPattern = pyparsing.QuotedString(quoteChar=r'/', escChar='\\', multiline=True, unquoteResults=True)
-01501     regexPattern.ignore(pyparsing.cStyleComment)
-01502     notRegexPattern = pyparsing.Word(pyparsing.printables)
-01503     notRegexPattern.setParseAction(lambda t: re.escape(t[0]))
-01504     expectationParser = regexPattern | notRegexPattern
-01505     anyWhitespace = re.compile(r'\s', re.DOTALL | re.MULTILINE)
-01506     def _test_transcript(self, fname, transcript):
-01507         lineNum = 0
-01508         finished = False
-01509         line = transcript.next()
-01510         lineNum += 1
-01511         tests_run = 0
-01512         while not finished:
-01513             # Scroll forward to where actual commands begin
-01514             while not line.startswith(self.cmdapp.prompt):
-01515                 try:
-01516                     line = transcript.next()
-01517                 except StopIteration:
-01518                     finished = True
-01519                     break
-01520                 lineNum += 1
-01521             command = [line[len(self.cmdapp.prompt):]]
-01522             line = transcript.next()
-01523             # Read the entirety of a multi-line command
-01524             while line.startswith(self.cmdapp.continuation_prompt):
-01525                 command.append(line[len(self.cmdapp.continuation_prompt):])
-01526                 try:
-01527                     line = transcript.next()
-01528                 except StopIteration:
-01529                     raise (StopIteration, 
-01530                            'Transcript broke off while reading command beginning at line %d with\n%s' 
-01531                            % (command[0]))
-01532                 lineNum += 1
-01533             command = ''.join(command)               
-01534             # Send the command into the application and capture the resulting output
-01535             stop = self.cmdapp.onecmd_plus_hooks(command)
-01536             #TODO: should act on ``stop``
-01537             result = self.outputTrap.read()
-01538             # Read the expected result from transcript
-01539             if line.startswith(self.cmdapp.prompt):
-01540                 message = '\nFile %s, line %d\nCommand was:\n%s\nExpected: (nothing)\nGot:\n%s\n'%\
-01541                     (fname, lineNum, command, result)     
-01542                 self.assert_(not(result.strip()), message)
-01543                 continue
-01544             expected = []
-01545             while not line.startswith(self.cmdapp.prompt):
-01546                 expected.append(line)
-01547                 try:
-01548                     line = transcript.next()
-01549                 except StopIteration:
-01550                     finished = True                       
-01551                     break
-01552                 lineNum += 1
-01553             expected = ''.join(expected)
-01554             # Compare actual result to expected
-01555             message = '\nFile %s, line %d\nCommand was:\n%s\nExpected:\n%s\nGot:\n%s\n'%\
-01556                 (fname, lineNum, command, expected, result)      
-01557             expected = self.expectationParser.transformString(expected)
-01558             # checking whitespace is a pain - let's skip it
-01559             expected = self.anyWhitespace.sub('', expected)
-01560             result = self.anyWhitespace.sub('', result)
-01561             self.assert_(re.match(expected, result, re.MULTILINE | re.DOTALL), message)
-01562 
-01563     def tearDown(self):
-01564         if self.CmdApp:
-01565             self.outputTrap.tearDown()
-01566 
-01567 if __name__ == '__main__':
-01568     doctest.testmod(optionflags = doctest.NORMALIZE_WHITESPACE)
-01569         
-01570 '''
-01571 To make your application transcript-testable, replace 
-01572 
-01573 ::
-01574 
-01575   app = MyApp()
-01576   app.cmdloop()
-01577   
-01578 with
-01579 
-01580 ::
-01581 
-01582   app = MyApp()
-01583   cmd2.run(app)
-01584   
-01585 Then run a session of your application and paste the entire screen contents
-01586 into a file, ``transcript.test``, and invoke the test like::
-01587 
-01588   python myapp.py --test transcript.test
-01589 
-01590 Wildcards can be used to test against multiple transcript files.
-01591 '''
-01592 
-01593 
-
-
- - - - - -- cgit v1.2.1