diff options
author | Steven Knight <knight@baldmt.com> | 2004-03-23 05:23:20 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2004-03-23 05:23:20 (GMT) |
commit | 6cb2c3b91699f1221810f3d1a20bcf3fc6c4e148 (patch) | |
tree | 9f6d601ec3b50d626b2612a2230c81050d235d5e | |
parent | 837e39eaf030cafcf619ddb390cc8a5854784185 (diff) | |
download | SCons-6cb2c3b91699f1221810f3d1a20bcf3fc6c4e148.zip SCons-6cb2c3b91699f1221810f3d1a20bcf3fc6c4e148.tar.gz SCons-6cb2c3b91699f1221810f3d1a20bcf3fc6c4e148.tar.bz2 |
Add a --debug= option to print commands before substitution. (Gary Oberbrunner)
-rw-r--r-- | doc/man/scons.1 | 19 | ||||
-rw-r--r-- | src/engine/SCons/Action.py | 159 | ||||
-rw-r--r-- | src/engine/SCons/ActionTests.py | 186 | ||||
-rw-r--r-- | src/engine/SCons/Script/__init__.py | 5 | ||||
-rw-r--r-- | test/option--debug.py | 153 |
5 files changed, 399 insertions, 123 deletions
diff --git a/doc/man/scons.1 b/doc/man/scons.1 index c12595e..3f8b282 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -494,11 +494,20 @@ This only works when run under Python 2.1 or later. Re-run SCons under the control of the .RI pdb Python debugger. -The ---debug=pdb -argument will be stripped from the command-line, -but all other arguments will be passed in-order -to the SCons invocation run by the debugger. +.EE + +.TP +--debug=presub +Print the raw command line used to build each target +before the construction environment variables are substituted. +Also shows which targets are being built by this command. +Output looks something like this: +.ES +$ scons --debug=presub +Building myprog.o with action(s): + $SHCC $SHCCFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES +... +.EE .TP --debug=time diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index 6759b02..c074de4 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -1,6 +1,54 @@ -"""engine.SCons.Action - -XXX +"""SCons.Action + +This encapsulates information about executing any sort of action that +can build one or more target Nodes (typically files) from one or more +source Nodes (also typically files) given a specific Environment. + +The base class here is ActionBase. The base class supplies just a few +OO utility methods and some generic methods for displaying information +about an Action in response to the various commands that control printing. + +The heavy lifting is handled by subclasses for the different types of +actions we might execute: + + CommandAction + CommandGeneratorAction + FunctionAction + ListAction + +The subclasses supply the following public interface methods used by +other modules: + + __call__() + THE public interface, "calling" an Action object executes the + command or Python function. This also takes care of printing + a pre-substitution command for debugging purposes. + + get_contents() + Fetches the "contents" of an Action for signature calculation. + This is what the Sig/*.py subsystem uses to decide if a target + needs to be rebuilt because its action changed. + +Subclasses also supply the following methods for internal use within +this module: + + __str__() + Returns a string representation of the Action *without* command + substitution. This is used by the __call__() methods to display + the pre-substitution command whenever the --debug=presub option + is used. + + strfunction() + Returns a substituted string representation of the Action. + This is used by the ActionBase.show() command to display the + command/function that will be executed to generate the target(s). + + _execute() + The internal method that really, truly, actually handles the + execution of a command or Python function. This is used so + that the __call__() methods can take care of displaying any + pre-substitution representations, and *then* execute an action + without worrying about the specific Actions involved. """ @@ -44,8 +92,9 @@ class _Null: _null = _Null -print_actions = 1; -execute_actions = 1; +print_actions = 1 +execute_actions = 1 +print_actions_presub = 0 default_ENV = None @@ -145,9 +194,18 @@ class ActionBase: def __cmp__(self, other): return cmp(self.__dict__, other.__dict__) - def show(self, string): + def show(self, s): if print_actions: - sys.stdout.write(string + '\n') + sys.stdout.write(s + '\n') + + def presub(self, target): + if print_actions_presub: + if not SCons.Util.is_List(target): + target = [target] + lines = string.split(str(self), '\n') + sys.stdout.write("Building %s with action(s):\n %s\n"% + (string.join(map(lambda x: str(x), target), ' and '), + string.join(lines, '\n '))) def get_actions(self): return [self] @@ -177,11 +235,14 @@ class CommandAction(ActionBase): if __debug__: logInstanceCreation(self) self.cmd_list = cmd + def __str__(self): + return str(self.cmd_list) + def strfunction(self, target, source, env): cmd_list = env.subst_list(self.cmd_list, 0, target, source) return map(_string_from_cmd_list, cmd_list) - def __call__(self, target, source, env): + def _execute(self, target, source, env): """Execute a command action. This will handle lists of commands as well as individual commands, @@ -265,15 +326,9 @@ class CommandAction(ActionBase): return ret return 0 - def get_raw_contents(self, target, source, env, dict=None): - """Return the complete contents of this action's command line. - """ - cmd = self.cmd_list - if SCons.Util.is_List(cmd): - cmd = string.join(map(str, cmd)) - else: - cmd = str(cmd) - return env.subst(cmd, SCons.Util.SUBST_RAW, target, source, dict) + def __call__(self, target, source, env): + self.presub(target) + return self._execute(target, source, env) def get_contents(self, target, source, env, dict=None): """Return the signature contents of this action's command line. @@ -313,12 +368,24 @@ class CommandGeneratorAction(ActionBase): act = self.__generate(target, source, env, 0) return act.strfunction(target, rsources, env) + def __str__(self): + act = self.__generate([], [], {}, 0) + return str(act) + + def _execute(self, target, source, env): + if not SCons.Util.is_List(source): + source = [source] + rsources = map(rfile, source) + act = self.__generate(target, source, env, 0) + return act._execute(target, rsources, env) + def __call__(self, target, source, env): if not SCons.Util.is_List(source): source = [source] rsources = map(rfile, source) act = self.__generate(target, source, env, 0) - return act(target, rsources, env) + act.presub(target) + return act._execute(target, source, env) def get_contents(self, target, source, env, dict=None): """Return the signature contents of this action's command line. @@ -329,10 +396,11 @@ class CommandGeneratorAction(ActionBase): return self.__generate(target, source, env, 1).get_contents(target, source, env, dict=None) class LazyCmdGenerator: - """This is a simple callable class that acts as a command generator. - It holds on to a key into an Environment dictionary, then waits - until execution time to see what type it is, then tries to - create an Action out of it.""" + """This is not really an Action, although it kind of looks like one. + This is really a simple callable class that acts as a command + generator. It holds on to a key into an Environment dictionary, + then waits until execution time to see what type it is, then tries + to create an Action out of it.""" def __init__(self, var): if __debug__: logInstanceCreation(self) self.var = SCons.Util.to_String(var) @@ -344,13 +412,16 @@ class LazyCmdGenerator: # The variable reference substitutes to nothing. return '' - def __call__(self, target, source, env, for_signature): + def _execute(self, target, source, env, for_signature): try: return env[self.var] except KeyError: # The variable reference substitutes to nothing. return '' + def __call__(self, target, source, env, for_signature): + return self._execute(target, source, env, for_signature) + def __cmp__(self, other): return cmp(self.__dict__, other.__dict__) @@ -361,25 +432,31 @@ class FunctionAction(ActionBase): if __debug__: logInstanceCreation(self) self.execfunction = execfunction if strfunction is _null: - def strfunction(target, source, env, execfunction=execfunction): + def strfunction(target, source, env, self=self): def quote(s): return '"' + str(s) + '"' def array(a, q=quote): return '[' + string.join(map(lambda x, q=q: q(x), a), ", ") + ']' - try: - name = execfunction.__name__ - except AttributeError: - try: - name = execfunction.__class__.__name__ - except AttributeError: - name = "unknown_python_function" + name = self.function_name() tstr = len(target) == 1 and quote(target[0]) or array(target) sstr = len(source) == 1 and quote(source[0]) or array(source) return "%s(%s, %s)" % (name, tstr, sstr) self.strfunction = strfunction self.varlist = varlist - def __call__(self, target, source, env): + def function_name(self): + try: + return self.execfunction.__name__ + except AttributeError: + try: + return self.execfunction.__class__.__name__ + except AttributeError: + return "unknown_python_function" + + def __str__(self): + return "%s(env, target, source)" % self.function_name() + + def _execute(self, target, source, env): r = 0 if not SCons.Util.is_List(target): target = [target] @@ -394,6 +471,10 @@ class FunctionAction(ActionBase): r = self.execfunction(target=target, source=rsources, env=env) return r + def __call__(self, target, source, env): + self.presub(target) + return self._execute(target, source, env) + def get_contents(self, target, source, env, dict=None): """Return the signature contents of this callable action. @@ -418,6 +499,12 @@ class ListAction(ActionBase): def get_actions(self): return self.list + def __str__(self): + s = [] + for l in self.list: + s.append(str(l)) + return string.join(s, "\n") + def strfunction(self, target, source, env): s = [] for l in self.list: @@ -428,13 +515,17 @@ class ListAction(ActionBase): s.extend(x) return string.join(s, "\n") - def __call__(self, target, source, env): + def _execute(self, target, source, env): for l in self.list: - r = l(target, source, env) + r = l._execute(target, source, env) if r: return r return 0 + def __call__(self, target, source, env): + self.presub(target) + return self._execute(target, source, env) + def get_contents(self, target, source, env, dict=None): """Return the signature contents of this action list. diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index b7006f9..75c82ae 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -241,7 +241,7 @@ class ActionTestCase(unittest.TestCase): class ActionBaseTestCase(unittest.TestCase): - def test_cmp(self): + def test___cmp__(self): """Test Action comparison """ a1 = SCons.Action.Action("x") @@ -256,26 +256,58 @@ class ActionBaseTestCase(unittest.TestCase): """ save_stdout = sys.stdout - save = SCons.Action.print_actions + save_print_actions = SCons.Action.print_actions SCons.Action.print_actions = 0 - sio = StringIO.StringIO() - sys.stdout = sio - a = SCons.Action.Action("x") - a.show("xyzzy") - s = sio.getvalue() - assert s == "", s + try: + a = SCons.Action.Action("x") + + sio = StringIO.StringIO() + sys.stdout = sio + a.show("xyzzy") + s = sio.getvalue() + assert s == "", s + + SCons.Action.print_actions = 1 + + sio = StringIO.StringIO() + sys.stdout = sio + a.show("foobar") + s = sio.getvalue() + assert s == "foobar\n", s + + finally: + SCons.Action.print_actions = save_print_actions + sys.stdout = save_stdout + + def test_presub(self): + """Test the presub() method + """ + save_stdout = sys.stdout + + save_print_actions_presub = SCons.Action.print_actions_presub + SCons.Action.print_actions_presub = 0 + + try: + a = SCons.Action.Action("x") + + sio = StringIO.StringIO() + sys.stdout = sio + a.presub("xyzzy") + s = sio.getvalue() + assert s == "", s - SCons.Action.print_actions = 1 + SCons.Action.print_actions_presub = 1 - sio = StringIO.StringIO() - sys.stdout = sio - a.show("foobar") - s = sio.getvalue() - assert s == "foobar\n", s + sio = StringIO.StringIO() + sys.stdout = sio + a.presub("foobar") + s = sio.getvalue() + assert s == "Building foobar with action(s):\n x\n", s - SCons.Action.print_actions = save - sys.stdout = save_stdout + finally: + SCons.Action.print_actions_presub = save_print_actions_presub + sys.stdout = save_stdout def test_get_actions(self): """Test the get_actions() method @@ -363,12 +395,26 @@ class ActionBaseTestCase(unittest.TestCase): class CommandActionTestCase(unittest.TestCase): - def test_init(self): + def test___init__(self): """Test creation of a command Action """ a = SCons.Action.CommandAction(["xyzzy"]) assert a.cmd_list == [ "xyzzy" ], a.cmd_list + def test___str__(self): + """Test fetching the pre-substitution string for command Actions + """ + env = Environment() + act = SCons.Action.CommandAction('xyzzy $TARGET $SOURCE') + s = str(act) + assert s == 'xyzzy $TARGET $SOURCE', s + + act = SCons.Action.CommandAction(['xyzzy', + '$TARGET', '$SOURCE', + '$TARGETS', '$SOURCES']) + s = str(act) + assert s == "['xyzzy', '$TARGET', '$SOURCE', '$TARGETS', '$SOURCES']", s + def test_strfunction(self): """Test fetching the string representation of command Actions """ @@ -526,7 +572,6 @@ class CommandActionTestCase(unittest.TestCase): r = act([], [], env.Copy(out = outfile)) assert r == expect_nonexecutable, "r == %d" % r - def test_pipe_execute(self): """Test capturing piped output from an action """ @@ -635,67 +680,6 @@ class CommandActionTestCase(unittest.TestCase): a([], [], e) assert t.executed == [ '**xyzzy**' ], t.executed - def test_get_raw_contents(self): - """Test fetching the contents of a command Action - """ - def CmdGen(target, source, env, for_signature): - assert for_signature - return "%s %s" % \ - (env["foo"], env["bar"]) - - # The number 1 is there to make sure all args get converted to strings. - a = SCons.Action.CommandAction(["|", "$(", "$foo", "|", "$bar", - "$)", "|", "$baz", 1]) - c = a.get_raw_contents(target=[], source=[], - env=Environment(foo = 'FFF', bar = 'BBB', - baz = CmdGen)) - assert c == "| $( FFF | BBB $) | FFF BBB 1", c - - # We've discusssed using the real target and source names in a - # CommandAction's signature contents. This would have have the - # advantage of recompiling when a file's name changes (keeping - # debug info current), but it would currently break repository - # logic that will change the file name based on whether the - # files come from a repository or locally. If we ever move to - # that scheme, then all of the '__t1__' and '__s6__' file names - # in the asserts below would change to 't1' and 's6' and the - # like. - t = map(DummyNode, ['t1', 't2', 't3', 't4', 't5', 't6']) - s = map(DummyNode, ['s1', 's2', 's3', 's4', 's5', 's6']) - env = Environment() - - a = SCons.Action.CommandAction(["$TARGET"]) - c = a.get_raw_contents(target=t, source=s, env=env) - assert c == "t1", c - - a = SCons.Action.CommandAction(["$TARGETS"]) - c = a.get_raw_contents(target=t, source=s, env=env) - assert c == "t1 t2 t3 t4 t5 t6", c - - a = SCons.Action.CommandAction(["${TARGETS[2]}"]) - c = a.get_raw_contents(target=t, source=s, env=env) - assert c == "t3", c - - a = SCons.Action.CommandAction(["${TARGETS[3:5]}"]) - c = a.get_raw_contents(target=t, source=s, env=env) - assert c == "t4 t5", c - - a = SCons.Action.CommandAction(["$SOURCE"]) - c = a.get_raw_contents(target=t, source=s, env=env) - assert c == "s1", c - - a = SCons.Action.CommandAction(["$SOURCES"]) - c = a.get_raw_contents(target=t, source=s, env=env) - assert c == "s1 s2 s3 s4 s5 s6", c - - a = SCons.Action.CommandAction(["${SOURCES[2]}"]) - c = a.get_raw_contents(target=t, source=s, env=env) - assert c == "s3", c - - a = SCons.Action.CommandAction(["${SOURCES[3:5]}"]) - c = a.get_raw_contents(target=t, source=s, env=env) - assert c == "s4 s5", c - def test_get_contents(self): """Test fetching the contents of a command Action """ @@ -767,7 +751,7 @@ class CommandActionTestCase(unittest.TestCase): class CommandGeneratorActionTestCase(unittest.TestCase): - def test_init(self): + def test___init__(self): """Test creation of a command generator Action """ def f(target, source, env): @@ -775,6 +759,15 @@ class CommandGeneratorActionTestCase(unittest.TestCase): a = SCons.Action.CommandGeneratorAction(f) assert a.generator == f + def test___str__(self): + """Test the pre-substitution strings for command generator Actions + """ + def f(target, source, env, for_signature, self=self): + return "FOO" + a = SCons.Action.CommandGeneratorAction(f) + s = str(a) + assert s == 'FOO', s + def test_strfunction(self): """Test the command generator Action string function """ @@ -866,7 +859,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase): class FunctionActionTestCase(unittest.TestCase): - def test_init(self): + def test___init__(self): """Test creation of a function Action """ def func1(): @@ -894,6 +887,22 @@ class FunctionActionTestCase(unittest.TestCase): assert a.execfunction == func4, a.execfunction assert a.strfunction is None, a.strfunction + def test___str__(self): + """Test the __str__() method for function Actions + """ + def func1(): + pass + a = SCons.Action.FunctionAction(func1) + s = str(a) + assert s == "func1(env, target, source)", s + + class class1: + def __call__(self): + pass + a = SCons.Action.FunctionAction(class1()) + s = str(a) + assert s == "class1(env, target, source)", s + def test_execute(self): """Test executing a function Action """ @@ -984,7 +993,7 @@ class FunctionActionTestCase(unittest.TestCase): class ListActionTestCase(unittest.TestCase): - def test_init(self): + def test___init__(self): """Test creation of a list of subsidiary Actions """ def func(): @@ -1008,6 +1017,17 @@ class ListActionTestCase(unittest.TestCase): g = l[1].get_actions() assert g == [l[1]], g + def test___str__(self): + """Test the __str__() method ffor a list of subsidiary Actions + """ + def f(target,source,env): + pass + def g(target,source,env): + pass + a = SCons.Action.ListAction([f, g, "XXX", f]) + s = str(a) + assert s == "f(env, target, source)\ng(env, target, source)\nXXX\nf(env, target, source)", s + def test_strfunction(self): """Test the string function for a list of subsidiary Actions """ @@ -1069,7 +1089,7 @@ class ListActionTestCase(unittest.TestCase): assert c == "xyz", c class LazyActionTestCase(unittest.TestCase): - def test_init(self): + def test___init__(self): """Test creation of a lazy-evaluation Action """ # Environment variable references should create a special diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 47fef2b..c59ce69 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -409,6 +409,8 @@ def _set_globals(options): memory_outf = sys.stdout elif options.debug == "objects": print_objects = 1 + elif options.debug == "presub": + SCons.Action.print_actions_presub = 1 elif options.debug == "time": print_time = 1 elif options.debug == "tree": @@ -492,7 +494,8 @@ class OptParser(OptionParser): "build all Default() targets.") def opt_debug(option, opt, value, parser): - if value in ["count", "dtree", "includes", "memory", "objects", "pdb", "time", "tree"]: + if value in ["count", "dtree", "includes", "memory", "objects", + "pdb", "presub", "time", "tree"]: setattr(parser.values, 'debug', value) else: raise OptionValueError("Warning: %s is not a valid debug type" % value) diff --git a/test/option--debug.py b/test/option--debug.py index dfa5503..0893170 100644 --- a/test/option--debug.py +++ b/test/option--debug.py @@ -230,5 +230,158 @@ else: # output at this point. test.run(arguments = "--debug=objects") +############################ +# test --debug=presub + +test.write('cat.py', """\ +import sys +open(sys.argv[2], "wb").write(open(sys.argv[1], "rb").read()) +sys.exit(0) +""") + +test.write('SConstruct', """\ +def cat(env, source, target): + target = str(target[0]) + source = map(str, source) + f = open(target, "wb") + for src in source: + f.write(open(src, "rb").read()) + f.close() +FILE = Builder(action="$FILECOM") +TEMP = Builder(action="$TEMPCOM") +LIST = Builder(action="$LISTCOM") +FUNC = Builder(action=cat) +env = Environment(PYTHON='%s', + BUILDERS = {'FILE':FILE, 'TEMP':TEMP, 'LIST':LIST, 'FUNC':FUNC}, + FILECOM="$PYTHON cat.py $SOURCES $TARGET", + TEMPCOM="$PYTHON cat.py $SOURCES temp\\n$PYTHON cat.py temp $TARGET", + LISTCOM=["$PYTHON cat.py $SOURCES temp", "$PYTHON cat.py temp $TARGET"], + FUNCCOM=cat) +env.Command('file01.out', 'file01.in', "$FILECOM") +env.Command('file02.out', 'file02.in', ["$FILECOM"]) +env.Command('file03.out', 'file03.in', "$TEMPCOM") +env.Command('file04.out', 'file04.in', ["$TEMPCOM"]) +env.Command('file05.out', 'file05.in', "$LISTCOM") +env.Command('file06.out', 'file06.in', ["$LISTCOM"]) +env.Command('file07.out', 'file07.in', cat) +env.Command('file08.out', 'file08.in', "$FUNCCOM") +env.Command('file09.out', 'file09.in', ["$FUNCCOM"]) +env.FILE('file11.out', 'file11.in') +env.FILE('file12.out', 'file12.in') +env.TEMP('file13.out', 'file13.in') +env.TEMP('file14.out', 'file14.in') +env.LIST('file15.out', 'file15.in') +env.LIST('file16.out', 'file16.in') +env.FUNC('file17.out', 'file17.in') +env.FUNC('file18.out', 'file18.in') +""" % TestSCons.python) + +test.write('file01.in', "file01.in\n") +test.write('file02.in', "file02.in\n") +test.write('file03.in', "file03.in\n") +test.write('file04.in', "file04.in\n") +test.write('file05.in', "file05.in\n") +test.write('file06.in', "file06.in\n") +test.write('file07.in', "file07.in\n") +test.write('file08.in', "file08.in\n") +test.write('file09.in', "file09.in\n") +test.write('file11.in', "file11.in\n") +test.write('file12.in', "file12.in\n") +test.write('file13.in', "file13.in\n") +test.write('file14.in', "file14.in\n") +test.write('file15.in', "file15.in\n") +test.write('file16.in', "file16.in\n") +test.write('file17.in', "file17.in\n") +test.write('file18.in', "file18.in\n") + +expect = """\ +Building file01.out with action(s): + $PYTHON cat.py $SOURCES $TARGET +__PYTHON__ cat.py file01.in file01.out +Building file02.out with action(s): + $PYTHON cat.py $SOURCES $TARGET +__PYTHON__ cat.py file02.in file02.out +Building file03.out with action(s): + $PYTHON cat.py $SOURCES temp + $PYTHON cat.py temp $TARGET +__PYTHON__ cat.py file03.in temp +__PYTHON__ cat.py temp file03.out +Building file04.out with action(s): + $PYTHON cat.py $SOURCES temp + $PYTHON cat.py temp $TARGET +__PYTHON__ cat.py file04.in temp +__PYTHON__ cat.py temp file04.out +Building file05.out with action(s): + $PYTHON cat.py $SOURCES temp + $PYTHON cat.py temp $TARGET +__PYTHON__ cat.py file05.in temp +__PYTHON__ cat.py temp file05.out +Building file06.out with action(s): + $PYTHON cat.py $SOURCES temp + $PYTHON cat.py temp $TARGET +__PYTHON__ cat.py file06.in temp +__PYTHON__ cat.py temp file06.out +Building file07.out with action(s): + cat(env, target, source) +cat("file07.out", "file07.in") +Building file08.out with action(s): + cat(env, target, source) +cat("file08.out", "file08.in") +Building file09.out with action(s): + cat(env, target, source) +cat("file09.out", "file09.in") +Building file11.out with action(s): + $PYTHON cat.py $SOURCES $TARGET +__PYTHON__ cat.py file11.in file11.out +Building file12.out with action(s): + $PYTHON cat.py $SOURCES $TARGET +__PYTHON__ cat.py file12.in file12.out +Building file13.out with action(s): + $PYTHON cat.py $SOURCES temp + $PYTHON cat.py temp $TARGET +__PYTHON__ cat.py file13.in temp +__PYTHON__ cat.py temp file13.out +Building file14.out with action(s): + $PYTHON cat.py $SOURCES temp + $PYTHON cat.py temp $TARGET +__PYTHON__ cat.py file14.in temp +__PYTHON__ cat.py temp file14.out +Building file15.out with action(s): + $PYTHON cat.py $SOURCES temp + $PYTHON cat.py temp $TARGET +__PYTHON__ cat.py file15.in temp +__PYTHON__ cat.py temp file15.out +Building file16.out with action(s): + $PYTHON cat.py $SOURCES temp + $PYTHON cat.py temp $TARGET +__PYTHON__ cat.py file16.in temp +__PYTHON__ cat.py temp file16.out +Building file17.out with action(s): + cat(env, target, source) +cat("file17.out", "file17.in") +Building file18.out with action(s): + cat(env, target, source) +cat("file18.out", "file18.in") +""" +expect = string.replace(expect, '__PYTHON__', TestSCons.python) +test.run(arguments = "--debug=presub .", stdout=test.wrap_stdout(expect)) + +test.must_match('file01.out', "file01.in\n") +test.must_match('file02.out', "file02.in\n") +test.must_match('file03.out', "file03.in\n") +test.must_match('file04.out', "file04.in\n") +test.must_match('file05.out', "file05.in\n") +test.must_match('file06.out', "file06.in\n") +test.must_match('file07.out', "file07.in\n") +test.must_match('file08.out', "file08.in\n") +test.must_match('file09.out', "file09.in\n") +test.must_match('file11.out', "file11.in\n") +test.must_match('file12.out', "file12.in\n") +test.must_match('file13.out', "file13.in\n") +test.must_match('file14.out', "file14.in\n") +test.must_match('file15.out', "file15.in\n") +test.must_match('file16.out', "file16.in\n") +test.must_match('file17.out', "file17.in\n") +test.must_match('file18.out', "file18.in\n") test.pass_test() |