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