diff options
author | Steven Knight <knight@baldmt.com> | 2004-11-21 16:35:29 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2004-11-21 16:35:29 (GMT) |
commit | 07c75889f874a050aff782d1488d0269fb936744 (patch) | |
tree | 5397bb5b86e09f0a292d3b714c7e527bff539a06 /src/engine | |
parent | 8781e4655cea19b34cd062768d9f09b359fe9a09 (diff) | |
download | SCons-07c75889f874a050aff782d1488d0269fb936744.zip SCons-07c75889f874a050aff782d1488d0269fb936744.tar.gz SCons-07c75889f874a050aff782d1488d0269fb936744.tar.bz2 |
Add a --debug=stree option to show Node status. (Kevin Quick)
Diffstat (limited to 'src/engine')
-rw-r--r-- | src/engine/SCons/Script/__init__.py | 11 | ||||
-rw-r--r-- | src/engine/SCons/Util.py | 45 | ||||
-rw-r--r-- | src/engine/SCons/UtilTests.py | 103 |
3 files changed, 118 insertions, 41 deletions
diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index a3d933d..7d139a1 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -126,6 +126,10 @@ class BuildTask(SCons.Taskmaster.Task): if print_tree and self.top: print SCons.Util.print_tree(self.targets[0], get_all_children) + if print_stree and self.top: + print + SCons.Util.print_tree(self.targets[0], get_all_children, + showtags=2) if print_dtree and self.top: print SCons.Util.print_tree(self.targets[0], get_derived_children) @@ -245,6 +249,7 @@ print_explanations = 0 print_includes = 0 print_objects = 0 print_stacktrace = 0 +print_stree = 0 print_time = 0 print_tree = 0 memory_stats = None @@ -405,7 +410,7 @@ def _set_globals(options): global repositories, keep_going_on_error, ignore_errors global print_count, print_dtree global print_explanations, print_includes - global print_objects, print_stacktrace + global print_objects, print_stacktrace, print_stree global print_time, print_tree global memory_outf, memory_stats @@ -433,6 +438,8 @@ def _set_globals(options): SCons.Action.print_actions_presub = 1 elif options.debug == "stacktrace": print_stacktrace = 1 + elif options.debug == "stree": + print_stree = 1 elif options.debug == "time": print_time = 1 elif options.debug == "tree": @@ -530,7 +537,7 @@ class OptParser(OptionParser): debug_options = ["count", "dtree", "explain", "findlibs", "includes", "memory", "objects", - "pdb", "presub", "stacktrace", + "pdb", "presub", "stacktrace", "stree", "time", "tree"] def opt_debug(option, opt, value, parser, debug_options=debug_options): diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 896abaf..87aba96 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -1052,7 +1052,9 @@ def render_tree(root, child_func, prune=0, margin=[0], visited={}): return retval -def print_tree(root, child_func, prune=0, margin=[0], visited={}): +IDX = lambda N: N and 1 or 0 + +def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited={}): """ Print a tree of nodes. This is like render_tree, except it prints lines directly instead of creating a string representation in memory, @@ -1061,6 +1063,7 @@ def print_tree(root, child_func, prune=0, margin=[0], visited={}): root - the root node of the tree child_func - the function called to get the children of a node prune - don't visit the same node twice + showtags - print status information to the left of each node line margin - the format of the left margin to use for children of root. 1 results in a pipe, and 0 results in no pipe. visited - a dictionary of visited nodes in the current branch if not prune, @@ -1072,23 +1075,51 @@ def print_tree(root, child_func, prune=0, margin=[0], visited={}): if visited.has_key(rname): return + if showtags: + + if showtags == 2: + print ' E = exists' + print ' R = exists in repository only' + print ' b = implicit builder' + print ' B = explicit builder' + print ' S = side effect' + print ' P = precious' + print ' A = always build' + print ' C = current' + print '' + + tags = ['['] + tags.append(' E'[IDX(root.exists())]) + tags.append(' R'[IDX(root.rexists() and not root.exists())]) + tags.append(' BbB'[[0,1][IDX(root.has_explicit_builder())] + + [0,2][IDX(root.has_builder())]]) + tags.append(' S'[IDX(root.side_effect)]) + tags.append(' P'[IDX(root.precious)]) + tags.append(' A'[IDX(root.always_build)]) + tags.append(' C'[IDX(root.current())]) + tags.append(']') + + else: + tags = [] + def MMM(m): return [" ","| "][m] - print string.join(map(MMM, margin[:-1]), '') + "+-" + rname + margins = map(MMM, margin[:-1]) + + print string.join(tags + margins + ['+-', rname], '') if prune: visited[rname] = 1 - + children = child_func(root) if children: margin.append(1) - map(lambda C, cf=child_func, p=prune, m=margin, v=visited: - print_tree(C, cf, p, m, v), + map(lambda C, cf=child_func, p=prune, i=IDX(showtags), m=margin, v=visited: + print_tree(C, cf, p, i, m, v), children[:-1]) margin[-1] = 0 - print_tree(children[-1], child_func, prune, margin, visited) + print_tree(children[-1], child_func, prune, IDX(showtags), margin, visited) margin.pop() - def is_Dict(e): return type(e) is types.DictType or isinstance(e, UserDict) diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index c5c5297..c28db37 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -942,23 +942,39 @@ class UtilTestCase(unittest.TestCase): q = quote_spaces('x\tx') assert q == '"x\tx"', q + class Node: + def __init__(self, name, children=[]): + self.children = children + self.name = name + def __str__(self): + return self.name + def exists(self): + return 1 + def rexists(self): + return 1 + def has_builder(self): + return 1 + def has_explicit_builder(self): + return 1 + def side_effect(self): + return 1 + def precious(self): + return 1 + def always_build(self): + return 1 + def current(self): + return 1 + def tree_case_1(self): """Fixture for the render_tree() and print_tree() tests.""" - class Node: - def __init__(self, name, children=[]): - self.children = children - self.name = name - def __str__(self): - return self.name - - windows_h = Node("windows.h") - stdlib_h = Node("stdlib.h") - stdio_h = Node("stdio.h") - bar_c = Node("bar.c", [stdlib_h, windows_h]) - bar_o = Node("bar.o", [bar_c]) - foo_c = Node("foo.c", [stdio_h]) - foo_o = Node("foo.o", [foo_c]) - foo = Node("foo", [foo_o, bar_o]) + windows_h = self.Node("windows.h") + stdlib_h = self.Node("stdlib.h") + stdio_h = self.Node("stdio.h") + bar_c = self.Node("bar.c", [stdlib_h, windows_h]) + bar_o = self.Node("bar.o", [bar_c]) + foo_c = self.Node("foo.c", [stdio_h]) + foo_o = self.Node("foo.o", [foo_c]) + foo = self.Node("foo", [foo_o, bar_o]) expect = """\ +-foo @@ -971,22 +987,20 @@ class UtilTestCase(unittest.TestCase): +-windows.h """ - return foo, expect + lines = string.split(expect, '\n')[:-1] + lines = map(lambda l: '[E BSPAC]'+l, lines) + withtags = string.join(lines, '\n') + '\n' + + return foo, expect, withtags def tree_case_2(self): """Fixture for the render_tree() and print_tree() tests.""" - class Node: - def __init__(self, name, children=[]): - self.children = children - self.name = name - def __str__(self): - return self.name - stdlib_h = Node("stdlib.h") - bar_h = Node('bar.h', [stdlib_h]) - blat_h = Node('blat.h', [stdlib_h]) - blat_c = Node('blat.c', [blat_h, bar_h]) - blat_o = Node('blat.o', [blat_c]) + stdlib_h = self.Node("stdlib.h") + bar_h = self.Node('bar.h', [stdlib_h]) + blat_h = self.Node('blat.h', [stdlib_h]) + blat_c = self.Node('blat.c', [blat_h, bar_h]) + blat_o = self.Node('blat.o', [blat_c]) expect = """\ +-blat.o @@ -996,18 +1010,22 @@ class UtilTestCase(unittest.TestCase): +-bar.h """ - return blat_o, expect + lines = string.split(expect, '\n')[:-1] + lines = map(lambda l: '[E BSPAC]'+l, lines) + withtags = string.join(lines, '\n') + '\n' + + return blat_o, expect, withtags def test_render_tree(self): """Test the render_tree() function""" def get_children(node): return node.children - node, expect = self.tree_case_1() + node, expect, withtags = self.tree_case_1() actual = render_tree(node, get_children) assert expect == actual, (expect, actual) - node, expect = self.tree_case_2() + node, expect, withtags = self.tree_case_2() actual = render_tree(node, get_children, 1) assert expect == actual, (expect, actual) @@ -1019,17 +1037,38 @@ class UtilTestCase(unittest.TestCase): save_stdout = sys.stdout try: + node, expect, withtags = self.tree_case_1() + sys.stdout = StringIO.StringIO() - node, expect = self.tree_case_1() print_tree(node, get_children) actual = sys.stdout.getvalue() assert expect == actual, (expect, actual) sys.stdout = StringIO.StringIO() - node, expect = self.tree_case_2() + print_tree(node, get_children, showtags=1) + actual = sys.stdout.getvalue() + assert withtags == actual, (withtags, actual) + + node, expect, withtags = self.tree_case_2() + + sys.stdout = StringIO.StringIO() print_tree(node, get_children, 1) actual = sys.stdout.getvalue() assert expect == actual, (expect, actual) + + sys.stdout = StringIO.StringIO() + # The following call should work here: + # print_tree(node, get_children, 1, showtags=1) + # For some reason I don't understand, though, *this* + # time that we call print_tree, the visited dictionary + # is still populated with the values from the last call! + # I can't see why this would be, short of a bug in Python, + # and rather than continue banging my head against the + # brick wall for a *test*, we're going to going with + # the cheap, easy workaround: + print_tree(node, get_children, 1, showtags=1, visited={}) + actual = sys.stdout.getvalue() + assert withtags == actual, (withtags, actual) finally: sys.stdout = save_stdout |