]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_codesigning/antlr2/src/BaseAST.cpp
Security-55471.tar.gz
[apple/security.git] / libsecurity_codesigning / antlr2 / src / BaseAST.cpp
diff --git a/libsecurity_codesigning/antlr2/src/BaseAST.cpp b/libsecurity_codesigning/antlr2/src/BaseAST.cpp
new file mode 100644 (file)
index 0000000..0d2fba4
--- /dev/null
@@ -0,0 +1,281 @@
+/* ANTLR Translator Generator
+ * Project led by Terence Parr at http://www.jGuru.com
+ * Software rights: http://www.antlr.org/license.html
+ *
+ * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/BaseAST.cpp#2 $
+ */
+
+#include "antlr/config.hpp"
+
+//#include <iostream>
+
+#include "antlr/AST.hpp"
+#include "antlr/BaseAST.hpp"
+
+ANTLR_USING_NAMESPACE(std)
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+namespace antlr {
+#endif
+
+size_t BaseAST::getNumberOfChildren() const
+{
+       RefBaseAST t = this->down;
+       size_t n = 0;
+       if( t )
+       {
+               n = 1;
+               while( t->right )
+               {
+                       t = t->right;
+                       n++;
+               }
+               return n;
+       }
+       return n;
+}
+
+void BaseAST::doWorkForFindAll(
+               ANTLR_USE_NAMESPACE(std)vector<RefAST>& v,
+               RefAST target,bool partialMatch)
+{
+       // Start walking sibling lists, looking for matches.
+       for (RefAST sibling=this;
+                       sibling;
+                       sibling=sibling->getNextSibling())
+       {
+               if ( (partialMatch && sibling->equalsTreePartial(target)) ||
+                               (!partialMatch && sibling->equalsTree(target)) ) {
+                       v.push_back(sibling);
+               }
+               // regardless of match or not, check any children for matches
+               if ( sibling->getFirstChild() ) {
+                       RefBaseAST(sibling->getFirstChild())->doWorkForFindAll(v, target, partialMatch);
+               }
+       }
+}
+
+/** Is t an exact structural and equals() match of this tree.  The
+ *  'this' reference is considered the start of a sibling list.
+ */
+bool BaseAST::equalsList(RefAST t) const
+{
+       // the empty tree is not a match of any non-null tree.
+       if (!t)
+               return false;
+
+       // Otherwise, start walking sibling lists.  First mismatch, return false.
+       RefAST sibling=this;
+       for (;sibling && t;
+                       sibling=sibling->getNextSibling(), t=t->getNextSibling()) {
+               // as a quick optimization, check roots first.
+               if (!sibling->equals(t))
+                       return false;
+               // if roots match, do full list match test on children.
+               if (sibling->getFirstChild()) {
+                       if (!sibling->getFirstChild()->equalsList(t->getFirstChild()))
+                               return false;
+               }
+               // sibling has no kids, make sure t doesn't either
+               else if (t->getFirstChild())
+                       return false;
+       }
+
+       if (!sibling && !t)
+               return true;
+
+       // one sibling list has more than the other
+       return false;
+}
+
+/** Is 'sub' a subtree of this list?
+ *  The siblings of the root are NOT ignored.
+ */
+bool BaseAST::equalsListPartial(RefAST sub) const
+{
+       // the empty tree is always a subset of any tree.
+       if (!sub)
+               return true;
+
+       // Otherwise, start walking sibling lists.  First mismatch, return false.
+       RefAST sibling=this;
+       for (;sibling && sub;
+                       sibling=sibling->getNextSibling(), sub=sub->getNextSibling()) {
+               // as a quick optimization, check roots first.
+               if (!sibling->equals(sub))
+                       return false;
+               // if roots match, do partial list match test on children.
+               if (sibling->getFirstChild())
+                       if (!sibling->getFirstChild()->equalsListPartial(sub->getFirstChild()))
+                               return false;
+       }
+
+       if (!sibling && sub)
+               // nothing left to match in this tree, but subtree has more
+               return false;
+
+       // either both are null or sibling has more, but subtree doesn't
+       return true;
+}
+
+/** Is tree rooted at 'this' equal to 't'?  The siblings
+ *  of 'this' are ignored.
+ */
+bool BaseAST::equalsTree(RefAST t) const
+{
+       // check roots first
+       if (!equals(t))
+               return false;
+       // if roots match, do full list match test on children.
+       if (getFirstChild()) {
+               if (!getFirstChild()->equalsList(t->getFirstChild()))
+                       return false;
+       }
+       // sibling has no kids, make sure t doesn't either
+       else if (t->getFirstChild())
+               return false;
+
+       return true;
+}
+
+/** Is 'sub' a subtree of the tree rooted at 'this'?  The siblings
+ *  of 'this' are ignored.
+ */
+bool BaseAST::equalsTreePartial(RefAST sub) const
+{
+       // the empty tree is always a subset of any tree.
+       if (!sub)
+               return true;
+
+       // check roots first
+       if (!equals(sub))
+               return false;
+       // if roots match, do full list partial match test on children.
+       if (getFirstChild())
+               if (!getFirstChild()->equalsListPartial(sub->getFirstChild()))
+                       return false;
+
+       return true;
+}
+
+/** Walk the tree looking for all exact subtree matches.  Return
+ *  an ASTEnumerator that lets the caller walk the list
+ *  of subtree roots found herein.
+ */
+ANTLR_USE_NAMESPACE(std)vector<RefAST> BaseAST::findAll(RefAST target)
+{
+       ANTLR_USE_NAMESPACE(std)vector<RefAST> roots;
+
+       // the empty tree cannot result in an enumeration
+       if (target) {
+               doWorkForFindAll(roots,target,false); // find all matches recursively
+       }
+
+       return roots;
+}
+
+/** Walk the tree looking for all subtrees.  Return
+ *  an ASTEnumerator that lets the caller walk the list
+ *  of subtree roots found herein.
+ */
+ANTLR_USE_NAMESPACE(std)vector<RefAST> BaseAST::findAllPartial(RefAST target)
+{
+       ANTLR_USE_NAMESPACE(std)vector<RefAST> roots;
+
+       // the empty tree cannot result in an enumeration
+       if (target)
+               doWorkForFindAll(roots,target,true); // find all matches recursively
+
+       return roots;
+}
+
+ANTLR_USE_NAMESPACE(std)string BaseAST::toStringList() const
+{
+       ANTLR_USE_NAMESPACE(std)string ts="";
+
+       if (getFirstChild())
+       {
+               ts+=" ( ";
+               ts+=toString();
+               ts+=getFirstChild()->toStringList();
+               ts+=" )";
+       }
+       else
+       {
+               ts+=" ";
+               ts+=toString();
+       }
+
+       if (getNextSibling())
+               ts+=getNextSibling()->toStringList();
+
+       return ts;
+}
+
+ANTLR_USE_NAMESPACE(std)string BaseAST::toStringTree() const
+{
+       ANTLR_USE_NAMESPACE(std)string ts = "";
+
+       if (getFirstChild())
+       {
+               ts+=" ( ";
+               ts+=toString();
+               ts+=getFirstChild()->toStringList();
+               ts+=" )";
+       }
+       else
+       {
+               ts+=" ";
+               ts+=toString();
+       }
+       return ts;
+}
+
+#ifdef ANTLR_SUPPORT_XML
+/* This whole XML output stuff needs a little bit more thought
+ * I'd like to store extra XML data in the node. e.g. for custom ast's
+ * with for instance symboltable references. This
+ * should be more pluggable..
+ * @returns boolean value indicating wether a closetag should be produced.
+ */
+bool BaseAST::attributesToStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const
+{
+       out << "text=\"" << this->getText()
+               << "\" type=\"" << this->getType() << "\"";
+
+       return false;
+}
+
+void BaseAST::toStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const
+{
+       for( RefAST node = this; node != 0; node = node->getNextSibling() )
+       {
+               out << "<" << this->typeName() << " ";
+
+               // Write out attributes and if there is extra data...
+               bool need_close_tag = node->attributesToStream( out );
+
+               if( need_close_tag )
+               {
+                       // got children so write them...
+                       if( node->getFirstChild() != 0 )
+                               node->getFirstChild()->toStream( out );
+
+                       // and a closing tag..
+                       out << "</" << node->typeName() << ">" << endl;
+               }
+       }
+}
+#endif
+
+// this is nasty, but it makes the code generation easier
+ANTLR_API RefAST nullAST;
+
+#if defined(_MSC_VER) && !defined(__ICL) // Microsoft Visual C++
+extern ANTLR_API AST* const nullASTptr = 0;
+#else
+ANTLR_API AST* const nullASTptr = 0;
+#endif
+
+#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
+}
+#endif