xref: /petsc/config/BuildSystem/help.py (revision 179860b23afbef20daed3359c1645679d1efa988)
1*179860b2SJed Brown'''This module is meant to provide support for information and help systems based upon RDict.'''
2*179860b2SJed Brownimport logger
3*179860b2SJed Brown
4*179860b2SJed Brownclass Info(logger.Logger):
5*179860b2SJed Brown  '''This basic class provides information independent of RDict'''
6*179860b2SJed Brown  def __init__(self, argDB = None):
7*179860b2SJed Brown    '''Creates a dictionary "sections" whose keys are section names, and values are a tuple of (ordinal, nameList)'''
8*179860b2SJed Brown    logger.Logger.__init__(self, None, argDB)
9*179860b2SJed Brown    self.sections = {}
10*179860b2SJed Brown    return
11*179860b2SJed Brown
12*179860b2SJed Brown  def getTitle(self):
13*179860b2SJed Brown    return self._title
14*179860b2SJed Brown
15*179860b2SJed Brown  def setTitle(self, title):
16*179860b2SJed Brown    self._title = str(title)
17*179860b2SJed Brown  title = property(getTitle, setTitle, None, 'Title of the Information Menu')
18*179860b2SJed Brown
19*179860b2SJed Brown  def getDescription(self, section, name):
20*179860b2SJed Brown    return self._desc[(section, name)]
21*179860b2SJed Brown
22*179860b2SJed Brown  def setDescription(self, section, name, desc):
23*179860b2SJed Brown    if not hasattr(self, '_desc'):
24*179860b2SJed Brown      self._desc = {}
25*179860b2SJed Brown    self._desc[(section, name)] = desc
26*179860b2SJed Brown    return
27*179860b2SJed Brown
28*179860b2SJed Brown  def addArgument(self, section, name, desc):
29*179860b2SJed Brown    '''Add an argument with given name and string to an information section'''
30*179860b2SJed Brown    if not section in self.sections:
31*179860b2SJed Brown      self.sections[section] = (len(self.sections), [])
32*179860b2SJed Brown    if name in self.sections[section][1]:
33*179860b2SJed Brown      name += '@'+str(len(filter(lambda n: name == n.split('@')[0], self.sections[section][1]))+1)
34*179860b2SJed Brown    self.sections[section][1].append(name)
35*179860b2SJed Brown    self.setDescription(section, name, desc)
36*179860b2SJed Brown    return
37*179860b2SJed Brown
38*179860b2SJed Brown  def printBanner(self, f):
39*179860b2SJed Brown    '''Print a banner for the information screen'''
40*179860b2SJed Brown    f.write(self.title+'\n')
41*179860b2SJed Brown    for i in range(max(map(len, self.title.split('\n')))): f.write('-')
42*179860b2SJed Brown    f.write('\n')
43*179860b2SJed Brown    return
44*179860b2SJed Brown
45*179860b2SJed Brown  def getTextSizes(self):
46*179860b2SJed Brown    '''Returns the maximum name and description lengths'''
47*179860b2SJed Brown    nameLen = 1
48*179860b2SJed Brown    descLen = 1
49*179860b2SJed Brown    for section in self.sections:
50*179860b2SJed Brown      nameLen = max([nameLen, max(map(lambda n: len(n.split('@')[0]), self.sections[section][1]))+1])
51*179860b2SJed Brown      descLen = max([descLen, max(map(lambda name: len(self.getDescription(section, name)), self.sections[section][1]))+1])
52*179860b2SJed Brown    return (nameLen, descLen)
53*179860b2SJed Brown
54*179860b2SJed Brown  def output(self, f = None):
55*179860b2SJed Brown    '''Print a help screen with all the argument information.'''
56*179860b2SJed Brown    if f is  None:
57*179860b2SJed Brown      import sys
58*179860b2SJed Brown      f = sys.stdout
59*179860b2SJed Brown    self.printBanner(f)
60*179860b2SJed Brown    (nameLen, descLen) = self.getTextSizes()
61*179860b2SJed Brown    format = '  %-'+str(nameLen)+'s: %s\n'
62*179860b2SJed Brown    items  = self.sections.items()
63*179860b2SJed Brown    items.sort(lambda a, b: a[1][0].__cmp__(b[1][0]))
64*179860b2SJed Brown    for section, names in items:
65*179860b2SJed Brown      f.write(section+':\n')
66*179860b2SJed Brown      for name in names[1]:
67*179860b2SJed Brown        f.write(format % (name.split('@')[0], self.getDescription(section, name)))
68*179860b2SJed Brown    return
69*179860b2SJed Brown
70*179860b2SJed Brownclass Help(Info):
71*179860b2SJed Brown  '''Help provides a simple help system for RDict'''
72*179860b2SJed Brown  def __init__(self, argDB):
73*179860b2SJed Brown    '''Creates a dictionary "sections" whose keys are section names, and values are a tuple of (ordinal, nameList). Also provide the RDict upon which this will be based.'''
74*179860b2SJed Brown    Info.__init__(self, argDB)
75*179860b2SJed Brown    self.title = 'Help'
76*179860b2SJed Brown    return
77*179860b2SJed Brown
78*179860b2SJed Brown  def getDescription(self, section, name):
79*179860b2SJed Brown    return self.argDB.getType(self.getArgName(name)).help
80*179860b2SJed Brown
81*179860b2SJed Brown  def setDescription(self, section, name, desc):
82*179860b2SJed Brown    return
83*179860b2SJed Brown
84*179860b2SJed Brown  def getArgName(self, name):
85*179860b2SJed Brown    '''Return the RDict key corresponding to a more verbose help name. Right now, this means discard everything after "=".'''
86*179860b2SJed Brown    #return name.split('=')[0].strip('-')
87*179860b2SJed Brown    argName = name.split('=')[0]
88*179860b2SJed Brown    while argName[0] == '-': argName = argName[1:]
89*179860b2SJed Brown    return argName
90*179860b2SJed Brown
91*179860b2SJed Brown  def addArgument(self, section, name, argType, ignoreDuplicates = 0):
92*179860b2SJed Brown    '''Add an argument with given name and type to a help section. The type, which can also have an initializer and help string, will be put into RDict.'''
93*179860b2SJed Brown##  super(Info, self).addArgument(section, name, None)
94*179860b2SJed Brown    if section in self.sections:
95*179860b2SJed Brown      if name in self.sections[section][1]:
96*179860b2SJed Brown        if ignoreDuplicates:
97*179860b2SJed Brown          return
98*179860b2SJed Brown        raise RuntimeError('Duplicate configure option '+name+' in section '+section)
99*179860b2SJed Brown    else:
100*179860b2SJed Brown      self.sections[section] = (len(self.sections), [])
101*179860b2SJed Brown    if not argType.deprecated:
102*179860b2SJed Brown      self.sections[section][1].append(name)
103*179860b2SJed Brown
104*179860b2SJed Brown    self.argDB.setType(self.getArgName(name), argType, forceLocal = 1)
105*179860b2SJed Brown    return
106*179860b2SJed Brown
107*179860b2SJed Brown  def output(self, f = None, sections = None):
108*179860b2SJed Brown    '''Print a help screen with all the argument information.'''
109*179860b2SJed Brown    if f is  None:
110*179860b2SJed Brown      import sys
111*179860b2SJed Brown      f = sys.stdout
112*179860b2SJed Brown    if sections: sections = [s.lower() for s in sections]
113*179860b2SJed Brown    self.printBanner(f)
114*179860b2SJed Brown    (nameLen, descLen) = self.getTextSizes()
115*179860b2SJed Brown#    format    = '  -%-'+str(nameLen)+'s: %s\n'
116*179860b2SJed Brown#    formatDef = '  -%-'+str(nameLen)+'s: %-'+str(descLen)+'s  current: %s\n'
117*179860b2SJed Brown    format    = '  -%s\n       %s\n'
118*179860b2SJed Brown    formatDef = '  -%s\n       %s  current: %s\n'
119*179860b2SJed Brown    items = self.sections.items()
120*179860b2SJed Brown    items.sort(lambda a, b: a[1][0].__cmp__(b[1][0]))
121*179860b2SJed Brown    for section, names in items:
122*179860b2SJed Brown      if sections and not section.lower() in sections: continue
123*179860b2SJed Brown      f.write(section+':\n')
124*179860b2SJed Brown      for name in names[1]:
125*179860b2SJed Brown        argName = self.getArgName(name)
126*179860b2SJed Brown        type    = self.argDB.getType(argName)
127*179860b2SJed Brown        if argName in self.argDB:
128*179860b2SJed Brown          f.write(formatDef % (name, type.help, str(self.argDB.getType(argName))))
129*179860b2SJed Brown        else:
130*179860b2SJed Brown          f.write(format % (name, type.help))
131*179860b2SJed Brown    return
132