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