Get the source_scanner from the target node, not the source node. (Kevin Quick)
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 24 Sep 2004 17:15:44 +0000 (17:15 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 24 Sep 2004 17:15:44 +0000 (17:15 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@1099 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/Node/NodeTests.py
src/engine/SCons/Node/__init__.py
test/Scanner.py

index 8e761e9e3849aad4f4e454462d08791b2d48d24b..4780aedbabaff2584a553fd9bfcfcc37f61d3672 100644 (file)
@@ -151,6 +151,9 @@ RELEASE 0.97 - XXX
   - Don't retrieve files from a CacheDir, but report what would happen,
     when the -n option is used.
 
+  - Use the source_scanner from the target Node, not the source node
+    itself.
+
   From Christoph Wiedemann:
 
   - Add an Environment.SetDefault() method that only sets values if
index 138b00bc240934242793a43ba2ee6e8643eceed3..e380318e7d69eb083c98a0dfea0e235c353200b5 100644 (file)
@@ -709,8 +709,8 @@ class NodeTestCase(unittest.TestCase):
         s = target.get_source_scanner(source)
         assert s is ts1, s
 
-        source.builder = Builder()
-        source.builder.source_scanner = ts2
+        target.builder = Builder()
+        target.builder.source_scanner = ts2
         s = target.get_source_scanner(source)
         assert s is ts2, s
 
index 47139fcd1b32fa8345e19e9e4d2a5bbc8f5fe661..6e7379ce3f903c982b54a52fc813e6644a68e647 100644 (file)
@@ -376,7 +376,7 @@ class Node:
         """
         Turn a cache implicit dependency path into a node.
         This is called so many times that doing caching
-        here is a significant perforamnce boost.
+        here is a significant performance boost.
         """
         try:
             return self.implicit_factory_cache[path]
@@ -394,7 +394,7 @@ class Node:
         if self.source_scanner:
             return self.source_scanner
         try:
-            scanner = node.builder.source_scanner
+            scanner = self.builder.source_scanner
             if scanner:
                 return scanner
         except AttributeError:
@@ -789,7 +789,7 @@ class Node:
         if self.is_derived() and self.env:
             env = self.get_build_env()
             for s in self.sources:
-                scanner = s.get_source_scanner(self)
+                scanner = self.get_source_scanner(s)
                 def f(node, env=env, scanner=scanner, target=self):
                     return node.get_found_includes(env, scanner, target)
                 return SCons.Util.render_tree(s, f, 1)
@@ -827,7 +827,7 @@ class Node:
         generator is being called to generate a signature for the
         command line, which determines if we should rebuild or not.
 
-        Such command generators shoud use this method in preference
+        Such command generators should use this method in preference
         to str(Node) when converting a Node to a string, passing
         in the for_signature parameter, such that we will call
         Node.for_signature() or str(Node) properly, depending on whether
index e1d52372619f8333eaa072f2b19ab5a28b85c887..281475972944bc75496e2976681eea71d682c0ed 100644 (file)
@@ -41,6 +41,10 @@ def process(infp, outfp):
         if line[:8] == 'include ':
             file = line[8:-1]
             process(open(file, 'rb'), outfp)
+        elif line[:8] == 'getfile ':
+            outfp.write('include ')
+            outfp.write(line[8:])
+            # note: converted, but not acted upon
         else:
             outfp.write(line)
 
@@ -61,7 +65,7 @@ import re
 
 include_re = re.compile(r'^include\s+(\S+)$', re.M)
 
-def kfile_scan(node, env, target, arg):
+def kfile_scan(node, env, scanpaths, arg):
     contents = node.get_contents()
     includes = include_re.findall(contents)
     return includes
@@ -82,18 +86,53 @@ k2scan = env.Scanner(name = 'k2',
                      argument = None,
                      skeys = ['.k2'])
 
+##########################################################
+# Test scanner as found automatically from the environment
+# (backup_source_scanner)
+
 env = Environment()
 env.Append(SCANNERS = kscan)
 
-env.Command('foo', 'foo.k', r'%s build.py $SOURCES $TARGET')
+env.Command('foo', 'foo.k', r'%(python)s build.py $SOURCES $TARGET')
+
+##########################################################
+# Test resetting the environment scanners (and specifying as a list).
 
 env2 = env.Copy()
 env2.Append(SCANNERS = [k2scan])
-env2.Command('junk', 'junk.k2', r'%s build.py $SOURCES $TARGET')
+env2.Command('junk', 'junk.k2', r'%(python)s build.py $SOURCES $TARGET')
 
-bar = env.Command('bar', 'bar.in', r'%s build.py $SOURCES  $TARGET')
+##########################################################
+# Test specifying a specific source scanner for a target Node
+
+bar = env.Command('bar', 'bar.in', r'%(python)s build.py $SOURCES  $TARGET')
 bar[0].source_scanner = kscan
-""" % (python, python, python))
+
+##########################################################
+# Test specifying a source scanner for a Builder that gets
+# automatically applied to targets generated from that Builder
+
+import string
+
+def blork(env, target, source):
+    open(str(target[0]), 'wb').write(
+        string.replace(source[0].get_contents(), 'getfile', 'MISSEDME'))
+
+kbld = Builder(action=r'%(python)s build.py $SOURCES $TARGET',
+               src_suffix='.lork',
+               suffix='.blork',
+               source_scanner=kscan)
+blorkbld = Builder(action=blork,
+                   src_suffix='.blork',
+                   suffix='.ork')
+
+env.Append(BUILDERS={'BLORK':blorkbld, 'KB':kbld})
+
+blork = env.KB('moo.lork')
+ork = env.BLORK(blork)
+Alias('make_ork', ork)
+
+""" % {'python': python})
 
 test.write('foo.k', 
 """foo.k 1 line 1
@@ -116,41 +155,80 @@ junk.k2 1 line 3
 include zzz
 """)
 
+test.write('moo.lork',
+"""include xxx
+moo.lork 1 line 2
+include yyy
+moo.lork 1 line 4
+include moo.inc
+""")
+
+test.write('moo.inc',
+"""getfile zzz
+""")
+
 test.write('xxx', "xxx 1\n")
 test.write('yyy', "yyy 1\n")
 test.write('zzz', "zzz 1\n")
 
-test.run(arguments = '.')
+test.run(arguments = '.',
+         stdout=test.wrap_stdout("""\
+%(python)s build.py bar.in bar
+%(python)s build.py foo.k foo
+%(python)s build.py junk.k2 junk
+%(python)s build.py moo.lork moo.blork
+blork(["moo.ork"], ["moo.blork"])
+""" % {'python':python}))
 
 test.must_match('foo', "foo.k 1 line 1\nxxx 1\nyyy 1\nfoo.k 1 line 4\n")
 test.must_match('bar', "yyy 1\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 1\n")
 test.must_match('junk', "yyy 1\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 1\n")
+test.must_match('moo.ork', "xxx 1\nmoo.lork 1 line 2\nyyy 1\nmoo.lork 1 line 4\ninclude zzz\n")
 
 test.up_to_date(arguments = '.')
 
 test.write('xxx', "xxx 2\n")
 
-test.run(arguments = '.')
+test.run(arguments = '.',
+         stdout=test.wrap_stdout("""\
+%(python)s build.py foo.k foo
+%(python)s build.py moo.lork moo.blork
+blork(["moo.ork"], ["moo.blork"])
+""" % {'python':python}))
 
 test.must_match('foo', "foo.k 1 line 1\nxxx 2\nyyy 1\nfoo.k 1 line 4\n")
 test.must_match('bar', "yyy 1\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 1\n")
 test.must_match('junk', "yyy 1\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 1\n")
+test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 1\nmoo.lork 1 line 4\ninclude zzz\n")
 
 test.write('yyy', "yyy 2\n")
 
-test.run(arguments = '.')
+test.run(arguments = '.',
+         stdout=test.wrap_stdout("""\
+%(python)s build.py bar.in bar
+%(python)s build.py foo.k foo
+%(python)s build.py junk.k2 junk
+%(python)s build.py moo.lork moo.blork
+blork(["moo.ork"], ["moo.blork"])
+""" % {'python':python}))
 
 test.must_match('foo', "foo.k 1 line 1\nxxx 2\nyyy 2\nfoo.k 1 line 4\n")
 test.must_match('bar', "yyy 2\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 1\n")
 test.must_match('junk', "yyy 2\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 1\n")
+test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 2\nmoo.lork 1 line 4\ninclude zzz\n")
 
 test.write('zzz', "zzz 2\n")
 
-test.run(arguments = '.')
+test.run(arguments = '.',
+         stdout=test.wrap_stdout("""\
+%(python)s build.py bar.in bar
+%(python)s build.py junk.k2 junk
+""" % {'python':python}))
 
 test.must_match('foo', "foo.k 1 line 1\nxxx 2\nyyy 2\nfoo.k 1 line 4\n")
 test.must_match('bar', "yyy 2\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 2\n")
 test.must_match('junk', "yyy 2\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 2\n")
+test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 2\nmoo.lork 1 line 4\ninclude zzz\n")
 
 test.up_to_date(arguments = 'foo')