| 
      
      
      From: <mad...@us...> - 2007-07-11 16:32:43
      
     | 
| Revision: 2495
          http://svn.sourceforge.net/selinux/?rev=2495&view=rev
Author:   madmethod
Date:     2007-07-11 09:32:42 -0700 (Wed, 11 Jul 2007)
Log Message:
-----------
Author: Karl MacMillan
Email: kma...@me...
Subject: Initial policyrep patch v3
Date: Wed, 11 Jul 2007 09:41:34 -0400
Initial patch to create a new policyrep branch using C++. This patch includes basic classes for
representing policy (Node and Parent), a few policy objects, a bison parser, a boost::python
binding, and basic test infrastructure.
Includes updates based on comments from James Antill
and Josh Brindle.
* * *
Signed-off-by: User "Karl MacMillan <kma...@me...>"
Acked-By: Joshua Brindle <me...@ma...>
Modified Paths:
--------------
    branches/policyrep/Makefile
Added Paths:
-----------
    branches/policyrep/libpolicyrep/
    branches/policyrep/libpolicyrep/Makefile
    branches/policyrep/libpolicyrep/include/
    branches/policyrep/libpolicyrep/include/Makefile
    branches/policyrep/libpolicyrep/include/policyrep/
    branches/policyrep/libpolicyrep/include/policyrep/conditional.hpp
    branches/policyrep/libpolicyrep/include/policyrep/idset.hpp
    branches/policyrep/libpolicyrep/include/policyrep/object_class.hpp
    branches/policyrep/libpolicyrep/include/policyrep/parse.hpp
    branches/policyrep/libpolicyrep/include/policyrep/policy.hpp
    branches/policyrep/libpolicyrep/include/policyrep/policy_base.hpp
    branches/policyrep/libpolicyrep/include/policyrep/rule.hpp
    branches/policyrep/libpolicyrep/include/policyrep/te_decl.hpp
    branches/policyrep/libpolicyrep/src/
    branches/policyrep/libpolicyrep/src/Makefile
    branches/policyrep/libpolicyrep/src/conditional.cpp
    branches/policyrep/libpolicyrep/src/idset.cpp
    branches/policyrep/libpolicyrep/src/object_class.cpp
    branches/policyrep/libpolicyrep/src/parse.cpp
    branches/policyrep/libpolicyrep/src/policy.cpp
    branches/policyrep/libpolicyrep/src/policy_base.cpp
    branches/policyrep/libpolicyrep/src/policy_base_internal.hpp
    branches/policyrep/libpolicyrep/src/policy_internal.hpp
    branches/policyrep/libpolicyrep/src/policy_parse.y
    branches/policyrep/libpolicyrep/src/policy_scan.l
    branches/policyrep/libpolicyrep/src/policyrep_python.cpp
    branches/policyrep/libpolicyrep/src/rule.cpp
    branches/policyrep/libpolicyrep/src/te_decl.cpp
    branches/policyrep/libpolicyrep/tests/
    branches/policyrep/libpolicyrep/tests/Makefile
    branches/policyrep/libpolicyrep/tests/example.te
    branches/policyrep/libpolicyrep/tests/libpolicyrep-test.cpp
Modified: branches/policyrep/Makefile
===================================================================
--- branches/policyrep/Makefile	2007-07-11 16:25:31 UTC (rev 2494)
+++ branches/policyrep/Makefile	2007-07-11 16:32:42 UTC (rev 2495)
@@ -1,4 +1,4 @@
-SUBDIRS=libsepol libselinux libsemanage sepolgen checkpolicy policycoreutils # policy
+SUBDIRS=libsepol libselinux libsemanage libpolicyrep sepolgen checkpolicy policycoreutils # policy
 PYSUBDIRS=libselinux libsemanage
 
 ifeq ($(DEBUG),1)
Added: branches/policyrep/libpolicyrep/Makefile
===================================================================
--- branches/policyrep/libpolicyrep/Makefile	                        (rev 0)
+++ branches/policyrep/libpolicyrep/Makefile	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,22 @@
+all: 
+	$(MAKE) -C src 
+
+install: 
+	$(MAKE) -C include install
+	$(MAKE) -C src install
+
+relabel:
+	$(MAKE) -C src relabel
+
+clean:
+	$(MAKE) -C src clean
+	$(MAKE) -C tests clean
+
+indent:
+	$(MAKE) -C src $@
+	$(MAKE) -C include $@
+	$(MAKE) -C utils $@
+
+test: all
+	$(MAKE) -C tests test
+
Added: branches/policyrep/libpolicyrep/include/Makefile
===================================================================
--- branches/policyrep/libpolicyrep/include/Makefile	                        (rev 0)
+++ branches/policyrep/libpolicyrep/include/Makefile	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,10 @@
+# Installation directories.
+PREFIX ?= $(DESTDIR)/usr
+INCDIR ?= $(PREFIX)/include/policyrep
+
+install:
+	test -d $(INCDIR) || install -m 755 -d $(INCDIR)
+	install -m 644 $(wildcard policyrep/*.hpp) $(INCDIR)
+
+indent:
+	../../scripts/Lindent $(wildcard policyrep/*.hpp)
Added: branches/policyrep/libpolicyrep/include/policyrep/conditional.hpp
===================================================================
--- branches/policyrep/libpolicyrep/include/policyrep/conditional.hpp	                        (rev 0)
+++ branches/policyrep/libpolicyrep/include/policyrep/conditional.hpp	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,136 @@
+/* Author: Karl MacMillan <kma...@me...> */
+
+#ifndef __conditional_hpp__
+#define __conditional_hpp__
+
+#include <policyrep/policy_base.hpp>
+
+#include <list>
+
+namespace policyrep
+{
+
+	/* Introduction
+	 *
+	 * Conditional policy in policyrep is handled in such a way that
+	 * the normal tree iteration works unchanged all the way to the
+	 * most nested leaf nodes. To achieve this the design is not
+	 * what might be most obvious.
+	 *
+	 * The conditional policy statements:
+	 *
+	 * if (foo) {
+	 *     allow foo_t bar_t : file read;
+	 * } else {
+	 *     allow baz_t bar_t : file write;
+	 * }
+	 *
+	 * Are enconded into the following tree struction:
+	 *
+	 * CondBlock
+	 *     CondBranch (with CondExpr foo)
+	 *          AVRule
+	 *     CondBranch (with else == true)
+	 *          AVRule
+	 *
+	 * The CondBranches are just children of the CondBlock,
+	 * but the CondBlock has an overloaded add_child implementation
+	 * to prevent more than two children from being added.
+	 */
+
+	struct CondBoolImpl;
+	class CondBool : public Node
+	{
+	public:
+		CondBool();
+		CondBool(const std::string& name, bool v);
+		CondBool(const CondBool& other);
+		virtual ~CondBool();
+		virtual void operator=(const CondBool& other);
+
+		virtual void set_name(const std::string& name);
+		virtual const std::string& get_name() const;
+
+		virtual void set_default_value(bool v);
+		virtual bool get_default_value() const;
+	protected:
+		virtual void do_output(std::ostream& o, const OutputFormatter& op) const;
+		CondBoolImpl* impl;
+	};
+
+	class CondOp;
+	std::ostream& operator<<(std::ostream& o, const CondOp& op);
+
+	struct CondOpImpl;
+	class CondOp
+	{
+	public:
+		enum Op { BOOL, NOT, OR, AND, XOR, EQ, NEQ };
+		CondOp();
+		CondOp(const std::string& b);
+		CondOp(Op op);
+		CondOp(const CondOp& other);
+		virtual ~CondOp();
+		virtual void operator=(const CondOp& other);
+
+		virtual void set_op(Op op);
+		virtual Op get_op() const;
+
+		/* changes op to BOOL in addition to setting the bool */
+		virtual void set_bool(const std::string& b);
+		virtual const std::string& get_bool() const;
+		friend std::ostream& operator<<(std::ostream& o, const CondOp& op);
+
+	protected:
+		CondOpImpl* impl;
+	};
+	typedef std::list<CondOp> CondExpr;
+
+
+	class CondBranch;
+	typedef boost::shared_ptr<CondBranch> CondBranchPtr;
+
+	struct CondBlockImpl;
+	class CondBlock : public Parent
+	{
+	public:
+		CondBlock();
+		CondBlock(CondBranchPtr if_);
+		CondBlock(CondBranchPtr if_, CondBranchPtr else_);
+		CondBlock(const CondBlock& other);
+		virtual ~CondBlock();
+		virtual void operator=(const CondBlock& other);
+
+		virtual void append_child(NodePtr node);
+
+		virtual bool has_if() const;
+		virtual CondBranch& get_if();
+		virtual void set_if(CondBranchPtr branch);
+		virtual bool has_else() const;
+		virtual CondBranch& get_else();
+		virtual void set_else(CondBranchPtr branch);
+		virtual bool ignore_indent() const;
+	protected:
+		CondBlockImpl* impl;
+	};
+
+	struct CondBranchImpl;
+	class CondBranch : public Parent
+	{
+	public:
+		CondBranch();
+		CondBranch(const CondBranch& other);
+		virtual ~CondBranch();
+		virtual void operator=(const CondBranch& other);
+
+		virtual CondExpr& expr();
+		virtual void set_else(bool v);
+		virtual bool get_else() const;
+		virtual void output(std::ostream& o, const OutputFormatter& op) const;
+	protected:
+		CondBranchImpl* impl;
+	};
+
+} // namespace policyrep
+
+#endif
Added: branches/policyrep/libpolicyrep/include/policyrep/idset.hpp
===================================================================
--- branches/policyrep/libpolicyrep/include/policyrep/idset.hpp	                        (rev 0)
+++ branches/policyrep/libpolicyrep/include/policyrep/idset.hpp	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,33 @@
+/* Author: Karl MacMillan <kma...@me...> */
+
+#ifndef __idset_hpp__
+#define __idset_hpp__
+
+#include <policyrep/policy_base.hpp>
+
+#include <set>
+
+namespace policyrep
+{
+	struct IdSetImpl;
+	class IdSet
+	{
+	public:
+		IdSet();
+		IdSet(const IdSet& other);
+		~IdSet();
+		void operator=(const IdSet& other);
+
+		void set_compl(bool val);
+		bool get_compl() const;
+
+		StringSet& ids();
+	protected:
+		void init();
+		IdSetImpl* impl;
+	};
+
+
+} // namespace policyrep
+
+#endif
Added: branches/policyrep/libpolicyrep/include/policyrep/object_class.hpp
===================================================================
--- branches/policyrep/libpolicyrep/include/policyrep/object_class.hpp	                        (rev 0)
+++ branches/policyrep/libpolicyrep/include/policyrep/object_class.hpp	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,83 @@
+/* Author: Karl MacMillan <kma...@me...> */
+
+#ifndef __object_class_hpp__
+#define __object_class_hpp__
+
+#include <policyrep/policy_base.hpp>
+
+namespace policyrep
+{
+
+        //
+        // CommonPerms
+        //
+
+        struct CommonPermsImpl;
+        class CommonPerms : public Node
+        {
+        public:
+                CommonPerms();
+                CommonPerms(const CommonPerms& other);
+                virtual ~CommonPerms();
+                virtual void operator=(const CommonPerms& other);
+
+		template<class T>
+                CommonPerms(const std::string& name, T perms_begin, T perms_end)
+		{
+			init();
+			set_name(name);
+			perms().insert(perms_begin, perms_end);
+		}
+
+                virtual const std::string& get_name() const;
+                virtual void set_name(const std::string& name);
+                virtual StringSet& perms();
+
+        protected:
+                virtual void do_output(std::ostream& o, const OutputFormatter& op) const;
+		void init();
+		CommonPermsImpl* impl;
+        };
+	typedef boost::shared_ptr<CommonPerms> CommonPermsPtr;
+
+        //
+        // ObjectClass
+        //
+
+        struct ObjectClassImpl;
+        class ObjectClass : public Node
+        {
+        public:
+                ObjectClass();
+                ObjectClass(const std::string& name, const std::string& commons);
+		ObjectClass(const ObjectClass& other);
+                virtual ~ObjectClass();
+		virtual void operator=(const ObjectClass& other);
+
+		template<class T>
+                ObjectClass(std::string name, std::string commons,
+			    T perms_begin, T perms_end)
+		{
+			init();
+			set_name(name);
+			set_common_perms(commons);
+			perms().insert(perms_begin, perms_end);
+		}
+
+                virtual const std::string& get_name() const;
+                virtual void set_name(const std::string& name);
+                virtual StringSet& perms();
+                virtual const std::string& get_common_perms() const;
+                virtual void set_common_perms(const std::string& name);
+
+        protected:
+                virtual void do_output(std::ostream& o, const OutputFormatter& op) const;
+		void init();
+        	ObjectClassImpl* impl;
+        };
+	typedef boost::shared_ptr<ObjectClass> ObjectClassPtr;
+
+
+} // namespace policyrep
+
+#endif
Added: branches/policyrep/libpolicyrep/include/policyrep/parse.hpp
===================================================================
--- branches/policyrep/libpolicyrep/include/policyrep/parse.hpp	                        (rev 0)
+++ branches/policyrep/libpolicyrep/include/policyrep/parse.hpp	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,47 @@
+// Author Karl MacMillan <kma...@me...>
+
+#ifndef __parse_hpp__
+#define __parse_hpp__
+
+#include <policyrep/policy.hpp>
+
+#include <string>
+
+namespace policyrep {
+
+	class location;
+
+	struct ParserImpl;
+	class Parser
+	{
+	public:
+		Parser();
+		Parser(const Parser& other);
+		virtual ~Parser();
+		virtual void operator=(const Parser& other);
+
+		// Parser
+		virtual ModulePtr parse(const std::string& f);
+
+                virtual std::string& get_filename() const;
+                virtual Module& get_module();
+
+		virtual void set_trace_scanning(bool val);
+		virtual bool get_trace_scanning() const;
+
+		virtual void set_trace_parsing(bool val);
+		virtual bool get_trace_parsing() const;
+
+                // error handling
+                virtual void error(const policyrep::location& l, const std::string& m);
+                virtual void error(const std::string& m);
+	protected:
+		// scanner
+		virtual void scan_begin();
+		virtual void scan_end();
+
+		ParserImpl* impl;
+	};
+}
+
+#endif
Added: branches/policyrep/libpolicyrep/include/policyrep/policy.hpp
===================================================================
--- branches/policyrep/libpolicyrep/include/policyrep/policy.hpp	                        (rev 0)
+++ branches/policyrep/libpolicyrep/include/policyrep/policy.hpp	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,86 @@
+/* Author: Karl MacMillan <kma...@me...> */
+
+#ifndef __policy_hpp__
+#define __policy_hpp__
+
+#include <policyrep/policy_base.hpp>
+#include <policyrep/object_class.hpp>
+#include <policyrep/te_decl.hpp>
+#include <policyrep/rule.hpp>
+#include <policyrep/conditional.hpp>
+
+namespace policyrep
+{
+
+	//
+	// Policy
+	//
+
+	struct PolicyImpl;
+	class Policy : public Parent
+	{
+	public:
+		Policy(bool mls=false);
+		Policy(const Policy& other);
+		virtual ~Policy();
+		virtual void operator=(const Policy& other);
+
+		virtual bool get_mls() const;
+		virtual void set_mls(bool val);
+		virtual bool ignore_indent() const;
+	protected:
+		PolicyImpl* impl;
+	};
+	typedef boost::shared_ptr<Policy> PolicyPtr;
+
+	//
+	// Module
+	//
+	struct ModuleImpl;
+        class Module : public Parent
+	{
+        public:
+		Module();
+                Module(const std::string& name, const std::string& version);
+		Module(const Module& other);
+                virtual ~Module();
+		virtual void operator=(const Module& other);
+
+                virtual const std::string& get_name() const;
+                virtual void set_name(const std::string& name);
+                virtual const std::string& get_version() const;
+                virtual void set_version(const std::string& version);
+		virtual bool ignore_indent() const;
+
+        protected:
+                virtual void do_output(std::ostream& o, const OutputFormatter& op) const;
+		ModuleImpl* impl;
+        };
+	typedef boost::shared_ptr<Module> ModulePtr;
+
+	//
+	// InitialSid
+	//
+
+	struct InitialSidImpl;
+        class InitialSid : public Node
+        {
+        public:
+                InitialSid();
+                InitialSid(const std::string& name);
+		InitialSid(const InitialSid& other);
+                virtual ~InitialSid();
+		virtual void operator=(const InitialSid& other);
+
+                virtual const std::string& get_name() const;
+                virtual void set_name(const std::string& name);
+
+        protected:
+                virtual void do_output(std::ostream& o, const OutputFormatter& op) const;
+		InitialSidImpl* impl;
+        };
+	typedef boost::shared_ptr<InitialSid> InitialSidPtr;
+
+}
+
+#endif
Added: branches/policyrep/libpolicyrep/include/policyrep/policy_base.hpp
===================================================================
--- branches/policyrep/libpolicyrep/include/policyrep/policy_base.hpp	                        (rev 0)
+++ branches/policyrep/libpolicyrep/include/policyrep/policy_base.hpp	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,183 @@
+/* Author: Karl MacMillan <kma...@me...> */
+
+#ifndef __policy_base_hpp__
+#define __policy_base_hpp__
+
+#include <vector>
+#include <set>
+#include <string>
+#include <functional>
+#include <ostream>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+
+namespace policyrep {
+
+	// Forward declarations
+        class Node;
+        typedef boost::shared_ptr<Node> NodePtr;
+
+        class Parent;
+        typedef boost::shared_ptr<Parent> ParentPtr;
+
+	class TreeIterator;
+        
+	// Convenience typedefs
+        typedef std::vector<NodePtr> NodeVector;
+        typedef boost::shared_ptr<NodeVector> NodeVectorPtr;
+        
+        typedef std::set<std::string> StringSet;
+        typedef boost::shared_ptr<StringSet> StringSetPtr;
+        
+        typedef std::vector<std::string> StringVector;
+        typedef boost::shared_ptr<StringVector> StringVectorPtr;
+
+	// util functions
+	template<class T>
+	bool is_instance(Node* n);
+
+	template<class T>
+	bool is_instance(NodePtr n);	
+
+	// Output (string output)
+        std::ostream& operator<<(std::ostream& o, const Node& n);
+
+        void output_set_space(std::ostream& o, const StringSet& set);
+        void output_set_comma(std::ostream& o, const StringSet& set);
+
+	struct OutputFormatterImpl;
+        class OutputFormatter {
+        public:
+		enum Style { DEFAULT, DEBUG };
+                OutputFormatter(const Node& n, bool end=false, enum Style style=DEFAULT);
+		OutputFormatter();
+		OutputFormatter(const OutputFormatter& other);
+		~OutputFormatter();
+		void operator=(const OutputFormatter& other);
+
+		OutputFormatter& operator()(const Node& n, bool end=false);
+		OutputFormatter& operator()(NodePtr n, bool end=false);
+		OutputFormatter& operator()(const TreeIterator& i);
+                friend std::ostream& operator<<(std::ostream& o, const OutputFormatter& op);
+		
+		void set_style(Style style);
+		Style get_style() const;
+
+		void set_indent(bool v);
+		bool get_indent() const;
+
+		void set_end(bool v);
+		bool get_end() const;
+
+		void set_newline(bool v);
+		bool get_newline() const;
+
+		void set_root(Parent* p);
+		Parent* get_root() const;
+        private:
+		OutputFormatterImpl* impl;
+        };
+
+	//
+	// NODE
+	//
+
+	struct NodeImpl;
+	class Node {
+        public:
+                Node();
+		Node(const Node& other);
+                virtual ~Node();
+		virtual void operator=(const Node& other);
+                
+                virtual void set_parent(Parent* p);
+                virtual Parent* get_parent() const;
+                
+                virtual bool get_visited() const;
+                virtual void set_visited(bool val);
+                
+                friend std::ostream& operator<<(std::ostream& o, const Node& n);
+                virtual void output(std::ostream& o, const OutputFormatter& op) const;
+                virtual std::string to_string() const;
+                virtual std::string to_string_end() const;
+        protected:
+		NodeImpl* node_impl;
+                static const int VISITED = 1;
+		virtual void output_indentation(std::ostream& o, const OutputFormatter& op) const;
+                virtual void do_output(std::ostream& o, const OutputFormatter& op) const;
+        };
+        
+        //
+	// TreeIterator
+	//
+	
+	struct TreeIteratorImpl;
+        class TreeIterator
+                : public boost::iterator_facade<TreeIterator, NodePtr,
+                                                boost::forward_traversal_tag, NodePtr>
+        {
+        public:
+                enum Strategy { POSTORDER, PREORDER, HYBRID };
+                TreeIterator(enum Strategy strategy=POSTORDER);
+		explicit TreeIterator(ParentPtr n, enum Strategy strategy=POSTORDER);
+		explicit TreeIterator(Parent* n, enum Strategy strategy=POSTORDER);
+		TreeIterator(const TreeIterator& other);
+		virtual ~TreeIterator();
+                void operator=(const TreeIterator& other);
+                bool get_visited() const;
+        private:
+                friend class boost::iterator_core_access;
+                void increment();
+                void increment_preorder();
+                void increment_postorder();
+                bool equal(const TreeIterator& other) const;
+                NodePtr dereference() const;
+		void add_children(Parent* parent);
+                
+		TreeIteratorImpl* impl;
+        };
+        
+	//
+	// Parent
+	//
+	
+	struct ParentImpl;
+        class Parent : public Node {
+        public:
+		Parent();
+		Parent(const Parent& other);
+		virtual ~Parent();
+		virtual void operator=(const Parent& other);
+                typedef TreeIterator iterator;                
+
+                virtual void append_child(NodePtr Node);
+		virtual void make_child(NodePtr node);
+
+		template<class T>
+		void append_children(T begin, T end)
+		{
+			for (; begin != end; ++begin)
+				append_child(*begin);
+		}
+
+                virtual NodeVector& children();
+                
+                virtual iterator begin(enum TreeIterator::Strategy strategy=TreeIterator::POSTORDER);
+                virtual iterator end();
+
+		virtual bool ignore_indent() const;
+        protected:
+		ParentImpl* parent_impl;   
+        };
+	typedef boost::shared_ptr<Parent> ParentPtr;
+
+	void output_tree(std::ostream& o, ParentPtr p);
+
+        void output_tree(std::ostream& o, ParentPtr p,
+			 OutputFormatter& op);
+
+
+} // namespace policyrep
+
+#endif
Added: branches/policyrep/libpolicyrep/include/policyrep/rule.hpp
===================================================================
--- branches/policyrep/libpolicyrep/include/policyrep/rule.hpp	                        (rev 0)
+++ branches/policyrep/libpolicyrep/include/policyrep/rule.hpp	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,71 @@
+/* Author: Karl MacMillan <kma...@me...> */
+
+#ifndef __rule_hpp__
+#define __rule_hpp__
+
+#include <policyrep/policy_base.hpp>
+#include <policyrep/idset.hpp>
+
+namespace policyrep
+{
+
+        //
+        // AVRule
+        //
+
+        struct AVRuleImpl;
+        class AVRule : public Node
+        {
+        public:
+                enum Type { ALLOW, AUDITDENY, AUDITALLOW, DONTAUDIT, NEVERALLOW };
+                AVRule(Type type=ALLOW);
+                AVRule(const AVRule& other);
+                virtual ~AVRule();
+                virtual void operator=(const AVRule& other);
+
+		virtual void set_type(Type type);
+		virtual Type get_type() const;
+
+                virtual IdSet& src_types();
+                virtual IdSet& tgt_types();
+                virtual StringSet& classes();
+                virtual IdSet& perms();
+
+        protected:
+                virtual void do_output(std::ostream& o, const OutputFormatter& op) const;
+                void init();
+                AVRuleImpl* impl;
+        };
+
+	//
+	// TypeRule
+	//
+
+	struct TypeRuleImpl;
+	class TypeRule : public Node
+	{
+	public:
+		enum Type { TRANSITION, CHANGE, MEMBER };
+		TypeRule(Type type=TRANSITION);
+		TypeRule(const TypeRule& other);
+		virtual ~TypeRule();
+		virtual void operator=(const TypeRule& other);
+
+		virtual void set_type(Type type);
+		virtual Type get_type() const;
+
+                virtual IdSet& src_types();
+                virtual IdSet& tgt_types();
+                virtual StringSet& classes();
+		virtual const std::string& get_target();
+		virtual void set_target(const std::string& target);
+
+        protected:
+                virtual void do_output(std::ostream& o, const OutputFormatter& op) const;
+                void init();
+                TypeRuleImpl* impl;		
+	};
+
+} // namepsace policyrep
+
+#endif
Added: branches/policyrep/libpolicyrep/include/policyrep/te_decl.hpp
===================================================================
--- branches/policyrep/libpolicyrep/include/policyrep/te_decl.hpp	                        (rev 0)
+++ branches/policyrep/libpolicyrep/include/policyrep/te_decl.hpp	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,144 @@
+/* Author: Karl MacMillan <kma...@me...> */
+
+#ifndef __te_decl_hpp__
+#define __te_decl_hpp__
+
+#include <policyrep/policy_base.hpp>
+
+namespace policyrep
+{
+
+        //
+        // Type
+        //
+
+	struct TypeImpl;
+        class Type : public Node
+	{
+        public:
+		Type();
+		Type(const std::string& name);
+		Type(const Type& other);
+		virtual ~Type();
+		virtual void operator=(const Type& other);
+
+		template<class T>
+                Type(const std::string& name, T attrs_begin, T end)
+		{
+			init();
+			set_name(name);
+			attributes().insert(attrs_begin, end);
+		}
+
+		template<class T, class U>
+                Type(const std::string name, T attrs_begin, T end,
+		     U aliases_begin, U aliases_end)
+		{
+			init();
+			set_name(name);
+			attributes().insert(attrs_begin, end);
+			aliases().insert(aliases_begin, aliases_end);
+		}
+
+                virtual const std::string& get_name() const;
+                virtual void set_name(const std::string& name);
+
+                virtual StringSet& aliases();
+                virtual StringSet& attributes();
+        protected:
+                virtual void do_output(std::ostream& o, const OutputFormatter& op) const;
+		void init();
+		TypeImpl* impl;
+        };
+	typedef boost::shared_ptr<Type> TypePtr;
+
+	//
+	// Attribute
+	//
+
+	struct AttributeImpl;
+	class Attribute : public Node
+        {
+	public:
+		Attribute();
+		Attribute(const std::string& name);
+		Attribute(const Attribute& other);
+		virtual ~Attribute();
+		virtual void operator=(const Attribute& other);
+
+		virtual const std::string& get_name() const;
+		virtual void set_name(const std::string& name);
+	protected:
+                virtual void do_output(std::ostream& o, const OutputFormatter& op) const;
+		AttributeImpl* impl;
+	};
+	typedef boost::shared_ptr<Attribute> AttributePtr;
+
+	//
+	// TypeAttribute
+	//
+
+	struct TypeAttributeImpl;
+	class TypeAttribute : public Node
+        {
+	public:
+		TypeAttribute();
+		TypeAttribute(const TypeAttribute& other);
+		virtual ~TypeAttribute();
+		virtual void operator=(const TypeAttribute& other);
+
+		template<class T>
+		TypeAttribute(const std::string& name, T attrs_begin,
+			      T attrs_end)
+		{
+			init();
+                        set_name(name);
+			attributes().insert(attrs_begin, attrs_end);
+		}
+
+		virtual const std::string& get_name() const;
+		virtual void set_name(const std::string& name);
+                virtual StringSet& attributes();
+	protected:
+                virtual void do_output(std::ostream& o, const OutputFormatter& op) const;
+		void init();
+		TypeAttributeImpl* impl;
+	};
+	typedef boost::shared_ptr<TypeAttribute> TypeAttributePtr;
+
+        //
+        // TypeAlias
+        //
+
+        struct TypeAliasImpl;
+        class TypeAlias : public Node
+        {
+        public:
+                TypeAlias();
+                TypeAlias(const TypeAlias& other);
+                virtual ~TypeAlias();
+                virtual void operator=(const TypeAlias& other);
+
+                template<class T>
+                TypeAlias(const std::string& name, T attrs_begin,
+                              T attrs_end)
+                {
+                        init();
+                        set_name(name);
+                        aliases().insert(attrs_begin, attrs_end);
+                }
+
+                virtual const std::string& get_name() const;
+                virtual void set_name(const std::string& name);
+                virtual StringSet& aliases();
+        protected:
+                virtual void do_output(std::ostream& o, const OutputFormatter& op) const;
+                void init();
+                TypeAliasImpl* impl;
+        };
+        typedef boost::shared_ptr<TypeAlias> TypeAliasPtr;
+
+
+} // namespace policyrep
+
+#endif
Added: branches/policyrep/libpolicyrep/src/Makefile
===================================================================
--- branches/policyrep/libpolicyrep/src/Makefile	                        (rev 0)
+++ branches/policyrep/libpolicyrep/src/Makefile	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,76 @@
+# Installation directories.
+PREFIX ?= $(DESTDIR)/usr
+LIBDIR ?= $(PREFIX)/lib
+SHLIBDIR ?= $(DESTDIR)/lib
+
+PYLIBVER ?= $(shell python -c 'import sys;print "python%d.%d" % sys.version_info[0:2]')
+PYINC ?= /usr/include/$(PYLIBVER)
+PYLIB ?= /usr/lib/$(PYLIBVER)
+PYTHONLIBDIR ?= $(LIBDIR)/$(PYLIBVER)
+PYTHONCPP=policyrep_python.cpp
+PYTHONLOBJ=policyrep_python.lo
+PYTHONSO=policyrep.so
+
+LIBVERSION = 1
+
+PARSERGENERATED=policy_parse.cpp policy_parse.hpp policy_scan.cpp stack.hh position.hh scanner-file.cpp location.hh
+PARSEROBJS=policy_parse.o policy_scan.o
+PARSERLOBJS=policy_parse.lo policy_scan.lo
+
+LIBA=libpolicyrep.a 
+TARGET=libpolicyrep.so
+LIBSO=$(TARGET).$(LIBVERSION)
+OBJS= $(PARSEROBJS) $(patsubst %.cpp,%.o,$(filter-out $(PYTHONCPP), $(wildcard *.cpp)))
+LOBJS= $(PARSERLOBJS) $(patsubst %.cpp,%.lo,$(filter-out $(PYTHONCPP), $(wildcard *.cpp)))
+CFLAGS ?= -g -Wall -W -Wmissing-format-attribute -Wno-unused-parameter
+override CFLAGS += -I. -I../include -D_GNU_SOURCE
+LDFLAGS += -lboost_serialization
+
+all: $(LIBA) $(LIBSO) $(PYTHONSO)
+
+$(LIBA):  $(OBJS)
+	$(AR) rcs $@ $^
+	ranlib $@
+
+$(LIBSO): $(LOBJS)
+	g++ $(LDFLAGS) -shared -o $@ $^ -Wl,-soname,$(LIBSO)
+	ln -sf $@ $(TARGET) 
+
+$(PYTHONSO): $(PYTHONLOBJ)
+	g++ $(LDFLAGS) -lboost_python -shared -o $@ $< $(LOBJS) -Wl,-soname,$@
+
+$(PYTHONLOBJ): $(PYTHONCPP)
+	g++ $(CFLAGS) -I$(PYINC) -fPIC -DSHARED -c -o $@ $<
+
+%.o:  %.cpp
+	g++ $(CFLAGS) -fPIC -c -o $@ $<
+
+%.lo:  %.cpp
+	g++ $(CFLAGS) -fPIC -DSHARED -c -o $@ $<
+
+policy_parse.cpp: policy_parse.y
+	bison -o policy_parse.cpp -p policyrep -d policy_parse.y
+
+policy_scan.cpp: policy_scan.l policy_parse.cpp
+	flex policy_scan.l
+
+install: all install-pywrap
+	test -d $(LIBDIR) || install -m 755 -d $(LIBDIR)
+	install -m 644 $(LIBA) $(LIBDIR)
+	test -d $(SHLIBDIR) || install -m 755 -d $(SHLIBDIR)
+	install -m 755 $(LIBSO) $(SHLIBDIR)
+	cd $(LIBDIR) && ln -sf ../../`basename $(SHLIBDIR)`/$(LIBSO) $(TARGET)
+
+install-pywrap:
+	test -d $(PYTHONLIBDIR)/site-packages || install -m 755 -d $(PYTHONLIBDIR)/site-packages
+	install -m 755 $(PYTHONSO) $(PYTHONLIBDIR)/site-packages
+
+relabel:
+	/sbin/restorecon $(SHLIBDIR)/$(LIBSO)
+
+clean: 
+	-rm -f $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(TARGET) $(PYTHONSO) $(PYTHONLOBJ) $(PARSERGENERATED)
+
+indent:
+	../../scripts/Lindent $(wildcard *.cpp)
+
Added: branches/policyrep/libpolicyrep/src/conditional.cpp
===================================================================
--- branches/policyrep/libpolicyrep/src/conditional.cpp	                        (rev 0)
+++ branches/policyrep/libpolicyrep/src/conditional.cpp	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,380 @@
+/*
+ * Author : Karl MacMillan <kma...@me...>
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <policyrep/conditional.hpp>
+#include "policy_base_internal.hpp"
+
+#include <list>
+#include <stdexcept>
+
+namespace policyrep
+{
+
+	//
+	// CondBool
+	//
+
+	struct CondBoolImpl
+	{
+		std::string name;
+		bool default_value;
+	};
+
+	CondBool::CondBool() : impl(new CondBoolImpl)
+	{
+
+	}
+
+	CondBool::CondBool(const std::string& name, bool v)
+		: impl(new CondBoolImpl)
+	{
+		impl->name = name;
+		impl->default_value = v;
+	}
+
+	CondBool::CondBool(const CondBool& other) : Node(), impl(new CondBoolImpl)
+	{
+		*impl = *other.impl;
+	}
+
+	CondBool::~CondBool()
+	{
+		delete impl;
+	}
+
+	void CondBool::operator=(const CondBool& other)
+	{
+		*impl = *other.impl;
+	}
+
+	void CondBool::set_name(const std::string& name)
+	{
+		impl->name = name;
+	}
+
+	const std::string& CondBool::get_name() const
+	{
+		return impl->name;
+	}
+
+	void CondBool::set_default_value(bool v)
+	{
+		impl->default_value = v;
+	}
+
+	bool CondBool::get_default_value() const
+	{
+		return impl->default_value;
+	}
+
+	void CondBool::do_output(std::ostream& o, const OutputFormatter& op) const
+	{
+		o << "bool " << impl->name << " ";
+		if (impl->default_value)
+			o << "true;";
+		else
+			o << "false;";
+	}
+
+	//
+	// CondOp
+	//
+
+	struct CondOpImpl
+	{
+		CondOpImpl() : op(CondOp::AND) { }
+		CondOp::Op op;
+		std::string b;
+	};
+
+	CondOp::CondOp() : impl(new CondOpImpl)
+	{
+
+	}
+
+	CondOp::CondOp(const std::string& b) : impl(new CondOpImpl)
+	{
+		impl->op = BOOL;
+		impl->b = b;
+	}
+
+	CondOp::CondOp(Op op) : impl(new CondOpImpl)
+	{
+		impl->op = op;
+	}
+
+	CondOp::CondOp(const CondOp& other) : impl(new CondOpImpl)
+	{
+		*impl = *other.impl;
+	}
+
+	CondOp::~CondOp()
+	{
+		delete impl;
+	}
+
+	void CondOp::operator=(const CondOp& other)
+	{
+		*impl = *other.impl;
+	}
+
+	void CondOp::set_bool(const std::string& b)
+	{
+		impl->b = b;
+	}
+
+	const std::string& CondOp::get_bool() const
+	{
+		return impl->b;
+	}
+
+	void CondOp::set_op(Op op)
+	{
+		impl->op = op;
+	}
+
+	CondOp::Op CondOp::get_op() const
+	{
+		return impl->op;
+	}
+
+	std::ostream& operator<<(std::ostream& o, const CondOp& op)
+	{
+		switch (op.get_op()) {
+		case CondOp::BOOL:
+			o << op.get_bool();
+			break;
+		case CondOp::NOT:
+			o << "!";
+			break;
+		case CondOp::OR:
+			o << "|";
+			break;
+		case CondOp::AND:
+			o << "&";
+			break;
+		case CondOp::XOR:
+			o << "^";
+			break;
+		case CondOp::EQ:
+			o << "==";
+			break;
+		case CondOp::NEQ:
+			o << "!=";
+			break;
+		};
+
+		return o;
+	}
+
+
+	//
+	// CondBlock
+	//
+
+	struct CondBlockImpl { };
+
+	CondBlock::CondBlock() : impl(new CondBlockImpl)
+	{
+
+	}
+
+	CondBlock::CondBlock(CondBranchPtr if_) : impl(new CondBlockImpl)
+	{
+		append_child(if_);
+	}
+
+	CondBlock::CondBlock(CondBranchPtr if_, CondBranchPtr else_) : impl(new CondBlockImpl)
+	{
+		append_child(if_);
+		append_child(else_);
+	}
+
+	CondBlock::CondBlock(const CondBlock& other) : Parent(), impl(new CondBlockImpl)
+	{
+		*impl = *other.impl;
+	}
+
+	CondBlock::~CondBlock()
+	{
+		delete impl;
+	}
+
+	void CondBlock::operator=(const CondBlock& other)
+	{
+		*impl = *other.impl;
+	}
+
+	void CondBlock::append_child(NodePtr node)
+	{
+		CondBranch* branch = dynamic_cast<CondBranch*>(node.get());
+		if (!branch) {
+			throw std::invalid_argument("only CondBranch can be a child of CondBlock");
+		}
+		
+		size_t num_children = children().size();
+		if (num_children >= 2) {
+			throw std::out_of_range("CondBlock can only have two children");
+		}
+
+		Parent::append_child(node);
+
+		if (num_children == 1) {
+			branch->set_else(true);
+		} else {
+			branch->set_else(false);
+		}
+	}
+
+	bool CondBlock::has_if() const
+	{
+		return !parent_impl->children.empty();
+	}
+
+	CondBranch& CondBlock::get_if()
+	{
+		if (!has_if())
+			throw std::out_of_range("no if block");
+
+		return dynamic_cast<CondBranch&>(*children()[0]);
+	}
+
+	void CondBlock::set_if(CondBranchPtr branch)
+	{
+		if (has_if()) {
+			children()[0] = branch;
+			make_child(branch);
+		} else {
+			append_child(branch);
+		}
+	}
+
+	bool CondBlock::has_else() const
+	{
+		return parent_impl->children.size() >= 2;
+	}
+
+	CondBranch& CondBlock::get_else()
+	{
+		if (!has_else())
+			throw std::out_of_range("no else block");
+		return dynamic_cast<CondBranch&>(*children()[1]);
+	}
+
+	void CondBlock::set_else(CondBranchPtr branch)
+	{
+		if (!has_if()) {
+			CondBranchPtr p(new CondBranch);
+			append_child(branch);
+		}
+		
+		if (has_else()) {
+			children()[1] = branch;
+			make_child(branch);
+		} else {
+			append_child(branch);			
+		}
+	}
+
+	bool CondBlock::ignore_indent() const
+	{
+		return true;
+	}
+
+	//
+	// CondBranch
+	//
+
+	struct CondBranchImpl
+	{
+		bool is_else;
+		CondExpr expr;
+	};
+
+	CondBranch::CondBranch() : impl(new CondBranchImpl)
+	{
+
+	}
+
+	CondBranch::CondBranch(const CondBranch& other) : Parent(), impl(new CondBranchImpl)
+	{
+		*impl = *other.impl;
+	}
+
+	CondBranch::~CondBranch()
+	{
+		delete impl;
+	}
+
+	void CondBranch::operator=(const CondBranch& other)
+	{
+		*impl = *other.impl;
+	}
+
+	CondExpr& CondBranch::expr()
+	{
+		return impl->expr;
+	}
+
+	void CondBranch::set_else(bool v)
+	{
+		impl->is_else = v;
+	}
+
+	bool CondBranch::get_else() const
+	{
+		return impl->is_else;
+	}
+
+	void CondBranch::output(std::ostream& o, const OutputFormatter& op) const
+	{
+		output_indentation(o, op);
+
+		if (op.get_end()) {
+			o << "}";
+		} else {
+			if (get_else()) {
+				o << "else {\n";
+			} else {
+				o << "if (";
+				
+				CondExpr::iterator i, end;
+				i = impl->expr.begin();
+				end = impl->expr.end();
+				bool first = true;
+			
+				for (; i != end; ++i) {
+					if (first)
+						first = false;
+					else
+						o << " ";
+					
+					o << *i;
+				}
+				
+				o << ") {";
+			}
+		}
+
+		if (op.get_newline())
+			o << "\n";
+	}
+
+}
Added: branches/policyrep/libpolicyrep/src/idset.cpp
===================================================================
--- branches/policyrep/libpolicyrep/src/idset.cpp	                        (rev 0)
+++ branches/policyrep/libpolicyrep/src/idset.cpp	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,67 @@
+/*
+ * Author : Karl MacMillan <kma...@me...>
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <policyrep/idset.hpp>
+
+namespace policyrep
+{
+
+	struct IdSetImpl
+	{
+		StringSet ids;
+		bool compliment;
+	};
+
+	void IdSet::init()
+	{
+		impl = new IdSetImpl;
+	}
+
+	IdSet::IdSet() { init(); }
+
+	IdSet::IdSet(const IdSet& other)
+	{
+		init();
+		*impl = *other.impl;
+	}
+
+	IdSet::~IdSet() { delete impl; }
+
+	void IdSet::operator=(const IdSet& other)
+	{
+		*impl = *other.impl;
+	}
+
+	void IdSet::set_compl(bool val)
+	{
+		impl->compliment = val;
+	}
+
+	bool IdSet::get_compl() const
+	{
+		return impl->compliment;
+	}
+
+	StringSet& IdSet::ids()
+	{
+		return impl->ids;
+	}
+
+} // namespace policyre
Added: branches/policyrep/libpolicyrep/src/object_class.cpp
===================================================================
--- branches/policyrep/libpolicyrep/src/object_class.cpp	                        (rev 0)
+++ branches/policyrep/libpolicyrep/src/object_class.cpp	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,153 @@
+/*
+ * Author : Karl MacMillan <kma...@me...>
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <policyrep/object_class.hpp>
+
+namespace policyrep {
+
+	//
+	// CommonPerms
+	//
+
+	struct CommonPermsImpl
+	{
+		std::string name;
+		StringSet perms;
+	};
+
+	void CommonPerms::init() { impl = new CommonPermsImpl; }
+
+	CommonPerms::CommonPerms() { init(); }
+
+	CommonPerms::CommonPerms(const CommonPerms& other)
+		: Node()
+	{
+		init();
+		*impl = *other.impl;
+	}
+
+	CommonPerms::~CommonPerms()
+	{
+		delete impl;
+	}
+
+	void CommonPerms::operator=(const CommonPerms& other)
+	{
+		*impl = *other.impl;
+	}
+
+	const std::string& CommonPerms::get_name() const
+	{
+		return impl->name;
+	}
+
+	void CommonPerms::set_name(const std::string& name)
+	{
+		impl->name = name;
+	}
+
+	StringSet& CommonPerms::perms()
+	{
+		return impl->perms;
+	}
+
+	void CommonPerms::do_output(std::ostream& o, const OutputFormatter& op) const
+	{
+		o << "common " << impl->name << " ";
+		output_set_space(o, impl->perms);
+	}
+
+	//
+	// ObjectClass
+	//
+
+	struct ObjectClassImpl
+	{
+		std::string name;
+		StringSet perms;
+		std::string common_perms;
+	};
+
+	void ObjectClass::init() { impl = new ObjectClassImpl; }
+
+	ObjectClass::ObjectClass() { init(); }
+
+	ObjectClass::ObjectClass(const std::string& name, const std::string& commons)
+	{
+		init();
+		set_name(name);
+		set_common_perms(commons);
+	}
+
+	ObjectClass::ObjectClass(const ObjectClass& other)
+		: Node()
+	{
+		init();
+		*impl = *other.impl;
+	}
+
+	ObjectClass::~ObjectClass()
+	{
+		delete impl;
+	}
+
+	void ObjectClass::operator=(const ObjectClass& other)
+	{
+		*impl = *other.impl;
+	}
+
+	const std::string& ObjectClass::get_name() const
+	{
+		return impl->name;
+	}
+
+	void ObjectClass::set_name(const std::string& name)
+	{
+		impl->name = name;
+	}
+
+	StringSet& ObjectClass::perms()
+	{
+		return impl->perms;
+	}
+
+	const std::string& ObjectClass::get_common_perms() const
+	{
+		return impl->common_perms;
+	}
+
+	void ObjectClass::set_common_perms(const std::string& name)
+	{
+		impl->common_perms = name;
+	}
+
+	void ObjectClass::do_output(std::ostream& o, const OutputFormatter& op) const
+	{
+		o << "class " << impl->name;
+		if (impl->common_perms != "")
+			o << " inherits " << impl->common_perms;
+		if (!impl->perms.empty()) {
+			o << " ";
+			output_set_space(o, impl->perms);
+		}
+	}
+
+
+} // namespace policyrep
Added: branches/policyrep/libpolicyrep/src/parse.cpp
===================================================================
--- branches/policyrep/libpolicyrep/src/parse.cpp	                        (rev 0)
+++ branches/policyrep/libpolicyrep/src/parse.cpp	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,107 @@
+/*
+ * Author : Karl MacMillan <kma...@me...>
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <policyrep/parse.hpp>
+#include <policyrep/policy.hpp>
+
+#include "policy_parse.hpp"
+
+namespace policyrep {
+
+
+	struct ParserImpl
+	{
+                ParserImpl() : trace_scanning(false), trace_parsing(false) { }
+		std::string filename;
+		ModulePtr module;
+		bool trace_scanning;
+		bool trace_parsing;
+	};
+
+	Parser::Parser()
+		: impl(new ParserImpl) { }
+
+	Parser::Parser(const Parser& other)
+		: impl(new ParserImpl)
+	{
+		*impl = *other.impl;
+	}
+
+	Parser::~Parser() { delete impl; }
+
+	void Parser::operator=(const Parser& other)
+	{
+		*impl = *other.impl;
+	}
+
+	ModulePtr Parser::parse(const std::string& f)
+	{
+		impl->module = ModulePtr(new Module);
+		impl->filename = f;
+		scan_begin();
+		policy_parser p(*this);
+		p.set_debug_level(impl->trace_parsing);
+		p.parse();
+		scan_end();
+
+		return impl->module;
+	}
+
+        std::string& Parser::get_filename() const
+        {
+                return impl->filename;
+        }
+
+        Module& Parser::get_module()
+        {
+                return *impl->module;
+        }
+
+	void Parser::set_trace_scanning(bool val)
+        {
+                impl->trace_scanning = val;
+        }
+
+	bool Parser::get_trace_scanning() const
+        {
+                return impl->trace_scanning;
+        }
+
+	void Parser::set_trace_parsing(bool val)
+        {
+                impl->trace_parsing = val;
+        }
+
+        bool Parser::get_trace_parsing() const
+        {
+                return impl->trace_parsing;
+        }
+
+	void Parser::error(const policyrep::location& l, const std::string& m)
+	{
+		std::cerr << l << ": " << m << std::endl;
+	}
+
+	void Parser::error(const std::string& m)
+	{
+		std::cerr << m << std::endl;
+	}
+
+} // namespace policyrep
Added: branches/policyrep/libpolicyrep/src/policy.cpp
===================================================================
--- branches/policyrep/libpolicyrep/src/policy.cpp	                        (rev 0)
+++ branches/policyrep/libpolicyrep/src/policy.cpp	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,181 @@
+/*
+ * Author : Karl MacMillan <kma...@me...>
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <policyrep/policy.hpp>
+
+
+namespace policyrep
+{
+
+
+        //
+        // Policy
+        //
+
+	struct PolicyImpl
+	{
+		PolicyImpl(bool m=false) : mls(m) { }
+		bool mls;
+	};
+
+
+	Policy::Policy(bool mls)
+		: impl(new PolicyImpl(mls)) { }
+
+	Policy::Policy(const Policy& other)
+		: Parent()
+	{
+		impl = new PolicyImpl;
+		*impl = *other.impl;
+	}
+
+	Policy::~Policy() { delete impl; }
+
+	void Policy::operator=(const Policy& other)
+	{
+		*impl = *other.impl;
+	}
+
+	bool Policy::get_mls() const
+	{
+		return impl->mls;
+	}
+
+	void Policy::set_mls(bool val)
+	{
+		impl->mls = val;
+	}
+
+	bool Policy::ignore_indent() const
+	{
+		return true;
+	}
+
+	//
+	// Module
+	//
+
+	struct ModuleImpl
+	{
+		ModuleImpl() { }
+		ModuleImpl(const std::string& n, const std::string& v) : name(n), version(v) { }
+		std::string name;
+		std::string version;
+	};
+
+	Module::Module() : impl(new ModuleImpl) { }
+
+	Module::Module(const std::string& name, const std::string& version)
+		: impl(new ModuleImpl(name, version)) { }
+
+	Module::Module(const Module& other)
+		: Parent(), impl(new ModuleImpl)
+	{
+		*impl = *other.impl;
+	}
+
+	Module::~Module() { delete impl; }
+
+	void Module::operator=(const Module& other)
+	{
+		*impl = *other.impl;
+	}
+
+	const std::string& Module::get_name() const
+	{
+		return impl->name;
+	}
+
+	void Module::set_name(const std::string& name)
+	{
+		impl->name = name;
+	}
+
+	const std::string& Module::get_version() const
+	{
+		return impl->version;
+	}
+
+	void Module::set_version(const std::string& version)
+	{
+		impl->version = version;
+	}
+
+	void Module::do_output(std::ostream& o, const OutputFormatter& op) const
+	{
+		if (op.get_style() == OutputFormatter::DEBUG)
+			o << "[MODULE " << this << "]";
+		o << "module " << impl->name << " " << impl->version << ";";
+	}
+
+	bool Module::ignore_indent() const
+	{
+		return true;
+	}
+
+
+	//
+	// InitialSid
+	//
+
+	struct InitialSidImpl
+	{
+		std::string name;
+	};
+
+	InitialSid::InitialSid()
+		: impl(new InitialSidImpl) { }
+
+	InitialSid::InitialSid(const std::string& name)
+		: impl(new InitialSidImpl)
+	{
+		impl->name = name;
+	}
+
+	InitialSid::InitialSid(const InitialSid& other)
+		: Node(), impl(new InitialSidImpl)
+	{
+		*impl = *other.impl;
+	}
+
+	InitialSid::~InitialSid() { delete impl; }
+
+	void InitialSid::operator=(const InitialSid& other)
+	{
+		*impl = *other.impl;
+	}
+
+	const std::string& InitialSid::get_name() const
+	{
+		return impl->name;
+	}
+
+	void InitialSid::set_name(const std::string& name)
+	{
+		impl->name = name;
+	}
+
+	void InitialSid::do_output(std::ostream& o, const OutputFormatter& op) const
+	{
+		o << "sid " << impl->name;
+	}
+
+
+} // namespace Policyrep
Added: branches/policyrep/libpolicyrep/src/policy_base.cpp
===================================================================
--- branches/policyrep/libpolicyrep/src/policy_base.cpp	                        (rev 0)
+++ branches/policyrep/libpolicyrep/src/policy_base.cpp	2007-07-11 16:32:42 UTC (rev 2495)
@@ -0,0 +1,533 @@
+/*
+ * Author : Karl MacMillan <kma...@me...>
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "policy_base_internal.hpp"
+
+#include <iostream>
+#include <algorithm>
+#include <fstream>
+#include <sstream>
+
+namespace policyrep
+{
+
+	//
+	// Util
+	//
+
+	template<class T>
+	bool is_instance(Node* n)
+	{
+		// dynamic_cast is preferred here because typeid
+		// matches the _exact_ type rather than any
+		// type that has the desired type (T) in its
+		// inheritance hierarchy.
+		T* x = dynamic_cast<T*>(n);
+		return x != 0;
+	}
+
+	template<class T>
+	bool is_instance(NodePtr n)
+	{
+		return is_instance<T>(n.get());
+	}
+
+	//
+	// Output
+	//
+
+	void output_set_space(std::ostream& o, const StringSet& set)
+	{
+		if (set.size() > 1)
+			o << "{ ";
+		StringSet::const_iterator i;
+		bool first = true;
+		for (i = set.begin(); i != set.end(); ++i) {
+			if (first)
+				first = false;
+			else
+				o << " ";
+			o << *i;
+		}
+		if (set.size() > 1)
+			o << " }";
+	}
+
+	void output_set_comma(std::ostream& o, const StringSet& set)
+	{
+		StringSet::const_iterator i;
+		bool first = true;
+		for (i = set.begin(); i != set.end(); ++i) {
+			if (first)
+				first = false;
+			else
+				o << ", ";
+			o << *i;
+		}
+	}
+
+	std::ostream& operator<<(std::ostream& o, const Node& n)
+	{
+		OutputFormatter op;
+		op.set_newline(false);
+		op.set_indent(false);
+		n.output(o, op);
+		return o;
+	}
+
+	//
+	// OutputFormatter
+	//
+
+	struct OutputFormatterImpl
+	{
+		OutputFormatterImpl()
+			: style(OutputFormatter::DEFAULT), newline(true), indent(true),
+			  node(0), end(false), root(0) { }
+		OutputFormatter::Style style;
+		bool newline;
+		bool indent;
+		const Node* node;
+		bool end;
+		Parent* root;
+	};
+
+	OutputFormatter::OutputFormatter(const Node &n, bool end, Style style)
+		: impl(new OutputFormatterImpl)
+	{
+		impl->node = &n;
+		impl->end = end;
+		impl->style = style;
+	}
+	
+	OutputFormatter::OutputFormatter() : impl(new OutputFormatterImpl)
+	{
+
+	}
+
+	OutputFormatter::OutputFormatter(const OutputFormatter& other)
+		: impl(new OutputFormatterImpl)
+	{
+		*impl = *other.impl;
+	}
+
+	OutputFormatter::~OutputFormatter()
+	{
+		delete impl;
+	}
+
+	void OutputFormatter::operator=(const OutputFormatter& other)
+	{
+		*impl = *other.impl;
+	}
+
+	OutputFormatter& OutputFormatter::operator()(const Node& n, bool end)
+	{
+		impl->node = &n;
+		impl->end = end;
+
+		return *this;
+	}
+
+	OutputFormatter& OutputFormatter::operator()(const NodePtr n, bool end)
+	{
+		return (*this)(*n.get(), end);
+	}
+
+	OutputFormatter& OutputFormatter::operator()(const TreeIterator& i)
+	{
+		impl->node = i->get();
+		impl->end = i.get_visited();
+
+		return *this;
+	}
+
+	std::ostream& operator<<(std::ostream& o, const OutputFormatter& op)
+	{
+		if (!op.impl->node)
+			return o;
+
+		op.impl->node->output(o, op);
+
+		return o;
+	}
+
+	void OutputFormatter::set_style(OutputFormatter::Style style)
+	{
+		impl->style = style;
+	}
+
+	OutputFormatter::Style OutputFormatter::get_style() const
+	{
+		return impl->style;
+	}
+
+	void OutputFormatter::set_indent(bool v)
+	{
+		impl->indent = v;
+	}
+
+	bool OutputFormatter::get_indent() const
+	{
+		return impl->indent;
+	}
+
+	void OutputFormatter::set_end(bool v)
+	{
+		impl->end = v;
+	}
+
+	bool OutputFormatter::get_end() const
+	{
+		return impl->end;
+	}
+
+	void OutputFormatter::set_newline(bool v)
+	{
+		impl->newline = v;
+	}
+
+	bool OutputFormatter::get_newline() const
+	{
+		return impl->newline;
+	}
+
+	void OutputFormatter::set_root(Parent* root)
+	{
+		impl->root = root;
+	}
+
+	Parent* OutputFormatter::get_root() const
+	{
+		return impl->root;
+	}	
+
+	//
+	// Node
+	//
+
+
+	Node::Node()
+	{
+		node_impl = new NodeImpl;
+	}
+
+	Node::Node(const Node& other)
+	{
+		node_impl = new NodeImpl;
+		*node_impl = *other.node_impl;
+	}
+
+	Node::~Node()
+	{
+		delete node_impl;
+	}
+
+	void Node::operator=(const Node& other)
+	{
+		*node_impl = *other.node_impl;
+	}
+
+	void Node::set_parent(Parent* parent)
+	{
+		node_impl->parent = parent;
+	}
+
+	Parent* Node::get_parent() const
+	{
+		return node_impl->parent;
+	}
+
+	bool Node::get_visited() const
+	{
+		return node_impl->flags & VISITED;
+	}
+
+	void Node::set_visited(bool val)
+	{
+		if (val)
+			node_impl->flags |= VISITED;
+		else
+			node_impl->flags &= ~VISITED;
+	}
+
+
+	std::string Node::to_string() const
+	{
+		std::stringstream s;
+		s << *this;
+		return s.str();
+	}
+
+	std::string Node::to_string_end() const
+	{
+		std::stringstream s;
+		s << OutputFormatter(*this, true, OutputFormatter::DEFAULT);
+		return s.str();
+	}
+
+	const int Node::VISITED;
+
+	void Node::output_indentation(std::ostream& o, const OutputFormatter& op) const
+	{
+		if (!op.get_indent())
+			return;
+
+		Parent* p = get_parent();
+		while (p && p != op.get_root()) {
+			if (!p->ignore_indent())
+				o << "\t";
+			p = p->get_parent();
+		}
+	}
+
+	void Node::output(std::ostream& o, const OutputFormatter& op) const
+	{
+		if (op.get_end()) {
+			if (op.get_style() == OutputFormatter::DEBUG) {
+				o << "[END " << typeid(this).name() << " " << this << "]";
+			};			
+			return;
+		}
+
+		output_indentation(o, op);
+
+		do_output(o, op);
+
+		if (op.get_newline())
+			o << "\n";
+		    
+	}
+
+	void Node::do_output(std::ostream& o, const OutputFormatter& op) const
+	{
+		if (op.get_style() == OutputFormatter::DEBUG) {
+			o << "[Node " << this << "]";
+		}
+	}
+
+	//
+	// TreeIterator
+	//
+
+	struct TreeIteratorImpl
+	{
+		TreeIteratorImpl() : strategy(TreeIterator::POSTORDER), cur(static_cast<Node*>(0)) { }
+		TreeIterator::Strategy strategy;
+		NodeVector stack;
+		NodePtr cur;
+		bool visited;
+	};
+
+	TreeIterator::TreeIterator(enum Strategy strategy)
+		: impl(new TreeIteratorImpl)
+	{
+		impl->strategy = strategy;
+	}
+
+	TreeIterator::TreeIterator(ParentPtr n, enum Strategy strategy)
+		: impl(new TreeIteratorImpl)
+	{
+		impl->strategy = strategy;
+		n->set_visited(false);
+		impl->stack.push_back(n);
+		increment();
+	}
+
+	TreeIterator::TreeIterator(Parent* n, enum Strategy strategy)
+		: impl(new TreeIteratorImpl)
+	{
+		impl->strategy = strategy;
+		add_children(n);
+		increment();
+	}
+
+	TreeIterator::TreeIterator(const TreeIterator& other)
+	{
+		impl = new TreeIteratorImpl;
+		*impl = *other.impl;
+	}
+
+	TreeIterator::~TreeIterator()
+	{
+		delete impl;
+	}
+
+	void TreeIterator::operator=(const TreeIterator& other)
+	{
+		*impl = *other.impl;
+	}
+
+	bool TreeIterator::get_visited() const
+	{
+		return impl->visited;
+	}
+
+	void TreeIterator::increment()
+	{
+		switch (impl->strategy) {
+		case POSTORDER:
+			this->increment_postorder();
+			break;
+		case PREORDER:
+		case HYBRID:
+			this->increment_preorder();
+			break;
+		};
+	}
+
+	void TreeIterator::add_children(Parent* p)
+	{
+		NodeVector::reverse_iterator i, rend;
+		rend = p->children().rend();
+		for (i = p->children().rbegin(); i != rend; ++i) {
+			(*i)->set_visited(false);
+			impl->stack.push_back(*i);
+		}
+
+	}
+
+	void TreeIterator::increment_preorder()
+	{
+		if (impl->stack.empty()) {
+			impl->cur.reset(static_cast<Node*>(0));
+			return;
+		}
+		impl->cur = impl->stack.back();
+		impl->visited = impl->cur->get_visited();
+		impl->stack.pop_back();
+
+		Parent* p = dynamic_cast<Parent*>(impl->cur.get());
+		if (p and !p->get_visited()) {
+			if (impl->strategy == HYBRID) {
+				p->set_visited(true);
+				impl->stack.push_back(impl->cur);
+			}
+			add_children(p);
+		}
+	}
+
+	void TreeIterator::increment_postorder()
+	{
+		while (1) {
+			if (impl->stack.empty()) {
+				impl->cur.reset(static_cast<Node*>(0));
+				return;
+			}
+			NodePtr n = impl->stack.back();
+			impl->stack.pop_back();
+
+			Parent* p = dynamic_cast<Parent*>(n.get());
+			if (n->get_visited() || p == 0) {
+				impl->cur = n;
+				break;
+			} else {
+				p->set_visited(true);
+				impl->stack.push_back(n);
+				add_children(p);
+			}
+		}
+	}
+
+	bool TreeIterator::equal(const TreeIterator& other) const
+	{
+		return impl->cur.get() == other.impl->cur.get();
+	}
+
+	NodePtr TreeIterator::dereference() const
+	{
+		return impl->cur;
+	}
+
+	//
+	// Parent
+	//
+
+
+	Parent::Parent()
+		: parent_impl(new ParentImpl) { }
+
+	Parent::Parent(const Parent& other)
+		: Node()
+	{
+		parent_impl = new ParentImpl;
+		*parent_impl = *other.parent_impl;
+	}
+
+	Parent::~Parent()
+	{
+		delete parent_impl;
+	}
+
+	void Parent::operator=(const Parent& other)
+	{
+		*parent_impl = *other.parent_impl;
+	}
+
+	void Parent::make_child(NodePtr node)
+	{
+		node->set_parent(this);		
+	}
+
+	void Parent::append_child(NodePtr node)
+	{
+		parent_impl->children.push_back(node);
+		make_child(node);
+	}
+
+	NodeVector& Parent::children()
+	{
+		return parent_impl->children;
+	}
+
+	Parent::iterator Parent::begin(enum TreeIterator::Strategy strategy)
+	{
+		return TreeIterator(this, strategy);
+	}
+
+	Parent::iterator Parent::end()
+	{
+		return TreeIterator();
+	}
+
+	bool Parent::ignore_indent() const
+	{
+		return false;
+	}
+
+	void output_tree(std::ostream& o, ParentPtr p)
+	{
+		OutputFormatter op;
+		output_tree(o, p, op);
+	}
+
+	void output_tree(std::ostream& o, ParentPtr p,
+			 OutputFormatter& op)
+	{
+		Parent::iterator i(p, TreeIterator::HYBRID), end;
+		
+		for (; i != end; ++i) {
+			o << op(i);
+		}
+		o << std::flush;
+
+	}
+
+} // namespace policyrep
Added: branches/policyrep/libpolicyrep/src/policy_base_internal.hpp
===================================================================
--- branches/policyrep/libpolicyrep/src/policy_base_internal.hpp	                        (rev 0)
+++ branches/policyrep/libpolicyrep/src/policy_base_internal.hpp	2007-07-11 16:3...
 
[truncated message content] |