diff options
author | Greg Ward <gward@python.net> | 1999-03-22 14:52:19 (GMT) |
---|---|---|
committer | Greg Ward <gward@python.net> | 1999-03-22 14:52:19 (GMT) |
commit | 2689e3ddce70e8acc5bc231a80221980d5bdfec3 (patch) | |
tree | 5c60133b1b4c8732503d4ecbe625091321be7217 /Lib/distutils/fancy_getopt.py | |
parent | 481ac8811e41f509e3a4ca6ef0151ce69671b43e (diff) | |
download | cpython-2689e3ddce70e8acc5bc231a80221980d5bdfec3.zip cpython-2689e3ddce70e8acc5bc231a80221980d5bdfec3.tar.gz cpython-2689e3ddce70e8acc5bc231a80221980d5bdfec3.tar.bz2 |
First checkin of real Distutils code.
Diffstat (limited to 'Lib/distutils/fancy_getopt.py')
-rw-r--r-- | Lib/distutils/fancy_getopt.py | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/Lib/distutils/fancy_getopt.py b/Lib/distutils/fancy_getopt.py new file mode 100644 index 0000000..c63ce61 --- /dev/null +++ b/Lib/distutils/fancy_getopt.py @@ -0,0 +1,115 @@ +"""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() |