"""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 = {}
|