224 args.append(arg) |
224 args.append(arg) |
225 args.extend(extraargs) |
225 args.extend(extraargs) |
226 return opts, args |
226 return opts, args |
227 |
227 |
228 |
228 |
229 def fancyopts(args, options, state, gnu=False, early=False): |
229 def fancyopts(args, options, state, gnu=False, early=False, optaliases=None): |
230 """ |
230 """ |
231 read args, parse options, and store options in state |
231 read args, parse options, and store options in state |
232 |
232 |
233 each option is a tuple of: |
233 each option is a tuple of: |
234 |
234 |
244 string - parameter string is stored in state |
244 string - parameter string is stored in state |
245 list - parameter string is added to a list |
245 list - parameter string is added to a list |
246 integer - parameter strings is stored as int |
246 integer - parameter strings is stored as int |
247 function - call function with parameter |
247 function - call function with parameter |
248 |
248 |
|
249 optaliases is a mapping from a canonical option name to a list of |
|
250 additional long options. This exists for preserving backward compatibility |
|
251 of early options. If we want to use it extensively, please consider moving |
|
252 the functionality to the options table (e.g separate long options by '|'.) |
|
253 |
249 non-option args are returned |
254 non-option args are returned |
250 """ |
255 """ |
|
256 if optaliases is None: |
|
257 optaliases = {} |
251 namelist = [] |
258 namelist = [] |
252 shortlist = '' |
259 shortlist = '' |
253 argmap = {} |
260 argmap = {} |
254 defmap = {} |
261 defmap = {} |
255 negations = {} |
262 negations = {} |
259 if len(option) == 5: |
266 if len(option) == 5: |
260 short, name, default, comment, dummy = option |
267 short, name, default, comment, dummy = option |
261 else: |
268 else: |
262 short, name, default, comment = option |
269 short, name, default, comment = option |
263 # convert opts to getopt format |
270 # convert opts to getopt format |
264 oname = name |
271 onames = [name] |
|
272 onames.extend(optaliases.get(name, [])) |
265 name = name.replace('-', '_') |
273 name = name.replace('-', '_') |
266 |
274 |
267 argmap['-' + short] = argmap['--' + oname] = name |
275 argmap['-' + short] = name |
|
276 for n in onames: |
|
277 argmap['--' + n] = name |
268 defmap[name] = default |
278 defmap[name] = default |
269 |
279 |
270 # copy defaults to state |
280 # copy defaults to state |
271 if isinstance(default, list): |
281 if isinstance(default, list): |
272 state[name] = default[:] |
282 state[name] = default[:] |
277 |
287 |
278 # does it take a parameter? |
288 # does it take a parameter? |
279 if not (default is None or default is True or default is False): |
289 if not (default is None or default is True or default is False): |
280 if short: |
290 if short: |
281 short += ':' |
291 short += ':' |
282 if oname: |
292 onames = [n + '=' for n in onames] |
283 oname += '=' |
293 elif name not in nevernegate: |
284 elif oname not in nevernegate: |
294 for n in onames: |
285 if oname.startswith('no-'): |
295 if n.startswith('no-'): |
286 insert = oname[3:] |
296 insert = n[3:] |
287 else: |
297 else: |
288 insert = 'no-' + oname |
298 insert = 'no-' + n |
289 # backout (as a practical example) has both --commit and |
299 # backout (as a practical example) has both --commit and |
290 # --no-commit options, so we don't want to allow the |
300 # --no-commit options, so we don't want to allow the |
291 # negations of those flags. |
301 # negations of those flags. |
292 if insert not in alllong: |
302 if insert not in alllong: |
293 assert ('--' + oname) not in negations |
303 assert ('--' + n) not in negations |
294 negations['--' + insert] = '--' + oname |
304 negations['--' + insert] = '--' + n |
295 namelist.append(insert) |
305 namelist.append(insert) |
296 if short: |
306 if short: |
297 shortlist += short |
307 shortlist += short |
298 if name: |
308 if name: |
299 namelist.append(oname) |
309 namelist.extend(onames) |
300 |
310 |
301 # parse arguments |
311 # parse arguments |
302 if early: |
312 if early: |
303 parse = functools.partial(earlygetopt, gnu=gnu) |
313 parse = functools.partial(earlygetopt, gnu=gnu) |
304 elif gnu: |
314 elif gnu: |