Show More
@@ -1,124 +1,127 | |||||
1 | # fancyopts.py - better command line parsing |
|
1 | # fancyopts.py - better command line parsing | |
2 | # |
|
2 | # | |
3 | # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others |
|
3 | # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms of the |
|
5 | # This software may be used and distributed according to the terms of the | |
6 | # GNU General Public License version 2 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
|
8 | from __future__ import absolute_import | |||
|
9 | ||||
8 | import getopt |
|
10 | import getopt | |
9 | import util |
|
11 | ||
10 | from i18n import _ |
|
12 | from .i18n import _ | |
|
13 | from . import util | |||
11 |
|
14 | |||
12 | def gnugetopt(args, options, longoptions): |
|
15 | def gnugetopt(args, options, longoptions): | |
13 | """Parse options mostly like getopt.gnu_getopt. |
|
16 | """Parse options mostly like getopt.gnu_getopt. | |
14 |
|
17 | |||
15 | This is different from getopt.gnu_getopt in that an argument of - will |
|
18 | This is different from getopt.gnu_getopt in that an argument of - will | |
16 | become an argument of - instead of vanishing completely. |
|
19 | become an argument of - instead of vanishing completely. | |
17 | """ |
|
20 | """ | |
18 | extraargs = [] |
|
21 | extraargs = [] | |
19 | if '--' in args: |
|
22 | if '--' in args: | |
20 | stopindex = args.index('--') |
|
23 | stopindex = args.index('--') | |
21 | extraargs = args[stopindex + 1:] |
|
24 | extraargs = args[stopindex + 1:] | |
22 | args = args[:stopindex] |
|
25 | args = args[:stopindex] | |
23 | opts, parseargs = getopt.getopt(args, options, longoptions) |
|
26 | opts, parseargs = getopt.getopt(args, options, longoptions) | |
24 | args = [] |
|
27 | args = [] | |
25 | while parseargs: |
|
28 | while parseargs: | |
26 | arg = parseargs.pop(0) |
|
29 | arg = parseargs.pop(0) | |
27 | if arg and arg[0] == '-' and len(arg) > 1: |
|
30 | if arg and arg[0] == '-' and len(arg) > 1: | |
28 | parseargs.insert(0, arg) |
|
31 | parseargs.insert(0, arg) | |
29 | topts, newparseargs = getopt.getopt(parseargs, options, longoptions) |
|
32 | topts, newparseargs = getopt.getopt(parseargs, options, longoptions) | |
30 | opts = opts + topts |
|
33 | opts = opts + topts | |
31 | parseargs = newparseargs |
|
34 | parseargs = newparseargs | |
32 | else: |
|
35 | else: | |
33 | args.append(arg) |
|
36 | args.append(arg) | |
34 | args.extend(extraargs) |
|
37 | args.extend(extraargs) | |
35 | return opts, args |
|
38 | return opts, args | |
36 |
|
39 | |||
37 |
|
40 | |||
38 | def fancyopts(args, options, state, gnu=False): |
|
41 | def fancyopts(args, options, state, gnu=False): | |
39 | """ |
|
42 | """ | |
40 | read args, parse options, and store options in state |
|
43 | read args, parse options, and store options in state | |
41 |
|
44 | |||
42 | each option is a tuple of: |
|
45 | each option is a tuple of: | |
43 |
|
46 | |||
44 | short option or '' |
|
47 | short option or '' | |
45 | long option |
|
48 | long option | |
46 | default value |
|
49 | default value | |
47 | description |
|
50 | description | |
48 | option value label(optional) |
|
51 | option value label(optional) | |
49 |
|
52 | |||
50 | option types include: |
|
53 | option types include: | |
51 |
|
54 | |||
52 | boolean or none - option sets variable in state to true |
|
55 | boolean or none - option sets variable in state to true | |
53 | string - parameter string is stored in state |
|
56 | string - parameter string is stored in state | |
54 | list - parameter string is added to a list |
|
57 | list - parameter string is added to a list | |
55 | integer - parameter strings is stored as int |
|
58 | integer - parameter strings is stored as int | |
56 | function - call function with parameter |
|
59 | function - call function with parameter | |
57 |
|
60 | |||
58 | non-option args are returned |
|
61 | non-option args are returned | |
59 | """ |
|
62 | """ | |
60 | namelist = [] |
|
63 | namelist = [] | |
61 | shortlist = '' |
|
64 | shortlist = '' | |
62 | argmap = {} |
|
65 | argmap = {} | |
63 | defmap = {} |
|
66 | defmap = {} | |
64 |
|
67 | |||
65 | for option in options: |
|
68 | for option in options: | |
66 | if len(option) == 5: |
|
69 | if len(option) == 5: | |
67 | short, name, default, comment, dummy = option |
|
70 | short, name, default, comment, dummy = option | |
68 | else: |
|
71 | else: | |
69 | short, name, default, comment = option |
|
72 | short, name, default, comment = option | |
70 | # convert opts to getopt format |
|
73 | # convert opts to getopt format | |
71 | oname = name |
|
74 | oname = name | |
72 | name = name.replace('-', '_') |
|
75 | name = name.replace('-', '_') | |
73 |
|
76 | |||
74 | argmap['-' + short] = argmap['--' + oname] = name |
|
77 | argmap['-' + short] = argmap['--' + oname] = name | |
75 | defmap[name] = default |
|
78 | defmap[name] = default | |
76 |
|
79 | |||
77 | # copy defaults to state |
|
80 | # copy defaults to state | |
78 | if isinstance(default, list): |
|
81 | if isinstance(default, list): | |
79 | state[name] = default[:] |
|
82 | state[name] = default[:] | |
80 | elif callable(default): |
|
83 | elif callable(default): | |
81 | state[name] = None |
|
84 | state[name] = None | |
82 | else: |
|
85 | else: | |
83 | state[name] = default |
|
86 | state[name] = default | |
84 |
|
87 | |||
85 | # does it take a parameter? |
|
88 | # does it take a parameter? | |
86 | if not (default is None or default is True or default is False): |
|
89 | if not (default is None or default is True or default is False): | |
87 | if short: |
|
90 | if short: | |
88 | short += ':' |
|
91 | short += ':' | |
89 | if oname: |
|
92 | if oname: | |
90 | oname += '=' |
|
93 | oname += '=' | |
91 | if short: |
|
94 | if short: | |
92 | shortlist += short |
|
95 | shortlist += short | |
93 | if name: |
|
96 | if name: | |
94 | namelist.append(oname) |
|
97 | namelist.append(oname) | |
95 |
|
98 | |||
96 | # parse arguments |
|
99 | # parse arguments | |
97 | if gnu: |
|
100 | if gnu: | |
98 | parse = gnugetopt |
|
101 | parse = gnugetopt | |
99 | else: |
|
102 | else: | |
100 | parse = getopt.getopt |
|
103 | parse = getopt.getopt | |
101 | opts, args = parse(args, shortlist, namelist) |
|
104 | opts, args = parse(args, shortlist, namelist) | |
102 |
|
105 | |||
103 | # transfer result to state |
|
106 | # transfer result to state | |
104 | for opt, val in opts: |
|
107 | for opt, val in opts: | |
105 | name = argmap[opt] |
|
108 | name = argmap[opt] | |
106 | obj = defmap[name] |
|
109 | obj = defmap[name] | |
107 | t = type(obj) |
|
110 | t = type(obj) | |
108 | if callable(obj): |
|
111 | if callable(obj): | |
109 | state[name] = defmap[name](val) |
|
112 | state[name] = defmap[name](val) | |
110 | elif t is type(1): |
|
113 | elif t is type(1): | |
111 | try: |
|
114 | try: | |
112 | state[name] = int(val) |
|
115 | state[name] = int(val) | |
113 | except ValueError: |
|
116 | except ValueError: | |
114 | raise util.Abort(_('invalid value %r for option %s, ' |
|
117 | raise util.Abort(_('invalid value %r for option %s, ' | |
115 | 'expected int') % (val, opt)) |
|
118 | 'expected int') % (val, opt)) | |
116 | elif t is type(''): |
|
119 | elif t is type(''): | |
117 | state[name] = val |
|
120 | state[name] = val | |
118 | elif t is type([]): |
|
121 | elif t is type([]): | |
119 | state[name].append(val) |
|
122 | state[name].append(val) | |
120 | elif t is type(None) or t is type(False): |
|
123 | elif t is type(None) or t is type(False): | |
121 | state[name] = True |
|
124 | state[name] = True | |
122 |
|
125 | |||
123 | # return unparsed args |
|
126 | # return unparsed args | |
124 | return args |
|
127 | return args |
General Comments 0
You need to be logged in to leave comments.
Login now