111 lines
3.1 KiB
Python
111 lines
3.1 KiB
Python
![]() |
# fancyopts.py - better command line parsing
|
||
|
#
|
||
|
# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
|
||
|
#
|
||
|
# This software may be used and distributed according to the terms of the
|
||
|
# GNU General Public License version 2, incorporated herein by reference.
|
||
|
|
||
|
import getopt
|
||
|
|
||
|
def gnugetopt(args, options, longoptions):
|
||
|
"""Parse options mostly like getopt.gnu_getopt.
|
||
|
|
||
|
This is different from getopt.gnu_getopt in that an argument of - will
|
||
|
become an argument of - instead of vanishing completely.
|
||
|
"""
|
||
|
extraargs = []
|
||
|
if '--' in args:
|
||
|
stopindex = args.index('--')
|
||
|
extraargs = args[stopindex+1:]
|
||
|
args = args[:stopindex]
|
||
|
opts, parseargs = getopt.getopt(args, options, longoptions)
|
||
|
args = []
|
||
|
while parseargs:
|
||
|
arg = parseargs.pop(0)
|
||
|
if arg and arg[0] == '-' and len(arg) > 1:
|
||
|
parseargs.insert(0, arg)
|
||
|
topts, newparseargs = getopt.getopt(parseargs, options, longoptions)
|
||
|
opts = opts + topts
|
||
|
parseargs = newparseargs
|
||
|
else:
|
||
|
args.append(arg)
|
||
|
args.extend(extraargs)
|
||
|
return opts, args
|
||
|
|
||
|
|
||
|
def fancyopts(args, options, state, gnu=False):
|
||
|
"""
|
||
|
read args, parse options, and store options in state
|
||
|
|
||
|
each option is a tuple of:
|
||
|
|
||
|
short option or ''
|
||
|
long option
|
||
|
default value
|
||
|
description
|
||
|
|
||
|
option types include:
|
||
|
|
||
|
boolean or none - option sets variable in state to true
|
||
|
string - parameter string is stored in state
|
||
|
list - parameter string is added to a list
|
||
|
integer - parameter strings is stored as int
|
||
|
function - call function with parameter
|
||
|
|
||
|
non-option args are returned
|
||
|
"""
|
||
|
namelist = []
|
||
|
shortlist = ''
|
||
|
argmap = {}
|
||
|
defmap = {}
|
||
|
|
||
|
for short, name, default, comment in options:
|
||
|
# convert opts to getopt format
|
||
|
oname = name
|
||
|
name = name.replace('-', '_')
|
||
|
|
||
|
argmap['-' + short] = argmap['--' + oname] = name
|
||
|
defmap[name] = default
|
||
|
|
||
|
# copy defaults to state
|
||
|
if isinstance(default, list):
|
||
|
state[name] = default[:]
|
||
|
elif hasattr(default, '__call__'):
|
||
|
state[name] = None
|
||
|
else:
|
||
|
state[name] = default
|
||
|
|
||
|
# does it take a parameter?
|
||
|
if not (default is None or default is True or default is False):
|
||
|
if short: short += ':'
|
||
|
if oname: oname += '='
|
||
|
if short:
|
||
|
shortlist += short
|
||
|
if name:
|
||
|
namelist.append(oname)
|
||
|
|
||
|
# parse arguments
|
||
|
if gnu:
|
||
|
parse = gnugetopt
|
||
|
else:
|
||
|
parse = getopt.getopt
|
||
|
opts, args = parse(args, shortlist, namelist)
|
||
|
|
||
|
# transfer result to state
|
||
|
for opt, val in opts:
|
||
|
name = argmap[opt]
|
||
|
t = type(defmap[name])
|
||
|
if t is type(fancyopts):
|
||
|
state[name] = defmap[name](val)
|
||
|
elif t is type(1):
|
||
|
state[name] = int(val)
|
||
|
elif t is type(''):
|
||
|
state[name] = val
|
||
|
elif t is type([]):
|
||
|
state[name].append(val)
|
||
|
elif t is type(None) or t is type(False):
|
||
|
state[name] = True
|
||
|
|
||
|
# return unparsed args
|
||
|
return args
|