From a1c6873e2f84240feab9a923ccc1ebcda3160339 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 9 Oct 2018 16:16:39 -0400 Subject: Incremental checkin. Pre merging current master branch --- src/engine/SCons/EnvironmentValueTests.py | 2 +- src/engine/SCons/EnvironmentValues.md | 6 +++- src/engine/SCons/EnvironmentValues.py | 39 +++++++++++++++---------- src/engine/SCons/EnvironmentValuesSubstTests.py | 15 +++++++--- src/engine/SCons/EnvironmentValuesTests.py | 2 ++ 5 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/engine/SCons/EnvironmentValueTests.py b/src/engine/SCons/EnvironmentValueTests.py index 5ea8156..feec1e2 100644 --- a/src/engine/SCons/EnvironmentValueTests.py +++ b/src/engine/SCons/EnvironmentValueTests.py @@ -115,7 +115,7 @@ class TestEnvironmentValue(unittest.TestCase): def foo(target, source, env, for_signature): return "bar" - one = EnvironmentValue(foo) + one = EnvironmentValue.factory(foo) self.assertEqual(one.var_type, ValueTypes.CALLABLE) # Test that callable is retrievable and callable and value is proper. diff --git a/src/engine/SCons/EnvironmentValues.md b/src/engine/SCons/EnvironmentValues.md index 24f6be2..5dbcfef 100644 --- a/src/engine/SCons/EnvironmentValues.md +++ b/src/engine/SCons/EnvironmentValues.md @@ -133,4 +133,8 @@ # EnvironmentValue * These objects need to be unique (for any given string value, there is only one EnvironmentValue object) - \ No newline at end of file + + +# TODO: + * intern() strings we want to never be duplicated + * use __missing__ method on dict'like objects to handle when key is not found. \ No newline at end of file diff --git a/src/engine/SCons/EnvironmentValues.py b/src/engine/SCons/EnvironmentValues.py index e6ae849..c82e7e6 100644 --- a/src/engine/SCons/EnvironmentValues.py +++ b/src/engine/SCons/EnvironmentValues.py @@ -188,7 +188,7 @@ class EnvironmentValues(object): else: nt = ValueTypes.PARSED elif v in gvars: - if callable(self[v].value): + if callable(v): nt = ValueTypes.CALLABLE else: nt = ValueTypes.PARSED @@ -270,12 +270,12 @@ class EnvironmentValues(object): # At this point it's possible to determine if we guessed callable correctly # or if it's actually evaluable - if t == ValueTypes.CALLABLE: - if callable(v): - t = ValueTypes.CALLABLE - else: - debug("Swapped to EVALUABLE:%s" % v) - t = ValueTypes.EVALUABLE + # if t == ValueTypes.CALLABLE: + # if callable(v): + # t = ValueTypes.CALLABLE + # else: + # debug("Swapped to EVALUABLE:%s" % v) + # t = ValueTypes.EVALUABLE # Now handle all the various types which can be in the value. if t == ValueTypes.STRING: @@ -304,18 +304,21 @@ class EnvironmentValues(object): new_parsed_values.append(None) elif value.var_type == ValueTypes.STRING: - if value[0] == '$' and value[1:] == v: + if len(value.value) > 1 and value.value[0] == '$' and value.value[1:] == v: # Special case, variables value references itself and only itself new_string_values.append(('', ValueTypes.STRING)) new_parsed_values.append(None) - else: new_string_values.append((value.value, ValueTypes.STRING)) new_parsed_values.append(None) - + elif value.var_type == ValueTypes.PARSED and value.value[0] == '$' and value.value[1:] == v: + # Handle when the value of the current value is a self reference 'R'='$R'. + # This prevents infinite recursion during evalualation and mimics previous + # functionality + new_string_values.append(('', ValueTypes.STRING)) + new_parsed_values.append(None) else: # TODO: Handle other recursive loops by empty stringing this value before recursing with copy of lvar? - # TODO: This should insert the return values into the arrays at the current position, not be a string print("Here") new_parsed_values.extend(value.all_dependencies) new_string_values.extend([None] * len(value.all_dependencies)) @@ -328,14 +331,15 @@ class EnvironmentValues(object): elif t == ValueTypes.CALLABLE: # Can return multiple values - to_call = v + # TODO: should this be self.values[v].value ? + to_call = self.values[v].value call_value = self.eval_callable(to_call, parsed_values, string_values, target=target, source=source, gvars=gvars, lvars=lvars, for_sig=for_signature) new_values = [] if is_String(call_value): - if '$' not in call_value: + if '$' not in call_value: new_string_values.append((call_value, ValueTypes.STRING)) new_parsed_values.append(None) @@ -403,10 +407,15 @@ class EnvironmentValues(object): try: # Note: this may return a callable or a string or a number or an object. # If it's callable, then it needs be executed by the logic above for ValueTypes.CALLABLE. + # TODO Fix gvars to have contents of variables rather than evaluating to EnvironmentValue object... sval = eval(v, gvars, lvars) except AllowableExceptions as e: sval = '' + # try: + # sval = sval.value + + if is_String(sval): new_string_values.append((sval, ValueTypes.NUMBER)) new_parsed_values.append(None) @@ -539,7 +548,7 @@ class EnvironmentValues(object): val = env.cached_values[(substString, override_string)] except KeyError as e: # No such value create one - val = EnvironmentValue(substString) + val = EnvironmentValue.factory(substString) string_values = [None] * len(val.all_dependencies) parsed_values = [None] * len(val.all_dependencies) @@ -678,7 +687,7 @@ class EnvironmentValues(object): retval.append([]) e_value = EnvironmentValue(element) - this_value = e_value.subst(env, mode=mode, + this_value = EnvironmentValues.subst(env, mode=mode, target=target, source=source, gvars=gvars, lvars=lvars, conv=conv) diff --git a/src/engine/SCons/EnvironmentValuesSubstTests.py b/src/engine/SCons/EnvironmentValuesSubstTests.py index f5443ef..d1edb0e 100644 --- a/src/engine/SCons/EnvironmentValuesSubstTests.py +++ b/src/engine/SCons/EnvironmentValuesSubstTests.py @@ -268,9 +268,9 @@ class SubstTestCase(unittest.TestCase): cases = self.basic_cases[:] total_tests = len(cases)/2 - kwargs = {'target' : self.target, - 'source' : self.source, - 'gvars' : env.values} + kwargs = {'target': self.target, + 'source': self.source, + 'gvars': env.values} failed = 0 while cases: @@ -424,6 +424,13 @@ class EnvVariablesSubstTestCase(SubstTestCase): def test_scons_subst(self): """Test EnvironmentValues.subst(): basic substitution""" + + self.basic_cases = [ + # Basics: strings without expansions are left alone, and + # the simplest possible expansion to a null-string value. + '$CALLABLE1', 'callable-1', + ] + return self.basic_comparisons(EnvironmentValues.subst, cvt) subst_cases = [ @@ -689,7 +696,7 @@ class TestCLVar(unittest.TestCase): cmd = SCons.Util.CLVar("test $FOO $BAR $CALL test") - newcmd = env.subst(cmd) + newcmd = EnvironmentValues.subst(cmd, env) self.assertEqual(newcmd, ['test', 'foo', 'bar', 'call', 'test'], newcmd) # Now build do as a list diff --git a/src/engine/SCons/EnvironmentValuesTests.py b/src/engine/SCons/EnvironmentValuesTests.py index 593148f..a90f472 100644 --- a/src/engine/SCons/EnvironmentValuesTests.py +++ b/src/engine/SCons/EnvironmentValuesTests.py @@ -160,7 +160,9 @@ class TestEnvironmentValues(unittest.TestCase): # and that the value is correct with the new function def foo(target, source, env, for_signature): return "bar" + env['XX'] = foo + xxx_3 = env.subst('$XXX', env) # print("1:%s 2:%s 3:%s"%(xxx, xxx_2, xxx_3)) self.assertNotEqual(xxx_3, xxx_2) -- cgit v0.12