|
1 | 1 | # module getopt -- Standard command line processing. |
2 | 2 |
|
3 | 3 | # Function getopt.getopt() has a different interface but provides the |
4 | | -# same functionality as the Unix getopt() function. |
5 | | - |
6 | | -# It has two arguments: the first should be argv[1:] (it doesn't want |
7 | | -# the script name), the second the string of option letters as passed |
8 | | -# to Unix getopt() (i.e., a string of allowable option letters, with |
9 | | -# options requiring an argument followed by a colon). |
| 4 | +# similar functionality to the Unix getopt() function, with the |
| 5 | +# addition of long-option support. (Long option support added by Lars |
| 6 | + |
| 7 | + |
| 8 | +# It has two required arguments: the first should be argv[1:] (it |
| 9 | +# doesn't want the script name), the second the string of option |
| 10 | +# letters as passed to Unix getopt() (i.e., a string of allowable |
| 11 | +# option letters, with options requiring an argument followed by a |
| 12 | +# colon). |
| 13 | + |
| 14 | +# The optional third argument, if present, getopt.getopt works similar |
| 15 | +# to the GNU getopt_long function (but optional arguments are not |
| 16 | +# supported). The third argument should be a list of strings that |
| 17 | +# name the long options. If the name ends '=', the argument requires |
| 18 | +# an argument. |
10 | 19 |
|
11 | 20 | # It raises the exception getopt.error with a string argument if it |
12 | 21 | # detects an error. |
13 | 22 |
|
14 | | -# It returns two items: |
| 23 | +# It returns two values: |
15 | 24 | # (1) a list of pairs (option, option_argument) giving the options in |
16 | 25 | # the order in which they were specified. (I'd use a dictionary |
17 | 26 | # but applications may depend on option order or multiple |
18 | 27 | # occurrences.) Boolean options have '' as option_argument. |
19 | 28 | # (2) the list of remaining arguments (may be empty). |
20 | 29 |
|
21 | | -# Added by Lars Wirzenius ([email protected]): A third argument is optional. |
22 | | -# If present, getopt.getopt works similar to the GNU getopt_long |
23 | | -# function (but optional arguments are not supported). The third |
24 | | -# argument should be a list of strings that name the long options. If |
25 | | -# the name ends '=', the argument requires an argument. |
26 | | - |
27 | | -# (While making this addition, I rewrote the whole thing.) |
28 | | - |
29 | 30 | import string |
30 | 31 |
|
31 | | -error = 'getopt error' |
| 32 | +error = 'getopt.error' |
32 | 33 |
|
33 | 34 | def getopt(args, shortopts, longopts = []): |
34 | | - list = [] |
35 | | - longopts = longopts[:] |
36 | | - longopts.sort() |
37 | | - while args and args[0][:1] == '-' and args[0] != '-': |
38 | | - if args[0] == '-' or args[0] == '--': |
39 | | - args = args[1:] |
40 | | - break |
41 | | - if args[0][:2] == '--': |
42 | | - list, args = do_longs(list, args[0][2:], |
43 | | - longopts, args[1:]) |
44 | | - else: |
45 | | - list, args = do_shorts(list, args[0][1:], |
46 | | - shortopts, args[1:]) |
47 | | - |
48 | | - return list, args |
| 35 | + list = [] |
| 36 | + longopts = longopts[:] |
| 37 | + longopts.sort() |
| 38 | + while args and args[0][:1] == '-' and args[0] != '-': |
| 39 | + if args[0] == '--': |
| 40 | + args = args[1:] |
| 41 | + break |
| 42 | + if args[0][:2] == '--': |
| 43 | + list, args = do_longs(list, args[0][2:], longopts, args[1:]) |
| 44 | + else: |
| 45 | + list, args = do_shorts(list, args[0][1:], shortopts, args[1:]) |
| 46 | + |
| 47 | + return list, args |
49 | 48 |
|
50 | 49 | def do_longs(list, opt, longopts, args): |
51 | | - try: |
52 | | - i = string.index(opt, '=') |
53 | | - opt, optarg = opt[:i], opt[i+1:] |
54 | | - except ValueError: |
55 | | - optarg = '' |
56 | | - |
57 | | - has_arg, opt = long_has_args(opt, longopts) |
58 | | - if has_arg: |
59 | | - if not optarg: |
60 | | - if not args: |
61 | | - raise error, 'option --' + opt + \ |
62 | | - ' requires argument' |
63 | | - optarg, args = args[0], args[1:] |
64 | | - else: |
65 | | - if optarg: |
66 | | - raise error, 'argument --' + opt + \ |
67 | | - ' must not have an argument' |
68 | | - list.append('--' + opt, optarg) |
69 | | - return list, args |
| 50 | + try: |
| 51 | + i = string.index(opt, '=') |
| 52 | + opt, optarg = opt[:i], opt[i+1:] |
| 53 | + except ValueError: |
| 54 | + optarg = None |
| 55 | + |
| 56 | + has_arg, opt = long_has_args(opt, longopts) |
| 57 | + if has_arg: |
| 58 | + if optarg is None: |
| 59 | + if not args: |
| 60 | + raise error, 'option --%s requires argument' % opt |
| 61 | + optarg, args = args[0], args[1:] |
| 62 | + elif optarg: |
| 63 | + raise error, 'option --%s must not have an argument' % opt |
| 64 | + list.append(('--' + opt, optarg or '')) |
| 65 | + return list, args |
70 | 66 |
|
71 | 67 | # Return: |
72 | 68 | # has_arg? |
73 | 69 | # full option name |
74 | 70 | def long_has_args(opt, longopts): |
75 | | - optlen = len(opt) |
76 | | - for i in range(len(longopts)): |
77 | | - x, y = longopts[i][:optlen], longopts[i][optlen:] |
78 | | - if opt != x: |
79 | | - continue |
80 | | - if y != '' and y != '=' and i+1 < len(longopts): |
81 | | - if opt == longopts[i+1][:optlen]: |
82 | | - raise error, 'option --' + opt + \ |
83 | | - ' not a unique prefix' |
84 | | - if longopts[i][-1:] == '=': |
85 | | - return 1, longopts[i][:-1] |
86 | | - return 0, longopts[i] |
87 | | - raise error, 'option --' + opt + ' not recognized' |
| 71 | + optlen = len(opt) |
| 72 | + for i in range(len(longopts)): |
| 73 | + x, y = longopts[i][:optlen], longopts[i][optlen:] |
| 74 | + if opt != x: |
| 75 | + continue |
| 76 | + if y != '' and y != '=' and i+1 < len(longopts): |
| 77 | + if opt == longopts[i+1][:optlen]: |
| 78 | + raise error, 'option --%s not a unique prefix' % opt |
| 79 | + if longopts[i][-1:] in ('=', ): |
| 80 | + return 1, longopts[i][:-1] |
| 81 | + return 0, longopts[i] |
| 82 | + raise error, 'option --' + opt + ' not recognized' |
88 | 83 |
|
89 | 84 | def do_shorts(list, optstring, shortopts, args): |
90 | | - while optstring != '': |
91 | | - opt, optstring = optstring[0], optstring[1:] |
92 | | - if short_has_arg(opt, shortopts): |
93 | | - if optstring == '': |
94 | | - if not args: |
95 | | - raise error, 'option -' + opt + \ |
96 | | - ' requires argument' |
97 | | - optstring, args = args[0], args[1:] |
98 | | - optarg, optstring = optstring, '' |
99 | | - else: |
100 | | - optarg = '' |
101 | | - list.append('-' + opt, optarg) |
102 | | - return list, args |
| 85 | + while optstring != '': |
| 86 | + opt, optstring = optstring[0], optstring[1:] |
| 87 | + if short_has_arg(opt, shortopts): |
| 88 | + if optstring == '': |
| 89 | + if not args: |
| 90 | + raise error, 'option -%s requires argument' % opt |
| 91 | + optstring, args = args[0], args[1:] |
| 92 | + optarg, optstring = optstring, '' |
| 93 | + else: |
| 94 | + optarg = '' |
| 95 | + list.append(('-' + opt, optarg)) |
| 96 | + return list, args |
103 | 97 |
|
104 | 98 | def short_has_arg(opt, shortopts): |
105 | | - for i in range(len(shortopts)): |
106 | | - if opt == shortopts[i] != ':': |
107 | | - return shortopts[i+1:i+2] == ':' |
108 | | - raise error, 'option -' + opt + ' not recognized' |
| 99 | + for i in range(len(shortopts)): |
| 100 | + if opt == shortopts[i] != ':': |
| 101 | + return shortopts[i+1:i+2] == ':' |
| 102 | + raise error, 'option -%s not recognized' % opt |
109 | 103 |
|
110 | 104 | if __name__ == '__main__': |
111 | | - import sys |
112 | | - print getopt(sys.argv[1:], "a:b") |
| 105 | + import sys |
| 106 | + print getopt(sys.argv[1:], "a:b", ["alpha=", "beta"]) |
0 commit comments