xref: /petsc/config/BuildSystem/nargs.py (revision 9992b25421ba8bb0688d84c613f293528435cb97)
1179860b2SJed Browntry:
2179860b2SJed Brown  import readline
3179860b2SJed Brownexcept ImportError: pass
4179860b2SJed Brown
5179860b2SJed Browndef getInteractive():
6179860b2SJed Brown  return isInteractive
7179860b2SJed Brown
8179860b2SJed Browndef setInteractive(interactive):
9179860b2SJed Brown  global isInteractive
10179860b2SJed Brown  isInteractive = interactive
11179860b2SJed Brown  return
12179860b2SJed Brown
13179860b2SJed Browndef checkInteractive(key):
14179860b2SJed Brown  if not isInteractive:
15179860b2SJed Brown    raise ValueError('Value not set for key '+str(key))
16179860b2SJed Brown  return
17179860b2SJed BrownsetInteractive(1)
18179860b2SJed Brown
19179860b2SJed Brownclass Arg(object):
20179860b2SJed Brown  '''This is the base class for all objects contained in RDict. Access to the raw argument values is
21179860b2SJed Brownprovided by getValue() and setValue(). These objects can be thought of as type objects for the
22179860b2SJed Brownvalues themselves. It is possible to set an Arg in the RDict which has not yet been assigned a value
23179860b2SJed Brownin order to declare the type of that option.
24179860b2SJed Brown
25179860b2SJed BrownInputs which cannot be converted to the correct type will cause TypeError, those failing validation
26179860b2SJed Browntests will cause ValueError.
27179860b2SJed Brown'''
28179860b2SJed Brown  def __init__(self, key, value = None, help = '', isTemporary = False, deprecated = False):
29179860b2SJed Brown    self.key         = key
30179860b2SJed Brown    self.help        = help
31179860b2SJed Brown    self.isTemporary = isTemporary
32179860b2SJed Brown    self.deprecated  = False
33179860b2SJed Brown    if not value is None:
34179860b2SJed Brown      self.setValue(value)
35179860b2SJed Brown    self.deprecated  = deprecated
36179860b2SJed Brown    return
37179860b2SJed Brown
38179860b2SJed Brown  def isValueSet(self):
39179860b2SJed Brown    '''Determines whether the value of this argument has been set'''
40179860b2SJed Brown    return hasattr(self, 'value')
41179860b2SJed Brown
42179860b2SJed Brown  def getTemporary(self):
43179860b2SJed Brown    '''Retrieve the flag indicating whether the item should be persistent'''
44179860b2SJed Brown    return self.isTemporary
45179860b2SJed Brown
46179860b2SJed Brown  def setTemporary(self, isTemporary):
47179860b2SJed Brown    '''Set the flag indicating whether the item should be persistent'''
48179860b2SJed Brown    self.isTemporary = isTemporary
49179860b2SJed Brown    return
50179860b2SJed Brown
51179860b2SJed Brown  def parseValue(arg):
52179860b2SJed Brown    '''Return the object represented by the value portion of a string argument'''
53179860b2SJed Brown    # Should I replace this with a lexer?
54179860b2SJed Brown    if arg: arg = arg.strip()
55179860b2SJed Brown    if arg and arg[0] == '[' and arg[-1] == ']':
56179860b2SJed Brown      if len(arg) > 2: value = arg[1:-1].split(',')
57179860b2SJed Brown      else:            value = []
58179860b2SJed Brown    elif arg and arg[0] == '{' and arg[-1] == '}':
59179860b2SJed Brown      value = {}
60179860b2SJed Brown      idx = 1
61179860b2SJed Brown      oldIdx = idx
62179860b2SJed Brown      while idx < len(arg)-1:
63179860b2SJed Brown        if arg[oldIdx] == ',':
64179860b2SJed Brown          oldIdx += 1
65179860b2SJed Brown        while not arg[idx] == ':': idx += 1
66179860b2SJed Brown        key = arg[oldIdx:idx]
67179860b2SJed Brown        idx += 1
68179860b2SJed Brown        oldIdx = idx
69179860b2SJed Brown        nesting = 0
70179860b2SJed Brown        while not (arg[idx] == ',' or arg[idx] == '}') or nesting:
71179860b2SJed Brown          if arg[idx] == '[':
72179860b2SJed Brown            nesting += 1
73179860b2SJed Brown          elif arg[idx] == ']':
74179860b2SJed Brown            nesting -= 1
75179860b2SJed Brown          idx += 1
76179860b2SJed Brown        value[key] = Arg.parseValue(arg[oldIdx:idx])
77179860b2SJed Brown        oldIdx = idx
78179860b2SJed Brown    else:
79179860b2SJed Brown      value = arg
80179860b2SJed Brown    return value
81179860b2SJed Brown  parseValue = staticmethod(parseValue)
82179860b2SJed Brown
83179860b2SJed Brown  def parseArgument(arg, ignoreDouble = 0):
84179860b2SJed Brown    '''Split an argument into a (key, value) tuple, stripping off the leading dashes. Return (None, None) on failure.'''
85179860b2SJed Brown    start = 0
86179860b2SJed Brown    if arg and arg[0] == '-':
87179860b2SJed Brown      start = 1
88179860b2SJed Brown      if arg[1] == '-' and not ignoreDouble:
89179860b2SJed Brown        start = 2
90179860b2SJed Brown    if arg.find('=') >= 0:
91179860b2SJed Brown      (key, value) = arg[start:].split('=', 1)
92179860b2SJed Brown    else:
93179860b2SJed Brown      if start == 0:
94179860b2SJed Brown        (key, value) = (None, arg)
95179860b2SJed Brown      else:
96179860b2SJed Brown        (key, value) = (arg[start:], '1')
97179860b2SJed Brown    return (key, Arg.parseValue(value))
98179860b2SJed Brown
99179860b2SJed Brown  parseArgument = staticmethod(parseArgument)
100179860b2SJed Brown
101179860b2SJed Brown  def findArgument(key, argList):
102179860b2SJed Brown    '''Locate an argument with the given key in argList, returning the value or None on failure
103179860b2SJed Brown       - This is generally used to process arguments which must take effect before canonical argument parsing'''
104179860b2SJed Brown    if not isinstance(argList, list): return None
105179860b2SJed Brown    # Reverse the list so that we preserve the semantics which state that the last
106179860b2SJed Brown    #   argument with a given key takes effect
107179860b2SJed Brown    l = argList[:]
108179860b2SJed Brown    l.reverse()
109179860b2SJed Brown    for arg in l:
110179860b2SJed Brown      (k, value) = Arg.parseArgument(arg)
111179860b2SJed Brown      if k == key:
112179860b2SJed Brown        return value
113179860b2SJed Brown    return None
114179860b2SJed Brown  findArgument = staticmethod(findArgument)
115179860b2SJed Brown
116179860b2SJed Brown  def processAlternatePrefixes(argList):
117179860b2SJed Brown    '''Convert alternate prefixes to our normal form'''
118179860b2SJed Brown    for l in range(0, len(argList)):
119179860b2SJed Brown      name = argList[l]
120179860b2SJed Brown      if name.find('enable-') >= 0:
121179860b2SJed Brown        argList[l] = name.replace('enable-','with-')
122179860b2SJed Brown        if name.find('=') == -1: argList[l] = argList[l]+'=1'
123179860b2SJed Brown      if name.find('disable-') >= 0:
124179860b2SJed Brown        argList[l] = name.replace('disable-','with-')
125179860b2SJed Brown        if name.find('=') == -1: argList[l] = argList[l]+'=0'
126179860b2SJed Brown        elif name.endswith('=1'): argList[l].replace('=1','=0')
127179860b2SJed Brown      if name.find('without-') >= 0:
128179860b2SJed Brown        argList[l] = name.replace('without-','with-')
129179860b2SJed Brown        if name.find('=') == -1: argList[l] = argList[l]+'=0'
130179860b2SJed Brown        elif name.endswith('=1'): argList[l].replace('=1','=0')
131179860b2SJed Brown    return
132179860b2SJed Brown  processAlternatePrefixes = staticmethod(processAlternatePrefixes)
133179860b2SJed Brown
134179860b2SJed Brown  def __str__(self):
135179860b2SJed Brown    if not self.isValueSet():
136179860b2SJed Brown      return 'Empty '+str(self.__class__)
137179860b2SJed Brown    elif isinstance(self.value, list):
138179860b2SJed Brown      return str(map(str, self.value))
139179860b2SJed Brown    return str(self.value)
140179860b2SJed Brown
141179860b2SJed Brown  def getEntryPrompt(self):
142179860b2SJed Brown    return 'Please enter value for '+str(self.key)+': '
143179860b2SJed Brown
144179860b2SJed Brown  def getKey(self):
145179860b2SJed Brown    '''Returns the key. SHOULD MAKE THIS A PROPERTY'''
146179860b2SJed Brown    return self.key
147179860b2SJed Brown
148179860b2SJed Brown  def setKey(self, key):
149179860b2SJed Brown    '''Set the key. SHOULD MAKE THIS A PROPERTY'''
150179860b2SJed Brown    self.key = key
151179860b2SJed Brown    return
152179860b2SJed Brown
153179860b2SJed Brown  def getValue(self):
154179860b2SJed Brown    '''Returns the value. SHOULD MAKE THIS A PROPERTY'''
155179860b2SJed Brown    if not self.isValueSet():
156179860b2SJed Brown      checkInteractive(self.key)
157179860b2SJed Brown      if self.help: print self.help
158179860b2SJed Brown      while 1:
159179860b2SJed Brown        try:
160179860b2SJed Brown          self.setValue(Arg.parseValue(raw_input(self.getEntryPrompt())))
161179860b2SJed Brown          break
162179860b2SJed Brown        except KeyboardInterrupt:
163179860b2SJed Brown          raise KeyError('Could not find value for key '+str(self.key))
164179860b2SJed Brown        except TypeError, e:
165179860b2SJed Brown          print str(e)
166179860b2SJed Brown    return self.value
167179860b2SJed Brown
168179860b2SJed Brown  def checkKey(self):
169179860b2SJed Brown    if self.deprecated:
170179860b2SJed Brown      if isinstance(self.deprecated, str):
171179860b2SJed Brown        raise KeyError('Deprecated option '+self.key+' should be '+self.deprecated)
172179860b2SJed Brown      raise KeyError('Deprecated option '+self.key)
173179860b2SJed Brown    return
174179860b2SJed Brown
175179860b2SJed Brown  def setValue(self, value):
176179860b2SJed Brown    '''Set the value. SHOULD MAKE THIS A PROPERTY'''
177179860b2SJed Brown    self.checkKey()
178179860b2SJed Brown    self.value = value
179179860b2SJed Brown    return
180179860b2SJed Brown
181179860b2SJed Brownclass ArgBool(Arg):
182179860b2SJed Brown  '''Arguments that represent boolean values'''
183179860b2SJed Brown  def __init__(self, key, value = None, help = '', isTemporary = 0, deprecated = False):
184179860b2SJed Brown    Arg.__init__(self, key, value, help, isTemporary, deprecated)
185179860b2SJed Brown    return
186179860b2SJed Brown
187179860b2SJed Brown  def getEntryPrompt(self):
188179860b2SJed Brown    return 'Please enter boolean value for '+str(self.key)+': '
189179860b2SJed Brown
190179860b2SJed Brown  def setValue(self, value):
191179860b2SJed Brown    '''Set the value. SHOULD MAKE THIS A PROPERTY'''
192179860b2SJed Brown    self.checkKey()
193179860b2SJed Brown    try:
194179860b2SJed Brown      if   value == 'no':    value = 0
195179860b2SJed Brown      elif value == 'yes':   value = 1
196179860b2SJed Brown      elif value == 'true':  value = 1
197179860b2SJed Brown      elif value == 'false': value = 0
198179860b2SJed Brown      elif value == 'True':  value = 1
199179860b2SJed Brown      elif value == 'False': value = 0
200179860b2SJed Brown      else:                  value = int(value)
201179860b2SJed Brown    except:
202179860b2SJed Brown      raise TypeError('Invalid boolean value: '+str(value)+' for key '+str(self.key))
203179860b2SJed Brown    self.value = value
204179860b2SJed Brown    return
205179860b2SJed Brown
206179860b2SJed Brownclass ArgFuzzyBool(Arg):
207179860b2SJed Brown  '''Arguments that represent boolean values of an extended set'''
208179860b2SJed Brown  def __init__(self, key, value = None, help = '', isTemporary = 0, deprecated = False):
209179860b2SJed Brown    Arg.__init__(self, key, value, help, isTemporary, deprecated)
210179860b2SJed Brown    return
211179860b2SJed Brown
212179860b2SJed Brown  def valueName(self, value):
213179860b2SJed Brown    if value == 0:
214179860b2SJed Brown      return 'no'
215179860b2SJed Brown    elif value == 1:
216179860b2SJed Brown      return 'yes'
217179860b2SJed Brown    elif value == 2:
218179860b2SJed Brown      return 'ifneeded'
219179860b2SJed Brown    return str(value)
220179860b2SJed Brown
221179860b2SJed Brown  def __str__(self):
222179860b2SJed Brown    if not self.isValueSet():
223179860b2SJed Brown      return 'Empty '+str(self.__class__)
224179860b2SJed Brown    elif isinstance(self.value, list):
225179860b2SJed Brown      return str(map(self.valueName, self.value))
226179860b2SJed Brown    return self.valueName(self.value)
227179860b2SJed Brown
228179860b2SJed Brown  def getEntryPrompt(self):
229179860b2SJed Brown    return 'Please enter fuzzy boolean value for '+str(self.key)+': '
230179860b2SJed Brown
231179860b2SJed Brown  def setValue(self, value):
232179860b2SJed Brown    '''Set the value. SHOULD MAKE THIS A PROPERTY'''
233179860b2SJed Brown    self.checkKey()
234179860b2SJed Brown    try:
235179860b2SJed Brown      if   value == '0':        value = 0
236179860b2SJed Brown      elif value == '1':        value = 1
237179860b2SJed Brown      elif value == 'no':       value = 0
238179860b2SJed Brown      elif value == 'yes':      value = 1
239179860b2SJed Brown      elif value == 'false':    value = 0
240179860b2SJed Brown      elif value == 'true':     value = 1
241179860b2SJed Brown      elif value == 'maybe':    value = 2
242179860b2SJed Brown      elif value == 'ifneeded': value = 2
243179860b2SJed Brown      elif value == 'client':   value = 2
244179860b2SJed Brown      elif value == 'server':   value = 3
245179860b2SJed Brown      else:                     value = int(value)
246179860b2SJed Brown    except:
247179860b2SJed Brown      raise TypeError('Invalid fuzzy boolean value: '+str(value)+' for key '+str(self.key))
248179860b2SJed Brown    self.value = value
249179860b2SJed Brown    return
250179860b2SJed Brown
251179860b2SJed Brownclass ArgInt(Arg):
252179860b2SJed Brown  '''Arguments that represent integer numbers'''
253179860b2SJed Brown  def __init__(self, key, value = None, help = '', min = -2147483647L, max = 2147483648L, isTemporary = 0, deprecated = False):
254179860b2SJed Brown    self.min = min
255179860b2SJed Brown    self.max = max
256179860b2SJed Brown    Arg.__init__(self, key, value, help, isTemporary, deprecated)
257179860b2SJed Brown    return
258179860b2SJed Brown
259179860b2SJed Brown  def getEntryPrompt(self):
260179860b2SJed Brown    return 'Please enter integer value for '+str(self.key)+': '
261179860b2SJed Brown
262179860b2SJed Brown  def setValue(self, value):
263179860b2SJed Brown    '''Set the value. SHOULD MAKE THIS A PROPERTY'''
264179860b2SJed Brown    self.checkKey()
265179860b2SJed Brown    try:
266179860b2SJed Brown      value = int(value)
267179860b2SJed Brown    except:
268179860b2SJed Brown      raise TypeError('Invalid integer number: '+str(value)+' for key '+str(self.key))
269179860b2SJed Brown    if value < self.min or value >= self.max:
270179860b2SJed Brown      raise ValueError('Number out of range: '+str(value)+' not in ['+str(self.min)+','+str(self.max)+')'+' for key '+str(self.key))
271179860b2SJed Brown    self.value = value
272179860b2SJed Brown    return
273179860b2SJed Brown
274179860b2SJed Brownclass ArgReal(Arg):
275179860b2SJed Brown  '''Arguments that represent floating point numbers'''
276179860b2SJed Brown  def __init__(self, key, value = None, help = '', min = -1.7976931348623157e308, max = 1.7976931348623157e308, isTemporary = 0, deprecated = False):
277179860b2SJed Brown    self.min = min
278179860b2SJed Brown    self.max = max
279179860b2SJed Brown    Arg.__init__(self, key, value, help, isTemporary, deprecated)
280179860b2SJed Brown    return
281179860b2SJed Brown
282179860b2SJed Brown  def getEntryPrompt(self):
283179860b2SJed Brown    return 'Please enter floating point value for '+str(self.key)+': '
284179860b2SJed Brown
285179860b2SJed Brown  def setValue(self, value):
286179860b2SJed Brown    '''Set the value. SHOULD MAKE THIS A PROPERTY'''
287179860b2SJed Brown    self.checkKey()
288179860b2SJed Brown    try:
289179860b2SJed Brown      value = float(value)
290179860b2SJed Brown    except:
291179860b2SJed Brown      raise TypeError('Invalid floating point number: '+str(value)+' for key '+str(self.key))
292179860b2SJed Brown    if value < self.min or value >= self.max:
293179860b2SJed Brown      raise ValueError('Number out of range: '+str(value)+' not in ['+str(self.min)+','+str(self.max)+')'+' for key '+str(self.key))
294179860b2SJed Brown    self.value = value
295179860b2SJed Brown    return
296179860b2SJed Brown
297179860b2SJed Brownclass ArgDir(Arg):
298179860b2SJed Brown  '''Arguments that represent directories'''
299179860b2SJed Brown  def __init__(self, key, value = None, help = '', mustExist = 1, isTemporary = 0, deprecated = False):
300179860b2SJed Brown    self.mustExist = mustExist
301179860b2SJed Brown    Arg.__init__(self, key, value, help, isTemporary, deprecated)
302179860b2SJed Brown    return
303179860b2SJed Brown
304179860b2SJed Brown  def getEntryPrompt(self):
305179860b2SJed Brown    return 'Please enter directory for '+str(self.key)+': '
306179860b2SJed Brown
307179860b2SJed Brown  def getValue(self):
308179860b2SJed Brown    '''Returns the value. SHOULD MAKE THIS A PROPERTY'''
309179860b2SJed Brown    if not self.isValueSet():
310179860b2SJed Brown      checkInteractive(self.key)
311179860b2SJed Brown      try:
312179860b2SJed Brown        import GUI.FileBrowser
313179860b2SJed Brown        import SIDL.Loader
314179860b2SJed Brown        db = GUI.FileBrowser.FileBrowser(SIDL.Loader.createClass('GUI.Default.DefaultFileBrowser'))
315179860b2SJed Brown        if self.help: db.setTitle(self.help)
316179860b2SJed Brown        else:         db.setTitle('Select the directory for '+self.key)
317179860b2SJed Brown        db.setMustExist(self.exist)
318179860b2SJed Brown        self.value = db.getDirectory()
319179860b2SJed Brown      except Exception:
320179860b2SJed Brown        return Arg.getValue(self)
321179860b2SJed Brown    return self.value
322179860b2SJed Brown
323179860b2SJed Brown  def setValue(self, value):
324179860b2SJed Brown    '''Set the value. SHOULD MAKE THIS A PROPERTY'''
325179860b2SJed Brown    import os
326179860b2SJed Brown    self.checkKey()
327179860b2SJed Brown    # Should check whether it is a well-formed path
328179860b2SJed Brown    if not isinstance(value, str):
329179860b2SJed Brown      raise TypeError('Invalid directory: '+str(value)+' for key '+str(self.key))
330179860b2SJed Brown    value = os.path.expanduser(value)
331*9992b254SSatish Balay    value = os.path.abspath(value)
332179860b2SJed Brown    if self.mustExist and value and not os.path.isdir(value):
333179860b2SJed Brown      raise ValueError('Nonexistent directory: '+str(value)+' for key '+str(self.key))
334179860b2SJed Brown    self.value = value
335179860b2SJed Brown    return
336179860b2SJed Brown
337179860b2SJed Brownclass ArgDirList(Arg):
338179860b2SJed Brown  '''Arguments that represent directory lists'''
339179860b2SJed Brown  def __init__(self, key, value = None, help = '', mustExist = 1, isTemporary = 0, deprecated = False):
340179860b2SJed Brown    self.mustExist = mustExist
341179860b2SJed Brown    Arg.__init__(self, key, value, help, isTemporary, deprecated)
342179860b2SJed Brown    return
343179860b2SJed Brown
344179860b2SJed Brown  def getEntryPrompt(self):
345179860b2SJed Brown    return 'Please enter directory list for '+str(self.key)+': '
346179860b2SJed Brown
347179860b2SJed Brown  def getValue(self):
348179860b2SJed Brown    '''Returns the value. SHOULD MAKE THIS A PROPERTY'''
349179860b2SJed Brown    if not self.isValueSet():
350179860b2SJed Brown      checkInteractive(self.key)
351179860b2SJed Brown      try:
352179860b2SJed Brown        import GUI.FileBrowser
353179860b2SJed Brown        import SIDL.Loader
354179860b2SJed Brown        db = GUI.FileBrowser.FileBrowser(SIDL.Loader.createClass('GUI.Default.DefaultFileBrowser'))
355179860b2SJed Brown        if self.help: db.setTitle(self.help)
356179860b2SJed Brown        else:         db.setTitle('Select the directory for '+self.key)
357179860b2SJed Brown        db.setMustExist(self.exist)
358179860b2SJed Brown        self.value = db.getDirectory()
359179860b2SJed Brown      except Exception:
360179860b2SJed Brown        return Arg.getValue(self)
361179860b2SJed Brown    return self.value
362179860b2SJed Brown
363179860b2SJed Brown  def setValue(self, value):
364179860b2SJed Brown    '''Set the value. SHOULD MAKE THIS A PROPERTY'''
365179860b2SJed Brown    import os
366179860b2SJed Brown    self.checkKey()
367179860b2SJed Brown    if not isinstance(value, list):
368179860b2SJed Brown      value = [value]
369179860b2SJed Brown    # Should check whether it is a well-formed path
370179860b2SJed Brown    nvalue = []
371179860b2SJed Brown    for dir in value:
372179860b2SJed Brown      nvalue.append(os.path.expanduser(dir))
373179860b2SJed Brown    value = nvalue
374179860b2SJed Brown    for dir in value:
375179860b2SJed Brown      if self.mustExist and not os.path.isdir(dir):
376179860b2SJed Brown        raise ValueError('Invalid directory: '+str(dir)+' for key '+str(self.key))
377179860b2SJed Brown    self.value = value
378179860b2SJed Brown    return
379179860b2SJed Brown
380179860b2SJed Brownclass ArgLibrary(Arg):
381179860b2SJed Brown  '''Arguments that represent libraries'''
382179860b2SJed Brown  def __init__(self, key, value = None, help = '', mustExist = 1, isTemporary = 0, deprecated = False):
383179860b2SJed Brown    self.mustExist = mustExist
384179860b2SJed Brown    Arg.__init__(self, key, value, help, isTemporary, deprecated)
385179860b2SJed Brown    return
386179860b2SJed Brown
387179860b2SJed Brown  def getEntryPrompt(self):
388179860b2SJed Brown    return 'Please enter library for '+str(self.key)+': '
389179860b2SJed Brown
390179860b2SJed Brown  def getValue(self):
391179860b2SJed Brown    '''Returns the value. SHOULD MAKE THIS A PROPERTY'''
392179860b2SJed Brown    if not self.isValueSet():
393179860b2SJed Brown      checkInteractive(self.key)
394179860b2SJed Brown      try:
395179860b2SJed Brown        import GUI.FileBrowser
396179860b2SJed Brown        import SIDL.Loader
397179860b2SJed Brown        db = GUI.FileBrowser.FileBrowser(SIDL.Loader.createClass('GUI.Default.DefaultFileBrowser'))
398179860b2SJed Brown        if self.help: db.setTitle(self.help)
399179860b2SJed Brown        else:         db.setTitle('Select the library for '+self.key)
400179860b2SJed Brown        db.setMustExist(self.exist)
401179860b2SJed Brown        self.value = db.getFile()
402179860b2SJed Brown      except Exception:
403179860b2SJed Brown        return Arg.getValue(self)
404179860b2SJed Brown    return self.value
405179860b2SJed Brown
406179860b2SJed Brown  def setValue(self, value):
407179860b2SJed Brown    '''Set the value. SHOULD MAKE THIS A PROPERTY'''
408179860b2SJed Brown    import os
409179860b2SJed Brown    self.checkKey()
410179860b2SJed Brown    # Should check whether it is a well-formed path and an archive or shared object
411179860b2SJed Brown    if self.mustExist:
412179860b2SJed Brown      if not isinstance(value, list):
413179860b2SJed Brown        value = value.split(' ')
414179860b2SJed Brown    self.value = value
415179860b2SJed Brown    return
416179860b2SJed Brown
417179860b2SJed Brownclass ArgExecutable(Arg):
418179860b2SJed Brown  '''Arguments that represent executables'''
419179860b2SJed Brown  def __init__(self, key, value = None, help = '', mustExist = 1, isTemporary = 0, deprecated = False):
420179860b2SJed Brown    self.mustExist = mustExist
421179860b2SJed Brown    Arg.__init__(self, key, value, help, isTemporary, deprecated)
422179860b2SJed Brown    return
423179860b2SJed Brown
424179860b2SJed Brown  def getEntryPrompt(self):
425179860b2SJed Brown    return 'Please enter executable for '+str(self.key)+': '
426179860b2SJed Brown
427179860b2SJed Brown  def getValue(self):
428179860b2SJed Brown    '''Returns the value. SHOULD MAKE THIS A PROPERTY'''
429179860b2SJed Brown    if not self.isValueSet():
430179860b2SJed Brown      checkInteractive(self.key)
431179860b2SJed Brown      try:
432179860b2SJed Brown        import GUI.FileBrowser
433179860b2SJed Brown        import SIDL.Loader
434179860b2SJed Brown        db = GUI.FileBrowser.FileBrowser(SIDL.Loader.createClass('GUI.Default.DefaultFileBrowser'))
435179860b2SJed Brown        if self.help: db.setTitle(self.help)
436179860b2SJed Brown        else:         db.setTitle('Select the executable for '+self.key)
437179860b2SJed Brown        db.setMustExist(self.exist)
438179860b2SJed Brown        self.value = db.getFile()
439179860b2SJed Brown      except Exception:
440179860b2SJed Brown        return Arg.getValue(self)
441179860b2SJed Brown    return self.value
442179860b2SJed Brown
443179860b2SJed Brown  def checkExecutable(self, dir, name):
444179860b2SJed Brown    import os
445179860b2SJed Brown    prog = os.path.join(dir, name)
446179860b2SJed Brown    return os.path.isfile(prog) and os.access(prog, os.X_OK)
447179860b2SJed Brown
448179860b2SJed Brown  def setValue(self, value):
449179860b2SJed Brown    '''Set the value. SHOULD MAKE THIS A PROPERTY'''
450179860b2SJed Brown    import os
451179860b2SJed Brown    self.checkKey()
452179860b2SJed Brown    # Should check whether it is a well-formed path
453179860b2SJed Brown    if self.mustExist:
454179860b2SJed Brown      index = value.find(' ')
455179860b2SJed Brown      if index >= 0:
456179860b2SJed Brown        options = value[index:]
457179860b2SJed Brown        value   = value[:index]
458179860b2SJed Brown      else:
459179860b2SJed Brown        options = ''
460179860b2SJed Brown      found = self.checkExecutable('', value)
461179860b2SJed Brown      if not found:
462179860b2SJed Brown        for dir in os.environ['PATH'].split(os.path.pathsep):
463179860b2SJed Brown          if self.checkExecutable(dir, value):
464179860b2SJed Brown            found = 1
465179860b2SJed Brown            break
466179860b2SJed Brown      if not found:
467179860b2SJed Brown        raise ValueError('Invalid executable: '+str(value)+' for key '+str(self.key))
468179860b2SJed Brown    self.value = value+options
469179860b2SJed Brown    return
470179860b2SJed Brown
471179860b2SJed Brownclass ArgString(Arg):
472179860b2SJed Brown  '''Arguments that represent strings satisfying a given regular expression'''
473179860b2SJed Brown  def __init__(self, key, value = None, help = '', regExp = None, isTemporary = 0, deprecated = False):
474179860b2SJed Brown    self.regExp = regExp
475179860b2SJed Brown    if self.regExp:
476179860b2SJed Brown      import re
477179860b2SJed Brown      self.re = re.compile(self.regExp)
478179860b2SJed Brown    Arg.__init__(self, key, value, help, isTemporary, deprecated)
479179860b2SJed Brown    return
480179860b2SJed Brown
481179860b2SJed Brown  def setValue(self, value):
482179860b2SJed Brown    '''Set the value. SHOULD MAKE THIS A PROPERTY'''
483179860b2SJed Brown    self.checkKey()
484179860b2SJed Brown    if self.regExp and not self.re.match(value):
485179860b2SJed Brown      raise ValueError('Invalid string '+str(value)+'. You must give a string satisfying "'+str(self.regExp)+'"'+' for key '+str(self.key))
486179860b2SJed Brown    self.value = value
487179860b2SJed Brown    return
488179860b2SJed Brown
489179860b2SJed Brownclass ArgDownload(Arg):
490179860b2SJed Brown  '''Arguments that represent software downloads'''
491179860b2SJed Brown  def __init__(self, key, value = None, help = '', isTemporary = 0, deprecated = False):
492179860b2SJed Brown    Arg.__init__(self, key, value, help, isTemporary, deprecated)
493179860b2SJed Brown    return
494179860b2SJed Brown
495179860b2SJed Brown  def valueName(self, value):
496179860b2SJed Brown    if value == 0:
497179860b2SJed Brown      return 'no'
498179860b2SJed Brown    elif value == 1:
499179860b2SJed Brown      return 'yes'
500179860b2SJed Brown    return str(value)
501179860b2SJed Brown
502179860b2SJed Brown  def __str__(self):
503179860b2SJed Brown    if not self.isValueSet():
504179860b2SJed Brown      return 'Empty '+str(self.__class__)
505179860b2SJed Brown    elif isinstance(self.value, list):
506179860b2SJed Brown      return str(map(self.valueName, self.value))
507179860b2SJed Brown    return self.valueName(self.value)
508179860b2SJed Brown
509179860b2SJed Brown  def getEntryPrompt(self):
510179860b2SJed Brown    return 'Please enter download value for '+str(self.key)+': '
511179860b2SJed Brown
512179860b2SJed Brown  def setValue(self, value):
513179860b2SJed Brown    '''Set the value. SHOULD MAKE THIS A PROPERTY'''
514179860b2SJed Brown    import os
515179860b2SJed Brown    self.checkKey()
516179860b2SJed Brown    try:
517179860b2SJed Brown      if   value == '0':        value = 0
518179860b2SJed Brown      elif value == '1':        value = 1
519179860b2SJed Brown      elif value == 'no':       value = 0
520179860b2SJed Brown      elif value == 'yes':      value = 1
521179860b2SJed Brown      elif value == 'false':    value = 0
522179860b2SJed Brown      elif value == 'true':     value = 1
523179860b2SJed Brown      elif not isinstance(value, int):
524179860b2SJed Brown        value = str(value)
525179860b2SJed Brown    except:
526179860b2SJed Brown      raise TypeError('Invalid download value: '+str(value)+' for key '+str(self.key))
527179860b2SJed Brown    if isinstance(value, str):
528179860b2SJed Brown      import urlparse
529179860b2SJed Brown      if not urlparse.urlparse(value)[0]: # how do we check if the URL is invalid?
530179860b2SJed Brown        if os.path.isfile(value):
531179860b2SJed Brown          value = 'file://'+os.path.abspath(value)
532179860b2SJed Brown        else:
533179860b2SJed Brown          raise ValueError('Invalid download location: '+str(value)+' for key '+str(self.key))
534179860b2SJed Brown    self.value = value
535179860b2SJed Brown    return
536