10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""Parser for command line options.
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30a8c90248264a8b26970b4473770bcc3df8515fJosh GaoThis module helps scripts to parse the command line arguments in
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gaosys.argv.  It supports the same conventions as the Unix getopt()
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofunction (including the special meanings of arguments of the form `-'
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoand `--').  Long options similar to those supported by GNU software
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gaomay be used as well via an optional third argument.  This module
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoprovides two functions and an exception:
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gaogetopt() -- Parse command line options
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gaognu_getopt() -- Like getopt(), but allow option and non-option arguments
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoto be intermixed.
130a8c90248264a8b26970b4473770bcc3df8515fJosh GaoGetoptError -- exception (class) raised with 'opt' attribute, which is the
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gaooption involved with the exception.
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Long option support added by Lars Wirzenius <liw@iki.fi>.
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Gerrit Holl <gerrit@nl.linux.org> moved the string-based exceptions
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# to class-based exceptions.
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Peter Astrand <astrand@lysator.liu.se> added gnu_getopt().
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# TODO for gnu_getopt():
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# - GNU getopt_long_only mechanism
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# - allow the caller to specify ordering
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# - RETURN_IN_ORDER option
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# - GNU extension with '-' as first character of option string
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# - optional arguments, specified by double colons
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# - a option string with a W followed by semicolon should
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   treat "-W foo" as "--foo"
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao__all__ = ["GetoptError","error","getopt","gnu_getopt"]
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport os
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass GetoptError(Exception):
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    opt = ''
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    msg = ''
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, msg, opt=''):
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.msg = msg
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.opt = opt
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Exception.__init__(self, msg, opt)
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __str__(self):
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.msg
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoerror = GetoptError # backward compatibility
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef getopt(args, shortopts, longopts = []):
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """getopt(args, options[, long_options]) -> opts, args
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Parses command line options and parameter list.  args is the
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    argument list to be parsed, without the leading reference to the
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    running program.  Typically, this means "sys.argv[1:]".  shortopts
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    is the string of option letters that the script wants to
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    recognize, with options that require an argument followed by a
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    colon (i.e., the same format that Unix getopt() uses).  If
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    specified, longopts is a list of strings with the names of the
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    long options which should be supported.  The leading '--'
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    characters should not be included in the option name.  Options
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    which require an argument should be followed by an equal sign
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ('=').
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    The return value consists of two elements: the first is a list of
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    (option, value) pairs; the second is the list of program arguments
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    left after the option list was stripped (this is a trailing slice
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    of the first argument).  Each option-and-value pair returned has
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    the option as its first element, prefixed with a hyphen (e.g.,
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    '-x'), and the option argument as its second element, or an empty
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    string if the option has no argument.  The options occur in the
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    list in the same order in which they were found, thus allowing
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    multiple occurrences.  Long and short options may be mixed.
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    opts = []
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if type(longopts) == type(""):
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        longopts = [longopts]
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        longopts = list(longopts)
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    while args and args[0].startswith('-') and args[0] != '-':
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if args[0] == '--':
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            args = args[1:]
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            break
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if args[0].startswith('--'):
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return opts, args
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef gnu_getopt(args, shortopts, longopts = []):
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """getopt(args, options[, long_options]) -> opts, args
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    This function works like getopt(), except that GNU style scanning
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    mode is used by default. This means that option and non-option
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    arguments may be intermixed. The getopt() function stops
1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    processing options as soon as a non-option argument is
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    encountered.
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    If the first character of the option string is `+', or if the
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    environment variable POSIXLY_CORRECT is set, then option
1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    processing stops as soon as a non-option argument is encountered.
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    opts = []
1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    prog_args = []
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if isinstance(longopts, str):
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        longopts = [longopts]
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        longopts = list(longopts)
1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Allow options after non-option arguments?
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if shortopts.startswith('+'):
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        shortopts = shortopts[1:]
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        all_options_first = True
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    elif os.environ.get("POSIXLY_CORRECT"):
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        all_options_first = True
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        all_options_first = False
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    while args:
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if args[0] == '--':
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            prog_args += args[1:]
1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            break
1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if args[0][:2] == '--':
1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elif args[0][:1] == '-' and args[0] != '-':
1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])
1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if all_options_first:
1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                prog_args += args
1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                break
1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                prog_args.append(args[0])
1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                args = args[1:]
1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return opts, prog_args
1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef do_longs(opts, opt, longopts, args):
1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    try:
1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        i = opt.index('=')
1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    except ValueError:
1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        optarg = None
1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        opt, optarg = opt[:i], opt[i+1:]
1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    has_arg, opt = long_has_args(opt, longopts)
1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if has_arg:
1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if optarg is None:
1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if not args:
1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                raise GetoptError('option --%s requires argument' % opt, opt)
1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            optarg, args = args[0], args[1:]
1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    elif optarg is not None:
1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise GetoptError('option --%s must not have an argument' % opt, opt)
1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    opts.append(('--' + opt, optarg or ''))
1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return opts, args
1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Return:
1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   has_arg?
1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   full option name
1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef long_has_args(opt, longopts):
1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    possibilities = [o for o in longopts if o.startswith(opt)]
1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not possibilities:
1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise GetoptError('option --%s not recognized' % opt, opt)
1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Is there an exact match?
1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if opt in possibilities:
1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return False, opt
1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    elif opt + '=' in possibilities:
1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return True, opt
1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # No exact match, so better be unique.
1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if len(possibilities) > 1:
1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # XXX since possibilities contains all valid continuations, might be
1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # nice to work them into the error msg
1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise GetoptError('option --%s not a unique prefix' % opt, opt)
1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    assert len(possibilities) == 1
1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    unique_match = possibilities[0]
1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    has_arg = unique_match.endswith('=')
1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if has_arg:
1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        unique_match = unique_match[:-1]
1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return has_arg, unique_match
1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef do_shorts(opts, optstring, shortopts, args):
1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    while optstring != '':
1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        opt, optstring = optstring[0], optstring[1:]
1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if short_has_arg(opt, shortopts):
1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if optstring == '':
1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if not args:
1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    raise GetoptError('option -%s requires argument' % opt,
1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                      opt)
1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                optstring, args = args[0], args[1:]
1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            optarg, optstring = optstring, ''
1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            optarg = ''
1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        opts.append(('-' + opt, optarg))
2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return opts, args
2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef short_has_arg(opt, shortopts):
2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for i in range(len(shortopts)):
2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if opt == shortopts[i] != ':':
2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return shortopts.startswith(':', i+1)
2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    raise GetoptError('option -%s not recognized' % opt, opt)
2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__ == '__main__':
2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    import sys
2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    print getopt(sys.argv[1:], "a:b", ["alpha=", "beta"])
211