From dd699b62c59d8fdbdf97a219a2a1125b691e5a98 Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Wed, 27 Dec 2000 08:05:05 +0000 Subject: [PATCH] Fix for SF bug https://sourceforge.net/bugs/?func=detailbug&bug_id=126863&group_id=5470 "getopt long option handling broken". Tossed the excruciating logic in long_has_args in favor of something obviously correct. --- Lib/getopt.py | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/Lib/getopt.py b/Lib/getopt.py index a6ddf44bb05..c93aad179c5 100644 --- a/Lib/getopt.py +++ b/Lib/getopt.py @@ -66,7 +66,7 @@ def getopt(args, shortopts, longopts = []): else: longopts = list(longopts) longopts.sort() - while args and args[0][:1] == '-' and args[0] != '-': + while args and args[0].startswith('-') and args[0] != '-': if args[0] == '--': args = args[1:] break @@ -80,9 +80,10 @@ def getopt(args, shortopts, longopts = []): def do_longs(opts, opt, longopts, args): try: i = opt.index('=') - opt, optarg = opt[:i], opt[i+1:] except ValueError: optarg = None + else: + opt, optarg = opt[:i], opt[i+1:] has_arg, opt = long_has_args(opt, longopts) if has_arg: @@ -98,19 +99,35 @@ def do_longs(opts, opt, longopts, args): # Return: # has_arg? # full option name +# Assumes longopts has been sorted (ASCII order). def long_has_args(opt, longopts): - optlen = len(opt) for i in range(len(longopts)): - x, y = longopts[i][:optlen], longopts[i][optlen:] - if opt != x: - continue - if y != '' and y != '=' and i+1 < len(longopts): - if opt == longopts[i+1][:optlen]: - raise GetoptError('option --%s not a unique prefix' % opt, opt) - if longopts[i][-1:] in ('=', ): - return 1, longopts[i][:-1] - return 0, longopts[i] - raise GetoptError('option --%s not recognized' % opt, opt) + if longopts[i].startswith(opt): + break + else: + raise GetoptError('option --%s not recognized' % opt, opt) + # opt is a prefix of longopts[i]; find j s.t. opt is a prefix of + # each possibility in longopts[i:j] + j = i+1 + while j < len(longopts) and longopts[j].startswith(opt): + j += 1 + possibilities = longopts[i:j] + # Is there an exact match? + if opt in possibilities: + return 0, opt + elif opt + '=' in possibilities: + return 1, opt + # No exact match, so better be unique. + if len(possibilities) > 1: + # XXX since possibilities contains all valid continuations, might be + # nice to work them into the error msg + raise GetoptError('option --%s not a unique prefix' % opt, opt) + assert len(possibilities) == 1 + unique_match = possibilities[0] + has_arg = unique_match.endswith('=') + if has_arg: + unique_match = unique_match[:-1] + return has_arg, unique_match def do_shorts(opts, optstring, shortopts, args): while optstring != '':