Anonymous avatar Anonymous committed 16180ea

Merged revisions 2121-2135 via svnmerge from
http://scons.tigris.org/svn/scons/branches/core

........
r2128 | stevenknight | 2007-07-13 06:27:11 -0500 (Fri, 13 Jul 2007) | 2 lines

Use the "swig -classic" option on pre-2.0 Python versions.
........
r2130 | stevenknight | 2007-07-13 09:42:45 -0500 (Fri, 13 Jul 2007) | 2 lines

Remove left-over cut-and-paste stuff about loadable modules and frameworks.
........
r2131 | stevenknight | 2007-07-13 12:08:37 -0500 (Fri, 13 Jul 2007) | 4 lines

Refactor the structure of the tests to make the java input strings
separate from the parse_java() calls. (Prep for enhancing the parser
for Java 1.5 anonymous class files.)
........
r2132 | stevenknight | 2007-07-13 12:24:09 -0500 (Fri, 13 Jul 2007) | 3 lines

Copy the Java 1.4 nested-anonymous-class test case from test/Java/live.py.
Remove a commented-out unit test already added elsewhere.
........
r2133 | stevenknight | 2007-07-13 16:16:51 -0500 (Fri, 13 Jul 2007) | 4 lines

Support the changed naming of .class files for nested anonymous inner
classes in Java 1.5 by adding a new $JAVAVERSION variable that can be set
to reflect the javac version being used.
........
r2134 | stevenknight | 2007-07-13 20:28:34 -0500 (Fri, 13 Jul 2007) | 5 lines

Add a $SWIGOUTDIR variable.
Add it, when set, to the command line as an argument to -outdir.
Have the emitter use it to figure out where the generated .java
files will be (something we didn't do at all before, -outdir aside).
........
r2135 | stevenknight | 2007-07-13 23:51:21 -0500 (Fri, 13 Jul 2007) | 2 lines

Minor unit test fixes for old Python versions (1.6 and 2.0).
........

Comments (0)

Files changed (18)

 <!ENTITY SCons          "<application>SCons</application>">
 <!ENTITY scons          "<application>scons</application>">
 <!ENTITY ScCons         "<application>ScCons</application>">
+<!ENTITY swig           "<application>swig</application>">
 <!ENTITY tar            "<application>tar</application>">
 <!ENTITY tex            "<application>tex</application>">
 <!ENTITY touch          "<application>touch</application>">
   - Fix the --debug=time option when the -j option is specified and all
     files are up to date.
 
+  - Add a $SWIGOUTDIR variable to allow setting the swig -outdir option,
+    and use it to identify files created by the swig -java option.
+
   From Leanid Nazdrynau:
 
   - When applying Tool modules after a construction environment has
   - Find Java anonymous classes when the next token after the name is
     an open parenthesis.
 
+  From Tilo Prutz:
+
+  - Add support for the file names that Java 1.5 (and 1.6) generates for
+    nested anonymous inner classes, which are different from Java 1.4.
+
   From Adam Simpkins:
 
   - Allow worker threads to terminate gracefully when all jobs are

src/engine/SCons/EnvironmentTests.py

         env['CLVar'] = CLVar([])
         env.AppendUnique(CLVar = 'bar')
         result = env['CLVar']
-        if sys.version[0] == '1':
-            # Python 1.5.2 has a quirky behavior where CLVar([]) actually
-            # matches '' and [] due to different __coerce__() semantics
-            # in the UserList implementation.  It isn't worth a lot of
-            # effort to get this corner case to work identically (support
-            # for Python 1.5 support will die soon anyway), so just treat
-            # it separately for now.
+        if sys.version[0] == '1' or sys.version[:3] == '2.0':
+            # Python 2.0 and before have a quirky behavior where CLVar([])
+            # actually matches '' and [] due to different __coerce__()
+            # semantics in the UserList implementation.  It isn't worth a
+            # lot of effort to get this corner case to work identically
+            # (support for Python 1.5 support will die soon anyway),
+            # so just treat it separately for now.
             assert result == 'bar', result
         else:
             assert isinstance(result, CLVar), repr(result)
         env['CLVar'] = CLVar([])
         env.PrependUnique(CLVar = 'bar')
         result = env['CLVar']
-        if sys.version[0] == '1':
-            # Python 1.5.2 has a quirky behavior where CLVar([]) actually
-            # matches '' and [] due to different __coerce__() semantics
-            # in the UserList implementation.  It isn't worth a lot of
-            # effort to get this corner case to work identically (support
-            # for Python 1.5 support will die soon anyway), so just treat
-            # it separately for now.
+        if sys.version[0] == '1' or sys.version[:3] == '2.0':
+            # Python 2.0 and before have a quirky behavior where CLVar([])
+            # actually matches '' and [] due to different __coerce__()
+            # semantics in the UserList implementation.  It isn't worth a
+            # lot of effort to get this corner case to work identically
+            # (support for Python 1.5 support will die soon anyway),
+            # so just treat it separately for now.
             assert result == 'bar', result
         else:
             assert isinstance(result, CLVar), repr(result)

src/engine/SCons/SubstTests.py

             expect = [
                 "AttributeError `bar' trying to evaluate `${foo.bar}'",
                 "AttributeError `Foo instance has no attribute 'bar'' trying to evaluate `${foo.bar}'",
+                "AttributeError `'Foo' instance has no attribute 'bar'' trying to evaluate `${foo.bar}'",
             ]
             assert str(e) in expect, e
         else:
             expect = [
                 "AttributeError `bar' trying to evaluate `${foo.bar}'",
                 "AttributeError `Foo instance has no attribute 'bar'' trying to evaluate `${foo.bar}'",
+                "AttributeError `'Foo' instance has no attribute 'bar'' trying to evaluate `${foo.bar}'",
             ]
             assert str(e) in expect, e
         else:

src/engine/SCons/Tool/JavaCommon.py

 
 java_parsing = 1
 
+default_java_version = '1.4'
+
 if java_parsing:
     # Parse Java files for class names.
     #
     class OuterState:
         """The initial state for parsing a Java file for classes,
         interfaces, and anonymous inner classes."""
-        def __init__(self):
+        def __init__(self, version=default_java_version):
+
+            if not version in ('1.1', '1.2', '1.3','1.4', '1.5', '1.6'):
+                msg = "Java version %s not supported" % version
+                raise NotImplementedError, msg
+
+            self.version = version
             self.listClasses = []
             self.listOutputs = []
             self.stackBrackets = []
             self.brackets = 0
             self.nextAnon = 1
+            self.stackAnonClassBrackets = []
+            self.anonStacksStack = [[0]]
             self.package = None
 
         def trace(self):
                 ret = SkipState(1, self)
                 self.skipState = ret
                 return ret
+        
+        def __getAnonStack(self):
+            return self.anonStacksStack[-1]
 
         def openBracket(self):
             self.brackets = self.brackets + 1
                self.brackets == self.stackBrackets[-1]:
                 self.listOutputs.append(string.join(self.listClasses, '$'))
                 self.listClasses.pop()
+                self.anonStacksStack.pop()
                 self.stackBrackets.pop()
+            if len(self.stackAnonClassBrackets) and \
+               self.brackets == self.stackAnonClassBrackets[-1]:
+                self.__getAnonStack().pop()
+                self.stackAnonClassBrackets.pop()
 
         def parseToken(self, token):
             if token[:2] == '//':
 
         def addAnonClass(self):
             """Add an anonymous inner class"""
-            clazz = self.listClasses[0]
-            self.listOutputs.append('%s$%d' % (clazz, self.nextAnon))
+            if self.version in ('1.1', '1.2', '1.3', '1.4'):
+                clazz = self.listClasses[0]
+                self.listOutputs.append('%s$%d' % (clazz, self.nextAnon))
+            elif self.version in ('1.5', '1.6'):
+                self.stackAnonClassBrackets.append(self.brackets)
+                className = []
+                className.extend(self.listClasses)
+                self.__getAnonStack()[-1] = self.__getAnonStack()[-1] + 1
+                for anon in self.__getAnonStack():
+                    className.append(str(anon))
+                self.listOutputs.append(string.join(className, '$'))
+
             self.nextAnon = self.nextAnon + 1
+            self.__getAnonStack().append(0)
 
         def setPackage(self, package):
             self.package = package
             if token == '\n':
                 return self
             self.outer_state.listClasses.append(token)
+            self.outer_state.anonStacksStack.append([0])
             return self.outer_state
 
     class IgnoreState:
             self.outer_state.setPackage(token)
             return self.outer_state
 
-    def parse_java_file(fn):
-        return parse_java(open(fn, 'r').read())
+    def parse_java_file(fn, version=default_java_version):
+        return parse_java(open(fn, 'r').read(), version)
 
-    def parse_java(contents, trace=None):
+    def parse_java(contents, version=default_java_version, trace=None):
         """Parse a .java file and return a double of package directory,
         plus a list of .class files that compiling that .java file will
         produce"""
         package = None
-        initial = OuterState()
+        initial = OuterState(version)
         currstate = initial
         for token in _reToken.findall(contents):
             # The regex produces a bunch of groups, but only one will

src/engine/SCons/Tool/JavaCommonTests.py

 import SCons.Tool.JavaCommon
 
 
-# Adding this trace to any of the calls below to the parse_java() method
-# will cause the parser to spit out trace messages of the tokens it sees
-# and state transitions.
+# Adding trace=trace to any of the parse_jave() calls below will cause
+# the parser to spit out trace messages of the tokens it sees and the
+# attendant transitions.
 
 def trace(token, newstate):
     from SCons.Debug import Trace
     def test_bare_bones(self):
         """Test a bare-bones class"""
 
-        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java("""\
+        input = """\
 package com.sub.bar;
 
 public class Foo
      }
 
 }
-""")
+"""
+        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
         assert pkg_dir == os.path.join('com', 'sub', 'bar'), pkg_dir
         assert classes == ['Foo'], classes
 
     def test_inner_classes(self):
         """Test parsing various forms of inner classes"""
 
-        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java("""\
+        input = """\
 class Empty {
 }
 
     };
   }
 }
-""")
-    
+"""
+
+        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4')
         assert pkg_dir is None, pkg_dir
         expect = [
                    'Empty',
                  ]
         assert classes == expect, classes
 
+        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5')
+        assert pkg_dir is None, pkg_dir
+        expect = [
+                   'Empty',
+                   'Listener',
+                   'Test$Inner$1',
+                   'Test$Inner',
+                   'Test$Inner2',
+                   'Test$Inner3',
+                   'Test$1',
+                   'Test$1$1',
+                   'Test',
+                   'Private$1',
+                   'Private',
+                 ]
+        assert classes == expect, (expect, classes)
+
+
 
     def test_comments(self):
         """Test a class with comments"""
 
-        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java("""\
+        input = """\
 package com.sub.foo;
 
 import java.rmi.Naming;
         }
     }
 }
-""")
+"""
 
+        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
         assert pkg_dir == os.path.join('com', 'sub', 'foo'), pkg_dir
         assert classes == ['Example1'], classes
 
     def test_arrays(self):
         """Test arrays of class instances"""
 
-        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java("""\
+        input = """\
 public class Test {
     MyClass abc = new MyClass();
     MyClass xyz = new MyClass();
         xyz
     }
 }
-""")
+"""
+
+        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
         assert pkg_dir == None, pkg_dir
         assert classes == ['Test'], classes
 
 
-# This test comes from bug report #1197470:
-#
-#    http://sourceforge.net/tracker/index.php?func=detail&aid=1194740&group_id=30337&atid=398971
-#
-# I've captured it here so that someone with a better grasp of Java syntax
-# and the parse_java() state machine can uncomment it and fix it some day.
-#
-#    def test_arrays_in_decls(self):
-#        """Test how arrays in method declarations affect class detection"""
-#
-#        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java("""\
-#public class A {
-#    public class B{
-#        public void F(Object[] o) {
-#            F(new Object[] {Object[].class});
-#        }
-#        public void G(Object[] o) {
-#            F(new Object[] {});
-#        }
-#    }
-#}
-#""")
-#        assert pkg_dir == None, pkg_dir
-#        assert classes == ['A$B', 'A'], classes
-
 
     def test_backslash(self):
         """Test backslash handling"""
 
-        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java("""\
+        input = """\
 public class MyTabs
 {
         private class MyInternal
         }
         private final static String PATH = "images\\\\";
 }
-""")
+"""
+
+        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
         assert pkg_dir == None, pkg_dir
         assert classes == ['MyTabs$MyInternal', 'MyTabs'], classes
 
     def test_enum(self):
         """Test the Java 1.5 enum keyword"""
 
-        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java("""\
+        input = """\
 package p;
 public enum a {}
-""")
+"""
+
+        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
         assert pkg_dir == 'p', pkg_dir
         assert classes == ['a'], classes
 
 
     def test_anon_classes(self):
         """Test anonymous classes"""
-        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java("""\
+
+        input = """\
 public abstract class TestClass
 {
     public void completed()
         }.start();
     }
 }
-""")
+"""
+
+        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
         assert pkg_dir == None, pkg_dir
         assert classes == ['TestClass$1', 'TestClass$2', 'TestClass'], classes
 
 
     def test_closing_bracket(self):
         """Test finding a closing bracket instead of an anonymous class"""
-        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java("""\
+
+        input = """\
 class TestSCons {
     public static void main(String[] args) {
         Foo[] fooArray = new Foo[] { new Foo() };
 }
 
 class Foo { }
-""")
+"""
+
+        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
         assert pkg_dir == None, pkg_dir
         assert classes == ['TestSCons', 'Foo'], classes
 
 
     def test_dot_class_attributes(self):
         """Test handling ".class" attributes"""
-        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java("""\
+
+        input = """\
 public class Test extends Object
 {
     static {
         Object[] s = new Object[] {};
     }
 }
-""")
+"""
+
+        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
         assert classes == ['Test'], classes
 
-        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java("""\
+        input = """\
 public class A {
     public class B {
         public void F(Object[] o) {
         }
     }
 }
-""")
+"""
+
+        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
         assert pkg_dir == None, pkg_dir
         assert classes == ['A$B', 'A'], classes
 
     def test_anonymous_classes_with_parentheses(self):
         """Test finding anonymous classes marked by parentheses"""
-        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java("""\
+
+        input = """\
 import java.io.File;
 
 public class Foo {
         };
     }
 }
-""")
+"""
+
+        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4')
         assert classes == ['Foo$1', 'Foo$2', 'Foo'], classes
 
+        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5')
+        assert classes == ['Foo$1', 'Foo$1$1', 'Foo'], classes
+
+
+
+    def test_nested_anonymous_inner_classes(self):
+        """Test finding nested anonymous inner classes"""
+
+        input = """\
+// import java.util.*;
+
+public class NestedExample
+{
+        public NestedExample()
+        {
+                Thread t = new Thread() {
+                        public void start()
+                        {
+                                Thread t = new Thread() {
+                                        public void start()
+                                        {
+                                                try {Thread.sleep(200);}
+                                                catch (Exception e) {}
+                                        }
+                                };
+                                while (true)
+                                {
+                                        try {Thread.sleep(200);}
+                                        catch (Exception e) {}
+                                }
+                        }
+                };
+        }
+
+
+        public static void main(String argv[])
+        {
+                NestedExample e = new NestedExample();
+        }
+}
+"""
+
+        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4')
+        expect = [ 'NestedExample$1', 'NestedExample$2', 'NestedExample' ]
+        assert expect == classes, (expect, classes)
+
+        pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5')
+        expect = [ 'NestedExample$1', 'NestedExample$1$1', 'NestedExample' ]
+        assert expect == classes, (expect, classes)
 
 
 

src/engine/SCons/Tool/javac.py

 
     tlist = []
     for f in slist:
-        pkg_dir, classes = parse_java_file(f.get_abspath())
+        version = env.get('JAVAVERSION', '1.4')
+        pkg_dir, classes = parse_java_file(f.get_abspath(), version)
         if pkg_dir:
             for c in classes:
                 t = target[0].Dir(pkg_dir).File(c+class_suffix)

src/engine/SCons/Tool/javac.xml

 by default.
 </summary>
 </cvar>
+
+<cvar name="JAVAVERSION">
+<summary>
+Specifies the Java version being used by the &b-Java; builder.
+This is <emphasis>not</emphasis> currently used to select one
+version of the Java compiler vs. another.
+Instead, you should set this to specify the version of Java
+supported by your &javac; compiler.
+The default is <literal>1.4</literal>.
+
+This is sometimes necessary because
+Java 1.5 changed the file names that are created
+for nested anonymous inner classes,
+which can cause a mismatch with the files
+that &SCons; expects will be generated by the &javac; compiler.
+Setting &cv-JAVAVERSION; to <literal>1.5</literal>
+(or <literal>1.6</literal>, as appropriate)
+can make &SCons; realize that a Java 1.5 or 1.6
+build is actually up to date.
+</summary>
+</cvar>

src/engine/SCons/Tool/swig.py

 def _swigEmitter(target, source, env):
     for src in source:
         src = str(src)
-        mname = None
         flags = SCons.Util.CLVar(env.subst("$SWIGFLAGS"))
+        mnames = None
         if "-python" in flags and "-noproxy" not in flags:
-            f = open(src)
-            try:
-                for l in f.readlines():
-                    m = _reModule.match(l)
-                    if m:
-                        mname = m.group(1)
-            finally:
-                f.close()
-            if mname is not None:
-                target.append(mname + ".py")
+            if mnames is None:
+                mnames = _reModule.findall(open(src).read())
+            target.extend(map(lambda m: m + ".py", mnames))
+        if "-java" in flags:
+            if mnames is None:
+                mnames = _reModule.findall(open(src).read())
+            java_files = map(lambda m: [m + ".java", m + "JNI.java"], mnames)
+            java_files = SCons.Util.flatten(java_files)
+            outdir = env.subst('$SWIGOUTDIR')
+            if outdir:
+                 java_files = map(lambda j, o=outdir: os.path.join(o, j), java_files)
+            target.extend(java_files)
     return (target, source)
 
 def generate(env):
     env['SWIGFLAGS']         = SCons.Util.CLVar('')
     env['SWIGCFILESUFFIX']   = '_wrap$CFILESUFFIX'
     env['SWIGCXXFILESUFFIX'] = '_wrap$CXXFILESUFFIX'
-    env['SWIGCOM']           = '$SWIG $SWIGFLAGS -o $TARGET $SOURCES'
+    env['_SWIGOUTDIR']       = '${"-outdir " + SWIGOUTDIR}'
+    env['SWIGCOM']           = '$SWIG -o $TARGET ${_SWIGOUTDIR} $SWIGFLAGS $SOURCES'
     env.Append(SCANNERS=Scanner(function=_scanSwig, skeys=[".i"]))
 
 def exists(env):

src/engine/SCons/Tool/swig.xml

 variable.
 </summary>
 </cvar>
+
+<cvar name="SWIGOUTDIR">
+<summary>
+Specifies the output directory in which
+the scripting language wrapper and interface generator
+should place generated language-specific files.
+This will be used by SCons to identify
+the files that will be generated by the &swig; call,
+and translated into the
+<literal>swig -outdir</literal> option on the command line.
+</summary>
+</cvar>

test/Java/Java-1.4.py

+#!/usr/bin/env python
+#
+# __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__"
+
+"""
+Test Java compilation with a live Java 1.4 "javac" compiler.
+"""
+
+import os
+import os.path
+import string
+import sys
+import TestSCons
+
+_python_ = TestSCons._python_
+
+test = TestSCons.TestSCons()
+
+ENV = test.java_ENV()
+
+if test.detect_tool('javac', ENV=ENV):
+    where_javac = test.detect('JAVAC', 'javac', ENV=ENV)
+else:
+    where_javac = test.where_is('javac')
+if not where_javac:
+    test.skip_test("Could not find Java javac, skipping test(s).\n")
+
+
+
+test.write('SConstruct', """
+env = Environment(tools = ['javac'],
+                  JAVAVERSION = '1.4',
+                  JAVAC = r'%(where_javac)s')
+env.Java(target = 'class1', source = 'com/sub/foo')
+env.Java(target = 'class2', source = 'com/sub/bar')
+env.Java(target = 'class3', source = ['src1', 'src2'])
+env.Java(target = 'class4', source = ['src4'])
+env.Java(target = 'class5', source = ['src5'])
+""" % locals())
+
+test.subdir('com',
+            ['com', 'sub'],
+            ['com', 'sub', 'foo'],
+            ['com', 'sub', 'bar'],
+            'src1',
+            'src2',
+            'src4',
+            'src5')
+
+test.write(['com', 'sub', 'foo', 'Example1.java'], """\
+package com.sub.foo;
+
+public class Example1
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['com', 'sub', 'foo', 'Example2.java'], """\
+package com.other;
+
+public class Example2
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['com', 'sub', 'foo', 'Example3.java'], """\
+package com.sub.foo;
+
+public class Example3
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['com', 'sub', 'bar', 'Example4.java'], """\
+package com.sub.bar;
+
+public class Example4
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['com', 'sub', 'bar', 'Example5.java'], """\
+package com.other;
+
+public class Example5
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['com', 'sub', 'bar', 'Example6.java'], """\
+package com.sub.bar;
+
+public class Example6
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['src1', 'Example7.java'], """\
+public class Example7
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+# Acid-test file for parsing inner Java classes, courtesy Chad Austin.
+test.write(['src2', 'Test.java'], """\
+class Empty {
+}
+
+interface Listener {
+  public void execute();
+}
+
+public
+class
+Test {
+  class Inner {
+    void go() {
+      use(new Listener() {
+        public void execute() {
+          System.out.println("In Inner");
+        }
+      });
+    }
+    String s1 = "class A";
+    String s2 = "new Listener() { }";
+    /* class B */
+    /* new Listener() { } */
+  }
+
+  public static void main(String[] args) {
+    new Test().run();
+  }
+
+  void run() {
+    use(new Listener() {
+      public void execute() {
+        use(new Listener( ) {
+          public void execute() {
+            System.out.println("Inside execute()");
+          }
+        });
+      }
+    });
+
+    new Inner().go();
+  }
+
+  void use(Listener l) {
+    l.execute();
+  }
+}
+
+class Private {
+  void run() {
+    new Listener() {
+      public void execute() {
+      }
+    };
+  }
+}
+""")
+
+# Testing nested anonymous inner classes, courtesy Brandon Mansfield.
+test.write(['src4', 'NestedExample.java'], """\
+// import java.util.*;
+
+public class NestedExample
+{
+        public NestedExample()
+        {
+                Thread t = new Thread() {
+                        public void start()
+                        {
+                                Thread t = new Thread() {
+                                        public void start()
+                                        {
+                                                try {Thread.sleep(200);}
+                                                catch (Exception e) {}
+                                        }
+                                };
+                                while (true)
+                                {
+                                        try {Thread.sleep(200);}
+                                        catch (Exception e) {}
+                                }
+                        }
+                };
+        }
+
+
+        public static void main(String argv[])
+        {
+                NestedExample e = new NestedExample();
+        }
+}
+""")
+
+# Test not finding an anonymous class when the second token after a
+# "new" is a closing brace.  This duplicates a test from the unit tests,
+# but lets us make sure that we correctly determine that everything is
+# up-to-date after the build.
+test.write(['src5', 'TestSCons.java'], """\
+class TestSCons {
+    public static void main(String[] args) {
+        Foo[] fooArray = new Foo[] { new Foo() };
+    }
+}
+
+class Foo { }
+""")
+
+test.run(arguments = '.')
+
+def get_class_files(dir):
+    def find_class_files(arg, dirname, fnames):
+        for fname in fnames:
+            if fname[-6:] == '.class':
+                arg.append(os.path.join(dirname, fname))
+    result = []
+    os.path.walk(dir, find_class_files, result)
+    result.sort()
+    return result
+
+classes_1 = get_class_files(test.workpath('class1'))
+classes_2 = get_class_files(test.workpath('class2'))
+classes_3 = get_class_files(test.workpath('class3'))
+classes_4 = get_class_files(test.workpath('class4'))
+classes_5 = get_class_files(test.workpath('class5'))
+
+expect_1 = [
+    test.workpath('class1', 'com', 'other', 'Example2.class'),
+    test.workpath('class1', 'com', 'sub', 'foo', 'Example1.class'),
+    test.workpath('class1', 'com', 'sub', 'foo', 'Example3.class'),
+]
+
+expect_2 = [
+    test.workpath('class2', 'com', 'other', 'Example5.class'),
+    test.workpath('class2', 'com', 'sub', 'bar', 'Example4.class'),
+    test.workpath('class2', 'com', 'sub', 'bar', 'Example6.class'),
+]
+
+expect_3 = [
+    test.workpath('class3', 'Empty.class'),
+    test.workpath('class3', 'Example7.class'),
+    test.workpath('class3', 'Listener.class'),
+    test.workpath('class3', 'Private$1.class'),
+    test.workpath('class3', 'Private.class'),
+    test.workpath('class3', 'Test$1.class'),
+    test.workpath('class3', 'Test$2.class'),
+    test.workpath('class3', 'Test$3.class'),
+    test.workpath('class3', 'Test$Inner.class'),
+    test.workpath('class3', 'Test.class'),
+]
+
+expect_4 = [
+    test.workpath('class4', 'NestedExample$1.class'),
+    test.workpath('class4', 'NestedExample$2.class'),
+    test.workpath('class4', 'NestedExample.class'),
+]
+
+expect_5 = [
+    test.workpath('class5', 'Foo.class'),
+    test.workpath('class5', 'TestSCons.class'),
+]
+
+failed = None
+
+def classes_must_match(dir, expect, got):
+    if expect != got:
+        sys.stderr.write("Expected the following class files in '%s':\n" % dir)
+        for c in expect:
+            sys.stderr.write('    %s\n' % c)
+        sys.stderr.write("Got the following class files in '%s':\n" % dir)
+        for c in got:
+            sys.stderr.write('    %s\n' % c)
+        failed = 1
+
+classes_must_match('class1', expect_1, classes_1)
+classes_must_match('class2', expect_2, classes_2)
+classes_must_match('class3', expect_3, classes_3)
+classes_must_match('class4', expect_4, classes_4)
+
+test.fail_test(failed)
+
+test.up_to_date(options='--debug=explain', arguments = '.')
+
+test.pass_test()

test/Java/Java-1.5.py

+#!/usr/bin/env python
+#
+# __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__"
+
+"""
+Test Java compilation with a live Java 1.5 "javac" compiler.
+"""
+
+import os
+import os.path
+import string
+import sys
+import TestSCons
+
+_python_ = TestSCons._python_
+
+test = TestSCons.TestSCons()
+
+ENV = test.java_ENV()
+ENV['PATH'] = '/usr/lib/jvm/java-1.5.0-sun-1.5.0.11/bin' + os.pathsep + os.environ['PATH']
+
+if test.detect_tool('javac', ENV=ENV):
+    where_javac = test.detect('JAVAC', 'javac', ENV=ENV)
+else:
+    where_javac = test.where_is('javac')
+if not where_javac:
+    test.skip_test("Could not find Java javac, skipping test(s).\n")
+
+
+
+test.write('SConstruct', """
+env = Environment(tools = ['javac'],
+                  JAVAVERSION = '1.5',
+                  JAVAC = r'%(where_javac)s')
+env.Java(target = 'class1', source = 'com/sub/foo')
+env.Java(target = 'class2', source = 'com/sub/bar')
+env.Java(target = 'class3', source = ['src1', 'src2'])
+env.Java(target = 'class4', source = ['src4'])
+env.Java(target = 'class5', source = ['src5'])
+""" % locals())
+
+test.subdir('com',
+            ['com', 'sub'],
+            ['com', 'sub', 'foo'],
+            ['com', 'sub', 'bar'],
+            'src1',
+            'src2',
+            'src4',
+            'src5')
+
+test.write(['com', 'sub', 'foo', 'Example1.java'], """\
+package com.sub.foo;
+
+public class Example1
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['com', 'sub', 'foo', 'Example2.java'], """\
+package com.other;
+
+public class Example2
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['com', 'sub', 'foo', 'Example3.java'], """\
+package com.sub.foo;
+
+public class Example3
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['com', 'sub', 'bar', 'Example4.java'], """\
+package com.sub.bar;
+
+public class Example4
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['com', 'sub', 'bar', 'Example5.java'], """\
+package com.other;
+
+public class Example5
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['com', 'sub', 'bar', 'Example6.java'], """\
+package com.sub.bar;
+
+public class Example6
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['src1', 'Example7.java'], """\
+public class Example7
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+# Acid-test file for parsing inner Java classes, courtesy Chad Austin.
+test.write(['src2', 'Test.java'], """\
+class Empty {
+}
+
+interface Listener {
+  public void execute();
+}
+
+public
+class
+Test {
+  class Inner {
+    void go() {
+      use(new Listener() {
+        public void execute() {
+          System.out.println("In Inner");
+        }
+      });
+    }
+    String s1 = "class A";
+    String s2 = "new Listener() { }";
+    /* class B */
+    /* new Listener() { } */
+  }
+
+  public static void main(String[] args) {
+    new Test().run();
+  }
+
+  void run() {
+    use(new Listener() {
+      public void execute() {
+        use(new Listener( ) {
+          public void execute() {
+            System.out.println("Inside execute()");
+          }
+        });
+      }
+    });
+
+    new Inner().go();
+  }
+
+  void use(Listener l) {
+    l.execute();
+  }
+}
+
+class Private {
+  void run() {
+    new Listener() {
+      public void execute() {
+      }
+    };
+  }
+}
+""")
+
+# Testing nested anonymous inner classes, courtesy Brandon Mansfield.
+test.write(['src4', 'NestedExample.java'], """\
+// import java.util.*;
+
+public class NestedExample
+{
+        public NestedExample()
+        {
+                Thread t = new Thread() {
+                        public void start()
+                        {
+                                Thread t = new Thread() {
+                                        public void start()
+                                        {
+                                                try {Thread.sleep(200);}
+                                                catch (Exception e) {}
+                                        }
+                                };
+                                while (true)
+                                {
+                                        try {Thread.sleep(200);}
+                                        catch (Exception e) {}
+                                }
+                        }
+                };
+        }
+
+
+        public static void main(String argv[])
+        {
+                NestedExample e = new NestedExample();
+        }
+}
+""")
+
+# Test not finding an anonymous class when the second token after a
+# "new" is a closing brace.  This duplicates a test from the unit tests,
+# but lets us make sure that we correctly determine that everything is
+# up-to-date after the build.
+test.write(['src5', 'TestSCons.java'], """\
+class TestSCons {
+    public static void main(String[] args) {
+        Foo[] fooArray = new Foo[] { new Foo() };
+    }
+}
+
+class Foo { }
+""")
+
+test.run(arguments = '.')
+
+def get_class_files(dir):
+    def find_class_files(arg, dirname, fnames):
+        for fname in fnames:
+            if fname[-6:] == '.class':
+                arg.append(os.path.join(dirname, fname))
+    result = []
+    os.path.walk(dir, find_class_files, result)
+    result.sort()
+    return result
+
+classes_1 = get_class_files(test.workpath('class1'))
+classes_2 = get_class_files(test.workpath('class2'))
+classes_3 = get_class_files(test.workpath('class3'))
+classes_4 = get_class_files(test.workpath('class4'))
+classes_5 = get_class_files(test.workpath('class5'))
+
+expect_1 = [
+    test.workpath('class1', 'com', 'other', 'Example2.class'),
+    test.workpath('class1', 'com', 'sub', 'foo', 'Example1.class'),
+    test.workpath('class1', 'com', 'sub', 'foo', 'Example3.class'),
+]
+
+expect_2 = [
+    test.workpath('class2', 'com', 'other', 'Example5.class'),
+    test.workpath('class2', 'com', 'sub', 'bar', 'Example4.class'),
+    test.workpath('class2', 'com', 'sub', 'bar', 'Example6.class'),
+]
+
+expect_3 = [
+    test.workpath('class3', 'Empty.class'),
+    test.workpath('class3', 'Example7.class'),
+    test.workpath('class3', 'Listener.class'),
+    test.workpath('class3', 'Private$1.class'),
+    test.workpath('class3', 'Private.class'),
+    test.workpath('class3', 'Test$1$1.class'),
+    test.workpath('class3', 'Test$1.class'),
+    test.workpath('class3', 'Test$Inner$1.class'),
+    test.workpath('class3', 'Test$Inner.class'),
+    test.workpath('class3', 'Test.class'),
+]
+
+expect_4 = [
+    test.workpath('class4', 'NestedExample$1$1.class'),
+    test.workpath('class4', 'NestedExample$1.class'),
+    test.workpath('class4', 'NestedExample.class'),
+]
+
+expect_5 = [
+    test.workpath('class5', 'Foo.class'),
+    test.workpath('class5', 'TestSCons.class'),
+]
+
+failed = None
+
+def classes_must_match(dir, expect, got):
+    if expect != got:
+        sys.stderr.write("Expected the following class files in '%s':\n" % dir)
+        for c in expect:
+            sys.stderr.write('    %s\n' % c)
+        sys.stderr.write("Got the following class files in '%s':\n" % dir)
+        for c in got:
+            sys.stderr.write('    %s\n' % c)
+        failed = 1
+
+classes_must_match('class1', expect_1, classes_1)
+classes_must_match('class2', expect_2, classes_2)
+classes_must_match('class3', expect_3, classes_3)
+classes_must_match('class4', expect_4, classes_4)
+
+test.fail_test(failed)
+
+test.up_to_date(options='--debug=explain', arguments = '.')
+
+test.pass_test()

test/Java/Java-1.6.py

+#!/usr/bin/env python
+#
+# __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__"
+
+"""
+Test Java compilation with a live Java 1.6 "javac" compiler.
+"""
+
+import os
+import os.path
+import string
+import sys
+import TestSCons
+
+_python_ = TestSCons._python_
+
+test = TestSCons.TestSCons()
+
+ENV = test.java_ENV()
+ENV['PATH'] = '/usr/lib/jvm/java-6-sun-1.6.0.00/bin' + os.pathsep + os.environ['PATH']
+
+if test.detect_tool('javac', ENV=ENV):
+    where_javac = test.detect('JAVAC', 'javac', ENV=ENV)
+else:
+    where_javac = test.where_is('javac')
+if not where_javac:
+    test.skip_test("Could not find Java javac, skipping test(s).\n")
+
+
+
+test.write('SConstruct', """
+env = Environment(tools = ['javac'],
+                  JAVAVERSION = '1.6',
+                  JAVAC = r'%(where_javac)s')
+env.Java(target = 'class1', source = 'com/sub/foo')
+env.Java(target = 'class2', source = 'com/sub/bar')
+env.Java(target = 'class3', source = ['src1', 'src2'])
+env.Java(target = 'class4', source = ['src4'])
+env.Java(target = 'class5', source = ['src5'])
+""" % locals())
+
+test.subdir('com',
+            ['com', 'sub'],
+            ['com', 'sub', 'foo'],
+            ['com', 'sub', 'bar'],
+            'src1',
+            'src2',
+            'src4',
+            'src5')
+
+test.write(['com', 'sub', 'foo', 'Example1.java'], """\
+package com.sub.foo;
+
+public class Example1
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['com', 'sub', 'foo', 'Example2.java'], """\
+package com.other;
+
+public class Example2
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['com', 'sub', 'foo', 'Example3.java'], """\
+package com.sub.foo;
+
+public class Example3
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['com', 'sub', 'bar', 'Example4.java'], """\
+package com.sub.bar;
+
+public class Example4
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['com', 'sub', 'bar', 'Example5.java'], """\
+package com.other;
+
+public class Example5
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['com', 'sub', 'bar', 'Example6.java'], """\
+package com.sub.bar;
+
+public class Example6
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+test.write(['src1', 'Example7.java'], """\
+public class Example7
+{
+
+     public static void main(String[] args)
+     {
+
+     }
+
+}
+""")
+
+# Acid-test file for parsing inner Java classes, courtesy Chad Austin.
+test.write(['src2', 'Test.java'], """\
+class Empty {
+}
+
+interface Listener {
+  public void execute();
+}
+
+public
+class
+Test {
+  class Inner {
+    void go() {
+      use(new Listener() {
+        public void execute() {
+          System.out.println("In Inner");
+        }
+      });
+    }
+    String s1 = "class A";
+    String s2 = "new Listener() { }";
+    /* class B */
+    /* new Listener() { } */
+  }
+
+  public static void main(String[] args) {
+    new Test().run();
+  }
+
+  void run() {
+    use(new Listener() {
+      public void execute() {
+        use(new Listener( ) {
+          public void execute() {
+            System.out.println("Inside execute()");
+          }
+        });
+      }
+    });
+
+    new Inner().go();
+  }
+
+  void use(Listener l) {
+    l.execute();
+  }
+}
+
+class Private {
+  void run() {
+    new Listener() {
+      public void execute() {
+      }
+    };
+  }
+}
+""")
+
+# Testing nested anonymous inner classes, courtesy Brandon Mansfield.
+test.write(['src4', 'NestedExample.java'], """\
+// import java.util.*;
+
+public class NestedExample
+{
+        public NestedExample()
+        {
+                Thread t = new Thread() {
+                        public void start()
+                        {
+                                Thread t = new Thread() {
+                                        public void start()
+                                        {
+                                                try {Thread.sleep(200);}
+                                                catch (Exception e) {}
+                                        }
+                                };
+                                while (true)
+                                {
+                                        try {Thread.sleep(200);}
+                                        catch (Exception e) {}
+                                }
+                        }
+                };
+        }
+
+
+        public static void main(String argv[])
+        {
+                NestedExample e = new NestedExample();
+        }
+}
+""")
+
+# Test not finding an anonymous class when the second token after a
+# "new" is a closing brace.  This duplicates a test from the unit tests,
+# but lets us make sure that we correctly determine that everything is
+# up-to-date after the build.
+test.write(['src5', 'TestSCons.java'], """\
+class TestSCons {
+    public static void main(String[] args) {
+        Foo[] fooArray = new Foo[] { new Foo() };
+    }
+}
+
+class Foo { }
+""")
+
+test.run(arguments = '.')
+
+def get_class_files(dir):
+    def find_class_files(arg, dirname, fnames):
+        for fname in fnames:
+            if fname[-6:] == '.class':
+                arg.append(os.path.join(dirname, fname))
+    result = []
+    os.path.walk(dir, find_class_files, result)
+    result.sort()
+    return result
+
+classes_1 = get_class_files(test.workpath('class1'))
+classes_2 = get_class_files(test.workpath('class2'))
+classes_3 = get_class_files(test.workpath('class3'))
+classes_4 = get_class_files(test.workpath('class4'))
+classes_5 = get_class_files(test.workpath('class5'))
+
+expect_1 = [
+    test.workpath('class1', 'com', 'other', 'Example2.class'),
+    test.workpath('class1', 'com', 'sub', 'foo', 'Example1.class'),
+    test.workpath('class1', 'com', 'sub', 'foo', 'Example3.class'),
+]
+
+expect_2 = [
+    test.workpath('class2', 'com', 'other', 'Example5.class'),
+    test.workpath('class2', 'com', 'sub', 'bar', 'Example4.class'),
+    test.workpath('class2', 'com', 'sub', 'bar', 'Example6.class'),
+]
+
+expect_3 = [
+    test.workpath('class3', 'Empty.class'),
+    test.workpath('class3', 'Example7.class'),
+    test.workpath('class3', 'Listener.class'),
+    test.workpath('class3', 'Private$1.class'),
+    test.workpath('class3', 'Private.class'),
+    test.workpath('class3', 'Test$1$1.class'),
+    test.workpath('class3', 'Test$1.class'),
+    test.workpath('class3', 'Test$Inner$1.class'),
+    test.workpath('class3', 'Test$Inner.class'),
+    test.workpath('class3', 'Test.class'),
+]
+
+expect_4 = [
+    test.workpath('class4', 'NestedExample$1$1.class'),
+    test.workpath('class4', 'NestedExample$1.class'),
+    test.workpath('class4', 'NestedExample.class'),
+]
+
+expect_5 = [
+    test.workpath('class5', 'Foo.class'),
+    test.workpath('class5', 'TestSCons.class'),
+]
+
+failed = None
+
+def classes_must_match(dir, expect, got):
+    if expect != got:
+        sys.stderr.write("Expected the following class files in '%s':\n" % dir)
+        for c in expect:
+            sys.stderr.write('    %s\n' % c)
+        sys.stderr.write("Got the following class files in '%s':\n" % dir)
+        for c in got:
+            sys.stderr.write('    %s\n' % c)
+        failed = 1
+
+classes_must_match('class1', expect_1, classes_1)
+classes_must_match('class2', expect_2, classes_2)
+classes_must_match('class3', expect_3, classes_3)
+classes_must_match('class4', expect_4, classes_4)
+
+test.fail_test(failed)
+
+test.up_to_date(options='--debug=explain', arguments = '.')
+
+test.pass_test()

test/Java/live.py

-#!/usr/bin/env python
-#
-# __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__"
-
-"""
-Test Java compilation with a live "javac" compiler.
-"""
-
-import os
-import os.path
-import string
-import sys
-import TestSCons
-
-_python_ = TestSCons._python_
-
-test = TestSCons.TestSCons()
-
-ENV = test.java_ENV()
-
-if test.detect_tool('javac', ENV=ENV):
-    where_javac = test.detect('JAVAC', 'javac', ENV=ENV)
-else:
-    where_javac = test.where_is('javac')
-if not where_javac:
-    test.skip_test("Could not find Java javac, skipping test(s).\n")
-
-
-
-test.write('SConstruct', """
-env = Environment(tools = ['javac'],
-                  JAVAC = r'%(where_javac)s')
-env.Java(target = 'class1', source = 'com/sub/foo')
-env.Java(target = 'class2', source = 'com/sub/bar')
-env.Java(target = 'class3', source = ['src1', 'src2'])
-env.Java(target = 'class4', source = ['src4'])
-env.Java(target = 'class5', source = ['src5'])
-""" % locals())
-
-test.subdir('com',
-            ['com', 'sub'],
-            ['com', 'sub', 'foo'],
-            ['com', 'sub', 'bar'],
-            'src1',
-            'src2',
-            'src4',
-            'src5')
-
-test.write(['com', 'sub', 'foo', 'Example1.java'], """\
-package com.sub.foo;
-
-public class Example1
-{
-
-     public static void main(String[] args)
-     {
-
-     }
-
-}
-""")
-
-test.write(['com', 'sub', 'foo', 'Example2.java'], """\
-package com.other;
-
-public class Example2
-{
-
-     public static void main(String[] args)
-     {
-
-     }
-
-}
-""")
-
-test.write(['com', 'sub', 'foo', 'Example3.java'], """\
-package com.sub.foo;
-
-public class Example3
-{
-
-     public static void main(String[] args)
-     {
-
-     }
-
-}
-""")
-
-test.write(['com', 'sub', 'bar', 'Example4.java'], """\
-package com.sub.bar;
-
-public class Example4
-{
-
-     public static void main(String[] args)
-     {
-
-     }
-
-}
-""")
-
-test.write(['com', 'sub', 'bar', 'Example5.java'], """\
-package com.other;
-
-public class Example5
-{
-
-     public static void main(String[] args)
-     {
-
-     }
-
-}
-""")
-
-test.write(['com', 'sub', 'bar', 'Example6.java'], """\
-package com.sub.bar;
-
-public class Example6
-{
-
-     public static void main(String[] args)
-     {
-
-     }
-
-}
-""")
-
-test.write(['src1', 'Example7.java'], """\
-public class Example7
-{
-
-     public static void main(String[] args)
-     {
-
-     }
-
-}
-""")
-
-# Acid-test file for parsing inner Java classes, courtesy Chad Austin.
-test.write(['src2', 'Test.java'], """\
-class Empty {
-}
-
-interface Listener {
-  public void execute();
-}
-
-public
-class
-Test {
-  class Inner {
-    void go() {
-      use(new Listener() {
-        public void execute() {
-          System.out.println("In Inner");
-        }
-      });
-    }
-    String s1 = "class A";
-    String s2 = "new Listener() { }";
-    /* class B */
-    /* new Listener() { } */
-  }
-
-  public static void main(String[] args) {
-    new Test().run();
-  }
-
-  void run() {
-    use(new Listener() {
-      public void execute() {
-        use(new Listener( ) {
-          public void execute() {
-            System.out.println("Inside execute()");
-          }
-        });
-      }
-    });
-
-    new Inner().go();
-  }
-
-  void use(Listener l) {
-    l.execute();
-  }
-}
-
-class Private {
-  void run() {
-    new Listener() {
-      public void execute() {
-      }
-    };
-  }
-}
-""")
-
-# Testing nested anonymous inner classes, courtesy Brandon Mansfield.
-test.write(['src4', 'NestedExample.java'], """\
-// import java.util.*;
-
-public class NestedExample
-{
-        public NestedExample()
-        {
-                Thread t = new Thread() {
-                        public void start()
-                        {
-                                Thread t = new Thread() {
-                                        public void start()
-                                        {
-                                                try {Thread.sleep(200);}
-                                                catch (Exception e) {}
-                                        }
-                                };
-                                while (true)
-                                {
-                                        try {Thread.sleep(200);}
-                                        catch (Exception e) {}
-                                }
-                        }
-                };
-        }
-
-
-        public static void main(String argv[])
-        {
-                NestedExample e = new NestedExample();
-        }
-}
-""")
-
-# Test not finding an anonymous class when the second token after a
-# "new" is a closing brace.  This duplicates a test from the unit tests,
-# but lets us make sure that we correctly determine that everything is
-# up-to-date after the build.
-test.write(['src5', 'TestSCons.java'], """\
-class TestSCons {
-    public static void main(String[] args) {
-        Foo[] fooArray = new Foo[] { new Foo() };
-    }
-}
-
-class Foo { }
-""")
-
-test.run(arguments = '.')
-
-def get_class_files(dir):
-    def find_class_files(arg, dirname, fnames):
-        for fname in fnames:
-            if fname[-6:] == '.class':
-                arg.append(os.path.join(dirname, fname))
-    result = []
-    os.path.walk(dir, find_class_files, result)
-    result.sort()
-    return result
-
-classes_1 = get_class_files(test.workpath('class1'))
-classes_2 = get_class_files(test.workpath('class2'))
-classes_3 = get_class_files(test.workpath('class3'))
-classes_4 = get_class_files(test.workpath('class4'))
-classes_5 = get_class_files(test.workpath('class5'))
-
-expect_1 = [
-    test.workpath('class1', 'com', 'other', 'Example2.class'),
-    test.workpath('class1', 'com', 'sub', 'foo', 'Example1.class'),
-    test.workpath('class1', 'com', 'sub', 'foo', 'Example3.class'),
-]
-
-expect_2 = [
-    test.workpath('class2', 'com', 'other', 'Example5.class'),
-    test.workpath('class2', 'com', 'sub', 'bar', 'Example4.class'),
-    test.workpath('class2', 'com', 'sub', 'bar', 'Example6.class'),
-]
-
-expect_3 = [
-    test.workpath('class3', 'Empty.class'),
-    test.workpath('class3', 'Example7.class'),
-    test.workpath('class3', 'Listener.class'),
-    test.workpath('class3', 'Private$1.class'),
-    test.workpath('class3', 'Private.class'),
-    test.workpath('class3', 'Test$1.class'),
-    test.workpath('class3', 'Test$2.class'),
-    test.workpath('class3', 'Test$3.class'),
-    test.workpath('class3', 'Test$Inner.class'),
-    test.workpath('class3', 'Test.class'),
-]
-
-expect_4 = [
-    test.workpath('class4', 'NestedExample$1.class'),
-    test.workpath('class4', 'NestedExample$2.class'),
-    test.workpath('class4', 'NestedExample.class'),
-]
-
-expect_5 = [
-    test.workpath('class5', 'Foo.class'),
-    test.workpath('class5', 'TestSCons.class'),
-]
-
-def classes_must_match(dir, expect, got):
-    if expect != got:
-        sys.stderr.write("Expected the following class files in '%s':\n" % dir)
-        for c in expect:
-            sys.stderr.write('    %s\n' % c)
-        sys.stderr.write("Got the following class files in '%s':\n" % dir)
-        for c in got:
-            sys.stderr.write('    %s\n' % c)
-        test.fail_test()
-
-classes_must_match('class1', expect_1, classes_1)
-classes_must_match('class2', expect_2, classes_2)
-classes_must_match('class3', expect_3, classes_3)
-classes_must_match('class4', expect_4, classes_4)
-
-test.up_to_date(arguments = '.')
-
-test.pass_test()

test/SWIG/SWIGOUTDIR.py

+#!/usr/bin/env python
+#
+# __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__"
+
+"""
+Verify that use of the $SWIGOUTDIR variable causes SCons to recognize
+that Java files are created in the specified output directory.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.write(['SConstruct'], """\
+env = Environment(tools = ['default', 'swig'])
+
+Java_foo_interface = env.SharedLibrary(
+    'Java_foo_interface', 
+    'Java_foo_interface.i', 
+    SWIGOUTDIR = 'java/build',
+    SWIGFLAGS = '-c++ -java -Wall',
+    SWIGCXXFILESUFFIX = "_wrap.cpp")
+""" % locals())
+
+test.write('Java_foo_interface.i', """\
+%module foopack
+""")
+
+# SCons should realize that it needs to create the java/build
+# subdirectory to hold the generate .java files.
+test.run(arguments = '.')
+
+# SCons should remove the built .java files.
+test.run(arguments = '-c java/build/foopack.java java/build/foopackJNI.java')
+
+test.must_not_exist('java/build/foopackJNI.java')
+test.must_not_exist('java/build/foopack.java') 
+
+# SCons should realize it needs to rebuild the removed .java files.
+test.not_up_to_date(arguments = '.')
+
+
+
+test.pass_test()

test/SWIG/implicit-dependencies.py

     python = TestSCons.python
     _python_ = TestSCons._python_
 
-# swig-python expects specific filenames.
-# the platform specific suffix won't necessarily work.
-if sys.platform == 'win32':
-    _dll = '.dll'
-else:
-    _dll   = '.so' 
-
 test = TestSCons.TestSCons()
 
 swig = test.where_is('swig')
 
 version = sys.version[:3] # see also sys.prefix documentation
 
-# handle testing on other platforms:
-ldmodule_prefix = '_'
-
-frameworks = ''
-platform_sys_prefix = sys.prefix
-if sys.platform == 'darwin':
-    # OS X has a built-in Python but no static libpython
-    # so you should link to it using apple's 'framework' scheme.
-    # (see top of file for further explanation)
-    frameworks = '-framework Python'
-    platform_sys_prefix = '/System/Library/Frameworks/Python.framework/Versions/%s/' % version
 
 test.write("dependency.i", """\
 %module dependency
 """)
 
 test.write('SConstruct', """
-foo = Environment(SWIGFLAGS='-python',
-                  CPPPATH='%(platform_sys_prefix)s/include/python%(version)s/',
-                  LDMODULEPREFIX='%(ldmodule_prefix)s',
-                  LDMODULESUFFIX='%(_dll)s',
-                  FRAMEWORKSFLAGS='%(frameworks)s',
-                  )
-
+foo = Environment(SWIGFLAGS='-python')
 swig = foo.Dictionary('SWIG')
 bar = foo.Clone(SWIG = r'%(_python_)s wrapper.py ' + swig)
 foo.CFile(target = 'dependent', source = ['dependent.i'])

test/SWIG/live.py

                   FRAMEWORKSFLAGS='%(frameworks)s',
                   )
 
+import sys
+if sys.version[0] == '1':
+    # SWIG requires the -classic flag on pre-2.0 Python versions.
+    foo.Append(SWIGFLAGS = ' -classic')
+
 swig = foo.Dictionary('SWIG')
 bar = foo.Clone(SWIG = r'%(_python_)s wrapper.py ' + swig)
 foo.LoadableModule(target = 'foo', source = ['foo.c', 'foo.i'])

test/SWIG/remove-modules.py

                   FRAMEWORKSFLAGS='%(frameworks)s',
                   )
 
+import sys
+if sys.version[0] == '1':
+    # SWIG requires the -classic flag on pre-2.0 Python versions.
+    foo.Append(SWIGFLAGS = ' -classic')
+
 foo.LoadableModule(target = 'modulename', source = ['module.i'])
 """ % locals())
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.