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 3266 2008/08/12 07:31:01 knight" 
 31   
 32  import SCons.compat 
 33   
 34  import os.path 
 35  import string 
 36  import sys 
 37   
 38  import SCons.Environment 
 39  import SCons.Errors 
 40  import SCons.Util 
 41  import SCons.Warnings 
 42   
 43  from BoolVariable import BoolVariable  # okay 
 44  from EnumVariable import EnumVariable  # okay 
 45  from ListVariable import ListVariable  # naja 
 46  from PackageVariable import PackageVariable # naja 
 47  from PathVariable import PathVariable # okay 
 48   
 49   
50 -class Variables:
51 instance=None 52 53 """ 54 Holds all the options, updates the environment with the variables, 55 and renders the help text. 56 """
57 - def __init__(self, files=[], args={}, is_global=1):
58 """ 59 files - [optional] List of option configuration files to load 60 (backward compatibility) If a single string is passed it is 61 automatically placed in a file list 62 """ 63 self.options = [] 64 self.args = args 65 if not SCons.Util.is_List(files): 66 if files: 67 files = [ files ] 68 else: 69 files = [] 70 self.files = files 71 self.unknown = {} 72 73 # create the singleton instance 74 if is_global: 75 self=Variables.instance 76 77 if not Variables.instance: 78 Variables.instance=self
79
80 - def _do_add(self, key, help="", default=None, validator=None, converter=None):
81 class Variable: 82 pass
83 84 option = Variable() 85 86 # if we get a list or a tuple, we take the first element as the 87 # option key and store the remaining in aliases. 88 if SCons.Util.is_List(key) or SCons.Util.is_Tuple(key): 89 option.key = key[0] 90 option.aliases = key[1:] 91 else: 92 option.key = key 93 option.aliases = [ key ] 94 option.help = help 95 option.default = default 96 option.validator = validator 97 option.converter = converter 98 99 self.options.append(option)
100
101 - def keys(self):
102 """ 103 Returns the keywords for the options 104 """ 105 return map(lambda o: o.key, self.options)
106
107 - def Add(self, key, help="", default=None, validator=None, converter=None, **kw):
108 """ 109 Add an option. 110 111 key - the name of the variable, or a list or tuple of arguments 112 help - optional help text for the options 113 default - optional default value 114 validator - optional function that is called to validate the option's value 115 Called with (key, value, environment) 116 converter - optional function that is called to convert the option's value before 117 putting it in the environment. 118 """ 119 120 if SCons.Util.is_List(key) or type(key) == type(()): 121 apply(self._do_add, key) 122 return 123 124 if not SCons.Util.is_String(key) or \ 125 not SCons.Environment.is_valid_construction_var(key): 126 raise SCons.Errors.UserError, "Illegal Variables.Add() key `%s'" % str(key) 127 128 self._do_add(key, help, default, validator, converter)
129
130 - def AddVariables(self, *optlist):
131 """ 132 Add a list of options. 133 134 Each list element is a tuple/list of arguments to be passed on 135 to the underlying method for adding options. 136 137 Example: 138 opt.AddVariables( 139 ('debug', '', 0), 140 ('CC', 'The C compiler'), 141 ('VALIDATE', 'An option for testing validation', 'notset', 142 validator, None), 143 ) 144 """ 145 for o in optlist: 146 apply(self._do_add, o)
147 148
149 - def Update(self, env, args=None):
150 """ 151 Update an environment with the option variables. 152 153 env - the environment to update. 154 """ 155 156 values = {} 157 158 # first set the defaults: 159 for option in self.options: 160 if not option.default is None: 161 values[option.key] = option.default 162 163 # next set the value specified in the options file 164 for filename in self.files: 165 if os.path.exists(filename): 166 dir = os.path.split(os.path.abspath(filename))[0] 167 if dir: 168 sys.path.insert(0, dir) 169 try: 170 values['__name__'] = filename 171 execfile(filename, {}, values) 172 finally: 173 if dir: 174 del sys.path[0] 175 del values['__name__'] 176 177 # set the values specified on the command line 178 if args is None: 179 args = self.args 180 181 for arg, value in args.items(): 182 added = False 183 for option in self.options: 184 if arg in option.aliases + [ option.key ]: 185 values[option.key] = value 186 added = True 187 if not added: 188 self.unknown[arg] = value 189 190 # put the variables in the environment: 191 # (don't copy over variables that are not declared as options) 192 for option in self.options: 193 try: 194 env[option.key] = values[option.key] 195 except KeyError: 196 pass 197 198 # Call the convert functions: 199 for option in self.options: 200 if option.converter and values.has_key(option.key): 201 value = env.subst('${%s}'%option.key) 202 try: 203 try: 204 env[option.key] = option.converter(value) 205 except TypeError: 206 env[option.key] = option.converter(value, env) 207 except ValueError, x: 208 raise SCons.Errors.UserError, 'Error converting option: %s\n%s'%(option.key, x) 209 210 211 # Finally validate the values: 212 for option in self.options: 213 if option.validator and values.has_key(option.key): 214 option.validator(option.key, env.subst('${%s}'%option.key), env)
215
216 - def UnknownVariables(self):
217 """ 218 Returns any options in the specified arguments lists that 219 were not known, declared options in this object. 220 """ 221 return self.unknown
222
223 - def Save(self, filename, env):
224 """ 225 Saves all the options in the given file. This file can 226 then be used to load the options next run. This can be used 227 to create an option cache file. 228 229 filename - Name of the file to save into 230 env - the environment get the option values from 231 """ 232 233 # Create the file and write out the header 234 try: 235 fh = open(filename, 'w') 236 237 try: 238 # Make an assignment in the file for each option 239 # within the environment that was assigned a value 240 # other than the default. 241 for option in self.options: 242 try: 243 value = env[option.key] 244 try: 245 prepare = value.prepare_to_store 246 except AttributeError: 247 try: 248 eval(repr(value)) 249 except KeyboardInterrupt: 250 raise 251 except: 252 # Convert stuff that has a repr() that 253 # cannot be evaluated into a string 254 value = SCons.Util.to_String(value) 255 else: 256 value = prepare() 257 258 defaultVal = env.subst(SCons.Util.to_String(option.default)) 259 if option.converter: 260 defaultVal = option.converter(defaultVal) 261 262 if str(env.subst('${%s}' % option.key)) != str(defaultVal): 263 fh.write('%s = %s\n' % (option.key, repr(value))) 264 except KeyError: 265 pass 266 finally: 267 fh.close() 268 269 except IOError, x: 270 raise SCons.Errors.UserError, 'Error writing options to file: %s\n%s' % (filename, x)
271
272 - def GenerateHelpText(self, env, sort=None):
273 """ 274 Generate the help text for the options. 275 276 env - an environment that is used to get the current values 277 of the options. 278 """ 279 280 if sort: 281 options = self.options[:] 282 options.sort(lambda x,y,func=sort: func(x.key,y.key)) 283 else: 284 options = self.options 285 286 def format(opt, self=self, env=env): 287 if env.has_key(opt.key): 288 actual = env.subst('${%s}' % opt.key) 289 else: 290 actual = None 291 return self.FormatVariableHelpText(env, opt.key, opt.help, opt.default, actual, opt.aliases)
292 lines = filter(None, map(format, options)) 293 294 return string.join(lines, '') 295 296 format = '\n%s: %s\n default: %s\n actual: %s\n' 297 format_ = '\n%s: %s\n default: %s\n actual: %s\n aliases: %s\n' 298
299 - def FormatVariableHelpText(self, env, key, help, default, actual, aliases=[]):
300 # Don't display the key name itself as an alias. 301 aliases = filter(lambda a, k=key: a != k, aliases) 302 if len(aliases)==0: 303 return self.format % (key, help, default, actual) 304 else: 305 return self.format_ % (key, help, default, actual, aliases)
306