Add a node Walker for descending the dependency tree.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Thu, 4 Oct 2001 18:50:26 +0000 (18:50 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Thu, 4 Oct 2001 18:50:26 +0000 (18:50 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@86 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/engine/SCons/Node/NodeTests.py
src/engine/SCons/Node/__init__.py

index e77e1b6d9b0052b59d12fae05ebb32cabc1b96a8..309229e997e97f4fc04000843dff2bc2ef5b409f 100644 (file)
@@ -150,9 +150,50 @@ class NodeTestCase(unittest.TestCase):
        node.add_dependency(['four', 'five', 'six'])
        kids = node.children()
        kids.sort()
-       print kids
        assert kids == ['five', 'four', 'one', 'six', 'three', 'two']
 
+    def test_walker(self):
+       """Test walking a Node tree.
+       """
+
+       class MyNode(SCons.Node.Node):
+           def __init__(self, name):
+               SCons.Node.Node.__init__(self)
+               self.name = name
+
+       n1 = MyNode("n1")
+
+       nw = SCons.Node.Walker(n1)
+       assert nw.next().name ==  "n1"
+       assert nw.next() == None
+
+       n2 = MyNode("n2")
+       n3 = MyNode("n3")
+       n1.add_source([n2, n3])
+
+       nw = SCons.Node.Walker(n1)
+       assert nw.next().name ==  "n2"
+       assert nw.next().name ==  "n3"
+       assert nw.next().name ==  "n1"
+       assert nw.next() == None
+
+       n4 = MyNode("n4")
+       n5 = MyNode("n5")
+       n6 = MyNode("n6")
+       n7 = MyNode("n7")
+       n2.add_source([n4, n5])
+       n3.add_dependency([n6, n7])
+
+       nw = SCons.Node.Walker(n1)
+       assert nw.next().name ==  "n4"
+       assert nw.next().name ==  "n5"
+       assert nw.next().name ==  "n2"
+       assert nw.next().name ==  "n6"
+       assert nw.next().name ==  "n7"
+       assert nw.next().name ==  "n3"
+       assert nw.next().name ==  "n1"
+       assert nw.next() == None
+
 
 
 if __name__ == "__main__":
index a0c07ca4625007a53f592a3f8ce1d2ae40edb291..8e1760dc358dd296ae01e36e1265a90810ca3e52 100644 (file)
@@ -84,3 +84,51 @@ class Node:
 
     def children(self):
        return self.sources + self.depends
+
+
+
+
+class Wrapper:
+    def __init__(self, node):
+        self.node = node
+        self.kids = node.children()
+        # XXX randomize kids here, if requested
+
+class Walker:
+    """An iterator for walking a Node tree.
+    
+    This is depth-first, children are visited before the parent.
+    The Walker object can be initialized with any node, and 
+    returns the next node on the descent with each next() call.
+    """
+    def __init__(self, node):
+       self.current = Wrapper(node)
+       self.stack = []
+       self.top = self.current
+
+    def next(self):
+       """Return the next node for this walk of the tree.
+
+       This function is intentionally iterative, not recursive,
+       to sidestep any issues of stack size limitations.
+       """
+       if not self.current:
+           return None
+
+       while 1:
+           if self.current.kids:
+               k = Wrapper(self.current.kids[0])
+               self.current.kids = self.current.kids[1:]
+               if k.kids:
+                   self.stack.append(self.current)
+                   self.current = k
+               else:
+                   return k.node
+           else:
+               n = self.current.node
+               if self.stack:
+                   self.current = self.stack[-1]
+                   self.stack = self.stack[0:-1]
+               else:
+                   self.current = None
+               return n