dict.update(kw)
- # Autogenerate necessary construction variables.
- SCons.Util.autogenerate(dict, dir = cwd)
-
return dict
_rm = re.compile(r'\$[()]')
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
"""
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:
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)
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] + ['$)']
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__":
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
class Environment:
def Dictionary(self, *args):
- pass
+ return {}
+ def autogenerate(self, **kw):
+ return {}
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:
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):
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.
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=[]):