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