From ccb63d7546b4a6b65fb43208868568d7d947cbed Mon Sep 17 00:00:00 2001 From: stevenknight Date: Fri, 22 Mar 2002 14:39:01 +0000 Subject: [PATCH] Move autogenerate() from SCons.Util.py to SCons.Environmentpy. git-svn-id: http://scons.tigris.org/svn/scons/trunk@301 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- src/engine/SCons/Action.py | 3 - src/engine/SCons/BuilderTests.py | 32 ------ src/engine/SCons/Environment.py | 142 +++++++++++++++++++++++++-- src/engine/SCons/EnvironmentTests.py | 43 ++++++++ src/engine/SCons/Node/FSTests.py | 4 +- src/engine/SCons/Node/NodeTests.py | 4 +- src/engine/SCons/Node/__init__.py | 13 ++- src/engine/SCons/Util.py | 132 ------------------------- src/engine/SCons/UtilTests.py | 44 --------- 9 files changed, 193 insertions(+), 224 deletions(-) diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index 503fe15c..9b65e389 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -254,9 +254,6 @@ class ActionBase: dict.update(kw) - # Autogenerate necessary construction variables. - SCons.Util.autogenerate(dict, dir = cwd) - return dict _rm = re.compile(r'\$[()]') diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index f853bc26..93636314 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -389,38 +389,6 @@ class BuilderTestCase(unittest.TestCase): contents = b3.get_contents() assert contents == "foo\177\036\000\177\037\000d\000\000Sbar", repr(contents) - b4 = SCons.Builder.Builder(name = "b4", action = "$_LIBFLAGS $_LIBDIRFLAGS $_INCFLAGS") - kw = {'LIBS' : ['l1', 'l2'], - 'LIBLINKPREFIX' : '-l', - 'LIBLINKSUFFIX' : '', - 'LIBPATH' : ['lib'], - 'LIBDIRPREFIX' : '-L', - 'LIBDIRSUFFIX' : 'X', - 'CPPPATH' : ['c', 'p'], - 'INCPREFIX' : '-I', - 'INCSUFFIX' : ''} - - contents = apply(b4.get_raw_contents, (), kw) - assert contents == "-ll1 -ll2 $( -LlibX $) $( -Ic -Ip $)", contents - - contents = apply(b4.get_contents, (), kw) - assert contents == "-ll1 -ll2", "'%s'" % contents - - # SCons.Node.FS has been imported by our import of - # SCons.Node.Builder. It's kind of bogus that we don't - # import this ourselves before using it this way, but it's - # maybe a little cleaner than tying these tests directly - # to the other module via a direct import. - kw['dir'] = SCons.Node.FS.default_fs.Dir('d') - - contents = apply(b4.get_raw_contents, (), kw) - expect = os.path.normpath("-ll1 -ll2 $( -Ld/libX $) $( -Id/c -Id/p $)") - assert contents == expect, contents + " != " + expect - - contents = apply(b4.get_contents, (), kw) - expect = os.path.normpath("-ll1 -ll2") - assert contents == expect, contents + " != " + expect - def test_node_factory(self): """Test a Builder that creates nodes of a specified class """ diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index d90e0295..d997d6f5 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -34,14 +34,15 @@ import os import copy import os.path import re +import string +import sys import types -import SCons.Util + import SCons.Builder import SCons.Defaults from SCons.Errors import UserError import SCons.Node.FS -import sys -import shutil +import SCons.Util def installFunc(env, target, source): try: @@ -93,11 +94,35 @@ class Environment: import SCons.Defaults self._dict = our_deepcopy(SCons.Defaults.ConstructionEnvironment) apply(self.Update, (), kw) - - def __mungeDict(self): - """Take care of any special attributes in our dictionary.""" - - + + # + # self.autogen_vars is a tuple of tuples. Each inner tuple + # has four elements, each strings referring to an environment + # variable, and describing how to autogenerate a particular + # variable. The elements are: + # + # 0 - The variable to generate + # 1 - The "source" variable, usually a list + # 2 - The "prefix" variable + # 3 - The "suffix" variable + # + # The autogenerated variable is a list, consisting of every + # element of the source list, or a single element if the source + # is a string, with the prefix and suffix concatenated. + # + self.autogen_vars = ( VarInterpolator('_LIBFLAGS', + 'LIBS', + 'LIBLINKPREFIX', + 'LIBLINKSUFFIX'), + DirVarInterp('_LIBDIRFLAGS', + 'LIBPATH', + 'LIBDIRPREFIX', + 'LIBDIRSUFFIX' ), + DirVarInterp('_INCFLAGS', + 'CPPPATH', + 'INCPREFIX', + 'INCSUFFIX') ) + def __cmp__(self, other): return cmp(self._dict, other._dict) @@ -257,3 +282,104 @@ class Environment: if skey in scanner.skeys: return scanner return None + + def autogenerate(self, fs = SCons.Node.FS.default_fs, dir = None): + """Return a dictionary of autogenerated "interpolated" + construction variables. + """ + dict = {} + for interp in self.autogen_vars: + interp.instance(dir, fs).generate(dict, self._dict) + return dict + +class VarInterpolator: + def __init__(self, dest, src, prefix, suffix): + self.dest = dest + self.src = src + self.prefix = prefix + self.suffix = suffix + + def prepareSrc(self, dict): + src = dict[self.src] + if SCons.Util.is_String(src): + src = string.split(src) + elif not SCons.Util.is_List(src): + src = [ src ] + + def prepare(x, dict=dict): + if isinstance(x, SCons.Node.Node): + return x + else: + return SCons.Util.scons_subst(x, {}, dict) + + return map(prepare, src) + + def generate(self, ddict, sdict): + if not sdict.has_key(self.src): + ddict[self.dest] = '' + return + + src = filter(lambda x: not x is None, self.prepareSrc(sdict)) + + if not src: + ddict[self.dest] = '' + return + + prefix = sdict.get(self.prefix, '') + suffix = sdict.get(self.suffix, '') + + def autogenFunc(x, suff=suffix, pref=prefix): + """Generate the interpolated variable. If the prefix + ends in a space, or the suffix begins in a space, + leave it as a separate element of the list.""" + ret = [ str(x) ] + if pref and pref[-1] == ' ': + ret.insert(0, pref[:-1]) + else: + ret[0] = pref + ret[0] + if suff and suff[0] == ' ': + ret.append(suff[1:]) + else: + ret[-1] = ret[-1] + suff + return ret + + ddict[self.dest] = reduce(lambda x, y: x+y, + map(autogenFunc, src)) + + def instance(self, dir, fs): + return self + +class DirVarInterp(VarInterpolator): + def __init__(self, dest, src, prefix, suffix): + VarInterpolator.__init__(self, dest, src, prefix, suffix) + self.fs = None + self.Dir = None + self.dictInstCache = {} + + def prepareSrc(self, dict): + src = VarInterpolator.prepareSrc(self, dict) + + def prepare(x, self=self): + if isinstance(x, SCons.Node.Node): + return x + elif str(x): + return self.fs.Dir(str(x), directory=self.dir) + else: + return None + + return map(prepare, src) + + def instance(self, dir, fs): + try: + ret = self.dictInstCache[(dir, fs)] + except KeyError: + ret = copy.copy(self) + ret.fs = fs + ret.dir = dir + self.dictInstCache[(dir, fs)] = ret + return ret + + def generate(self, ddict, sdict): + VarInterpolator.generate(self, ddict, sdict) + if ddict[self.dest]: + ddict[self.dest] = ['$('] + ddict[self.dest] + ['$)'] diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 4917c83f..86f179a5 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -322,6 +322,49 @@ class EnvironmentTestCase(unittest.TestCase): str = env.subst("$AAA ${AAA}A ${AAA}B $BBB") assert str == "c c", str + def test_autogenerate(dict): + """Test autogenerating variables in a dictionary.""" + env = Environment(LIBS = [ 'foo', 'bar', 'baz' ], + LIBLINKPREFIX = 'foo', + LIBLINKSUFFIX = 'bar') + dict = env.autogenerate(dir = SCons.Node.FS.default_fs.Dir('/xx')) + assert len(dict['_LIBFLAGS']) == 3, dict['_LIBFLAGS'] + assert dict['_LIBFLAGS'][0] == 'foofoobar', \ + dict['_LIBFLAGS'][0] + assert dict['_LIBFLAGS'][1] == 'foobarbar', \ + dict['_LIBFLAGS'][1] + assert dict['_LIBFLAGS'][2] == 'foobazbar', \ + dict['_LIBFLAGS'][2] + + blat = SCons.Node.FS.default_fs.File('blat') + env = Environment(CPPPATH = [ 'foo', '$FOO/bar', blat], + INCPREFIX = 'foo ', + INCSUFFIX = 'bar', + FOO = 'baz') + dict = env.autogenerate(dir = SCons.Node.FS.default_fs.Dir('/xx')) + assert len(dict['_INCFLAGS']) == 8, dict['_INCFLAGS'] + assert dict['_INCFLAGS'][0] == '$(', \ + dict['_INCFLAGS'][0] + assert dict['_INCFLAGS'][1] == os.path.normpath('foo'), \ + dict['_INCFLAGS'][1] + assert dict['_INCFLAGS'][2] == os.path.normpath('/xx/foobar'), \ + dict['_INCFLAGS'][2] + assert dict['_INCFLAGS'][3] == os.path.normpath('foo'), \ + dict['_INCFLAGS'][3] + assert dict['_INCFLAGS'][4] == os.path.normpath('/xx/baz/barbar'), \ + dict['_INCFLAGS'][4] + assert dict['_INCFLAGS'][5] == os.path.normpath('foo'), \ + dict['_INCFLAGS'][5] + assert dict['_INCFLAGS'][6] == os.path.normpath('blatbar'), \ + dict['_INCFLAGS'][6] + assert dict['_INCFLAGS'][7] == '$)', \ + dict['_INCFLAGS'][7] + + env = Environment(CPPPATH = '', LIBPATH = '') + dict = env.autogenerate(dir = SCons.Node.FS.default_fs.Dir('/yy')) + assert len(dict['_INCFLAGS']) == 0, dict['_INCFLAGS'] + assert len(dict['_LIBDIRFLAGS']) == 0, dict['_LIBDIRFLAGS'] + if __name__ == "__main__": diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index e9e24ecc..6cf8f1af 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -57,7 +57,9 @@ class Environment: def __init__(self): self.scanner = Scanner() def Dictionary(self, *args): - pass + return {} + def autogenerate(self, **kw): + return {} def get_scanner(self, skey): return self.scanner diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index ec506aaf..8a166f22 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -77,7 +77,9 @@ class ExceptBuilder2: class Environment: def Dictionary(self, *args): - pass + return {} + def autogenerate(self, **kw): + return {} diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index e8d45e18..c66a1a4c 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -84,7 +84,13 @@ class Node: stat = self.builder.status except AttributeError: try: - stat = self.builder.execute(env = self.env.Dictionary(), + dict = copy.copy(self.env.Dictionary()) + if hasattr(self, 'dir'): + auto = self.env.autogenerate(dir = self.dir) + else: + auto = self.env.autogenerate() + dict.update(auto) + stat = self.builder.execute(env = dict, target = self, source = self.sources) except: @@ -119,12 +125,13 @@ class Node: def __init__(self, node): self.node = node def get_contents(self): - env = self.node.env.Dictionary() + dict = self.node.env.Dictionary() + dict.update(self.node.env.autogenerate()) try: dir = self.node.getcwd() except AttributeError: dir = None - return self.node.builder.get_contents(env = env) + return self.node.builder.get_contents(env = dict) return Adapter(self) def scanner_set(self, scanner): diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 3fb56d96..5175ac57 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -232,138 +232,6 @@ def scons_subst(strSubst, globals, locals, remove=None): cmd_list = scons_subst_list(strSubst, globals, locals, remove) return string.join(map(string.join, cmd_list), '\n') -class VarInterpolator: - def __init__(self, dest, src, prefix, suffix): - self.dest = dest - self.src = src - self.prefix = prefix - self.suffix = suffix - - def prepareSrc(self, dict): - src = dict[self.src] - if is_String(src): - src = string.split(src) - elif not is_List(src): - src = [ src ] - - def prepare(x, dict=dict): - if isinstance(x, SCons.Node.Node): - return x - else: - return scons_subst(x, {}, dict) - - return map(prepare, src) - - def generate(self, dict): - if not dict.has_key(self.src): - dict[self.dest] = '' - return - - src = filter(lambda x: not x is None, self.prepareSrc(dict)) - - if not src: - dict[self.dest] = '' - return - - try: - prefix = str(dict[self.prefix]) - except KeyError: - prefix='' - - try: - suffix = str(dict[self.suffix]) - except KeyError: - suffix ='' - - def autogenFunc(x, suff=suffix, pref=prefix): - """Generate the interpolated variable. If the prefix - ends in a space, or the suffix begins in a space, - leave it as a separate element of the list.""" - ret = [ str(x) ] - if pref and pref[-1] == ' ': - ret.insert(0, pref[:-1]) - else: - ret[0] = pref + ret[0] - if suff and suff[0] == ' ': - ret.append(suff[1:]) - else: - ret[-1] = ret[-1] + suff - return ret - dict[self.dest] = reduce(lambda x, y: x+y, - map(autogenFunc, - src)) - - def instance(self, dir, fs): - return self - -class DirVarInterp(VarInterpolator): - def __init__(self, dest, src, prefix, suffix): - VarInterpolator.__init__(self, dest, src, prefix, suffix) - self.fs = None - self.Dir = None - self.dictInstCache = {} - - def prepareSrc(self, dict): - src = VarInterpolator.prepareSrc(self, dict) - - def prepare(x, self=self): - if isinstance(x, SCons.Node.Node): - return x - elif str(x): - return self.fs.Dir(str(x), directory=self.dir) - else: - return None - - return map(prepare, src) - - def instance(self, dir, fs): - try: - ret = self.dictInstCache[(dir, fs)] - except KeyError: - ret = copy.copy(self) - ret.fs = fs - ret.dir = dir - self.dictInstCache[(dir, fs)] = ret - return ret - - def generate(self, dict): - VarInterpolator.generate(self, dict) - if dict[self.dest]: - dict[self.dest] = ['$('] + dict[self.dest] + ['$)'] - -AUTO_GEN_VARS = ( VarInterpolator('_LIBFLAGS', - 'LIBS', - 'LIBLINKPREFIX', - 'LIBLINKSUFFIX'), - DirVarInterp('_LIBDIRFLAGS', - 'LIBPATH', - 'LIBDIRPREFIX', - 'LIBDIRSUFFIX' ), - DirVarInterp('_INCFLAGS', - 'CPPPATH', - 'INCPREFIX', - 'INCSUFFIX') ) - -def autogenerate(dict, fs = SCons.Node.FS.default_fs, dir = None): - """Autogenerate the "interpolated" environment variables. - We read a static structure that tells us how. AUTO_GEN_VARS - is a tuple of tuples. Each inner tuple has four elements, - each strings referring to an environment variable, and describing - how to autogenerate a particular variable. The elements are: - - 0 - The variable to generate - 1 - The "source" variable, usually a list - 2 - The "prefix" variable - 3 - The "suffix" variable - - The autogenerated variable is a list, consisting of every - element of the source list, or a single element if the source - is a string, with the prefix and suffix - concatenated.""" - - for interp in AUTO_GEN_VARS: - interp.instance(dir, fs).generate(dict) - def render_tree(root, child_func, margin=[0], visited={}): """ Render a tree of nodes into an ASCII tree view. diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index 40553eea..0b0003a7 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -207,50 +207,6 @@ class UtilTestCase(unittest.TestCase): assert len(cmd_list) == 1, cmd_list assert cmd_list[0] == ['test', '3', '2', '4', 'test'], cmd_list - def test_autogenerate(dict): - """Test autogenerating variables in a dictionary.""" - dict = {'LIBS' : [ 'foo', 'bar', 'baz' ], - 'LIBLINKPREFIX' : 'foo', - 'LIBLINKSUFFIX' : 'bar'} - autogenerate(dict, dir = SCons.Node.FS.default_fs.Dir('/xx')) - assert len(dict['_LIBFLAGS']) == 3, dict('_LIBFLAGS') - assert dict['_LIBFLAGS'][0] == 'foofoobar', \ - dict['_LIBFLAGS'][0] - assert dict['_LIBFLAGS'][1] == 'foobarbar', \ - dict['_LIBFLAGS'][1] - assert dict['_LIBFLAGS'][2] == 'foobazbar', \ - dict['_LIBFLAGS'][2] - - blat = SCons.Node.FS.default_fs.File('blat') - dict = {'CPPPATH' : [ 'foo', '$FOO/bar', blat], - 'INCPREFIX' : 'foo ', - 'INCSUFFIX' : 'bar', - 'FOO' : 'baz' } - autogenerate(dict, dir = SCons.Node.FS.default_fs.Dir('/xx')) - assert len(dict['_INCFLAGS']) == 8, dict['_INCFLAGS'] - assert dict['_INCFLAGS'][0] == '$(', \ - dict['_INCFLAGS'][0] - assert dict['_INCFLAGS'][1] == os.path.normpath('foo'), \ - dict['_INCFLAGS'][1] - assert dict['_INCFLAGS'][2] == os.path.normpath('/xx/foobar'), \ - dict['_INCFLAGS'][2] - assert dict['_INCFLAGS'][3] == os.path.normpath('foo'), \ - dict['_INCFLAGS'][3] - assert dict['_INCFLAGS'][4] == os.path.normpath('/xx/baz/barbar'), \ - dict['_INCFLAGS'][4] - assert dict['_INCFLAGS'][5] == os.path.normpath('foo'), \ - dict['_INCFLAGS'][5] - assert dict['_INCFLAGS'][6] == os.path.normpath('blatbar'), \ - dict['_INCFLAGS'][6] - assert dict['_INCFLAGS'][7] == '$)', \ - dict['_INCFLAGS'][7] - - dict = {'CPPPATH' : '', - 'LIBPATH' : '' } - autogenerate(dict, dir = SCons.Node.FS.default_fs.Dir('/yy')) - assert len(dict['_INCFLAGS']) == 0, dict['_INCFLAGS'] - assert len(dict['_LIBDIRFLAGS']) == 0, dict['_LIBDIRFLAGS'] - def test_render_tree(self): class Node: def __init__(self, name, children=[]): -- 2.26.2