mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			115 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			115 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """distutils.fancy_getopt
 | |
| 
 | |
| Wrapper around the standard getopt module that provides the following
 | |
| additional features:
 | |
|   * short and long options are tied together
 | |
|   * options have help strings, so fancy_getopt could potentially
 | |
|     create a complete usage summary
 | |
|   * options set attributes of a passed-in object
 | |
| """
 | |
| 
 | |
| # created 1999/03/03, Greg Ward
 | |
| 
 | |
| __rcsid__ = "$Id$"
 | |
| 
 | |
| import string, re
 | |
| from types import *
 | |
| import getopt
 | |
| from distutils.errors import *
 | |
| 
 | |
| # Much like command_re in distutils.core, this is close to but not quite
 | |
| # the same as a Python NAME -- except, in the spirit of most GNU
 | |
| # utilities, we use '-' in place of '_'.  (The spirit of LISP lives on!)
 | |
| # The similarities to NAME are again not a coincidence...
 | |
| longopt_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9-]*)$')
 | |
| 
 | |
| # This is used to translate long options to legitimate Python identifiers
 | |
| # (for use as attributes of some object).
 | |
| longopt_xlate = string.maketrans ('-', '_')
 | |
| 
 | |
| 
 | |
| def fancy_getopt (options, object, args):
 | |
| 
 | |
|     # The 'options' table is a list of 3-tuples:
 | |
|     #   (long_option, short_option, help_string)
 | |
|     # if an option takes an argument, its long_option should have '='
 | |
|     # appended; short_option should just be a single character, no ':' in
 | |
|     # any case.  If a long_option doesn't have a corresponding
 | |
|     # short_option, short_option should be None.  All option tuples must
 | |
|     # have long options.
 | |
| 
 | |
|     # Build the short_opts string and long_opts list, remembering how
 | |
|     # the two are tied together
 | |
| 
 | |
|     short_opts = []                     # we'll join 'em when done
 | |
|     long_opts = []
 | |
|     short2long = {}
 | |
|     attr_name = {}
 | |
|     takes_arg = {}
 | |
| 
 | |
|     for (long, short, help) in options:
 | |
|         # Type-check the option names
 | |
|         if type (long) is not StringType or len (long) < 2:
 | |
|             raise DistutilsGetoptError, \
 | |
|                   "long option must be a string of length >= 2"
 | |
| 
 | |
|         if (not ((short is None) or
 | |
|                  (type (short) is StringType and len (short) == 1))):
 | |
|             raise DistutilsGetoptError, \
 | |
|                   "short option must be None or string of length 1"
 | |
| 
 | |
|         long_opts.append (long)
 | |
| 
 | |
|         if long[-1] == '=':             # option takes an argument?
 | |
|             if short: short = short + ':'
 | |
|             long = long[0:-1]
 | |
|             takes_arg[long] = 1
 | |
|         else:
 | |
|             takes_arg[long] = 0
 | |
| 
 | |
|         # Now enforce some bondage on the long option name, so we can later
 | |
|         # translate it to an attribute name in 'object'.  Have to do this a
 | |
|         # bit late to make sure we've removed any trailing '='.
 | |
|         if not longopt_re.match (long):
 | |
|             raise DistutilsGetoptError, \
 | |
|                   ("invalid long option name '%s' " +
 | |
|                    "(must be letters, numbers, hyphens only") % long
 | |
| 
 | |
|         attr_name[long] = string.translate (long, longopt_xlate)
 | |
|         if short:
 | |
|             short_opts.append (short)
 | |
|             short2long[short[0]] = long
 | |
| 
 | |
|     # end loop over 'options'
 | |
| 
 | |
|     short_opts = string.join (short_opts)
 | |
|     try:
 | |
|         (opts, args) = getopt.getopt (args, short_opts, long_opts)
 | |
|     except getopt.error, msg:
 | |
|         raise DistutilsArgError, msg
 | |
| 
 | |
|     for (opt, val) in opts:
 | |
|         if len (opt) == 2 and opt[0] == '-': # it's a short option
 | |
|             opt = short2long[opt[1]]
 | |
| 
 | |
|         elif len (opt) > 2 and opt[0:2] == '--':
 | |
|             opt = opt[2:]
 | |
| 
 | |
|         else:
 | |
|             raise RuntimeError, "getopt lies! (bad option string '%s')" % \
 | |
|                   opt
 | |
| 
 | |
|         attr = attr_name[opt]
 | |
|         if takes_arg[opt]:
 | |
|             setattr (object, attr, val)
 | |
|         else:
 | |
|             if val == '':
 | |
|                 setattr (object, attr, 1)
 | |
|             else:
 | |
|                 raise RuntimeError, "getopt lies! (bad value '%s')" % value
 | |
| 
 | |
|     # end loop over options found in 'args'
 | |
| 
 | |
|     return args
 | |
| 
 | |
| # end fancy_getopt()
 | 
