15b6bfdb9SJed Brownfrom __future__ import print_function 2179860b2SJed Browntry: 3179860b2SJed Brown import readline 4179860b2SJed Brownexcept ImportError: pass 5179860b2SJed Brown 6179860b2SJed Brownclass Arg(object): 7179860b2SJed Brown '''This is the base class for all objects contained in RDict. Access to the raw argument values is 8179860b2SJed Brownprovided by getValue() and setValue(). These objects can be thought of as type objects for the 9179860b2SJed Brownvalues themselves. It is possible to set an Arg in the RDict which has not yet been assigned a value 10179860b2SJed Brownin order to declare the type of that option. 11179860b2SJed Brown 12179860b2SJed BrownInputs which cannot be converted to the correct type will cause TypeError, those failing validation 13179860b2SJed Browntests will cause ValueError. 14179860b2SJed Brown''' 15179860b2SJed Brown def __init__(self, key, value = None, help = '', isTemporary = False, deprecated = False): 16179860b2SJed Brown self.key = key 17179860b2SJed Brown self.help = help 18179860b2SJed Brown self.isTemporary = isTemporary 19179860b2SJed Brown self.deprecated = False 20179860b2SJed Brown if not value is None: 21179860b2SJed Brown self.setValue(value) 22179860b2SJed Brown self.deprecated = deprecated 23179860b2SJed Brown return 24179860b2SJed Brown 25179860b2SJed Brown def isValueSet(self): 26179860b2SJed Brown '''Determines whether the value of this argument has been set''' 27179860b2SJed Brown return hasattr(self, 'value') 28179860b2SJed Brown 29179860b2SJed Brown def getTemporary(self): 30179860b2SJed Brown '''Retrieve the flag indicating whether the item should be persistent''' 31179860b2SJed Brown return self.isTemporary 32179860b2SJed Brown 33179860b2SJed Brown def setTemporary(self, isTemporary): 34179860b2SJed Brown '''Set the flag indicating whether the item should be persistent''' 35179860b2SJed Brown self.isTemporary = isTemporary 36179860b2SJed Brown return 37179860b2SJed Brown 38179860b2SJed Brown def parseValue(arg): 39179860b2SJed Brown '''Return the object represented by the value portion of a string argument''' 40179860b2SJed Brown # Should I replace this with a lexer? 41179860b2SJed Brown if arg: arg = arg.strip() 42179860b2SJed Brown if arg and arg[0] == '[' and arg[-1] == ']': 43179860b2SJed Brown if len(arg) > 2: value = arg[1:-1].split(',') 44179860b2SJed Brown else: value = [] 45179860b2SJed Brown elif arg and arg[0] == '{' and arg[-1] == '}': 46179860b2SJed Brown value = {} 47179860b2SJed Brown idx = 1 48179860b2SJed Brown oldIdx = idx 49179860b2SJed Brown while idx < len(arg)-1: 50179860b2SJed Brown if arg[oldIdx] == ',': 51179860b2SJed Brown oldIdx += 1 52179860b2SJed Brown while not arg[idx] == ':': idx += 1 53179860b2SJed Brown key = arg[oldIdx:idx] 54179860b2SJed Brown idx += 1 55179860b2SJed Brown oldIdx = idx 56179860b2SJed Brown nesting = 0 57179860b2SJed Brown while not (arg[idx] == ',' or arg[idx] == '}') or nesting: 58179860b2SJed Brown if arg[idx] == '[': 59179860b2SJed Brown nesting += 1 60179860b2SJed Brown elif arg[idx] == ']': 61179860b2SJed Brown nesting -= 1 62179860b2SJed Brown idx += 1 63179860b2SJed Brown value[key] = Arg.parseValue(arg[oldIdx:idx]) 64179860b2SJed Brown oldIdx = idx 65179860b2SJed Brown else: 66179860b2SJed Brown value = arg 67179860b2SJed Brown return value 68179860b2SJed Brown parseValue = staticmethod(parseValue) 69179860b2SJed Brown 70179860b2SJed Brown def parseArgument(arg, ignoreDouble = 0): 71179860b2SJed Brown '''Split an argument into a (key, value) tuple, stripping off the leading dashes. Return (None, None) on failure.''' 72179860b2SJed Brown start = 0 73179860b2SJed Brown if arg and arg[0] == '-': 74179860b2SJed Brown start = 1 75179860b2SJed Brown if arg[1] == '-' and not ignoreDouble: 76179860b2SJed Brown start = 2 77179860b2SJed Brown if arg.find('=') >= 0: 78179860b2SJed Brown (key, value) = arg[start:].split('=', 1) 79179860b2SJed Brown else: 80179860b2SJed Brown if start == 0: 81179860b2SJed Brown (key, value) = (None, arg) 82179860b2SJed Brown else: 83179860b2SJed Brown (key, value) = (arg[start:], '1') 84179860b2SJed Brown return (key, Arg.parseValue(value)) 85179860b2SJed Brown 86179860b2SJed Brown parseArgument = staticmethod(parseArgument) 87179860b2SJed Brown 88179860b2SJed Brown def findArgument(key, argList): 89179860b2SJed Brown '''Locate an argument with the given key in argList, returning the value or None on failure 90179860b2SJed Brown - This is generally used to process arguments which must take effect before canonical argument parsing''' 91179860b2SJed Brown if not isinstance(argList, list): return None 92179860b2SJed Brown # Reverse the list so that we preserve the semantics which state that the last 93179860b2SJed Brown # argument with a given key takes effect 94179860b2SJed Brown l = argList[:] 95179860b2SJed Brown l.reverse() 96179860b2SJed Brown for arg in l: 97179860b2SJed Brown (k, value) = Arg.parseArgument(arg) 98179860b2SJed Brown if k == key: 99179860b2SJed Brown return value 100179860b2SJed Brown return None 101179860b2SJed Brown findArgument = staticmethod(findArgument) 102179860b2SJed Brown 103179860b2SJed Brown def processAlternatePrefixes(argList): 104179860b2SJed Brown '''Convert alternate prefixes to our normal form''' 105179860b2SJed Brown for l in range(0, len(argList)): 106179860b2SJed Brown name = argList[l] 107179860b2SJed Brown if name.find('enable-') >= 0: 108179860b2SJed Brown argList[l] = name.replace('enable-','with-') 109179860b2SJed Brown if name.find('=') == -1: argList[l] = argList[l]+'=1' 110179860b2SJed Brown if name.find('disable-') >= 0: 111179860b2SJed Brown argList[l] = name.replace('disable-','with-') 112179860b2SJed Brown if name.find('=') == -1: argList[l] = argList[l]+'=0' 113179860b2SJed Brown elif name.endswith('=1'): argList[l].replace('=1','=0') 114179860b2SJed Brown if name.find('without-') >= 0: 115179860b2SJed Brown argList[l] = name.replace('without-','with-') 116179860b2SJed Brown if name.find('=') == -1: argList[l] = argList[l]+'=0' 117179860b2SJed Brown elif name.endswith('=1'): argList[l].replace('=1','=0') 118179860b2SJed Brown return 119179860b2SJed Brown processAlternatePrefixes = staticmethod(processAlternatePrefixes) 120179860b2SJed Brown 121179860b2SJed Brown def __str__(self): 122179860b2SJed Brown if not self.isValueSet(): 123179860b2SJed Brown return 'Empty '+str(self.__class__) 124cc267e83SJacob Faibussowitsch value = self.value 125cc267e83SJacob Faibussowitsch if isinstance(value, list): 126cc267e83SJacob Faibussowitsch return str(list(map(str, value))) 127cc267e83SJacob Faibussowitsch return str(value) 128179860b2SJed Brown 129179860b2SJed Brown def getKey(self): 130179860b2SJed Brown '''Returns the key. SHOULD MAKE THIS A PROPERTY''' 131179860b2SJed Brown return self.key 132179860b2SJed Brown 133179860b2SJed Brown def setKey(self, key): 134179860b2SJed Brown '''Set the key. SHOULD MAKE THIS A PROPERTY''' 135179860b2SJed Brown self.key = key 136179860b2SJed Brown return 137179860b2SJed Brown 138179860b2SJed Brown def getValue(self): 139179860b2SJed Brown '''Returns the value. SHOULD MAKE THIS A PROPERTY''' 140179860b2SJed Brown if not self.isValueSet(): 141179860b2SJed Brown raise KeyError('Could not find value for key '+str(self.key)) 142179860b2SJed Brown return self.value 143179860b2SJed Brown 144179860b2SJed Brown def checkKey(self): 145179860b2SJed Brown if self.deprecated: 146179860b2SJed Brown if isinstance(self.deprecated, str): 147179860b2SJed Brown raise KeyError('Deprecated option '+self.key+' should be '+self.deprecated) 148179860b2SJed Brown raise KeyError('Deprecated option '+self.key) 149179860b2SJed Brown return 150179860b2SJed Brown 151179860b2SJed Brown def setValue(self, value): 152179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 153179860b2SJed Brown self.checkKey() 154179860b2SJed Brown self.value = value 155179860b2SJed Brown return 156179860b2SJed Brown 157179860b2SJed Brownclass ArgBool(Arg): 158179860b2SJed Brown '''Arguments that represent boolean values''' 159179860b2SJed Brown def __init__(self, key, value = None, help = '', isTemporary = 0, deprecated = False): 160179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 161179860b2SJed Brown return 162179860b2SJed Brown 163179860b2SJed Brown def setValue(self, value): 164179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 165179860b2SJed Brown self.checkKey() 166179860b2SJed Brown try: 167179860b2SJed Brown if value == 'no': value = 0 168179860b2SJed Brown elif value == 'yes': value = 1 169179860b2SJed Brown elif value == 'true': value = 1 170179860b2SJed Brown elif value == 'false': value = 0 171179860b2SJed Brown elif value == 'True': value = 1 172179860b2SJed Brown elif value == 'False': value = 0 173179860b2SJed Brown else: value = int(value) 174179860b2SJed Brown except: 175179860b2SJed Brown raise TypeError('Invalid boolean value: '+str(value)+' for key '+str(self.key)) 176179860b2SJed Brown self.value = value 177179860b2SJed Brown return 178179860b2SJed Brown 179179860b2SJed Brownclass ArgFuzzyBool(Arg): 180179860b2SJed Brown '''Arguments that represent boolean values of an extended set''' 181179860b2SJed Brown def __init__(self, key, value = None, help = '', isTemporary = 0, deprecated = False): 182179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 183179860b2SJed Brown return 184179860b2SJed Brown 185179860b2SJed Brown def valueName(self, value): 186179860b2SJed Brown if value == 0: 187179860b2SJed Brown return 'no' 188179860b2SJed Brown elif value == 1: 189179860b2SJed Brown return 'yes' 190179860b2SJed Brown elif value == 2: 191179860b2SJed Brown return 'ifneeded' 192179860b2SJed Brown return str(value) 193179860b2SJed Brown 194179860b2SJed Brown def __str__(self): 195179860b2SJed Brown if not self.isValueSet(): 196179860b2SJed Brown return 'Empty '+str(self.__class__) 197179860b2SJed Brown elif isinstance(self.value, list): 198179860b2SJed Brown return str(map(self.valueName, self.value)) 199179860b2SJed Brown return self.valueName(self.value) 200179860b2SJed Brown 201179860b2SJed Brown def setValue(self, value): 202179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 203179860b2SJed Brown self.checkKey() 204179860b2SJed Brown try: 205179860b2SJed Brown if value == '0': value = 0 206179860b2SJed Brown elif value == '1': value = 1 207179860b2SJed Brown elif value == 'no': value = 0 208179860b2SJed Brown elif value == 'yes': value = 1 209179860b2SJed Brown elif value == 'false': value = 0 210179860b2SJed Brown elif value == 'true': value = 1 211179860b2SJed Brown elif value == 'maybe': value = 2 212179860b2SJed Brown elif value == 'ifneeded': value = 2 213179860b2SJed Brown elif value == 'client': value = 2 214179860b2SJed Brown elif value == 'server': value = 3 215179860b2SJed Brown else: value = int(value) 216179860b2SJed Brown except: 217179860b2SJed Brown raise TypeError('Invalid fuzzy boolean value: '+str(value)+' for key '+str(self.key)) 218179860b2SJed Brown self.value = value 219179860b2SJed Brown return 220179860b2SJed Brown 221179860b2SJed Brownclass ArgInt(Arg): 222179860b2SJed Brown '''Arguments that represent integer numbers''' 2235b6bfdb9SJed Brown def __init__(self, key, value = None, help = '', min = -2147483647, max = 2147483648, isTemporary = 0, deprecated = False): 224179860b2SJed Brown self.min = min 225179860b2SJed Brown self.max = max 226179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 227179860b2SJed Brown return 228179860b2SJed Brown 229179860b2SJed Brown def setValue(self, value): 230179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 231179860b2SJed Brown self.checkKey() 232179860b2SJed Brown try: 233179860b2SJed Brown value = int(value) 234179860b2SJed Brown except: 235179860b2SJed Brown raise TypeError('Invalid integer number: '+str(value)+' for key '+str(self.key)) 236179860b2SJed Brown if value < self.min or value >= self.max: 237179860b2SJed Brown raise ValueError('Number out of range: '+str(value)+' not in ['+str(self.min)+','+str(self.max)+')'+' for key '+str(self.key)) 238179860b2SJed Brown self.value = value 239179860b2SJed Brown return 240179860b2SJed Brown 241179860b2SJed Brownclass ArgReal(Arg): 242179860b2SJed Brown '''Arguments that represent floating point numbers''' 243179860b2SJed Brown def __init__(self, key, value = None, help = '', min = -1.7976931348623157e308, max = 1.7976931348623157e308, isTemporary = 0, deprecated = False): 244179860b2SJed Brown self.min = min 245179860b2SJed Brown self.max = max 246179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 247179860b2SJed Brown return 248179860b2SJed Brown 249179860b2SJed Brown def setValue(self, value): 250179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 251179860b2SJed Brown self.checkKey() 252179860b2SJed Brown try: 253179860b2SJed Brown value = float(value) 254179860b2SJed Brown except: 255179860b2SJed Brown raise TypeError('Invalid floating point number: '+str(value)+' for key '+str(self.key)) 256179860b2SJed Brown if value < self.min or value >= self.max: 257179860b2SJed Brown raise ValueError('Number out of range: '+str(value)+' not in ['+str(self.min)+','+str(self.max)+')'+' for key '+str(self.key)) 258179860b2SJed Brown self.value = value 259179860b2SJed Brown return 260179860b2SJed Brown 261179860b2SJed Brownclass ArgDir(Arg): 262179860b2SJed Brown '''Arguments that represent directories''' 263179860b2SJed Brown def __init__(self, key, value = None, help = '', mustExist = 1, isTemporary = 0, deprecated = False): 264179860b2SJed Brown self.mustExist = mustExist 265179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 266179860b2SJed Brown return 267179860b2SJed Brown 268179860b2SJed Brown def getValue(self): 269179860b2SJed Brown '''Returns the value. SHOULD MAKE THIS A PROPERTY''' 270179860b2SJed Brown if not self.isValueSet(): 271179860b2SJed Brown return Arg.getValue(self) 272179860b2SJed Brown return self.value 273179860b2SJed Brown 274179860b2SJed Brown def setValue(self, value): 275179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 276179860b2SJed Brown import os 277179860b2SJed Brown self.checkKey() 278179860b2SJed Brown # Should check whether it is a well-formed path 279179860b2SJed Brown if not isinstance(value, str): 280179860b2SJed Brown raise TypeError('Invalid directory: '+str(value)+' for key '+str(self.key)) 281179860b2SJed Brown value = os.path.expanduser(value) 2829992b254SSatish Balay value = os.path.abspath(value) 283179860b2SJed Brown if self.mustExist and value and not os.path.isdir(value): 284179860b2SJed Brown raise ValueError('Nonexistent directory: '+str(value)+' for key '+str(self.key)) 285179860b2SJed Brown self.value = value 286179860b2SJed Brown return 287179860b2SJed Brown 288179860b2SJed Brownclass ArgDirList(Arg): 289179860b2SJed Brown '''Arguments that represent directory lists''' 290179860b2SJed Brown def __init__(self, key, value = None, help = '', mustExist = 1, isTemporary = 0, deprecated = False): 291179860b2SJed Brown self.mustExist = mustExist 292179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 293179860b2SJed Brown return 294179860b2SJed Brown 295179860b2SJed Brown def getValue(self): 296179860b2SJed Brown '''Returns the value. SHOULD MAKE THIS A PROPERTY''' 297179860b2SJed Brown if not self.isValueSet(): 298179860b2SJed Brown return Arg.getValue(self) 299179860b2SJed Brown return self.value 300179860b2SJed Brown 301179860b2SJed Brown def setValue(self, value): 302179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 303179860b2SJed Brown import os 304179860b2SJed Brown self.checkKey() 305179860b2SJed Brown if not isinstance(value, list): 306158e955bSSatish Balay value = value.split(':') 307179860b2SJed Brown # Should check whether it is a well-formed path 308179860b2SJed Brown nvalue = [] 309179860b2SJed Brown for dir in value: 310928c5b42SSatish Balay if dir: 311179860b2SJed Brown nvalue.append(os.path.expanduser(dir)) 312179860b2SJed Brown value = nvalue 313179860b2SJed Brown for dir in value: 314179860b2SJed Brown if self.mustExist and not os.path.isdir(dir): 315179860b2SJed Brown raise ValueError('Invalid directory: '+str(dir)+' for key '+str(self.key)) 316179860b2SJed Brown self.value = value 317179860b2SJed Brown return 318179860b2SJed Brown 319c88f93c3SSatish Balayclass ArgFile(Arg): 320c88f93c3SSatish Balay '''Arguments that represent a file''' 321c88f93c3SSatish Balay def __init__(self, key, value = None, help = '', mustExist = 1, isTemporary = 0, deprecated = False): 322c88f93c3SSatish Balay self.mustExist = mustExist 323c88f93c3SSatish Balay Arg.__init__(self, key, value, help, isTemporary, deprecated) 324c88f93c3SSatish Balay return 325c88f93c3SSatish Balay 326c88f93c3SSatish Balay def getValue(self): 327c88f93c3SSatish Balay '''Returns the value. SHOULD MAKE THIS A PROPERTY''' 328c88f93c3SSatish Balay if not self.isValueSet(): 329c88f93c3SSatish Balay return Arg.getValue(self) 330c88f93c3SSatish Balay return self.value 331c88f93c3SSatish Balay 332c88f93c3SSatish Balay def setValue(self, value): 333c88f93c3SSatish Balay '''Set the value. SHOULD MAKE THIS A PROPERTY''' 334c88f93c3SSatish Balay import os 335c88f93c3SSatish Balay self.checkKey() 336c88f93c3SSatish Balay # Should check whether it is a well-formed path 337c88f93c3SSatish Balay if not isinstance(value, str): 338c88f93c3SSatish Balay raise TypeError('Invalid file: '+str(value)+' for key '+str(self.key)) 339c88f93c3SSatish Balay value = os.path.expanduser(value) 340c88f93c3SSatish Balay value = os.path.abspath(value) 341c88f93c3SSatish Balay if self.mustExist and value and not os.path.isfile(value): 342c88f93c3SSatish Balay raise ValueError('Nonexistent file: '+str(value)+' for key '+str(self.key)) 343c88f93c3SSatish Balay self.value = value 344c88f93c3SSatish Balay return 345c88f93c3SSatish Balay 346c88f93c3SSatish Balayclass ArgFileList(Arg): 347c88f93c3SSatish Balay '''Arguments that represent file lists''' 348c88f93c3SSatish Balay def __init__(self, key, value = None, help = '', mustExist = 1, isTemporary = 0, deprecated = False): 349c88f93c3SSatish Balay self.mustExist = mustExist 350c88f93c3SSatish Balay Arg.__init__(self, key, value, help, isTemporary, deprecated) 351c88f93c3SSatish Balay return 352c88f93c3SSatish Balay 353c88f93c3SSatish Balay def getValue(self): 354c88f93c3SSatish Balay '''Returns the value. SHOULD MAKE THIS A PROPERTY''' 355c88f93c3SSatish Balay if not self.isValueSet(): 356c88f93c3SSatish Balay return Arg.getValue(self) 357c88f93c3SSatish Balay return self.value 358c88f93c3SSatish Balay 359c88f93c3SSatish Balay def setValue(self, value): 360c88f93c3SSatish Balay '''Set the value. SHOULD MAKE THIS A PROPERTY''' 361c88f93c3SSatish Balay import os 362c88f93c3SSatish Balay self.checkKey() 363c88f93c3SSatish Balay if not isinstance(value, list): 364c88f93c3SSatish Balay value = value.split(':') 365c88f93c3SSatish Balay # Should check whether it is a well-formed path 366c88f93c3SSatish Balay nvalue = [] 367c88f93c3SSatish Balay for file in value: 368c88f93c3SSatish Balay if file: 369c88f93c3SSatish Balay nvalue.append(os.path.expanduser(file)) 370c88f93c3SSatish Balay value = nvalue 371c88f93c3SSatish Balay for file in value: 372c88f93c3SSatish Balay if self.mustExist and not os.path.isfile(file): 373c88f93c3SSatish Balay raise ValueError('Invalid file: '+str(file)+' for key '+str(self.key)) 374c88f93c3SSatish Balay self.value = value 375c88f93c3SSatish Balay return 376c88f93c3SSatish Balay 377179860b2SJed Brownclass ArgLibrary(Arg): 378179860b2SJed Brown '''Arguments that represent libraries''' 379179860b2SJed Brown def __init__(self, key, value = None, help = '', mustExist = 1, isTemporary = 0, deprecated = False): 380179860b2SJed Brown self.mustExist = mustExist 381179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 382179860b2SJed Brown return 383179860b2SJed Brown 384179860b2SJed Brown def getValue(self): 385179860b2SJed Brown '''Returns the value. SHOULD MAKE THIS A PROPERTY''' 386179860b2SJed Brown if not self.isValueSet(): 387179860b2SJed Brown return Arg.getValue(self) 388179860b2SJed Brown return self.value 389179860b2SJed Brown 390179860b2SJed Brown def setValue(self, value): 391179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 392179860b2SJed Brown import os 393179860b2SJed Brown self.checkKey() 394179860b2SJed Brown # Should check whether it is a well-formed path and an archive or shared object 395179860b2SJed Brown if self.mustExist: 396179860b2SJed Brown if not isinstance(value, list): 397179860b2SJed Brown value = value.split(' ') 398179860b2SJed Brown self.value = value 399179860b2SJed Brown return 400179860b2SJed Brown 401179860b2SJed Brownclass ArgExecutable(Arg): 402179860b2SJed Brown '''Arguments that represent executables''' 403179860b2SJed Brown def __init__(self, key, value = None, help = '', mustExist = 1, isTemporary = 0, deprecated = False): 404179860b2SJed Brown self.mustExist = mustExist 405179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 406179860b2SJed Brown return 407179860b2SJed Brown 408179860b2SJed Brown def getValue(self): 409179860b2SJed Brown '''Returns the value. SHOULD MAKE THIS A PROPERTY''' 410179860b2SJed Brown if not self.isValueSet(): 411179860b2SJed Brown return Arg.getValue(self) 412179860b2SJed Brown return self.value 413179860b2SJed Brown 414179860b2SJed Brown def checkExecutable(self, dir, name): 415179860b2SJed Brown import os 416179860b2SJed Brown prog = os.path.join(dir, name) 417179860b2SJed Brown return os.path.isfile(prog) and os.access(prog, os.X_OK) 418179860b2SJed Brown 419179860b2SJed Brown def setValue(self, value): 420179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 421179860b2SJed Brown import os 422179860b2SJed Brown self.checkKey() 423179860b2SJed Brown # Should check whether it is a well-formed path 424179860b2SJed Brown if self.mustExist: 425179860b2SJed Brown index = value.find(' ') 426179860b2SJed Brown if index >= 0: 427179860b2SJed Brown options = value[index:] 428179860b2SJed Brown value = value[:index] 429179860b2SJed Brown else: 430179860b2SJed Brown options = '' 431179860b2SJed Brown found = self.checkExecutable('', value) 432179860b2SJed Brown if not found: 433179860b2SJed Brown for dir in os.environ['PATH'].split(os.path.pathsep): 434179860b2SJed Brown if self.checkExecutable(dir, value): 435179860b2SJed Brown found = 1 436179860b2SJed Brown break 437179860b2SJed Brown if not found: 438179860b2SJed Brown raise ValueError('Invalid executable: '+str(value)+' for key '+str(self.key)) 4397ce81a4bSJacob Faibussowitsch value += options 4407ce81a4bSJacob Faibussowitsch self.value = value 441179860b2SJed Brown return 442179860b2SJed Brown 443179860b2SJed Brownclass ArgString(Arg): 444179860b2SJed Brown '''Arguments that represent strings satisfying a given regular expression''' 445179860b2SJed Brown def __init__(self, key, value = None, help = '', regExp = None, isTemporary = 0, deprecated = False): 446179860b2SJed Brown self.regExp = regExp 447179860b2SJed Brown if self.regExp: 448179860b2SJed Brown import re 449179860b2SJed Brown self.re = re.compile(self.regExp) 450179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 451179860b2SJed Brown return 452179860b2SJed Brown 453179860b2SJed Brown def setValue(self, value): 454179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 455179860b2SJed Brown self.checkKey() 456179860b2SJed Brown if self.regExp and not self.re.match(value): 457179860b2SJed Brown raise ValueError('Invalid string '+str(value)+'. You must give a string satisfying "'+str(self.regExp)+'"'+' for key '+str(self.key)) 458179860b2SJed Brown self.value = value 459179860b2SJed Brown return 460179860b2SJed Brown 461179860b2SJed Brownclass ArgDownload(Arg): 462179860b2SJed Brown '''Arguments that represent software downloads''' 463179860b2SJed Brown def __init__(self, key, value = None, help = '', isTemporary = 0, deprecated = False): 464179860b2SJed Brown Arg.__init__(self, key, value, help, isTemporary, deprecated) 465179860b2SJed Brown return 466179860b2SJed Brown 467179860b2SJed Brown def valueName(self, value): 468179860b2SJed Brown if value == 0: 469179860b2SJed Brown return 'no' 470179860b2SJed Brown elif value == 1: 471179860b2SJed Brown return 'yes' 472179860b2SJed Brown return str(value) 473179860b2SJed Brown 474179860b2SJed Brown def __str__(self): 475179860b2SJed Brown if not self.isValueSet(): 476179860b2SJed Brown return 'Empty '+str(self.__class__) 477179860b2SJed Brown elif isinstance(self.value, list): 478179860b2SJed Brown return str(map(self.valueName, self.value)) 479179860b2SJed Brown return self.valueName(self.value) 480179860b2SJed Brown 481179860b2SJed Brown def setValue(self, value): 482179860b2SJed Brown '''Set the value. SHOULD MAKE THIS A PROPERTY''' 483179860b2SJed Brown import os 484179860b2SJed Brown self.checkKey() 485179860b2SJed Brown try: 486179860b2SJed Brown if value == '0': value = 0 487179860b2SJed Brown elif value == '1': value = 1 488179860b2SJed Brown elif value == 'no': value = 0 489179860b2SJed Brown elif value == 'yes': value = 1 490179860b2SJed Brown elif value == 'false': value = 0 491179860b2SJed Brown elif value == 'true': value = 1 492179860b2SJed Brown elif not isinstance(value, int): 493179860b2SJed Brown value = str(value) 494179860b2SJed Brown except: 495179860b2SJed Brown raise TypeError('Invalid download value: '+str(value)+' for key '+str(self.key)) 496*ffde4defSBarry Smith if isinstance(value, str) and value.startswith('git@'): 497*ffde4defSBarry Smith # git@github.com:xrq-phys/blis_apple.git -> git://https://github.com/xrq-phys/blis_apple.git 498*ffde4defSBarry Smith value = 'git://https://'+(value[len('git@'):].replace(':','/')) 499179860b2SJed Brown if isinstance(value, str): 500df3bd252SSatish Balay from urllib import parse as urlparse_local 501465d835dSVaclav Hapla if not urlparse_local.urlparse(value)[0] and not os.path.exists(value): 502179860b2SJed Brown raise ValueError('Invalid download location: '+str(value)+' for key '+str(self.key)) 503179860b2SJed Brown self.value = value 504179860b2SJed Brown return 505