Package SCons :: Package Variables
[hide private]
[frames] | no frames]

Source Code for Package SCons.Variables

  1  """engine.SCons.Variables 
  2   
  3  This file defines the Variables class that is used to add user-friendly 
  4  customizable variables to an SCons build. 
  5  """ 
  6   
  7  # 
  8  # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation 
  9  # 
 10  # Permission is hereby granted, free of charge, to any person obtaining 
 11  # a copy of this software and associated documentation files (the 
 12  # "Software"), to deal in the Software without restriction, including 
 13  # without limitation the rights to use, copy, modify, merge, publish, 
 14  # distribute, sublicense, and/or sell copies of the Software, and to 
 15  # permit persons to whom the Software is furnished to do so, subject to 
 16  # the following conditions: 
 17  # 
 18  # The above copyright notice and this permission notice shall be included 
 19  # in all copies or substantial portions of the Software. 
 20  # 
 21  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 
 22  # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 
 23  # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 24  # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
 25  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
 26  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
 27  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
 28  # 
 29   
 30  __revision__ = "src/engine/SCons/Variables/__init__.py 3842 2008/12/20 22:59:52 scons" 
 31   
 32  import os.path 
 33  import string 
 34  import sys 
 35   
 36  import SCons.Environment 
 37  import SCons.Errors 
 38  import SCons.Util 
 39  import SCons.Warnings 
 40   
 41  from BoolVariable import BoolVariable  # okay 
 42  from EnumVariable import EnumVariable  # okay 
 43  from ListVariable import ListVariable  # naja 
 44  from PackageVariable import PackageVariable # naja 
 45  from PathVariable import PathVariable # okay 
 46   
 47   
48 -class Variables:
49 instance=None 50 51 """ 52 Holds all the options, updates the environment with the variables, 53 and renders the help text. 54 """
55 - def __init__(self, files=[], args={}, is_global=1):
56 """ 57 files - [optional] List of option configuration files to load 58 (backward compatibility) If a single string is passed it is 59 automatically placed in a file list 60 """ 61 self.options = [] 62 self.args = args 63 if not SCons.Util.is_List(files): 64 if files: 65 files = [ files ] 66 else: 67 files = [] 68 self.files = files 69 self.unknown = {} 70 71 # create the singleton instance 72 if is_global: 73 self=Variables.instance 74 75 if not Variables.instance: 76 Variables.instance=self
77
78 - def _do_add(self, key, help="", default=None, validator=None, converter=None):
79 class Variable: 80 pass
81 82 option = Variable() 83 84 # if we get a list or a tuple, we take the first element as the 85 # option key and store the remaining in aliases. 86 if SCons.Util.is_List(key) or SCons.Util.is_Tuple(key): 87 option.key = key[0] 88 option.aliases = key[1:] 89 else: 90 option.key = key 91 option.aliases = [ key ] 92 option.help = help 93 option.default = default 94 option.validator = validator 95 option.converter = converter 96 97 self.options.append(option)
98
99 - def keys(self):
100 """ 101 Returns the keywords for the options 102 """ 103 return map(lambda o: o.key, self.options)
104
105 - def Add(self, key, help="", default=None, validator=None, converter=None, **kw):
106 """ 107 Add an option. 108 109 key - the name of the variable, or a list or tuple of arguments 110 help - optional help text for the options 111 default - optional default value 112 validator - optional function that is called to validate the option's value 113 Called with (key, value, environment) 114 converter - optional function that is called to convert the option's value before 115 putting it in the environment. 116 """ 117 118 if SCons.Util.is_List(key) or type(key) == type(()): 119 apply(self._do_add, key) 120 return 121 122 if not SCons.Util.is_String(key) or \ 123 not SCons.Environment.is_valid_construction_var(key): 124 raise SCons.Errors.UserError, "Illegal Variables.Add() key `%s'" % str(key) 125 126 self._do_add(key, help, default, validator, converter)
127
128 - def AddVariables(self, *optlist):
129 """ 130 Add a list of options. 131 132 Each list element is a tuple/list of arguments to be passed on 133 to the underlying method for adding options. 134 135 Example: 136 opt.AddVariables( 137 ('debug', '', 0), 138 ('CC', 'The C compiler'), 139 ('VALIDATE', 'An option for testing validation', 'notset', 140 validator, None), 141 ) 142 """ 143 for o in optlist: 144 apply(self._do_add, o)
145 146
147 - def Update(self, env, args=None):
148 """ 149 Update an environment with the option variables. 150 151 env - the environment to update. 152 """ 153 154 values = {} 155 156 # first set the defaults: 157 for option in self.options: 158 if not option.default is None: 159 values[option.key] = option.default 160 161 # next set the value specified in the options file 162 for filename in self.files: 163 if os.path.exists(filename): 164 dir = os.path.split(os.path.abspath(filename))[0] 165 if dir: 166 sys.path.insert(0, dir) 167 try: 168 values['__name__'] = filename 169 execfile(filename, {}, values) 170 finally: 171 if dir: 172 del sys.path[0] 173 del values['__name__'] 174 175 # set the values specified on the command line 176 if args is None: 177 args = self.args 178 179 for arg, value in args.items(): 180 added = False 181 for option in self.options: 182 if arg in option.aliases + [ option.key ]: 183 values[option.key] = value 184 added = True 185 if not added: 186 self.unknown[arg] = value 187 188 # put the variables in the environment: 189 # (don't copy over variables that are not declared as options) 190 for option in self.options: 191 try: 192 env[option.key] = values[option.key] 193 except KeyError: 194 pass 195 196 # Call the convert functions: 197 for option in self.options: 198 if option.converter and values.has_key(option.key): 199 value = env.subst('${%s}'%option.key) 200 try: 201 try: 202 env[option.key] = option.converter(value) 203 except TypeError: 204 env[option.key] = option.converter(value, env) 205 except ValueError, x: 206 raise SCons.Errors.UserError, 'Error converting option: %s\n%s'%(option.key, x) 207 208 209 # Finally validate the values: 210 for option in self.options: 211 if option.validator and values.has_key(option.key): 212 option.validator(option.key, env.subst('${%s}'%option.key), env)
213
214 - def UnknownVariables(self):
215 """ 216 Returns any options in the specified arguments lists that 217 were not known, declared options in this object. 218 """ 219 return self.unknown
220
221 - def Save(self, filename, env):
222 """ 223 Saves all the options in the given file. This file can 224 then be used to load the options next run. This can be used 225 to create an option cache file. 226 227 filename - Name of the file to save into 228 env - the environment get the option values from 229 """ 230 231 # Create the file and write out the header 232 try: 233 fh = open(filename, 'w') 234 235 try: 236 # Make an assignment in the file for each option 237 # within the environment that was assigned a value 238 # other than the default. 239 for option in self.options: 240 try: 241 value = env[option.key] 242 try: 243 prepare = value.prepare_to_store 244 except AttributeError: 245 try: 246 eval(repr(value)) 247 except KeyboardInterrupt: 248 raise 249 except: 250 # Convert stuff that has a repr() that 251 # cannot be evaluated into a string 252 value = SCons.Util.to_String(value) 253 else: 254 value = prepare() 255 256 defaultVal = env.subst(SCons.Util.to_String(option.default)) 257 if option.converter: 258 defaultVal = option.converter(defaultVal) 259 260 if str(env.subst('${%s}' % option.key)) != str(defaultVal): 261 fh.write('%s = %s\n' % (option.key, repr(value))) 262 except KeyError: 263 pass 264 finally: 265 fh.close() 266 267 except IOError, x: 268 raise SCons.Errors.UserError, 'Error writing options to file: %s\n%s' % (filename, x)
269
270 - def GenerateHelpText(self, env, sort=None):
271 """ 272 Generate the help text for the options. 273 274 env - an environment that is used to get the current values 275 of the options. 276 """ 277 278 if sort: 279 options = self.options[:] 280 options.sort(lambda x,y,func=sort: func(x.key,y.key)) 281 else: 282 options = self.options 283 284 def format(opt, self=self, env=env): 285 if env.has_key(opt.key): 286 actual = env.subst('${%s}' % opt.key) 287 else: 288 actual = None 289 return self.FormatVariableHelpText(env, opt.key, opt.help, opt.default, actual, opt.aliases)
290 lines = filter(None, map(format, options)) 291 292 return string.join(lines, '') 293 294 format = '\n%s: %s\n default: %s\n actual: %s\n' 295 format_ = '\n%s: %s\n default: %s\n actual: %s\n aliases: %s\n' 296
297 - def FormatVariableHelpText(self, env, key, help, default, actual, aliases=[]):
298 # Don't display the key name itself as an alias. 299 aliases = filter(lambda a, k=key: a != k, aliases) 300 if len(aliases)==0: 301 return self.format % (key, help, default, actual) 302 else: 303 return self.format_ % (key, help, default, actual, aliases)
304