diff options
Diffstat (limited to '3rdParty/SCons/scons-3.0.1/engine/SCons/Variables')
12 files changed, 2439 insertions, 0 deletions
diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/BoolVariable.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/BoolVariable.py new file mode 100644 index 0000000..ce46eda --- /dev/null +++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/BoolVariable.py @@ -0,0 +1,89 @@ +"""engine.SCons.Variables.BoolVariable + +This file defines the option type for SCons implementing true/false values. + +Usage example:: + + opts = Variables() + opts.Add(BoolVariable('embedded', 'build for an embedded system', 0)) + ... + if env['embedded'] == 1: + ... +""" + +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +__all__ = ['BoolVariable',] + +import SCons.Errors + +__true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' ) +__false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none') + + +def _text2bool(val): + """ + Converts strings to True/False depending on the 'truth' expressed by + the string. If the string can't be converted, the original value + will be returned. + + See '__true_strings' and '__false_strings' for values considered + 'true' or 'false respectively. + + This is usable as 'converter' for SCons' Variables. + """ + lval = val.lower() + if lval in __true_strings: return True + if lval in __false_strings: return False + raise ValueError("Invalid value for boolean option: %s" % val) + + +def _validator(key, val, env): + """ + Validates the given value to be either '0' or '1'. + + This is usable as 'validator' for SCons' Variables. + """ + if not env[key] in (True, False): + raise SCons.Errors.UserError( + 'Invalid value for boolean option %s: %s' % (key, env[key])) + + +def BoolVariable(key, help, default): + """ + The input parameters describe a boolean option, thus they are + returned with the correct converter and validator appended. The + 'help' text will by appended by '(yes|no) to show the valid + valued. The result is usable for input to opts.Add(). + """ + return (key, '%s (yes|no)' % help, default, + _validator, _text2bool) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/BoolVariableTests.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/BoolVariableTests.py new file mode 100644 index 0000000..7110f6f --- /dev/null +++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/BoolVariableTests.py @@ -0,0 +1,128 @@ +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import sys +import unittest + +import TestUnit + +import SCons.Errors +import SCons.Variables + +class BoolVariableTestCase(unittest.TestCase): + def test_BoolVariable(self): + """Test BoolVariable creation""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.BoolVariable('test', 'test option help', 0)) + + o = opts.options[0] + assert o.key == 'test', o.key + assert o.help == 'test option help (yes|no)', o.help + assert o.default == 0, o.default + assert o.validator is not None, o.validator + assert o.converter is not None, o.converter + + def test_converter(self): + """Test the BoolVariable converter""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.BoolVariable('test', 'test option help', 0)) + + o = opts.options[0] + + true_values = [ + 'y', 'Y', + 'yes', 'YES', + 't', 'T', + 'true', 'TRUE', + 'on', 'ON', + 'all', 'ALL', + '1', + ] + false_values = [ + 'n', 'N', + 'no', 'NO', + 'f', 'F', + 'false', 'FALSE', + 'off', 'OFF', + 'none', 'NONE', + '0', + ] + + for t in true_values: + x = o.converter(t) + assert x, "converter returned false for '%s'" % t + + for f in false_values: + x = o.converter(f) + assert not x, "converter returned true for '%s'" % f + + caught = None + try: + o.converter('x') + except ValueError: + caught = 1 + assert caught, "did not catch expected ValueError" + + def test_validator(self): + """Test the BoolVariable validator""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.BoolVariable('test', 'test option help', 0)) + + o = opts.options[0] + + env = { + 'T' : True, + 'F' : False, + 'N' : 'xyzzy', + } + + o.validator('T', 0, env) + + o.validator('F', 0, env) + + caught = None + try: + o.validator('N', 0, env) + except SCons.Errors.UserError: + caught = 1 + assert caught, "did not catch expected UserError for N" + + caught = None + try: + o.validator('NOSUCHKEY', 0, env) + except KeyError: + caught = 1 + assert caught, "did not catch expected KeyError for NOSUCHKEY" + + +if __name__ == "__main__": + suite = unittest.makeSuite(BoolVariableTestCase, 'test_') + TestUnit.run(suite) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/EnumVariable.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/EnumVariable.py new file mode 100644 index 0000000..a9fb100 --- /dev/null +++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/EnumVariable.py @@ -0,0 +1,101 @@ +"""engine.SCons.Variables.EnumVariable + +This file defines the option type for SCons allowing only specified +input-values. + +Usage example:: + + opts = Variables() + opts.Add(EnumVariable('debug', 'debug output and symbols', 'no', + allowed_values=('yes', 'no', 'full'), + map={}, ignorecase=2)) + ... + if env['debug'] == 'full': + ... +""" + +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +__all__ = ['EnumVariable',] + + +import SCons.Errors + +def _validator(key, val, env, vals): + if not val in vals: + raise SCons.Errors.UserError( + 'Invalid value for option %s: %s. Valid values are: %s' % (key, val, vals)) + + +def EnumVariable(key, help, default, allowed_values, map={}, ignorecase=0): + """ + The input parameters describe an option with only certain values + allowed. They are returned with an appropriate converter and + validator appended. The result is usable for input to + Variables.Add(). + + 'key' and 'default' are the values to be passed on to Variables.Add(). + + 'help' will be appended by the allowed values automatically + + 'allowed_values' is a list of strings, which are allowed as values + for this option. + + The 'map'-dictionary may be used for converting the input value + into canonical values (e.g. for aliases). + + 'ignorecase' defines the behaviour of the validator: + + If ignorecase == 0, the validator/converter are case-sensitive. + If ignorecase == 1, the validator/converter are case-insensitive. + If ignorecase == 2, the validator/converter is case-insensitive and the converted value will always be lower-case. + + The 'validator' tests whether the value is in the list of allowed values. The 'converter' converts input values + according to the given 'map'-dictionary (unmapped input values are returned unchanged). + """ + + help = '%s (%s)' % (help, '|'.join(allowed_values)) + # define validator + if ignorecase >= 1: + validator = lambda key, val, env: \ + _validator(key, val.lower(), env, allowed_values) + else: + validator = lambda key, val, env: \ + _validator(key, val, env, allowed_values) + # define converter + if ignorecase == 2: + converter = lambda val: map.get(val.lower(), val).lower() + elif ignorecase == 1: + converter = lambda val: map.get(val.lower(), val) + else: + converter = lambda val: map.get(val, val) + return (key, help, default, validator, converter) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/EnumVariableTests.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/EnumVariableTests.py new file mode 100644 index 0000000..931dfe2 --- /dev/null +++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/EnumVariableTests.py @@ -0,0 +1,205 @@ +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import sys +import unittest + +import TestUnit + +import SCons.Errors +import SCons.Variables + +class EnumVariableTestCase(unittest.TestCase): + def test_EnumVariable(self): + """Test EnumVariable creation""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.EnumVariable('test', 'test option help', 0, + ['one', 'two', 'three'], + {})) + + o = opts.options[0] + assert o.key == 'test', o.key + assert o.help == 'test option help (one|two|three)', o.help + assert o.default == 0, o.default + assert o.validator is not None, o.validator + assert o.converter is not None, o.converter + + def test_converter(self): + """Test the EnumVariable converter""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.EnumVariable('test', 'test option help', 0, + ['one', 'two', 'three'])) + + o = opts.options[0] + + for a in ['one', 'two', 'three', 'no_match']: + x = o.converter(a) + assert x == a, x + + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.EnumVariable('test', 'test option help', 0, + ['one', 'two', 'three'], + {'1' : 'one', + '2' : 'two', + '3' : 'three'})) + + o = opts.options[0] + + x = o.converter('one') + assert x == 'one', x + x = o.converter('1') + assert x == 'one', x + + x = o.converter('two') + assert x == 'two', x + x = o.converter('2') + assert x == 'two', x + + x = o.converter('three') + assert x == 'three', x + x = o.converter('3') + assert x == 'three', x + + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.EnumVariable('test0', 'test option help', 0, + ['one', 'two', 'three'], + {'a' : 'one', + 'b' : 'two', + 'c' : 'three'}, + ignorecase=0)) + opts.Add(SCons.Variables.EnumVariable('test1', 'test option help', 0, + ['one', 'two', 'three'], + {'a' : 'one', + 'b' : 'two', + 'c' : 'three'}, + ignorecase=1)) + opts.Add(SCons.Variables.EnumVariable('test2', 'test option help', 0, + ['one', 'two', 'three'], + {'a' : 'one', + 'b' : 'two', + 'c' : 'three'}, + ignorecase=2)) + + o0 = opts.options[0] + o1 = opts.options[1] + o2 = opts.options[2] + + table = { + 'one' : ['one', 'one', 'one'], + 'One' : ['One', 'One', 'one'], + 'ONE' : ['ONE', 'ONE', 'one'], + 'two' : ['two', 'two', 'two'], + 'twO' : ['twO', 'twO', 'two'], + 'TWO' : ['TWO', 'TWO', 'two'], + 'three' : ['three', 'three', 'three'], + 'thRee' : ['thRee', 'thRee', 'three'], + 'THREE' : ['THREE', 'THREE', 'three'], + 'a' : ['one', 'one', 'one'], + 'A' : ['A', 'one', 'one'], + 'b' : ['two', 'two', 'two'], + 'B' : ['B', 'two', 'two'], + 'c' : ['three', 'three', 'three'], + 'C' : ['C', 'three', 'three'], + } + + for k, l in table.items(): + x = o0.converter(k) + assert x == l[0], "o0 got %s, expected %s" % (x, l[0]) + x = o1.converter(k) + assert x == l[1], "o1 got %s, expected %s" % (x, l[1]) + x = o2.converter(k) + assert x == l[2], "o2 got %s, expected %s" % (x, l[2]) + + def test_validator(self): + """Test the EnumVariable validator""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.EnumVariable('test0', 'test option help', 0, + ['one', 'two', 'three'], + {'a' : 'one', + 'b' : 'two', + 'c' : 'three'}, + ignorecase=0)) + opts.Add(SCons.Variables.EnumVariable('test1', 'test option help', 0, + ['one', 'two', 'three'], + {'a' : 'one', + 'b' : 'two', + 'c' : 'three'}, + ignorecase=1)) + opts.Add(SCons.Variables.EnumVariable('test2', 'test option help', 0, + ['one', 'two', 'three'], + {'a' : 'one', + 'b' : 'two', + 'c' : 'three'}, + ignorecase=2)) + + o0 = opts.options[0] + o1 = opts.options[1] + o2 = opts.options[2] + + def valid(o, v): + o.validator('X', v, {}) + + def invalid(o, v): + caught = None + try: + o.validator('X', v, {}) + except SCons.Errors.UserError: + caught = 1 + assert caught, "did not catch expected UserError for o = %s, v = %s" % (o.key, v) + + table = { + 'one' : [ valid, valid, valid], + 'One' : [invalid, valid, valid], + 'ONE' : [invalid, valid, valid], + 'two' : [ valid, valid, valid], + 'twO' : [invalid, valid, valid], + 'TWO' : [invalid, valid, valid], + 'three' : [ valid, valid, valid], + 'thRee' : [invalid, valid, valid], + 'THREE' : [invalid, valid, valid], + 'a' : [invalid, invalid, invalid], + 'A' : [invalid, invalid, invalid], + 'b' : [invalid, invalid, invalid], + 'B' : [invalid, invalid, invalid], + 'c' : [invalid, invalid, invalid], + 'C' : [invalid, invalid, invalid], + 'no_v' : [invalid, invalid, invalid], + } + + for v, l in table.items(): + l[0](o0, v) + l[1](o1, v) + l[2](o2, v) + + +if __name__ == "__main__": + suite = unittest.makeSuite(EnumVariableTestCase, 'test_') + TestUnit.run(suite) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/ListVariable.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/ListVariable.py new file mode 100644 index 0000000..9024867 --- /dev/null +++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/ListVariable.py @@ -0,0 +1,135 @@ +"""engine.SCons.Variables.ListVariable + +This file defines the option type for SCons implementing 'lists'. + +A 'list' option may either be 'all', 'none' or a list of names +separated by comma. After the option has been processed, the option +value holds either the named list elements, all list elements or no +list elements at all. + +Usage example:: + + list_of_libs = Split('x11 gl qt ical') + + opts = Variables() + opts.Add(ListVariable('shared', + 'libraries to build as shared libraries', + 'all', + elems = list_of_libs)) + ... + for lib in list_of_libs: + if lib in env['shared']: + env.SharedObject(...) + else: + env.Object(...) +""" + +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +# Known Bug: This should behave like a Set-Type, but does not really, +# since elements can occur twice. + +__all__ = ['ListVariable',] + +import collections + +import SCons.Util + + +class _ListVariable(collections.UserList): + def __init__(self, initlist=[], allowedElems=[]): + collections.UserList.__init__(self, [_f for _f in initlist if _f]) + self.allowedElems = sorted(allowedElems) + + def __cmp__(self, other): + raise NotImplementedError + def __eq__(self, other): + raise NotImplementedError + def __ge__(self, other): + raise NotImplementedError + def __gt__(self, other): + raise NotImplementedError + def __le__(self, other): + raise NotImplementedError + def __lt__(self, other): + raise NotImplementedError + def __str__(self): + if len(self) == 0: + return 'none' + self.data.sort() + if self.data == self.allowedElems: + return 'all' + else: + return ','.join(self) + def prepare_to_store(self): + return self.__str__() + +def _converter(val, allowedElems, mapdict): + """ + """ + if val == 'none': + val = [] + elif val == 'all': + val = allowedElems + else: + val = [_f for _f in val.split(',') if _f] + val = [mapdict.get(v, v) for v in val] + notAllowed = [v for v in val if not v in allowedElems] + if notAllowed: + raise ValueError("Invalid value(s) for option: %s" % + ','.join(notAllowed)) + return _ListVariable(val, allowedElems) + + +## def _validator(key, val, env): +## """ +## """ +## # todo: write validator for pgk list +## return 1 + + +def ListVariable(key, help, default, names, map={}): + """ + The input parameters describe a 'package list' option, thus they + are returned with the correct converter and validator appended. The + result is usable for input to opts.Add() . + + A 'package list' option may either be 'all', 'none' or a list of + package names (separated by space). + """ + names_str = 'allowed names: %s' % ' '.join(names) + if SCons.Util.is_List(default): + default = ','.join(default) + help = '\n '.join( + (help, '(all|none|comma-separated list of names)', names_str)) + return (key, help, default, + None, #_validator, + lambda val: _converter(val, names, map)) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/ListVariableTests.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/ListVariableTests.py new file mode 100644 index 0000000..adfd353 --- /dev/null +++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/ListVariableTests.py @@ -0,0 +1,135 @@ +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import copy +import sys +import unittest + +import TestUnit + +import SCons.Errors +import SCons.Variables + +class ListVariableTestCase(unittest.TestCase): + def test_ListVariable(self): + """Test ListVariable creation""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.ListVariable('test', 'test option help', 'all', + ['one', 'two', 'three'])) + + o = opts.options[0] + assert o.key == 'test', o.key + assert o.help == 'test option help\n (all|none|comma-separated list of names)\n allowed names: one two three', repr(o.help) + assert o.default == 'all', o.default + assert o.validator is None, o.validator + assert not o.converter is None, o.converter + + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.ListVariable('test2', 'test2 help', + ['one', 'three'], + ['one', 'two', 'three'])) + + o = opts.options[0] + assert o.default == 'one,three' + + def test_converter(self): + """Test the ListVariable converter""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.ListVariable('test', 'test option help', 'all', + ['one', 'two', 'three'], + {'ONE':'one', 'TWO':'two'})) + + o = opts.options[0] + + x = o.converter('all') + assert str(x) == 'all', x + + x = o.converter('none') + assert str(x) == 'none', x + + x = o.converter('one') + assert str(x) == 'one', x + x = o.converter('ONE') + assert str(x) == 'one', x + + x = o.converter('two') + assert str(x) == 'two', x + x = o.converter('TWO') + assert str(x) == 'two', x + + x = o.converter('three') + assert str(x) == 'three', x + + x = o.converter('one,two') + assert str(x) == 'one,two', x + x = o.converter('two,one') + assert str(x) == 'one,two', x + + x = o.converter('one,three') + assert str(x) == 'one,three', x + x = o.converter('three,one') + assert str(x) == 'one,three', x + + x = o.converter('two,three') + assert str(x) == 'three,two', x + x = o.converter('three,two') + assert str(x) == 'three,two', x + + x = o.converter('one,two,three') + assert str(x) == 'all', x + + x = o.converter('three,two,one') + assert str(x) == 'all', x + + x = o.converter('three,ONE,TWO') + assert str(x) == 'all', x + + caught = None + try: + x = o.converter('no_match') + except ValueError: + caught = 1 + assert caught, "did not catch expected ValueError" + + def test_copy(self): + """Test copying a ListVariable like an Environment would""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.ListVariable('test', 'test option help', 'all', + ['one', 'two', 'three'])) + + o = opts.options[0] + + l = o.converter('all') + n = l.__class__(copy.copy(l)) + +if __name__ == "__main__": + suite = unittest.makeSuite(ListVariableTestCase, 'test_') + TestUnit.run(suite) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/PackageVariable.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/PackageVariable.py new file mode 100644 index 0000000..a0ace25 --- /dev/null +++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/PackageVariable.py @@ -0,0 +1,106 @@ +"""engine.SCons.Variables.PackageVariable + +This file defines the option type for SCons implementing 'package +activation'. + +To be used whenever a 'package' may be enabled/disabled and the +package path may be specified. + +Usage example: + + Examples: + x11=no (disables X11 support) + x11=yes (will search for the package installation dir) + x11=/usr/local/X11 (will check this path for existence) + + To replace autoconf's --with-xxx=yyy :: + + opts = Variables() + opts.Add(PackageVariable('x11', + 'use X11 installed here (yes = search some places', + 'yes')) + ... + if env['x11'] == True: + dir = ... search X11 in some standard places ... + env['x11'] = dir + if env['x11']: + ... build with x11 ... +""" + +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +__all__ = ['PackageVariable',] + +import SCons.Errors + +__enable_strings = ('1', 'yes', 'true', 'on', 'enable', 'search') +__disable_strings = ('0', 'no', 'false', 'off', 'disable') + +def _converter(val): + """ + """ + lval = val.lower() + if lval in __enable_strings: return True + if lval in __disable_strings: return False + #raise ValueError("Invalid value for boolean option: %s" % val) + return val + + +def _validator(key, val, env, searchfunc): + # NB: searchfunc is currently undocumented and unsupported + """ + """ + # TODO write validator, check for path + import os + if env[key] is True: + if searchfunc: + env[key] = searchfunc(key, val) + elif env[key] and not os.path.exists(val): + raise SCons.Errors.UserError( + 'Path does not exist for option %s: %s' % (key, val)) + + +def PackageVariable(key, help, default, searchfunc=None): + # NB: searchfunc is currently undocumented and unsupported + """ + The input parameters describe a 'package list' option, thus they + are returned with the correct converter and validator appended. The + result is usable for input to opts.Add() . + + A 'package list' option may either be 'all', 'none' or a list of + package names (separated by space). + """ + help = '\n '.join( + (help, '( yes | no | /path/to/%s )' % key)) + return (key, help, default, + lambda k, v, e: _validator(k,v,e,searchfunc), + _converter) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/PackageVariableTests.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/PackageVariableTests.py new file mode 100644 index 0000000..3aa411d --- /dev/null +++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/PackageVariableTests.py @@ -0,0 +1,125 @@ +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import sys +import unittest + +import SCons.Errors +import SCons.Variables + +import TestCmd +import TestUnit + + +class PackageVariableTestCase(unittest.TestCase): + def test_PackageVariable(self): + """Test PackageVariable creation""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.PackageVariable('test', 'test option help', '/default/path')) + + o = opts.options[0] + assert o.key == 'test', o.key + assert o.help == 'test option help\n ( yes | no | /path/to/test )', repr(o.help) + assert o.default == '/default/path', o.default + assert o.validator is not None, o.validator + assert o.converter is not None, o.converter + + def test_converter(self): + """Test the PackageVariable converter""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.PackageVariable('test', 'test option help', '/default/path')) + + o = opts.options[0] + + true_values = [ + 'yes', 'YES', + 'true', 'TRUE', + 'on', 'ON', + 'enable', 'ENABLE', + 'search', 'SEARCH', + ] + false_values = [ + 'no', 'NO', + 'false', 'FALSE', + 'off', 'OFF', + 'disable', 'DISABLE', + ] + + for t in true_values: + x = o.converter(t) + assert x, "converter returned false for '%s'" % t + + for f in false_values: + x = o.converter(f) + assert not x, "converter returned true for '%s'" % f + + x = o.converter('/explicit/path') + assert x == '/explicit/path', x + + # Make sure the converter returns True if we give it str(True) and + # False when we give it str(False). This assures consistent operation + # through a cycle of Variables.Save(<file>) -> Variables(<file>). + x = o.converter(str(True)) + assert x == True, "converter returned a string when given str(True)" + + x = o.converter(str(False)) + assert x == False, "converter returned a string when given str(False)" + + def test_validator(self): + """Test the PackageVariable validator""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.PackageVariable('test', 'test option help', '/default/path')) + + test = TestCmd.TestCmd(workdir='') + test.write('exists', 'exists\n') + + o = opts.options[0] + + env = {'F':False, 'T':True, 'X':'x'} + + exists = test.workpath('exists') + does_not_exist = test.workpath('does_not_exist') + + o.validator('F', '/path', env) + o.validator('T', '/path', env) + o.validator('X', exists, env) + + caught = None + try: + o.validator('X', does_not_exist, env) + except SCons.Errors.UserError: + caught = 1 + assert caught, "did not catch expected UserError" + + +if __name__ == "__main__": + suite = unittest.makeSuite(PackageVariableTestCase, 'test_') + TestUnit.run(suite) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/PathVariable.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/PathVariable.py new file mode 100644 index 0000000..0ffcbc5 --- /dev/null +++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/PathVariable.py @@ -0,0 +1,145 @@ +"""SCons.Variables.PathVariable + +This file defines an option type for SCons implementing path settings. + +To be used whenever a user-specified path override should be allowed. + +Arguments to PathVariable are: + option-name = name of this option on the command line (e.g. "prefix") + option-help = help string for option + option-dflt = default value for this option + validator = [optional] validator for option value. Predefined validators are: + + PathAccept -- accepts any path setting; no validation + PathIsDir -- path must be an existing directory + PathIsDirCreate -- path must be a dir; will create + PathIsFile -- path must be a file + PathExists -- path must exist (any type) [default] + + The validator is a function that is called and which + should return True or False to indicate if the path + is valid. The arguments to the validator function + are: (key, val, env). The key is the name of the + option, the val is the path specified for the option, + and the env is the env to which the Options have been + added. + +Usage example:: + + Examples: + prefix=/usr/local + + opts = Variables() + + opts = Variables() + opts.Add(PathVariable('qtdir', + 'where the root of Qt is installed', + qtdir, PathIsDir)) + opts.Add(PathVariable('qt_includes', + 'where the Qt includes are installed', + '$qtdir/includes', PathIsDirCreate)) + opts.Add(PathVariable('qt_libraries', + 'where the Qt library is installed', + '$qtdir/lib')) + +""" + +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +__all__ = ['PathVariable',] + +import os +import os.path + +import SCons.Errors + +class _PathVariableClass(object): + + def PathAccept(self, key, val, env): + """Accepts any path, no checking done.""" + pass + + def PathIsDir(self, key, val, env): + """Validator to check if Path is a directory.""" + if not os.path.isdir(val): + if os.path.isfile(val): + m = 'Directory path for option %s is a file: %s' + else: + m = 'Directory path for option %s does not exist: %s' + raise SCons.Errors.UserError(m % (key, val)) + + def PathIsDirCreate(self, key, val, env): + """Validator to check if Path is a directory, + creating it if it does not exist.""" + if os.path.isfile(val): + m = 'Path for option %s is a file, not a directory: %s' + raise SCons.Errors.UserError(m % (key, val)) + if not os.path.isdir(val): + os.makedirs(val) + + def PathIsFile(self, key, val, env): + """Validator to check if Path is a file""" + if not os.path.isfile(val): + if os.path.isdir(val): + m = 'File path for option %s is a directory: %s' + else: + m = 'File path for option %s does not exist: %s' + raise SCons.Errors.UserError(m % (key, val)) + + def PathExists(self, key, val, env): + """Validator to check if Path exists""" + if not os.path.exists(val): + m = 'Path for option %s does not exist: %s' + raise SCons.Errors.UserError(m % (key, val)) + + def __call__(self, key, help, default, validator=None): + """ + The input parameters describe a 'path list' option, thus they + are returned with the correct converter and validator appended. The + result is usable for input to opts.Add() . + + The 'default' option specifies the default path to use if the + user does not specify an override with this option. + + validator is a validator, see this file for examples + """ + if validator is None: + validator = self.PathExists + + if SCons.Util.is_List(key) or SCons.Util.is_Tuple(key): + return (key, '%s ( /path/to/%s )' % (help, key[0]), default, + validator, None) + else: + return (key, '%s ( /path/to/%s )' % (help, key), default, + validator, None) + +PathVariable = _PathVariableClass() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/PathVariableTests.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/PathVariableTests.py new file mode 100644 index 0000000..3d9d25c --- /dev/null +++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/PathVariableTests.py @@ -0,0 +1,238 @@ +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import os.path +import sys +import unittest + +import SCons.Errors +import SCons.Variables + +import TestCmd +import TestUnit + + +class PathVariableTestCase(unittest.TestCase): + def test_PathVariable(self): + """Test PathVariable creation""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.PathVariable('test', + 'test option help', + '/default/path')) + + o = opts.options[0] + assert o.key == 'test', o.key + assert o.help == 'test option help ( /path/to/test )', repr(o.help) + assert o.default == '/default/path', o.default + assert o.validator is not None, o.validator + assert o.converter is None, o.converter + + def test_PathExists(self): + """Test the PathExists validator""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.PathVariable('test', + 'test option help', + '/default/path', + SCons.Variables.PathVariable.PathExists)) + + test = TestCmd.TestCmd(workdir='') + test.write('exists', 'exists\n') + + o = opts.options[0] + + o.validator('X', test.workpath('exists'), {}) + + dne = test.workpath('does_not_exist') + try: + o.validator('X', dne, {}) + except SCons.Errors.UserError as e: + assert str(e) == 'Path for option X does not exist: %s' % dne, e + except: + raise Exception("did not catch expected UserError") + + def test_PathIsDir(self): + """Test the PathIsDir validator""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.PathVariable('test', + 'test option help', + '/default/path', + SCons.Variables.PathVariable.PathIsDir)) + + test = TestCmd.TestCmd(workdir='') + test.subdir('dir') + test.write('file', "file\n") + + o = opts.options[0] + + o.validator('X', test.workpath('dir'), {}) + + f = test.workpath('file') + try: + o.validator('X', f, {}) + except SCons.Errors.UserError as e: + assert str(e) == 'Directory path for option X is a file: %s' % f, e + except: + raise Exception("did not catch expected UserError") + + dne = test.workpath('does_not_exist') + try: + o.validator('X', dne, {}) + except SCons.Errors.UserError as e: + assert str(e) == 'Directory path for option X does not exist: %s' % dne, e + except: + raise Exception("did not catch expected UserError") + + def test_PathIsDirCreate(self): + """Test the PathIsDirCreate validator""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.PathVariable('test', + 'test option help', + '/default/path', + SCons.Variables.PathVariable.PathIsDirCreate)) + + test = TestCmd.TestCmd(workdir='') + test.write('file', "file\n") + + o = opts.options[0] + + d = test.workpath('dir') + o.validator('X', d, {}) + assert os.path.isdir(d) + + f = test.workpath('file') + try: + o.validator('X', f, {}) + except SCons.Errors.UserError as e: + assert str(e) == 'Path for option X is a file, not a directory: %s' % f, e + except: + raise Exception("did not catch expected UserError") + + def test_PathIsFile(self): + """Test the PathIsFile validator""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.PathVariable('test', + 'test option help', + '/default/path', + SCons.Variables.PathVariable.PathIsFile)) + + test = TestCmd.TestCmd(workdir='') + test.subdir('dir') + test.write('file', "file\n") + + o = opts.options[0] + + o.validator('X', test.workpath('file'), {}) + + d = test.workpath('d') + try: + o.validator('X', d, {}) + except SCons.Errors.UserError as e: + assert str(e) == 'File path for option X does not exist: %s' % d, e + except: + raise Exception("did not catch expected UserError") + + dne = test.workpath('does_not_exist') + try: + o.validator('X', dne, {}) + except SCons.Errors.UserError as e: + assert str(e) == 'File path for option X does not exist: %s' % dne, e + except: + raise Exception("did not catch expected UserError") + + def test_PathAccept(self): + """Test the PathAccept validator""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.PathVariable('test', + 'test option help', + '/default/path', + SCons.Variables.PathVariable.PathAccept)) + + test = TestCmd.TestCmd(workdir='') + test.subdir('dir') + test.write('file', "file\n") + + o = opts.options[0] + + o.validator('X', test.workpath('file'), {}) + + d = test.workpath('d') + o.validator('X', d, {}) + + dne = test.workpath('does_not_exist') + o.validator('X', dne, {}) + + def test_validator(self): + """Test the PathVariable validator argument""" + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.PathVariable('test', + 'test option help', + '/default/path')) + + test = TestCmd.TestCmd(workdir='') + test.write('exists', 'exists\n') + + o = opts.options[0] + + o.validator('X', test.workpath('exists'), {}) + + dne = test.workpath('does_not_exist') + try: + o.validator('X', dne, {}) + except SCons.Errors.UserError as e: + expect = 'Path for option X does not exist: %s' % dne + assert str(e) == expect, e + else: + raise Exception("did not catch expected UserError") + + def my_validator(key, val, env): + raise Exception("my_validator() got called for %s, %s!" % (key, val)) + + opts = SCons.Variables.Variables() + opts.Add(SCons.Variables.PathVariable('test2', + 'more help', + '/default/path/again', + my_validator)) + + o = opts.options[0] + + try: + o.validator('Y', 'value', {}) + except Exception as e: + assert str(e) == 'my_validator() got called for Y, value!', e + else: + raise Exception("did not catch expected exception from my_validator()") + + + + +if __name__ == "__main__": + suite = unittest.makeSuite(PathVariableTestCase, 'test_') + TestUnit.run(suite) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/VariablesTests.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/VariablesTests.py new file mode 100644 index 0000000..175a14b --- /dev/null +++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/VariablesTests.py @@ -0,0 +1,705 @@ +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import sys +import unittest + +import TestSCons +import TestUnit + +import SCons.Variables +import SCons.Subst +import SCons.Warnings +from SCons.Util import cmp + + +class Environment(object): + def __init__(self): + self.dict = {} + def subst(self, x): + return SCons.Subst.scons_subst(x, self, gvars=self.dict) + def __setitem__(self, key, value): + self.dict[key] = value + def __getitem__(self, key): + return self.dict[key] + def __contains__(self, key): + return self.dict.__contains__(key) + def has_key(self, key): + return key in self.dict + + + + +def check(key, value, env): + assert int(value) == 6 * 9, "key %s = %s" % (key, repr(value)) + +# Check saved option file by executing and comparing against +# the expected dictionary +def checkSave(file, expected): + gdict = {} + ldict = {} + exec(open(file, 'r').read(), gdict, ldict) + assert expected == ldict, "%s\n...not equal to...\n%s" % (expected, ldict) + +class VariablesTestCase(unittest.TestCase): + + def test_keys(self): + """Test the Variables.keys() method""" + opts = SCons.Variables.Variables() + + opts.Add('VAR1') + opts.Add('VAR2', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + keys = list(opts.keys()) + assert keys == ['VAR1', 'VAR2'], keys + + def test_Add(self): + """Test adding to a Variables object""" + opts = SCons.Variables.Variables() + + opts.Add('VAR') + opts.Add('ANSWER', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + + o = opts.options[0] + assert o.key == 'VAR' + assert o.help == '' + assert o.default is None + assert o.validator is None + assert o.converter is None + + o = opts.options[1] + assert o.key == 'ANSWER' + assert o.help == 'THE answer to THE question' + assert o.default == "42" + o.validator(o.key, o.converter(o.default), {}) + + def test_it(var, opts=opts): + exc_caught = None + try: + opts.Add(var) + except SCons.Errors.UserError: + exc_caught = 1 + assert exc_caught, "did not catch UserError for '%s'" % var + test_it('foo/bar') + test_it('foo-bar') + test_it('foo.bar') + + def test_AddVariables(self): + """Test adding a list of options to a Variables object""" + opts = SCons.Variables.Variables() + + opts.AddVariables(('VAR2',), + ('ANSWER2', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12)) + + o = opts.options[0] + assert o.key == 'VAR2', o.key + assert o.help == '', o.help + assert o.default is None, o.default + assert o.validator is None, o.validator + assert o.converter is None, o.converter + + o = opts.options[1] + assert o.key == 'ANSWER2', o.key + assert o.help == 'THE answer to THE question', o.help + assert o.default == "42", o.default + o.validator(o.key, o.converter(o.default), {}) + + def test_Update(self): + """Test updating an Environment""" + + # Test that a default value is validated correctly. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + opts = SCons.Variables.Variables(file) + + opts.Add('ANSWER', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + + env = Environment() + opts.Update(env) + assert env['ANSWER'] == 54 + + env = Environment() + opts.Update(env, {}) + assert env['ANSWER'] == 54 + + # Test that a bad value from the file is used and + # validation fails correctly. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + test.write('custom.py', 'ANSWER=54') + opts = SCons.Variables.Variables(file) + + opts.Add('ANSWER', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + + env = Environment() + exc_caught = None + try: + opts.Update(env) + except AssertionError: + exc_caught = 1 + assert exc_caught, "did not catch expected assertion" + + env = Environment() + exc_caught = None + try: + opts.Update(env, {}) + except AssertionError: + exc_caught = 1 + assert exc_caught, "did not catch expected assertion" + + # Test that a good value from the file is used and validated. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + test.write('custom.py', 'ANSWER=42') + opts = SCons.Variables.Variables(file) + + opts.Add('ANSWER', + 'THE answer to THE question', + "10", + check, + lambda x: int(x) + 12) + + env = Environment() + opts.Update(env) + assert env['ANSWER'] == 54 + + env = Environment() + opts.Update(env, {}) + assert env['ANSWER'] == 54 + + # Test that a bad value from an args dictionary passed to + # Update() is used and validation fails correctly. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + test.write('custom.py', 'ANSWER=10') + opts = SCons.Variables.Variables(file) + + opts.Add('ANSWER', + 'THE answer to THE question', + "12", + check, + lambda x: int(x) + 12) + + env = Environment() + exc_caught = None + try: + opts.Update(env, {'ANSWER':'54'}) + except AssertionError: + exc_caught = 1 + assert exc_caught, "did not catch expected assertion" + + # Test that a good value from an args dictionary + # passed to Update() is used and validated. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + test.write('custom.py', 'ANSWER=10') + opts = SCons.Variables.Variables(file) + + opts.Add('ANSWER', + 'THE answer to THE question', + "12", + check, + lambda x: int(x) + 12) + + env = Environment() + opts.Update(env, {'ANSWER':'42'}) + assert env['ANSWER'] == 54 + + # Test against a former bug. If we supply a converter, + # but no default, the value should *not* appear in the + # Environment if no value is specified in the options file + # or args. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + opts = SCons.Variables.Variables(file) + + opts.Add('ANSWER', + help='THE answer to THE question', + converter=str) + + env = Environment() + opts.Update(env, {}) + assert 'ANSWER' not in env + + # Test that a default value of None is all right. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + opts = SCons.Variables.Variables(file) + + opts.Add('ANSWER', + "This is the answer", + None, + check) + + env = Environment() + opts.Update(env, {}) + assert 'ANSWER' not in env + + def test_noaggregation(self): + """Test that the 'files' and 'args' attributes of the Variables class + don't aggregate entries from one instance to another. + This used to be a bug in SCons version 2.4.1 and earlier. + """ + + opts = SCons.Variables.Variables() + opts.files.append('custom.py') + opts.args['ANSWER'] = 54 + nopts = SCons.Variables.Variables() + + # Ensure that both attributes are initialized to + # an empty list and dict, respectively. + assert len(nopts.files) == 0 + assert len(nopts.args) == 0 + + def test_args(self): + """Test updating an Environment with arguments overridden""" + + # Test that a bad (command-line) argument is used + # and the validation fails correctly. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + test.write('custom.py', 'ANSWER=42') + opts = SCons.Variables.Variables(file, {'ANSWER':54}) + + opts.Add('ANSWER', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + + env = Environment() + exc_caught = None + try: + opts.Update(env) + except AssertionError: + exc_caught = 1 + assert exc_caught, "did not catch expected assertion" + + # Test that a good (command-line) argument is used and validated. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + test.write('custom.py', 'ANSWER=54') + opts = SCons.Variables.Variables(file, {'ANSWER':42}) + + opts.Add('ANSWER', + 'THE answer to THE question', + "54", + check, + lambda x: int(x) + 12) + + env = Environment() + opts.Update(env) + assert env['ANSWER'] == 54 + + # Test that a (command-line) argument is overridden by a dictionary + # supplied to Update() and the dictionary value is validated correctly. + test = TestSCons.TestSCons() + file = test.workpath('custom.py') + test.write('custom.py', 'ANSWER=54') + opts = SCons.Variables.Variables(file, {'ANSWER':54}) + + opts.Add('ANSWER', + 'THE answer to THE question', + "54", + check, + lambda x: int(x) + 12) + + env = Environment() + opts.Update(env, {'ANSWER':42}) + assert env['ANSWER'] == 54 + + def test_Save(self): + """Testing saving Variables""" + + test = TestSCons.TestSCons() + cache_file = test.workpath('cached.options') + opts = SCons.Variables.Variables() + + def bool_converter(val): + if val in [1, 'y']: val = 1 + if val in [0, 'n']: val = 0 + return val + + # test saving out empty file + opts.Add('OPT_VAL', + 'An option to test', + 21, + None, + None) + opts.Add('OPT_VAL_2', + default='foo') + opts.Add('OPT_VAL_3', + default=1) + opts.Add('OPT_BOOL_0', + default='n', + converter=bool_converter) + opts.Add('OPT_BOOL_1', + default='y', + converter=bool_converter) + opts.Add('OPT_BOOL_2', + default=0, + converter=bool_converter) + + env = Environment() + opts.Update(env, {'OPT_VAL_3' : 2}) + assert env['OPT_VAL'] == 21, env['OPT_VAL'] + assert env['OPT_VAL_2'] == 'foo', env['OPT_VAL_2'] + assert env['OPT_VAL_3'] == 2, env['OPT_VAL_3'] + assert env['OPT_BOOL_0'] == 0, env['OPT_BOOL_0'] + assert env['OPT_BOOL_1'] == 1, env['OPT_BOOL_1'] + assert env['OPT_BOOL_2'] == '0', env['OPT_BOOL_2'] + + env['OPT_VAL_2'] = 'bar' + env['OPT_BOOL_0'] = 0 + env['OPT_BOOL_1'] = 1 + env['OPT_BOOL_2'] = 2 + + opts.Save(cache_file, env) + checkSave(cache_file, { 'OPT_VAL_2' : 'bar', + 'OPT_VAL_3' : 2, + 'OPT_BOOL_2' : 2}) + + # Test against some old bugs + class Foo(object): + def __init__(self, x): + self.x = x + def __str__(self): + return self.x + + test = TestSCons.TestSCons() + cache_file = test.workpath('cached.options') + opts = SCons.Variables.Variables() + + opts.Add('THIS_USED_TO_BREAK', + 'An option to test', + "Default") + + opts.Add('THIS_ALSO_BROKE', + 'An option to test', + "Default2") + + opts.Add('THIS_SHOULD_WORK', + 'An option to test', + Foo('bar')) + + env = Environment() + opts.Update(env, { 'THIS_USED_TO_BREAK' : "Single'Quotes'In'String", + 'THIS_ALSO_BROKE' : "\\Escape\nSequences\t", + 'THIS_SHOULD_WORK' : Foo('baz') }) + opts.Save(cache_file, env) + checkSave(cache_file, { 'THIS_USED_TO_BREAK' : "Single'Quotes'In'String", + 'THIS_ALSO_BROKE' : "\\Escape\nSequences\t", + 'THIS_SHOULD_WORK' : 'baz' }) + + def test_GenerateHelpText(self): + """Test generating the default format help text""" + opts = SCons.Variables.Variables() + + opts.Add('ANSWER', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + + opts.Add('B', + 'b - alpha test', + "42", + check, + lambda x: int(x) + 12) + + opts.Add('A', + 'a - alpha test', + "42", + check, + lambda x: int(x) + 12) + + env = Environment() + opts.Update(env, {}) + + expect = """ +ANSWER: THE answer to THE question + default: 42 + actual: 54 + +B: b - alpha test + default: 42 + actual: 54 + +A: a - alpha test + default: 42 + actual: 54 +""" + + text = opts.GenerateHelpText(env) + assert text == expect, text + + expectAlpha = """ +A: a - alpha test + default: 42 + actual: 54 + +ANSWER: THE answer to THE question + default: 42 + actual: 54 + +B: b - alpha test + default: 42 + actual: 54 +""" + + expectBackwards = """ +B: b - alpha test + default: 42 + actual: 54 + +ANSWER: THE answer to THE question + default: 42 + actual: 54 + +A: a - alpha test + default: 42 + actual: 54 +""" + text = opts.GenerateHelpText(env, sort=cmp) + assert text == expectAlpha, text + + textBool = opts.GenerateHelpText(env, sort=True) + assert text == expectAlpha, text + + textBackwards = opts.GenerateHelpText(env, sort=lambda x, y: cmp(y, x)) + assert textBackwards == expectBackwards, "Expected:\n%s\nGot:\n%s\n"%(textBackwards, expectBackwards) + + def test_FormatVariableHelpText(self): + """Test generating custom format help text""" + opts = SCons.Variables.Variables() + + def my_format(env, opt, help, default, actual, aliases): + return '%s %s %s %s %s\n' % (opt, default, actual, help, aliases) + + opts.FormatVariableHelpText = my_format + + opts.Add('ANSWER', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + + opts.Add('B', + 'b - alpha test', + "42", + check, + lambda x: int(x) + 12) + + opts.Add('A', + 'a - alpha test', + "42", + check, + lambda x: int(x) + 12) + + env = Environment() + opts.Update(env, {}) + + expect = """\ +ANSWER 42 54 THE answer to THE question ['ANSWER'] +B 42 54 b - alpha test ['B'] +A 42 54 a - alpha test ['A'] +""" + + text = opts.GenerateHelpText(env) + assert text == expect, text + + expectAlpha = """\ +A 42 54 a - alpha test ['A'] +ANSWER 42 54 THE answer to THE question ['ANSWER'] +B 42 54 b - alpha test ['B'] +""" + text = opts.GenerateHelpText(env, sort=cmp) + assert text == expectAlpha, text + + def test_Aliases(self): + """Test option aliases""" + # test alias as a tuple + opts = SCons.Variables.Variables() + opts.AddVariables( + (('ANSWER', 'ANSWERALIAS'), + 'THE answer to THE question', + "42"), + ) + + env = Environment() + opts.Update(env, {'ANSWER' : 'answer'}) + + assert 'ANSWER' in env + + env = Environment() + opts.Update(env, {'ANSWERALIAS' : 'answer'}) + + assert 'ANSWER' in env and 'ANSWERALIAS' not in env + + # test alias as a list + opts = SCons.Variables.Variables() + opts.AddVariables( + (['ANSWER', 'ANSWERALIAS'], + 'THE answer to THE question', + "42"), + ) + + env = Environment() + opts.Update(env, {'ANSWER' : 'answer'}) + + assert 'ANSWER' in env + + env = Environment() + opts.Update(env, {'ANSWERALIAS' : 'answer'}) + + assert 'ANSWER' in env and 'ANSWERALIAS' not in env + + + +class UnknownVariablesTestCase(unittest.TestCase): + + def test_unknown(self): + """Test the UnknownVariables() method""" + opts = SCons.Variables.Variables() + + opts.Add('ANSWER', + 'THE answer to THE question', + "42") + + args = { + 'ANSWER' : 'answer', + 'UNKNOWN' : 'unknown', + } + + env = Environment() + opts.Update(env, args) + + r = opts.UnknownVariables() + assert r == {'UNKNOWN' : 'unknown'}, r + assert env['ANSWER'] == 'answer', env['ANSWER'] + + def test_AddOptionUpdatesUnknown(self): + """Test updating of the 'unknown' dict""" + opts = SCons.Variables.Variables() + + opts.Add('A', + 'A test variable', + "1") + + args = { + 'A' : 'a', + 'ADDEDLATER' : 'notaddedyet', + } + + env = Environment() + opts.Update(env,args) + + r = opts.UnknownVariables() + assert r == {'ADDEDLATER' : 'notaddedyet'}, r + assert env['A'] == 'a', env['A'] + + opts.Add('ADDEDLATER', + 'An option not present initially', + "1") + + args = { + 'A' : 'a', + 'ADDEDLATER' : 'added', + } + + opts.Update(env, args) + + r = opts.UnknownVariables() + assert len(r) == 0, r + assert env['ADDEDLATER'] == 'added', env['ADDEDLATER'] + + def test_AddOptionWithAliasUpdatesUnknown(self): + """Test updating of the 'unknown' dict (with aliases)""" + opts = SCons.Variables.Variables() + + opts.Add('A', + 'A test variable', + "1") + + args = { + 'A' : 'a', + 'ADDEDLATERALIAS' : 'notaddedyet', + } + + env = Environment() + opts.Update(env,args) + + r = opts.UnknownVariables() + assert r == {'ADDEDLATERALIAS' : 'notaddedyet'}, r + assert env['A'] == 'a', env['A'] + + opts.AddVariables( + (('ADDEDLATER', 'ADDEDLATERALIAS'), + 'An option not present initially', + "1"), + ) + + args['ADDEDLATERALIAS'] = 'added' + + opts.Update(env, args) + + r = opts.UnknownVariables() + assert len(r) == 0, r + assert env['ADDEDLATER'] == 'added', env['ADDEDLATER'] + + +if __name__ == "__main__": + suite = unittest.TestSuite() + tclasses = [ VariablesTestCase, + UnknownVariablesTestCase ] + for tclass in tclasses: + names = unittest.getTestCaseNames(tclass, 'test_') + suite.addTests(list(map(tclass, names))) + TestUnit.run(suite) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/__init__.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/__init__.py new file mode 100644 index 0000000..6ad40ed --- /dev/null +++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Variables/__init__.py @@ -0,0 +1,327 @@ +"""engine.SCons.Variables + +This file defines the Variables class that is used to add user-friendly +customizable variables to an SCons build. +""" + +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import os.path +import sys +from functools import cmp_to_key + +import SCons.Environment +import SCons.Errors +import SCons.Util +import SCons.Warnings + +from .BoolVariable import BoolVariable # okay +from .EnumVariable import EnumVariable # okay +from .ListVariable import ListVariable # naja +from .PackageVariable import PackageVariable # naja +from .PathVariable import PathVariable # okay + + +class Variables(object): + instance=None + + """ + Holds all the options, updates the environment with the variables, + and renders the help text. + """ + def __init__(self, files=None, args=None, is_global=1): + """ + files - [optional] List of option configuration files to load + (backward compatibility) If a single string is passed it is + automatically placed in a file list + """ + # initialize arguments + if files is None: + files = [] + if args is None: + args = {} + self.options = [] + self.args = args + if not SCons.Util.is_List(files): + if files: + files = [ files ] + else: + files = [] + self.files = files + self.unknown = {} + + # create the singleton instance + if is_global: + self=Variables.instance + + if not Variables.instance: + Variables.instance=self + + def _do_add(self, key, help="", default=None, validator=None, converter=None): + class Variable(object): + pass + + option = Variable() + + # if we get a list or a tuple, we take the first element as the + # option key and store the remaining in aliases. + if SCons.Util.is_List(key) or SCons.Util.is_Tuple(key): + option.key = key[0] + option.aliases = key[1:] + else: + option.key = key + option.aliases = [ key ] + option.help = help + option.default = default + option.validator = validator + option.converter = converter + + self.options.append(option) + + # options might be added after the 'unknown' dict has been set up, + # so we remove the key and all its aliases from that dict + for alias in list(option.aliases) + [ option.key ]: + if alias in self.unknown: + del self.unknown[alias] + + def keys(self): + """ + Returns the keywords for the options + """ + return [o.key for o in self.options] + + def Add(self, key, help="", default=None, validator=None, converter=None, **kw): + """ + Add an option. + + + @param key: the name of the variable, or a list or tuple of arguments + @param help: optional help text for the options + @param default: optional default value + @param validator: optional function that is called to validate the option's value + @type validator: Called with (key, value, environment) + @param converter: optional function that is called to convert the option's value before putting it in the environment. + """ + + if SCons.Util.is_List(key) or isinstance(key, tuple): + self._do_add(*key) + return + + if not SCons.Util.is_String(key) or \ + not SCons.Environment.is_valid_construction_var(key): + raise SCons.Errors.UserError("Illegal Variables.Add() key `%s'" % str(key)) + + self._do_add(key, help, default, validator, converter) + + def AddVariables(self, *optlist): + """ + Add a list of options. + + Each list element is a tuple/list of arguments to be passed on + to the underlying method for adding options. + + Example:: + + opt.AddVariables( + ('debug', '', 0), + ('CC', 'The C compiler'), + ('VALIDATE', 'An option for testing validation', 'notset', + validator, None), + ) + + """ + + for o in optlist: + self._do_add(*o) + + + def Update(self, env, args=None): + """ + Update an environment with the option variables. + + env - the environment to update. + """ + + values = {} + + # first set the defaults: + for option in self.options: + if not option.default is None: + values[option.key] = option.default + + # next set the value specified in the options file + for filename in self.files: + if os.path.exists(filename): + dir = os.path.split(os.path.abspath(filename))[0] + if dir: + sys.path.insert(0, dir) + try: + values['__name__'] = filename + with open(filename, 'r') as f: + contents = f.read() + exec(contents, {}, values) + finally: + if dir: + del sys.path[0] + del values['__name__'] + + # set the values specified on the command line + if args is None: + args = self.args + + for arg, value in args.items(): + added = False + for option in self.options: + if arg in list(option.aliases) + [ option.key ]: + values[option.key] = value + added = True + if not added: + self.unknown[arg] = value + + # put the variables in the environment: + # (don't copy over variables that are not declared as options) + for option in self.options: + try: + env[option.key] = values[option.key] + except KeyError: + pass + + # Call the convert functions: + for option in self.options: + if option.converter and option.key in values: + value = env.subst('${%s}'%option.key) + try: + try: + env[option.key] = option.converter(value) + except TypeError: + env[option.key] = option.converter(value, env) + except ValueError as x: + raise SCons.Errors.UserError('Error converting option: %s\n%s'%(option.key, x)) + + + # Finally validate the values: + for option in self.options: + if option.validator and option.key in values: + option.validator(option.key, env.subst('${%s}'%option.key), env) + + def UnknownVariables(self): + """ + Returns any options in the specified arguments lists that + were not known, declared options in this object. + """ + return self.unknown + + def Save(self, filename, env): + """ + Saves all the options in the given file. This file can + then be used to load the options next run. This can be used + to create an option cache file. + + filename - Name of the file to save into + env - the environment get the option values from + """ + + # Create the file and write out the header + try: + fh = open(filename, 'w') + + try: + # Make an assignment in the file for each option + # within the environment that was assigned a value + # other than the default. + for option in self.options: + try: + value = env[option.key] + try: + prepare = value.prepare_to_store + except AttributeError: + try: + eval(repr(value)) + except KeyboardInterrupt: + raise + except: + # Convert stuff that has a repr() that + # cannot be evaluated into a string + value = SCons.Util.to_String(value) + else: + value = prepare() + + defaultVal = env.subst(SCons.Util.to_String(option.default)) + if option.converter: + defaultVal = option.converter(defaultVal) + + if str(env.subst('${%s}' % option.key)) != str(defaultVal): + fh.write('%s = %s\n' % (option.key, repr(value))) + except KeyError: + pass + finally: + fh.close() + + except IOError as x: + raise SCons.Errors.UserError('Error writing options to file: %s\n%s' % (filename, x)) + + def GenerateHelpText(self, env, sort=None): + """ + Generate the help text for the options. + + env - an environment that is used to get the current values + of the options. + cmp - Either a function as follows: The specific sort function should take two arguments and return -1, 0 or 1 + or a boolean to indicate if it should be sorted. + """ + + if callable(sort): + options = sorted(self.options, key=cmp_to_key(lambda x,y: sort(x.key,y.key))) + elif sort is True: + options = sorted(self.options, key=lambda x: x.key) + else: + options = self.options + + def format(opt, self=self, env=env): + if opt.key in env: + actual = env.subst('${%s}' % opt.key) + else: + actual = None + return self.FormatVariableHelpText(env, opt.key, opt.help, opt.default, actual, opt.aliases) + lines = [_f for _f in map(format, options) if _f] + + return ''.join(lines) + + format = '\n%s: %s\n default: %s\n actual: %s\n' + format_ = '\n%s: %s\n default: %s\n actual: %s\n aliases: %s\n' + + def FormatVariableHelpText(self, env, key, help, default, actual, aliases=[]): + # Don't display the key name itself as an alias. + aliases = [a for a in aliases if a != key] + if len(aliases)==0: + return self.format % (key, help, default, actual) + else: + return self.format_ % (key, help, default, actual, aliases) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: |