# simopts.py -- provide central repository/interface for importing/exposing known commandline options # across several utilities # --[no]yaycct # # Michael Thomas # Center for Computation & Technology # Louisiana State University # # import os import sys import optparse from optparse import OptionParser from optparse import OptionGroup import pyini import libutil class OptionManager: def __init__(self, optiondir): self.optionDirectory = optiondir self.parsers = dict() self.usedGroups = ["common"] self.usageString = "usage: %prog [options] arg" self.optionParser = None self.options = None self.args = None self.optionParser = None # find and init our option groups. self.Discovery() def PrintHelp(self): self.optionParser.print_help() def BuildOptionString(self, stripArguments=None): if self.options == None: return "" keys = self.options.__dict__.keys() ostr = str() for key in keys: if stripArguments != None and key in stripArguments: continue if key.startswith("__"): continue if key.startswith("["): continue value = getattr(self.options, key) if value == None: continue if value == True: ostr = "%s --%s" % (ostr, key) elif value == False: ostr = "%s --no%s" % (ostr, key) else: ostr = "%s --%s=%s" % (ostr, key, value) return ostr.strip() # -- ACCESSOR METHODS -- def HasOption(self, option): o = getattr(self.options, option, None) if o == None: return False return True def GetOption(self, option): return getattr(self.options, option, None) # -- BUILD METHODS -- def Discovery(self): try: os.stat(self.optionDirectory) except OSError: print "Error while attempting to read option dir: could not open %s for reading" % self.optionDirectory sys.exit(1) files = os.listdir(self.optionDirectory) for f in files: if f.count(".ini"): parts = os.path.splitext(f) basename = parts[0] full_path = "%s/%s" % (self.optionDirectory, f) self.parsers[basename] = pyini.IniParser(full_path) def SetUsage(self, ss): self.usageString = ss def HasGroup(self, group): return self.parsers.has_key(group) def UseGroup(self, group): if self.HasGroup(group): self.usedGroups.append(group) return print "Error when specifying option group %s: group %s does not exist" % (group, group) sys.exit(1) def Build(self): self.optionParser = OptionParser(usage=self.usageString) for group in self.usedGroups: if group == "common": self.AddOptions(self.optionParser, group) else: og = OptionGroup(self.optionParser, "Options from %s" % group) self.AddOptions(og, group) self.optionParser.add_option_group(og) (self.options, self.args) = self.optionParser.parse_args() def AddOptions(self, op, group): if not(self.HasGroup(group)): print "Could not retreive ini parser for option group %s" % group sys.exit(1) parser = self.parsers[group] options = parser.GetSections() for o in options: sdict = parser.GetSectionAsDict(o) self.AddOption(op, o, sdict) def AddOption(self, op, option, sdict): if sdict['negatable'].value == 'yes' and sdict.has_key('short'): print "Error parsing option %s: cannot negate a short option" % option sys.exit(1) if sdict.has_key("short"): optstring = '"%s", "%s"' % (sdict['short'].value, sdict['long'].value) else: optstring = '"%s"' % sdict['long'].value optstring = self.AddOptionToOptionString(optstring, 'dest', option) if sdict['arg'].value == "yes": optstring = self.AddOptionToOptionString(optstring, 'metavar', sdict['argformat'].value) optstring = self.AddOptionToOptionString(optstring, 'type', sdict['argtype'].value) else: optstring = self.AddOptionToOptionString(optstring, 'action', 'store_true') if sdict.has_key('default'): optstring = '%s,%s=%s' % (optstring, 'default', libutil.CoerseBool(sdict['default'].value)) help = sdict['desc'].value if sdict.has_key('default'): help = "%s %s" % (help, '[default: %default]') if sdict['negatable'].value == 'yes': optstring = '%s,%s=%s' % (optstring, 'help', 'optparse.SUPPRESS_HELP') else: optstring = self.AddOptionToOptionString(optstring, 'help', help) cmd = "op.add_option(%s)" % optstring #print cmd eval(cmd) if sdict['negatable'].value == 'yes': self.AddMetaOption(op, option, sdict) self.AddNegatedOption(op, option, sdict, "no") self.AddNegatedOption(op, option, sdict, "no-") return def AddNegatedOption(self, op, option, sdict, prefix): optstring = '"--%s%s"' % (prefix, option) optstring = self.AddOptionToOptionString(optstring, 'dest', option) optstring = self.AddOptionToOptionString(optstring, 'action', 'store_false') #optstring = self.AddOptionToOptionString(optstring, 'default', False) optstring = '%s,%s=%s' % (optstring, 'help', 'optparse.SUPPRESS_HELP') cmd = "op.add_option(%s)" % optstring eval(cmd) def AddMetaOption(self, op, option, sdict): sdict['long'].value = "--[no]%s" % option optstring = '"%s"' % sdict['long'].value if sdict.has_key('default'): optstring = self.AddOptionToOptionString(optstring, 'default', libutil.CoerseBool(sdict['default'].value)) help = sdict['desc'].value if sdict.has_key('default'): help = "%s %s" % (help, '[default: %default]') optstring = self.AddOptionToOptionString(optstring, 'metavar', option) optstring = self.AddOptionToOptionString(optstring, 'help', help) cmd = "op.add_option(%s)" % optstring eval(cmd) def AddOptionToOptionString(self, os, option, value): return '%s,%s="%s"' % (os, option, value)