summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons/Tool
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/SCons/Tool')
-rw-r--r--src/engine/SCons/Tool/JavaCommon.py14
-rw-r--r--src/engine/SCons/Tool/JavaCommonTests.py69
-rw-r--r--src/engine/SCons/Tool/__init__.py119
-rw-r--r--src/engine/SCons/Tool/applelink.py3
-rw-r--r--src/engine/SCons/Tool/dvips.py2
-rw-r--r--src/engine/SCons/Tool/install.py25
-rw-r--r--src/engine/SCons/Tool/msvc.py4
-rw-r--r--src/engine/SCons/Tool/msvs.py2
-rw-r--r--src/engine/SCons/Tool/qt.xml4
9 files changed, 183 insertions, 59 deletions
diff --git a/src/engine/SCons/Tool/JavaCommon.py b/src/engine/SCons/Tool/JavaCommon.py
index 0991c37..d028a39 100644
--- a/src/engine/SCons/Tool/JavaCommon.py
+++ b/src/engine/SCons/Tool/JavaCommon.py
@@ -49,14 +49,16 @@ if java_parsing:
# double-backslashes;
# a single-line comment "//";
# single or double quotes preceeded by a backslash;
- # single quotes, double quotes, open or close braces, semi-colons;
+ # single quotes, double quotes, open or close braces, semi-colons,
+ # periods, open or close parentheses;
+ # floating-point numbers;
# any alphanumeric token (keyword, class name, specifier);
+ # any alphanumeric token surrounded by angle brackets (generics);
# the multi-line comment begin and end tokens /* and */;
- # array declarations "[]";
- # semi-colons;
- # periods.
+ # array declarations "[]".
_reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"\{\}\;\.\(\)]|' +
- r'[A-Za-z_][\w\$\.]*|/\*|\*/|\[\])')
+ r'\d*\.\d*|[A-Za-z_][\w\$\.]*|<[A-Za-z_]\w+>|' +
+ r'/\*|\*/|\[\])')
class OuterState:
"""The initial state for parsing a Java file for classes,
@@ -199,6 +201,8 @@ if java_parsing:
return IgnoreState('*/', self)
elif token == '\n':
return self
+ elif token[0] == '<' and token[-1] == '>':
+ return self
elif token == '(':
self.brace_level = self.brace_level + 1
return self
diff --git a/src/engine/SCons/Tool/JavaCommonTests.py b/src/engine/SCons/Tool/JavaCommonTests.py
index 1675190..bffe09e 100644
--- a/src/engine/SCons/Tool/JavaCommonTests.py
+++ b/src/engine/SCons/Tool/JavaCommonTests.py
@@ -466,6 +466,75 @@ class test
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5')
assert expect == classes, (expect, classes)
+ def test_floating_point_numbers(self):
+ """Test floating-point numbers in the input stream"""
+ input = """
+// Broken.java
+class Broken
+{
+ /**
+ * Detected.
+ */
+ Object anonymousInnerOK = new Runnable() { public void run () {} };
+
+ /**
+ * Detected.
+ */
+ class InnerOK { InnerOK () { } }
+
+ {
+ System.out.println("a number: " + 1000.0 + "");
+ }
+
+ /**
+ * Not detected.
+ */
+ Object anonymousInnerBAD = new Runnable() { public void run () {} };
+
+ /**
+ * Not detected.
+ */
+ class InnerBAD { InnerBAD () { } }
+}
+"""
+
+ expect = ['Broken$1', 'Broken$InnerOK', 'Broken$2', 'Broken$InnerBAD', 'Broken']
+
+ pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4')
+ assert expect == classes, (expect, classes)
+
+ pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5')
+ assert expect == classes, (expect, classes)
+
+
+ def test_genercis(self):
+ """Test that generics don't interfere with detecting anonymous classes"""
+
+ input = """\
+import java.util.Date;
+import java.util.Comparator;
+
+public class Foo
+{
+ public void foo()
+ {
+ Comparator<Date> comp = new Comparator<Date>()
+ {
+ static final long serialVersionUID = 1L;
+ public int compare(Date lhs, Date rhs)
+ {
+ return 0;
+ }
+ };
+ }
+}
+"""
+
+ expect = [ 'Foo$1', 'Foo' ]
+
+ pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.6')
+ assert expect == classes, (expect, classes)
+
if __name__ == "__main__":
diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py
index d4e3815..1e69f1e 100644
--- a/src/engine/SCons/Tool/__init__.py
+++ b/src/engine/SCons/Tool/__init__.py
@@ -422,32 +422,33 @@ def CreateJavaFileBuilder(env):
env['JAVASUFFIX'] = '.java'
return java_file
-class ToolInitializer:
+class ToolInitializerMethod:
"""
- A class for delayed initialization of Tools modules.
-
- This is intended to be added to a construction environment in
- place of the method(s) normally called for a Builder (env.Object,
- env.StaticObject, etc.). When called, it searches the specified
- list of tools, applies the first one that exists to the construction
- environment, and calls whatever builder was (presumably) added the
- construction environment in our place.
+ This is added to a construction environment in place of a
+ method(s) normally called for a Builder (env.Object, env.StaticObject,
+ etc.). When called, it has its associated ToolInitializer
+ object search the specified list of tools and apply the first
+ one that exists to the construction environment. It then calls
+ whatever builder was (presumably) added to the construction
+ environment in place of this particular instance.
"""
- def __init__(self, name, tools):
+ def __init__(self, name, initializer):
"""
Note: we store the tool name as __name__ so it can be used by
the class that attaches this to a construction environment.
"""
self.__name__ = name
- if not SCons.Util.is_List(tools):
- tools = [tools]
- self.tools = tools
- def __call__(self, env, *args, **kw):
- for t in self.tools:
- tool = SCons.Tool.Tool(t)
- if tool.exists(env):
- env.Tool(tool)
- break
+ self.initializer = initializer
+
+ def get_builder(self, env):
+ """
+ Returns the appropriate real Builder for this method name
+ after having the associated ToolInitializer object apply
+ the appropriate Tool module.
+ """
+ builder = getattr(env, self.__name__)
+
+ self.initializer.apply_tools(env)
builder = getattr(env, self.__name__)
if builder is self:
@@ -455,21 +456,79 @@ class ToolInitializer:
# for this name was found (or possibly there's a mismatch
# between the name we were called by and the Builder name
# added by the Tool module).
- #
- # (Eventually this is where we'll put a more informative
- # error message about the inability to find that tool
- # as cut over more Builders+Tools to using this.
- return [], []
+ return None
+
+ self.initializer.remove_methods(env)
+
+ return builder
- # Let the construction environment remove the added method
- # so we no longer copy and re-bind this method when the
- # construction environment gets cloned.
- env.RemoveMethod(self)
+ def __call__(self, env, *args, **kw):
+ """
+ """
+ builder = self.get_builder(env)
+ if builder is None:
+ return [], []
return apply(builder, args, kw)
+class ToolInitializer:
+ """
+ A class for delayed initialization of Tools modules.
+
+ Instances of this class associate a list of Tool modules with
+ a list of Builder method names that will be added by those Tool
+ modules. As part of instantiating this object for a particular
+ construction environment, we also add the appropriate
+ ToolInitializerMethod objects for the various Builder methods
+ that we want to use to delay Tool searches until necessary.
+ """
+ def __init__(self, env, tools, names):
+ if not SCons.Util.is_List(tools):
+ tools = [tools]
+ if not SCons.Util.is_List(names):
+ names = [names]
+ self.env = env
+ self.tools = tools
+ self.names = names
+ self.methods = {}
+ for name in names:
+ method = ToolInitializerMethod(name, self)
+ self.methods[name] = method
+ env.AddMethod(method)
+
+ def remove_methods(self, env):
+ """
+ Removes the methods that were added by the tool initialization
+ so we no longer copy and re-bind them when the construction
+ environment gets cloned.
+ """
+ for method in self.methods.values():
+ env.RemoveMethod(method)
+
+ def apply_tools(self, env):
+ """
+ Searches the list of associated Tool modules for one that
+ exists, and applies that to the construction environment.
+ """
+ for t in self.tools:
+ tool = SCons.Tool.Tool(t)
+ if tool.exists(env):
+ env.Tool(tool)
+ return
+
+ # If we fall through here, there was no tool module found.
+ # This is where we can put an informative error message
+ # about the inability to find the tool. We'll start doing
+ # this as we cut over more pre-defined Builder+Tools to use
+ # the ToolInitializer class.
+
def Initializers(env):
- env.AddMethod(ToolInitializer('Install', 'install'))
- env.AddMethod(ToolInitializer('InstallAs', 'install'))
+ ToolInitializer(env, ['install'], ['_InternalInstall', '_InternalInstallAs'])
+ def Install(self, *args, **kw):
+ return apply(self._InternalInstall, args, kw)
+ def InstallAs(self, *args, **kw):
+ return apply(self._InternalInstallAs, args, kw)
+ env.AddMethod(Install)
+ env.AddMethod(InstallAs)
def FindTool(tools, env):
for tool in tools:
diff --git a/src/engine/SCons/Tool/applelink.py b/src/engine/SCons/Tool/applelink.py
index 532301f..7500133 100644
--- a/src/engine/SCons/Tool/applelink.py
+++ b/src/engine/SCons/Tool/applelink.py
@@ -62,5 +62,4 @@ def generate(env):
def exists(env):
- import sys
- return sys.platform == 'darwin'
+ return env['PLATFORM'] == 'darwin'
diff --git a/src/engine/SCons/Tool/dvips.py b/src/engine/SCons/Tool/dvips.py
index 9996fc2..ec95f16 100644
--- a/src/engine/SCons/Tool/dvips.py
+++ b/src/engine/SCons/Tool/dvips.py
@@ -58,7 +58,7 @@ def generate(env):
env['DVIPS'] = 'dvips'
env['DVIPSFLAGS'] = SCons.Util.CLVar('')
- # I'm not quite sure I got the directories and filenames right for build_dir
+ # I'm not quite sure I got the directories and filenames right for variant_dir
# We need to be in the correct directory for the sake of latex \includegraphics eps included files.
env['PSCOM'] = 'cd ${TARGET.dir} && $DVIPS $DVIPSFLAGS -o ${TARGET.file} ${SOURCE.file}'
env['PSPREFIX'] = ''
diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py
index c7eee61..983fb12 100644
--- a/src/engine/SCons/Tool/install.py
+++ b/src/engine/SCons/Tool/install.py
@@ -75,7 +75,8 @@ def installFunc(target, source, env):
except KeyError:
raise SCons.Errors.UserError('Missing INSTALL construction variable.')
- assert( len(target)==len(source) )
+ assert len(target)==len(source), \
+ "Installing source %s into target %s: target and source lists must have same length."%(map(str, source), map(str, target))
for t,s in zip(target,source):
if install(t.get_path(),s.get_path(),env):
return 1
@@ -131,8 +132,9 @@ installas_action = SCons.Action.Action(installFunc, stringFunc)
BaseInstallBuilder = None
-def InstallBuilderWrapper(env, target, source, dir=None):
+def InstallBuilderWrapper(env, target=None, source=None, dir=None, **kw):
if target and dir:
+ import SCons.Errors
raise SCons.Errors.UserError, "Both target and dir defined for Install(), only one may be defined."
if not dir:
dir=target
@@ -156,13 +158,15 @@ def InstallBuilderWrapper(env, target, source, dir=None):
# '#' on the file name portion as meaning the Node should
# be relative to the top-level SConstruct directory.
target = env.fs.Entry('.'+os.sep+src.name, dnode)
- tgt.extend(BaseInstallBuilder(env, target, src))
+ #tgt.extend(BaseInstallBuilder(env, target, src, **kw))
+ tgt.extend(apply(BaseInstallBuilder, (env, target, src), kw))
return tgt
-def InstallAsBuilderWrapper(env, target, source):
+def InstallAsBuilderWrapper(env, target=None, source=None, **kw):
result = []
for src, tgt in map(lambda x, y: (x, y), source, target):
- result.extend(BaseInstallBuilder(env, tgt, src))
+ #result.extend(BaseInstallBuilder(env, tgt, src, **kw))
+ result.extend(apply(BaseInstallBuilder, (env, tgt, src), kw))
return result
added = None
@@ -195,15 +199,8 @@ def generate(env):
emitter = [ add_targets_to_INSTALLED_FILES, ],
name = 'InstallBuilder')
- try:
- env['BUILDERS']['Install']
- except KeyError, e:
- env['BUILDERS']['Install'] = InstallBuilderWrapper
-
- try:
- env['BUILDERS']['InstallAs']
- except KeyError, e:
- env['BUILDERS']['InstallAs'] = InstallAsBuilderWrapper
+ env['BUILDERS']['_InternalInstall'] = InstallBuilderWrapper
+ env['BUILDERS']['_InternalInstallAs'] = InstallAsBuilderWrapper
# We'd like to initialize this doing something like the following,
# but there isn't yet support for a ${SOURCE.type} expansion that
diff --git a/src/engine/SCons/Tool/msvc.py b/src/engine/SCons/Tool/msvc.py
index c6fe461..a1067c0 100644
--- a/src/engine/SCons/Tool/msvc.py
+++ b/src/engine/SCons/Tool/msvc.py
@@ -513,10 +513,6 @@ def _get_msvc8_default_paths(env, version, suite, use_mfc_dirs):
include_paths.append( os.path.join( atlmfc_path, 'include' ) )
lib_paths.append( os.path.join( atlmfc_path, 'lib' ) )
- env_include_path = SCons.Util.get_environment_var('INCLUDE')
- if env_include_path:
- include_paths.append( env_include_path )
-
if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKSDKDIR'):
fwdir = paths['FRAMEWORKSDKDIR']
include_paths.append( os.path.join( fwdir, 'include' ) )
diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py
index d4efa74..ca1b5f6 100644
--- a/src/engine/SCons/Tool/msvs.py
+++ b/src/engine/SCons/Tool/msvs.py
@@ -1504,7 +1504,7 @@ def GenerateProject(target, source, env):
builddspfile = target[0]
dspfile = builddspfile.srcnode()
- # this detects whether or not we're using a BuildDir
+ # this detects whether or not we're using a VariantDir
if not dspfile is builddspfile:
try:
bdsp = open(str(builddspfile), "w+")
diff --git a/src/engine/SCons/Tool/qt.xml b/src/engine/SCons/Tool/qt.xml
index 66fe554..ea73698 100644
--- a/src/engine/SCons/Tool/qt.xml
+++ b/src/engine/SCons/Tool/qt.xml
@@ -112,7 +112,7 @@ As stated in the qt documentation, include the moc file at the end of
the cxx file. Note that you have to include the file, which is generated
by the transformation ${QT_MOCCXXPREFIX}&lt;basename&gt;${QT_MOCCXXSUFFIX}, by default
&lt;basename&gt;.moc. A warning is generated after building the moc file, if you
-do not include the correct file. If you are using BuildDir, you may
+do not include the correct file. If you are using VariantDir, you may
need to specify duplicate=1. You can turn off automatic moc file generation
by setting QT_AUTOSCAN to 0. See also the corresponding
&b-Moc;
@@ -123,7 +123,7 @@ The implementation files generated from .ui files are handled much the same
as yacc or lex files. Each .ui file given as a source of Program, Library or
SharedLibrary will generate three files, the declaration file, the
implementation file and a moc file. Because there are also generated headers,
-you may need to specify duplicate=1 in calls to BuildDir.
+you may need to specify duplicate=1 in calls to VariantDir.
See also the corresponding
&b-Uic;
builder method.