These files are a subset of the python-2.7.2.tgz distribution from python.org. Changed files from PyMod-2.7.2 have been copied into the corresponding directories of this tree, replacing the original files in the distribution. Signed-off-by: daryl.mcdaniel@intel.com git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13197 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			635 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			635 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """ CommandLine - Get and parse command line options
 | |
| 
 | |
|     NOTE: This still is very much work in progress !!!
 | |
| 
 | |
|     Different version are likely to be incompatible.
 | |
| 
 | |
|     TODO:
 | |
| 
 | |
|     * Incorporate the changes made by (see Inbox)
 | |
|     * Add number range option using srange()
 | |
| 
 | |
| """
 | |
| 
 | |
| __copyright__ = """\
 | |
| Copyright (c), 1997-2006, Marc-Andre Lemburg (mal@lemburg.com)
 | |
| Copyright (c), 2000-2006, eGenix.com Software GmbH (info@egenix.com)
 | |
| See the documentation for further information on copyrights,
 | |
| or contact the author. All Rights Reserved.
 | |
| """
 | |
| 
 | |
| __version__ = '1.2'
 | |
| 
 | |
| import sys, getopt, string, glob, os, re, exceptions, traceback
 | |
| 
 | |
| ### Helpers
 | |
| 
 | |
| def _getopt_flags(options):
 | |
| 
 | |
|     """ Convert the option list to a getopt flag string and long opt
 | |
|         list
 | |
| 
 | |
|     """
 | |
|     s = []
 | |
|     l = []
 | |
|     for o in options:
 | |
|         if o.prefix == '-':
 | |
|             # short option
 | |
|             s.append(o.name)
 | |
|             if o.takes_argument:
 | |
|                 s.append(':')
 | |
|         else:
 | |
|             # long option
 | |
|             if o.takes_argument:
 | |
|                 l.append(o.name+'=')
 | |
|             else:
 | |
|                 l.append(o.name)
 | |
|     return string.join(s,''),l
 | |
| 
 | |
| def invisible_input(prompt='>>> '):
 | |
| 
 | |
|     """ Get raw input from a terminal without echoing the characters to
 | |
|         the terminal, e.g. for password queries.
 | |
| 
 | |
|     """
 | |
|     import getpass
 | |
|     entry = getpass.getpass(prompt)
 | |
|     if entry is None:
 | |
|         raise KeyboardInterrupt
 | |
|     return entry
 | |
| 
 | |
| def fileopen(name, mode='wb', encoding=None):
 | |
| 
 | |
|     """ Open a file using mode.
 | |
| 
 | |
|         Default mode is 'wb' meaning to open the file for writing in
 | |
|         binary mode. If encoding is given, I/O to and from the file is
 | |
|         transparently encoded using the given encoding.
 | |
| 
 | |
|         Files opened for writing are chmod()ed to 0600.
 | |
| 
 | |
|     """
 | |
|     if name == 'stdout':
 | |
|         return sys.stdout
 | |
|     elif name == 'stderr':
 | |
|         return sys.stderr
 | |
|     elif name == 'stdin':
 | |
|         return sys.stdin
 | |
|     else:
 | |
|         if encoding is not None:
 | |
|             import codecs
 | |
|             f = codecs.open(name, mode, encoding)
 | |
|         else:
 | |
|             f = open(name, mode)
 | |
|         if 'w' in mode:
 | |
|             os.chmod(name, 0600)
 | |
|         return f
 | |
| 
 | |
| def option_dict(options):
 | |
| 
 | |
|     """ Return a dictionary mapping option names to Option instances.
 | |
|     """
 | |
|     d = {}
 | |
|     for option in options:
 | |
|         d[option.name] = option
 | |
|     return d
 | |
| 
 | |
| # Alias
 | |
| getpasswd = invisible_input
 | |
| 
 | |
| _integerRE = re.compile('\s*(-?\d+)\s*$')
 | |
| _integerRangeRE = re.compile('\s*(-?\d+)\s*-\s*(-?\d+)\s*$')
 | |
| 
 | |
| def srange(s,
 | |
| 
 | |
|            split=string.split,integer=_integerRE,
 | |
|            integerRange=_integerRangeRE):
 | |
| 
 | |
|     """ Converts a textual representation of integer numbers and ranges
 | |
|         to a Python list.
 | |
| 
 | |
|         Supported formats: 2,3,4,2-10,-1 - -3, 5 - -2
 | |
| 
 | |
|         Values are appended to the created list in the order specified
 | |
|         in the string.
 | |
| 
 | |
|     """
 | |
|     l = []
 | |
|     append = l.append
 | |
|     for entry in split(s,','):
 | |
|         m = integer.match(entry)
 | |
|         if m:
 | |
|             append(int(m.groups()[0]))
 | |
|             continue
 | |
|         m = integerRange.match(entry)
 | |
|         if m:
 | |
|             start,end = map(int,m.groups())
 | |
|             l[len(l):] = range(start,end+1)
 | |
|     return l
 | |
| 
 | |
| def abspath(path,
 | |
| 
 | |
|             expandvars=os.path.expandvars,expanduser=os.path.expanduser,
 | |
|             join=os.path.join,getcwd=os.getcwd):
 | |
| 
 | |
|     """ Return the corresponding absolute path for path.
 | |
| 
 | |
|         path is expanded in the usual shell ways before
 | |
|         joining it with the current working directory.
 | |
| 
 | |
|     """
 | |
|     try:
 | |
|         path = expandvars(path)
 | |
|     except AttributeError:
 | |
|         pass
 | |
|     try:
 | |
|         path = expanduser(path)
 | |
|     except AttributeError:
 | |
|         pass
 | |
|     return join(getcwd(), path)
 | |
| 
 | |
| ### Option classes
 | |
| 
 | |
| class Option:
 | |
| 
 | |
|     """ Option base class. Takes no argument.
 | |
| 
 | |
|     """
 | |
|     default = None
 | |
|     helptext = ''
 | |
|     prefix = '-'
 | |
|     takes_argument = 0
 | |
|     has_default = 0
 | |
|     tab = 15
 | |
| 
 | |
|     def __init__(self,name,help=None):
 | |
| 
 | |
|         if not name[:1] == '-':
 | |
|             raise TypeError,'option names must start with "-"'
 | |
|         if name[1:2] == '-':
 | |
|             self.prefix = '--'
 | |
|             self.name = name[2:]
 | |
|         else:
 | |
|             self.name = name[1:]
 | |
|         if help:
 | |
|             self.help = help
 | |
| 
 | |
|     def __str__(self):
 | |
| 
 | |
|         o = self
 | |
|         name = o.prefix + o.name
 | |
|         if o.takes_argument:
 | |
|             name = name + ' arg'
 | |
|         if len(name) > self.tab:
 | |
|             name = name + '\n' + ' ' * (self.tab + 1 + len(o.prefix))
 | |
|         else:
 | |
|             name = '%-*s ' % (self.tab, name)
 | |
|         description = o.help
 | |
|         if o.has_default:
 | |
|             description = description + ' (%s)' % o.default
 | |
|         return '%s %s' % (name, description)
 | |
| 
 | |
| class ArgumentOption(Option):
 | |
| 
 | |
|     """ Option that takes an argument.
 | |
| 
 | |
|         An optional default argument can be given.
 | |
| 
 | |
|     """
 | |
|     def __init__(self,name,help=None,default=None):
 | |
| 
 | |
|         # Basemethod
 | |
|         Option.__init__(self,name,help)
 | |
| 
 | |
|         if default is not None:
 | |
|             self.default = default
 | |
|             self.has_default = 1
 | |
|         self.takes_argument = 1
 | |
| 
 | |
| class SwitchOption(Option):
 | |
| 
 | |
|     """ Options that can be on or off. Has an optional default value.
 | |
| 
 | |
|     """
 | |
|     def __init__(self,name,help=None,default=None):
 | |
| 
 | |
|         # Basemethod
 | |
|         Option.__init__(self,name,help)
 | |
| 
 | |
|         if default is not None:
 | |
|             self.default = default
 | |
|             self.has_default = 1
 | |
| 
 | |
| ### Application baseclass
 | |
| 
 | |
| class Application:
 | |
| 
 | |
|     """ Command line application interface with builtin argument
 | |
|         parsing.
 | |
| 
 | |
|     """
 | |
|     # Options the program accepts (Option instances)
 | |
|     options = []
 | |
| 
 | |
|     # Standard settings; these are appended to options in __init__
 | |
|     preset_options = [SwitchOption('-v',
 | |
|                                    'generate verbose output'),
 | |
|                       SwitchOption('-h',
 | |
|                                    'show this help text'),
 | |
|                       SwitchOption('--help',
 | |
|                                    'show this help text'),
 | |
|                       SwitchOption('--debug',
 | |
|                                    'enable debugging'),
 | |
|                       SwitchOption('--copyright',
 | |
|                                    'show copyright'),
 | |
|                       SwitchOption('--examples',
 | |
|                                    'show examples of usage')]
 | |
| 
 | |
|     # The help layout looks like this:
 | |
|     # [header]   - defaults to ''
 | |
|     #
 | |
|     # [synopsis] - formatted as '<self.name> %s' % self.synopsis
 | |
|     #
 | |
|     # options:
 | |
|     # [options]  - formatted from self.options
 | |
|     #
 | |
|     # [version]  - formatted as 'Version:\n %s' % self.version, if given
 | |
|     #
 | |
|     # [about]    - defaults to ''
 | |
|     #
 | |
|     # Note: all fields that do not behave as template are formatted
 | |
|     #       using the instances dictionary as substitution namespace,
 | |
|     #       e.g. %(name)s will be replaced by the applications name.
 | |
|     #
 | |
| 
 | |
|     # Header (default to program name)
 | |
|     header = ''
 | |
| 
 | |
|     # Name (defaults to program name)
 | |
|     name = ''
 | |
| 
 | |
|     # Synopsis (%(name)s is replaced by the program name)
 | |
|     synopsis = '%(name)s [option] files...'
 | |
| 
 | |
|     # Version (optional)
 | |
|     version = ''
 | |
| 
 | |
|     # General information printed after the possible options (optional)
 | |
|     about = ''
 | |
| 
 | |
|     # Examples of usage to show when the --examples option is given (optional)
 | |
|     examples = ''
 | |
| 
 | |
|     # Copyright to show
 | |
|     copyright = __copyright__
 | |
| 
 | |
|     # Apply file globbing ?
 | |
|     globbing = 1
 | |
| 
 | |
|     # Generate debug output ?
 | |
|     debug = 0
 | |
| 
 | |
|     # Generate verbose output ?
 | |
|     verbose = 0
 | |
| 
 | |
|     # Internal errors to catch
 | |
|     InternalError = exceptions.Exception
 | |
| 
 | |
|     # Instance variables:
 | |
|     values = None       # Dictionary of passed options (or default values)
 | |
|                         # indexed by the options name, e.g. '-h'
 | |
|     files = None        # List of passed filenames
 | |
|     optionlist = None   # List of passed options
 | |
| 
 | |
|     def __init__(self,argv=None):
 | |
| 
 | |
|         # Setup application specs
 | |
|         if argv is None:
 | |
|             argv = sys.argv
 | |
|         self.filename = os.path.split(argv[0])[1]
 | |
|         if not self.name:
 | |
|             self.name = os.path.split(self.filename)[1]
 | |
|         else:
 | |
|             self.name = self.name
 | |
|         if not self.header:
 | |
|             self.header = self.name
 | |
|         else:
 | |
|             self.header = self.header
 | |
| 
 | |
|         # Init .arguments list
 | |
|         self.arguments = argv[1:]
 | |
| 
 | |
|         # Setup Option mapping
 | |
|         self.option_map = option_dict(self.options)
 | |
| 
 | |
|         # Append preset options
 | |
|         for option in self.preset_options:
 | |
|             if not self.option_map.has_key(option.name):
 | |
|                 self.add_option(option)
 | |
| 
 | |
|         # Init .files list
 | |
|         self.files = []
 | |
| 
 | |
|         # Start Application
 | |
|         try:
 | |
|             # Process startup
 | |
|             rc = self.startup()
 | |
|             if rc is not None:
 | |
|                 raise SystemExit,rc
 | |
| 
 | |
|             # Parse command line
 | |
|             rc = self.parse()
 | |
|             if rc is not None:
 | |
|                 raise SystemExit,rc
 | |
| 
 | |
|             # Start application
 | |
|             rc = self.main()
 | |
|             if rc is None:
 | |
|                 rc = 0
 | |
| 
 | |
|         except SystemExit,rc:
 | |
|             pass
 | |
| 
 | |
|         except KeyboardInterrupt:
 | |
|             print
 | |
|             print '* User Break'
 | |
|             print
 | |
|             rc = 1
 | |
| 
 | |
|         except self.InternalError:
 | |
|             print
 | |
|             print '* Internal Error (use --debug to display the traceback)'
 | |
|             if self.debug:
 | |
|                 print
 | |
|                 traceback.print_exc(20, sys.stdout)
 | |
|             elif self.verbose:
 | |
|                 print '  %s: %s' % sys.exc_info()[:2]
 | |
|             print
 | |
|             rc = 1
 | |
| 
 | |
|         raise SystemExit,rc
 | |
| 
 | |
|     def add_option(self, option):
 | |
| 
 | |
|         """ Add a new Option instance to the Application dynamically.
 | |
| 
 | |
|             Note that this has to be done *before* .parse() is being
 | |
|             executed.
 | |
| 
 | |
|         """
 | |
|         self.options.append(option)
 | |
|         self.option_map[option.name] = option
 | |
| 
 | |
|     def startup(self):
 | |
| 
 | |
|         """ Set user defined instance variables.
 | |
| 
 | |
|             If this method returns anything other than None, the
 | |
|             process is terminated with the return value as exit code.
 | |
| 
 | |
|         """
 | |
|         return None
 | |
| 
 | |
|     def exit(self, rc=0):
 | |
| 
 | |
|         """ Exit the program.
 | |
| 
 | |
|             rc is used as exit code and passed back to the calling
 | |
|             program. It defaults to 0 which usually means: OK.
 | |
| 
 | |
|         """
 | |
|         raise SystemExit, rc
 | |
| 
 | |
|     def parse(self):
 | |
| 
 | |
|         """ Parse the command line and fill in self.values and self.files.
 | |
| 
 | |
|             After having parsed the options, the remaining command line
 | |
|             arguments are interpreted as files and passed to .handle_files()
 | |
|             for processing.
 | |
| 
 | |
|             As final step the option handlers are called in the order
 | |
|             of the options given on the command line.
 | |
| 
 | |
|         """
 | |
|         # Parse arguments
 | |
|         self.values = values = {}
 | |
|         for o in self.options:
 | |
|             if o.has_default:
 | |
|                 values[o.prefix+o.name] = o.default
 | |
|             else:
 | |
|                 values[o.prefix+o.name] = 0
 | |
|         flags,lflags = _getopt_flags(self.options)
 | |
|         try:
 | |
|             optlist,files = getopt.getopt(self.arguments,flags,lflags)
 | |
|             if self.globbing:
 | |
|                 l = []
 | |
|                 for f in files:
 | |
|                     gf = glob.glob(f)
 | |
|                     if not gf:
 | |
|                         l.append(f)
 | |
|                     else:
 | |
|                         l[len(l):] = gf
 | |
|                 files = l
 | |
|             self.optionlist = optlist
 | |
|             self.files = files + self.files
 | |
|         except getopt.error,why:
 | |
|             self.help(why)
 | |
|             sys.exit(1)
 | |
| 
 | |
|         # Call file handler
 | |
|         rc = self.handle_files(self.files)
 | |
|         if rc is not None:
 | |
|             sys.exit(rc)
 | |
| 
 | |
|         # Call option handlers
 | |
|         for optionname, value in optlist:
 | |
| 
 | |
|             # Try to convert value to integer
 | |
|             try:
 | |
|                 value = string.atoi(value)
 | |
|             except ValueError:
 | |
|                 pass
 | |
| 
 | |
|             # Find handler and call it (or count the number of option
 | |
|             # instances on the command line)
 | |
|             handlername = 'handle' + string.replace(optionname, '-', '_')
 | |
|             try:
 | |
|                 handler = getattr(self, handlername)
 | |
|             except AttributeError:
 | |
|                 if value == '':
 | |
|                     # count the number of occurances
 | |
|                     if values.has_key(optionname):
 | |
|                         values[optionname] = values[optionname] + 1
 | |
|                     else:
 | |
|                         values[optionname] = 1
 | |
|                 else:
 | |
|                     values[optionname] = value
 | |
|             else:
 | |
|                 rc = handler(value)
 | |
|                 if rc is not None:
 | |
|                     raise SystemExit, rc
 | |
| 
 | |
|         # Apply final file check (for backward compatibility)
 | |
|         rc = self.check_files(self.files)
 | |
|         if rc is not None:
 | |
|             sys.exit(rc)
 | |
| 
 | |
|     def check_files(self,filelist):
 | |
| 
 | |
|         """ Apply some user defined checks on the files given in filelist.
 | |
| 
 | |
|             This may modify filelist in place. A typical application
 | |
|             is checking that at least n files are given.
 | |
| 
 | |
|             If this method returns anything other than None, the
 | |
|             process is terminated with the return value as exit code.
 | |
| 
 | |
|         """
 | |
|         return None
 | |
| 
 | |
|     def help(self,note=''):
 | |
| 
 | |
|         self.print_header()
 | |
|         if self.synopsis:
 | |
|             print 'Synopsis:'
 | |
|             # To remain backward compatible:
 | |
|             try:
 | |
|                 synopsis = self.synopsis % self.name
 | |
|             except (NameError, KeyError, TypeError):
 | |
|                 synopsis = self.synopsis % self.__dict__
 | |
|             print ' ' + synopsis
 | |
|         print
 | |
|         self.print_options()
 | |
|         if self.version:
 | |
|             print 'Version:'
 | |
|             print ' %s' % self.version
 | |
|             print
 | |
|         if self.about:
 | |
|             print string.strip(self.about % self.__dict__)
 | |
|             print
 | |
|         if note:
 | |
|             print '-'*72
 | |
|             print 'Note:',note
 | |
|             print
 | |
| 
 | |
|     def notice(self,note):
 | |
| 
 | |
|         print '-'*72
 | |
|         print 'Note:',note
 | |
|         print '-'*72
 | |
|         print
 | |
| 
 | |
|     def print_header(self):
 | |
| 
 | |
|         print '-'*72
 | |
|         print self.header % self.__dict__
 | |
|         print '-'*72
 | |
|         print
 | |
| 
 | |
|     def print_options(self):
 | |
| 
 | |
|         options = self.options
 | |
|         print 'Options and default settings:'
 | |
|         if not options:
 | |
|             print '  None'
 | |
|             return
 | |
|         long = filter(lambda x: x.prefix == '--', options)
 | |
|         short = filter(lambda x: x.prefix == '-', options)
 | |
|         items = short + long
 | |
|         for o in options:
 | |
|             print ' ',o
 | |
|         print
 | |
| 
 | |
|     #
 | |
|     # Example handlers:
 | |
|     #
 | |
|     # If a handler returns anything other than None, processing stops
 | |
|     # and the return value is passed to sys.exit() as argument.
 | |
|     #
 | |
| 
 | |
|     # File handler
 | |
|     def handle_files(self,files):
 | |
| 
 | |
|         """ This may process the files list in place.
 | |
|         """
 | |
|         return None
 | |
| 
 | |
|     # Short option handler
 | |
|     def handle_h(self,arg):
 | |
| 
 | |
|         self.help()
 | |
|         return 0
 | |
| 
 | |
|     def handle_v(self, value):
 | |
| 
 | |
|         """ Turn on verbose output.
 | |
|         """
 | |
|         self.verbose = 1
 | |
| 
 | |
|     # Handlers for long options have two underscores in their name
 | |
|     def handle__help(self,arg):
 | |
| 
 | |
|         self.help()
 | |
|         return 0
 | |
| 
 | |
|     def handle__debug(self,arg):
 | |
| 
 | |
|         self.debug = 1
 | |
|         # We don't want to catch internal errors:
 | |
|         self.InternalError = None
 | |
| 
 | |
|     def handle__copyright(self,arg):
 | |
| 
 | |
|         self.print_header()
 | |
|         print string.strip(self.copyright % self.__dict__)
 | |
|         print
 | |
|         return 0
 | |
| 
 | |
|     def handle__examples(self,arg):
 | |
| 
 | |
|         self.print_header()
 | |
|         if self.examples:
 | |
|             print 'Examples:'
 | |
|             print
 | |
|             print string.strip(self.examples % self.__dict__)
 | |
|             print
 | |
|         else:
 | |
|             print 'No examples available.'
 | |
|             print
 | |
|         return 0
 | |
| 
 | |
|     def main(self):
 | |
| 
 | |
|         """ Override this method as program entry point.
 | |
| 
 | |
|             The return value is passed to sys.exit() as argument.  If
 | |
|             it is None, 0 is assumed (meaning OK). Unhandled
 | |
|             exceptions are reported with exit status code 1 (see
 | |
|             __init__ for further details).
 | |
| 
 | |
|         """
 | |
|         return None
 | |
| 
 | |
| # Alias
 | |
| CommandLine = Application
 | |
| 
 | |
| def _test():
 | |
| 
 | |
|     class MyApplication(Application):
 | |
|         header = 'Test Application'
 | |
|         version = __version__
 | |
|         options = [Option('-v','verbose')]
 | |
| 
 | |
|         def handle_v(self,arg):
 | |
|             print 'VERBOSE, Yeah !'
 | |
| 
 | |
|     cmd = MyApplication()
 | |
|     if not cmd.values['-h']:
 | |
|         cmd.help()
 | |
|     print 'files:',cmd.files
 | |
|     print 'Bye...'
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     _test()
 |