summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2004-11-21 16:35:29 (GMT)
committerSteven Knight <knight@baldmt.com>2004-11-21 16:35:29 (GMT)
commit07c75889f874a050aff782d1488d0269fb936744 (patch)
tree5397bb5b86e09f0a292d3b714c7e527bff539a06 /src/engine
parent8781e4655cea19b34cd062768d9f09b359fe9a09 (diff)
downloadSCons-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__.py11
-rw-r--r--src/engine/SCons/Util.py45
-rw-r--r--src/engine/SCons/UtilTests.py103
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