xref: /petsc/config/BuildSystem/help.py (revision 75f179b0abb60d7a0785d4b2da66cfd7fd2e6844) !
1179860b2SJed Brown'''This module is meant to provide support for information and help systems based upon RDict.'''
2179860b2SJed Brownimport logger
3179860b2SJed Brown
4179860b2SJed Brownclass Info(logger.Logger):
5179860b2SJed Brown  '''This basic class provides information independent of RDict'''
6179860b2SJed Brown  def __init__(self, argDB = None):
7179860b2SJed Brown    '''Creates a dictionary "sections" whose keys are section names, and values are a tuple of (ordinal, nameList)'''
8179860b2SJed Brown    logger.Logger.__init__(self, None, argDB)
9179860b2SJed Brown    self.sections = {}
10179860b2SJed Brown    return
11179860b2SJed Brown
12179860b2SJed Brown  def getTitle(self):
13179860b2SJed Brown    return self._title
14179860b2SJed Brown
15179860b2SJed Brown  def setTitle(self, title):
16179860b2SJed Brown    self._title = str(title)
17179860b2SJed Brown  title = property(getTitle, setTitle, None, 'Title of the Information Menu')
18179860b2SJed Brown
19179860b2SJed Brown  def getDescription(self, section, name):
20179860b2SJed Brown    return self._desc[(section, name)]
21179860b2SJed Brown
22179860b2SJed Brown  def setDescription(self, section, name, desc):
23179860b2SJed Brown    if not hasattr(self, '_desc'):
24179860b2SJed Brown      self._desc = {}
25179860b2SJed Brown    self._desc[(section, name)] = desc
26179860b2SJed Brown    return
27179860b2SJed Brown
28179860b2SJed Brown  def addArgument(self, section, name, desc):
29179860b2SJed Brown    '''Add an argument with given name and string to an information section'''
30179860b2SJed Brown    if not section in self.sections:
31179860b2SJed Brown      self.sections[section] = (len(self.sections), [])
32179860b2SJed Brown    if name in self.sections[section][1]:
33179860b2SJed Brown      name += '@'+str(len(filter(lambda n: name == n.split('@')[0], self.sections[section][1]))+1)
34179860b2SJed Brown    self.sections[section][1].append(name)
35179860b2SJed Brown    self.setDescription(section, name, desc)
36179860b2SJed Brown    return
37179860b2SJed Brown
38179860b2SJed Brown  def printBanner(self, f):
39179860b2SJed Brown    '''Print a banner for the information screen'''
40179860b2SJed Brown    f.write(self.title+'\n')
41179860b2SJed Brown    for i in range(max(map(len, self.title.split('\n')))): f.write('-')
42179860b2SJed Brown    f.write('\n')
43179860b2SJed Brown    return
44179860b2SJed Brown
45179860b2SJed Brown  def getTextSizes(self):
46179860b2SJed Brown    '''Returns the maximum name and description lengths'''
47179860b2SJed Brown    nameLen = 1
48179860b2SJed Brown    descLen = 1
49179860b2SJed Brown    for section in self.sections:
50179860b2SJed Brown      nameLen = max([nameLen, max(map(lambda n: len(n.split('@')[0]), self.sections[section][1]))+1])
51179860b2SJed Brown      descLen = max([descLen, max(map(lambda name: len(self.getDescription(section, name)), self.sections[section][1]))+1])
52179860b2SJed Brown    return (nameLen, descLen)
53179860b2SJed Brown
54179860b2SJed Brown  def output(self, f = None):
55179860b2SJed Brown    '''Print a help screen with all the argument information.'''
56179860b2SJed Brown    if f is  None:
57179860b2SJed Brown      import sys
58179860b2SJed Brown      f = sys.stdout
59179860b2SJed Brown    self.printBanner(f)
60179860b2SJed Brown    (nameLen, descLen) = self.getTextSizes()
61179860b2SJed Brown    format = '  %-'+str(nameLen)+'s: %s\n'
62179860b2SJed Brown    items  = self.sections.items()
63179860b2SJed Brown    items.sort(lambda a, b: a[1][0].__cmp__(b[1][0]))
64179860b2SJed Brown    for section, names in items:
65179860b2SJed Brown      f.write(section+':\n')
66179860b2SJed Brown      for name in names[1]:
67179860b2SJed Brown        f.write(format % (name.split('@')[0], self.getDescription(section, name)))
68179860b2SJed Brown    return
69179860b2SJed Brown
70179860b2SJed Brownclass Help(Info):
71179860b2SJed Brown  '''Help provides a simple help system for RDict'''
72179860b2SJed Brown  def __init__(self, argDB):
73179860b2SJed 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.'''
74179860b2SJed Brown    Info.__init__(self, argDB)
75179860b2SJed Brown    self.title = 'Help'
76179860b2SJed Brown    return
77179860b2SJed Brown
78179860b2SJed Brown  def getDescription(self, section, name):
79179860b2SJed Brown    return self.argDB.getType(self.getArgName(name)).help
80179860b2SJed Brown
81179860b2SJed Brown  def setDescription(self, section, name, desc):
82179860b2SJed Brown    return
83179860b2SJed Brown
84179860b2SJed Brown  def getArgName(self, name):
85179860b2SJed Brown    '''Return the RDict key corresponding to a more verbose help name. Right now, this means discard everything after "=".'''
86179860b2SJed Brown    #return name.split('=')[0].strip('-')
87179860b2SJed Brown    argName = name.split('=')[0]
88179860b2SJed Brown    while argName[0] == '-': argName = argName[1:]
89179860b2SJed Brown    return argName
90179860b2SJed Brown
91179860b2SJed Brown  def addArgument(self, section, name, argType, ignoreDuplicates = 0):
92179860b2SJed 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.'''
93179860b2SJed Brown##  super(Info, self).addArgument(section, name, None)
94179860b2SJed Brown    if section in self.sections:
95179860b2SJed Brown      if name in self.sections[section][1]:
96179860b2SJed Brown        if ignoreDuplicates:
97179860b2SJed Brown          return
98179860b2SJed Brown        raise RuntimeError('Duplicate configure option '+name+' in section '+section)
99179860b2SJed Brown    else:
100179860b2SJed Brown      self.sections[section] = (len(self.sections), [])
101179860b2SJed Brown    if not argType.deprecated:
102179860b2SJed Brown      self.sections[section][1].append(name)
103179860b2SJed Brown
104179860b2SJed Brown    self.argDB.setType(self.getArgName(name), argType, forceLocal = 1)
105179860b2SJed Brown    return
106179860b2SJed Brown
107*75f179b0SBarry Smith  def addDownload(self,name,dlist):
108*75f179b0SBarry Smith    if not hasattr(self.argDB,'dlist'):
109*75f179b0SBarry Smith      self.argDB.dlist = {}
110*75f179b0SBarry Smith    else:
111*75f179b0SBarry Smith      self.argDB.dlist[name] = dlist
112*75f179b0SBarry Smith
113179860b2SJed Brown  def output(self, f = None, sections = None):
114179860b2SJed Brown    '''Print a help screen with all the argument information.'''
115179860b2SJed Brown    if f is  None:
116179860b2SJed Brown      import sys
117179860b2SJed Brown      f = sys.stdout
118179860b2SJed Brown    if sections: sections = [s.lower() for s in sections]
119179860b2SJed Brown    self.printBanner(f)
120179860b2SJed Brown    (nameLen, descLen) = self.getTextSizes()
121179860b2SJed Brown#    format    = '  -%-'+str(nameLen)+'s: %s\n'
122179860b2SJed Brown#    formatDef = '  -%-'+str(nameLen)+'s: %-'+str(descLen)+'s  current: %s\n'
123179860b2SJed Brown    format    = '  -%s\n       %s\n'
124179860b2SJed Brown    formatDef = '  -%s\n       %s  current: %s\n'
125179860b2SJed Brown    items = self.sections.items()
126179860b2SJed Brown    items.sort(lambda a, b: a[1][0].__cmp__(b[1][0]))
127179860b2SJed Brown    for section, names in items:
128179860b2SJed Brown      if sections and not section.lower() in sections: continue
129179860b2SJed Brown      f.write(section+':\n')
130179860b2SJed Brown      for name in names[1]:
131179860b2SJed Brown        argName = self.getArgName(name)
132179860b2SJed Brown        type    = self.argDB.getType(argName)
133179860b2SJed Brown        if argName in self.argDB:
134179860b2SJed Brown          f.write(formatDef % (name, type.help, str(self.argDB.getType(argName))))
135179860b2SJed Brown        else:
136179860b2SJed Brown          f.write(format % (name, type.help))
137179860b2SJed Brown    return
138*75f179b0SBarry Smith
139*75f179b0SBarry Smith  def outputDownload(self):
140*75f179b0SBarry Smith    import nargs
141*75f179b0SBarry Smith    import os
142*75f179b0SBarry Smith    import sys
143*75f179b0SBarry Smith    pkgdir = nargs.Arg.findArgument('with-packages-dir', self.clArgs)
144*75f179b0SBarry Smith    missing = 0
145*75f179b0SBarry Smith    print 'Download the following packages to '+pkgdir+' \n'
146*75f179b0SBarry Smith    for i in self.argDB.dlist.keys():
147*75f179b0SBarry Smith      if not nargs.Arg.findArgument('download-'+i, self.clArgs) == None and not nargs.Arg.findArgument('download-'+i, self.clArgs) == '0':
148*75f179b0SBarry Smith        dlist = self.argDB.dlist[i]
149*75f179b0SBarry Smith        found = 0
150*75f179b0SBarry Smith        for k in range(0,len(dlist)):
151*75f179b0SBarry Smith          fd = os.path.join(pkgdir,os.path.basename(dlist[k]))
152*75f179b0SBarry Smith          if os.path.isdir(fd) or os.path.isfile(fd):
153*75f179b0SBarry Smith            found = 1
154*75f179b0SBarry Smith            for k in range(0,len(self.clArgs)):
155*75f179b0SBarry Smith              if self.clArgs[k].startswith('--download-'+i):
156*75f179b0SBarry Smith                self.clArgs[k] = 'download-'+i+'='+fd
157*75f179b0SBarry Smith                self.argDB.insertArgs([self.clArgs[k]])
158*75f179b0SBarry Smith            break
159*75f179b0SBarry Smith        if not found:
160*75f179b0SBarry Smith          print i + ' ' + str(self.argDB.dlist[i])
161*75f179b0SBarry Smith          missing = 1
162*75f179b0SBarry Smith    if missing:
163*75f179b0SBarry Smith      sys.exit()
164*75f179b0SBarry Smith
165*75f179b0SBarry Smith
166