Use the right scanner if the same source file is used for targets in two different...
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 15 Dec 2004 04:10:39 +0000 (04:10 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 15 Dec 2004 04:10:39 +0000 (04:10 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@1187 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/Node/FS.py
src/engine/SCons/Node/FSTests.py
test/Scanner.py

index fe0f879f194a66d1bb31152e2df37ffc4c5e9db6..41a96cec93b6357429b87d53c0c159b6ea7f0bdd 100644 (file)
@@ -330,6 +330,12 @@ RELEASE 0.97 - XXX
 
   - Fix command-line expansion of Python Value Nodes.
 
+  - Internal cleanups:  Remove an unnecessary scan argument.  Associate
+    Scanners only with Builders, not nodes.
+
+  - Use the correct scanner if the same source file is used for targets in
+    two different environments with the same path but different scanners.
+
   From Levi Stephen:
 
   - Allow $JARCHDIR to be expanded to other construction variables.
index bc9e68290ba3e43c381b3a325e95a6e7befacb79..1af739f2958f85d121793bf301aabe1b84e576c6 100644 (file)
@@ -1497,11 +1497,12 @@ class File(Base):
             path = scanner.path(env, target.cwd)
             target.scanner_paths[scanner] = path
 
+        key = str(id(env)) + '|' + str(id(scanner)) + '|' + string.join(map(str,path), ':')
         try:
-            includes = self.found_includes[path]
+            includes = self.found_includes[key]
         except KeyError:
             includes = scanner(self, env, path)
-            self.found_includes[path] = includes
+            self.found_includes[key] = includes
 
         return includes
 
index 747fdf117ce7ced113f70bc229de86013c67d7be..5ed377cebc63830ee69e2eabb0af065a1cd4396e 100644 (file)
@@ -909,6 +909,14 @@ class FSTestCase(unittest.TestCase):
         assert deps == [xyz], deps
         assert s.call_count == 2, s.call_count
 
+        env2 = Environment()
+
+        deps = f12.get_found_includes(env2, s, t1)
+        assert deps == [xyz], deps
+        assert s.call_count == 3, s.call_count
+
+
+
         # Make sure we can scan this file even if the target isn't
         # a file that has a scanner (it might be an Alias, e.g.).
         class DummyNode:
index 828d198081fbeafff30ea8b4cc32ce4a9c26cd80..7936e59ca01bd7a94e0abde0856d30d9251ed022 100644 (file)
@@ -232,4 +232,82 @@ test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 2\nmoo.lork 1 line 4\n
 
 test.up_to_date(arguments = 'foo')
 
+# Now make sure that using the same source file in different
+# environments will get the proper scanner for the environment being
+# used.
+
+test.write('SConstruct2', """
+import re
+
+include_re = re.compile(r'^include\s+(\S+)$', re.M)
+input_re = re.compile(r'^input\s+(\S+)$', re.M)
+
+scan1 = Scanner(name = 'Include',
+                function = lambda N,E,P,A: A.findall(N.get_contents()),
+                argument = include_re,
+                skeys = ['.inp'])
+
+scan2 = Scanner(name = 'Input',
+                function = lambda N,E,P,A: A.findall(N.get_contents()),
+                argument = input_re,
+                skeys = ['.inp'])
+
+env1 = Environment()
+env2 = Environment()
+
+env1.Append(SCANNERS=scan1)
+env2.Append(SCANNERS=scan2)
+
+env1.Command('frog.1', 'frog.inp', r'%(python)s do_incl.py $TARGET $SOURCES')
+env2.Command('frog.2', 'frog.inp', r'%(python)s do_inp.py $TARGET $SOURCES')
+
+"""%{'python':python})
+
+process = r"""
+import sys
+
+def process(infp, outfp):
+    prefix = '%(command)s '
+    l = len(prefix)
+    for line in infp.readlines():
+        if line[:l] == prefix:
+            process(open(line[l:-1], 'rb'), outfp)
+        else:
+            outfp.write(line)
+
+process(open(sys.argv[2], 'rb'),
+        open(sys.argv[1], 'wb'))
+sys.exit(0)
+"""
+
+test.write('do_incl.py', process % { 'command' : 'include' })
+test.write('do_inp.py', process % { 'command' : 'input' })
+
+test.write('frog.inp', """\
+include sound1
+input sound2
+""")
+
+test.write('sound1', 'croak\n')
+test.write('sound2', 'ribbet\n')
+
+test.run(arguments='-f SConstruct2 .',
+stdout=test.wrap_stdout("""\
+%(python)s do_incl.py frog.1 frog.inp
+%(python)s do_inp.py frog.2 frog.inp
+""" % { 'python':python }))
+
+test.must_match('frog.1', 'croak\ninput sound2\n')
+test.must_match('frog.2', 'include sound1\nribbet\n')
+
+test.write('sound2', 'rudeep\n')
+
+test.run(arguments='-f SConstruct2 .',
+stdout=test.wrap_stdout("""\
+%(python)s do_inp.py frog.2 frog.inp
+""" % { 'python':python }))
+
+test.must_match('frog.1', 'croak\ninput sound2\n')
+test.must_match('frog.2', 'include sound1\nrudeep\n')
+
 test.pass_test()