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, 2009, 2010 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 4720 2010/03/24 03:14:11 jars" 
 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 # options might be added after the 'unknown' dict has been set up, 100 # so we remove the key and all its aliases from that dict 101 for alias in list(option.aliases) + [ option.key ]: 102 # TODO(1.5) 103 #if alias in self.unknown: 104 if alias in self.unknown.keys(): 105 del self.unknown[alias]
106
107 - def keys(self):
108 """ 109 Returns the keywords for the options 110 """ 111 return map(lambda o: o.key, self.options)
112
113 - def Add(self, key, help="", default=None, validator=None, converter=None, **kw):
114 """ 115 Add an option. 116 117 key - the name of the variable, or a list or tuple of arguments 118 help - optional help text for the options 119 default - optional default value 120 validator - optional function that is called to validate the option's value 121 Called with (key, value, environment) 122 converter - optional function that is called to convert the option's value before 123 putting it in the environment. 124 """ 125 126 if SCons.Util.is_List(key) or type(key) == type(()): 127 apply(self._do_add, key) 128 return 129 130 if not SCons.Util.is_String(key) or \ 131 not SCons.Environment.is_valid_construction_var(key): 132 raise SCons.Errors.UserError, "Illegal Variables.Add() key `%s'" % str(key) 133 134 self._do_add(key, help, default, validator, converter)
135
136 - def AddVariables(self, *optlist):
137 """ 138 Add a list of options. 139 140 Each list element is a tuple/list of arguments to be passed on 141 to the underlying method for adding options. 142 143 Example: 144 opt.AddVariables( 145 ('debug', '', 0), 146 ('CC', 'The C compiler'), 147 ('VALIDATE', 'An option for testing validation', 'notset', 148 validator, None), 149 ) 150 """ 151 for o in optlist: 152 apply(self._do_add, o)
153 154
155 - def Update(self, env, args=None):
156 """ 157 Update an environment with the option variables. 158 159 env - the environment to update. 160 """ 161 162 values = {} 163 164 # first set the defaults: 165 for option in self.options: 166 if not option.default is None: 167 values[option.key] = option.default 168 169 # next set the value specified in the options file 170 for filename in self.files: 171 if os.path.exists(filename): 172 dir = os.path.split(os.path.abspath(filename))[0] 173 if dir: 174 sys.path.insert(0, dir) 175 try: 176 values['__name__'] = filename 177 exec open(filename, 'rU').read() in {}, values 178 finally: 179 if dir: 180 del sys.path[0] 181 del values['__name__'] 182 183 # set the values specified on the command line 184 if args is None: 185 args = self.args 186 187 for arg, value in args.items(): 188 added = False 189 for option in self.options: 190 if arg in list(option.aliases) + [ option.key ]: 191 values[option.key] = value 192 added = True 193 if not added: 194 self.unknown[arg] = value 195 196 # put the variables in the environment: 197 # (don't copy over variables that are not declared as options) 198 for option in self.options: 199 try: 200 env[option.key] = values[option.key] 201 except KeyError: 202 pass 203 204 # Call the convert functions: 205 for option in self.options: 206 if option.converter and values.has_key(option.key): 207 value = env.subst('${%s}'%option.key) 208 try: 209 try: 210 env[option.key] = option.converter(value) 211 except TypeError: 212 env[option.key] = option.converter(value, env) 213 except ValueError, x: 214 raise SCons.Errors.UserError, 'Error converting option: %s\n%s'%(option.key, x) 215 216 217 # Finally validate the values: 218 for option in self.options: 219 if option.validator and values.has_key(option.key): 220 option.validator(option.key, env.subst('${%s}'%option.key), env)
221
222 - def UnknownVariables(self):
223 """ 224 Returns any options in the specified arguments lists that 225 were not known, declared options in this object. 226 """ 227 return self.unknown
228
229 - def Save(self, filename, env):
230 """ 231 Saves all the options in the given file. This file can 232 then be used to load the options next run. This can be used 233 to create an option cache file. 234 235 filename - Name of the file to save into 236 env - the environment get the option values from 237 """ 238 239 # Create the file and write out the header 240 try: 241 fh = open(filename, 'w') 242 243 try: 244 # Make an assignment in the file for each option 245 # within the environment that was assigned a value 246 # other than the default. 247 for option in self.options: 248 try: 249 value = env[option.key] 250 try: 251 prepare = value.prepare_to_store 252 except AttributeError: 253 try: 254 eval(repr(value)) 255 except KeyboardInterrupt: 256 raise 257 except: 258 # Convert stuff that has a repr() that 259 # cannot be evaluated into a string 260 value = SCons.Util.to_String(value) 261 else: 262 value = prepare() 263 264 defaultVal = env.subst(SCons.Util.to_String(option.default)) 265 if option.converter: 266 defaultVal = option.converter(defaultVal) 267 268 if str(env.subst('${%s}' % option.key)) != str(defaultVal): 269 fh.write('%s = %s\n' % (option.key, repr(value))) 270 except KeyError: 271 pass 272 finally: 273 fh.close() 274 275 except IOError, x: 276 raise SCons.Errors.UserError, 'Error writing options to file: %s\n%s' % (filename, x)
277
278 - def GenerateHelpText(self, env, sort=None):
279 """ 280 Generate the help text for the options. 281 282 env - an environment that is used to get the current values 283 of the options. 284 """ 285 286 if sort: 287 options = self.options[:] 288 options.sort(lambda x,y,func=sort: func(x.key,y.key)) 289 else: 290 options = self.options 291 292 def format(opt, self=self, env=env): 293 if env.has_key(opt.key): 294 actual = env.subst('${%s}' % opt.key) 295 else: 296 actual = None 297 return self.FormatVariableHelpText(env, opt.key, opt.help, opt.default, actual, opt.aliases)
298 lines = filter(None, map(format, options)) 299 300 return string.join(lines, '') 301 302 format = '\n%s: %s\n default: %s\n actual: %s\n' 303 format_ = '\n%s: %s\n default: %s\n actual: %s\n aliases: %s\n' 304
305 - def FormatVariableHelpText(self, env, key, help, default, actual, aliases=[]):
306 # Don't display the key name itself as an alias. 307 aliases = filter(lambda a, k=key: a != k, aliases) 308 if len(aliases)==0: 309 return self.format % (key, help, default, actual) 310 else: 311 return self.format_ % (key, help, default, actual, aliases)
312 313 # Local Variables: 314 # tab-width:4 315 # indent-tabs-mode:nil 316 # End: 317 # vim: set expandtab tabstop=4 shiftwidth=4: 318