[apparmor] [PATCH 03/20] Rework depth first traversal of expr trees

John Johansen john.johansen at canonical.com
Fri Nov 5 05:50:59 GMT 2010


Rework the depth first traversal of expr trees, to remove the use of the
unneeded visited table, and give a little speed up and cleanup.

Signed-off-by: John Johansen <john.johansen at canonical.com>
---
 parser/libapparmor_re/regexp.y |   50 +++++++++++++++++++++------------------
 1 files changed, 27 insertions(+), 23 deletions(-)

diff --git a/parser/libapparmor_re/regexp.y b/parser/libapparmor_re/regexp.y
index 36153af..89b945a 100644
--- a/parser/libapparmor_re/regexp.y
+++ b/parser/libapparmor_re/regexp.y
@@ -19,6 +19,7 @@
 
     #include <list>
     #include <vector>
+    #include <stack>
     #include <set>
     #include <map>
     #include <ostream>
@@ -1088,43 +1089,46 @@ cset_char   : CHAR
 
 /* Traverse the syntax tree depth-first in an iterator-like manner. */
 class depth_first_traversal {
-    vector<Node *> stack;
-    vector<bool> visited;
+    stack<Node *> pos;
+    void push_left(Node *node)
+    {
+	pos.push(node);
+
+        while (dynamic_cast<InnerNode *>(node)) {
+	    pos.push(node->child[0]);
+            node = node->child[0];
+        }
+    }
+
 public:
     depth_first_traversal(Node *node) {
-	stack.push_back(node);
-	while (node->child[0]) {
-	    visited.push_back(false);
-	    stack.push_back(node->child[0]);
-	    node = node->child[0];
-	}
+	push_left(node);
     }
     Node *operator*()
     {
-	return stack.back();
+	return pos.top();
     }
     Node* operator->()
     {
-	return stack.back();
+	return pos.top();
     }
     operator bool()
     {
-	return !stack.empty();
+	return !pos.empty();
     }
     void operator++(int)
     {
-	stack.pop_back();
-	if (!stack.empty()) {
-	    if (!visited.back() && stack.back()->child[1]) {
-		visited.pop_back();
-		visited.push_back(true);
-		stack.push_back(stack.back()->child[1]);
-		while (stack.back()->child[0]) {
-		    visited.push_back(false);
-		    stack.push_back(stack.back()->child[0]);
-		}
-	    } else
-		visited.pop_back();
+        Node *last = pos.top();
+	pos.pop();
+
+	if (!pos.empty()) {
+  	    /* no need to dynamic cast, as we just popped a node so the top node
+	     * must be an inner node */
+	    InnerNode *node = (InnerNode *)(pos.top());
+
+	    if (node->child[1] && node->child[1] != last) {
+		push_left(node->child[1]);
+	    }
 	}
     }
 };
-- 
1.7.1




More information about the AppArmor mailing list