From 6069f3ce2807d9915f74f5d5bcca7300ed7616fd Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Wed, 15 Dec 2004 04:10:39 +0000 Subject: Use the right scanner if the same source file is used for targets in two different environments. --- src/CHANGES.txt | 6 ++++ src/engine/SCons/Node/FS.py | 5 +-- src/engine/SCons/Node/FSTests.py | 8 +++++ test/Scanner.py | 78 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 2 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index fe0f879..41a96ce 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -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. diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index bc9e682..1af739f 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -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 diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index 747fdf1..5ed377c 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -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: diff --git a/test/Scanner.py b/test/Scanner.py index 828d198..7936e59 100644 --- a/test/Scanner.py +++ b/test/Scanner.py @@ -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() -- cgit v0.12