"""Handle command line arguments.
This module contains functions to parse and access the arguments given
to the program on the command line.
"""
import types
import string
import sys
# Symbolic constants for the indexes into an argument specifier tuple.
NAME = 0
MANDATORY = 1
TYPE = 2
HELP = 3
DEFAULT = 4
SPEC_LENGTH = 5
Bool = []
helpSpec = (
('help', 0, Bool, 'print help and exit'),
)
def parseArgs(title, argv, argSpecs, filesOK):
"""Parse and check command line arguments.
Scan the command line arguments in *argv* according to the argument
specifier *argSpecs*. Return **None** if there are no errors in
the arguments, otherwise return an error string describing the error.
This function must be called to initialise this module.
title -- The name of the program. This is used when returning
error messages or help text.
argv -- A sequence containing the arguments given to the program.
Normally **sys.argv**.
argSpecs -- A sequence of argument specifiers. Each specifier describes
a valid command line argument and consists of 4 or 5 items:
- The argument name (without a leading minus sign **-**).
- A boolean value, true if the argument is mandatory.
- This should be **Args.Bool** if the argument has no option.
Otherwise it should be a string describing the option
required for this argument. This is used when printing help.
- A short string describing the argument.
- The default value of the argument. This should only be used
for non-mandatory arguments expecting an option.
For example:
(
('foreground', 0, 'colour', 'colour of text', 'black'),
('geometry', 0, 'spec', 'geometry of initial window'),
('server', 1, 'ompserver', 'ompserver to connect to'),
('silent', 0, Args.Bool, 'do not sound bell'),
)
"""
global programName
global _fileList
errMsg = title + ' command line error: '
programName = argv[0];
argSpecs = helpSpec + argSpecs
argSpecDic = {}
for spec in argSpecs:
arg = spec[NAME]
argSpecDic[arg] = spec
if len(spec) >= SPEC_LENGTH:
set(arg, spec[DEFAULT])
elif spec[TYPE] is Bool:
set(arg, 0)
else:
set(arg, None)
knownKeys = argSpecDic.keys()
i = 1
_fileList = []
argc = len(argv)
while i < argc:
arg = argv[i]
key = arg[1:]
if key in knownKeys:
spec = argSpecDic[key]
if spec[TYPE] is Bool:
set(key, 1)
else:
i = i + 1
if i >= argc:
return errMsg + 'missing argument to \'' + arg + '\' option.'
value = argv[i]
if len(spec) >= SPEC_LENGTH:
try:
if type(spec[DEFAULT]) == types.IntType:
typeStr = 'integer'
value = string.atoi(value)
elif type(spec[DEFAULT]) == types.FloatType:
typeStr = 'float'
value = string.atof(value)
except:
sys.exc_traceback = None # Clean up object references
return errMsg + 'cannot convert string \'' + value + \
'\' to ' + typeStr + ' for option \'-' + key + '\'.'
set(key, value)
else:
_fileList.append(arg)
i = i + 1
if get('help'):
return _helpString(title, argSpecs)
if not filesOK and len(_fileList) > 0:
if len(_fileList) == 1:
return errMsg + 'unknown option \'' + str(_fileList[0]) + '\'.'
else:
return errMsg + 'unknown options ' + str(_fileList) + '.'
_missing = []
for spec in argSpecs:
if spec[MANDATORY] and get(spec[NAME]) is None:
_missing.append(spec[NAME])
if len(_missing) == 1:
return errMsg + 'required argument \'-' + \
str(_missing[0]) + '\' is missing.'
elif len(_missing) > 1:
return errMsg + 'required arguments ' + \
str(map(lambda s: '-' + s, _missing)) + ' are missing.'
return None
def fileList():
return _fileList
def _helpString(title, argSpecs):
max = 0
for spec in argSpecs:
if spec[TYPE] is Bool:
width = len(spec[NAME]) + 1
else:
width = len(spec[NAME]) + 4 + len(spec[TYPE])
if width > max:
max = width
rtn = title + ' command line arguments:'
format = '\n %-' + str(max) + 's %s'
for mandatory in (1, 0):
needHeader = 1
for spec in argSpecs:
if mandatory and spec[MANDATORY] or not mandatory and not spec[MANDATORY]:
if needHeader:
if mandatory:
rtn = rtn + '\n Mandatory arguments:'
else:
rtn = rtn + '\n Optional arguments (defaults in parentheses):'
needHeader = 0
if spec[TYPE] is Bool:
arg = '-%s' % spec[NAME]
else:
arg = '-%s <%s>' % (spec[NAME], spec[TYPE])
if len(spec) >= SPEC_LENGTH:
if type(spec[DEFAULT]) == types.StringType:
definition = spec[HELP] + ' (' + spec[DEFAULT] + ')'
else:
definition = spec[HELP] + ' (' + str(spec[DEFAULT]) + ')'
else:
definition = spec[HELP]
rtn = rtn + format % (arg, definition)
return rtn
def exists(key):
return configDict.has_key(key)
def get(key):
return configDict[key]
def set(key, value):
global configDict
configDict[key] = value
configDict = {}
|