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