Utils: Refactor hexdump() helper to move code out of template function
g0dil [Wed, 14 May 2008 18:01:51 +0000 (18:01 +0000)]
Utils: Replace TypeInfo demangle implementation from binutils with cxxabi implementation
Console: Implement Executor chroot and security policy support
Console: Refactor Node::traverse() implementaiton to move code out of template function

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@843 270642c3-0616-0410-b53a-bc976706d245

25 files changed:
Console/Executor.cc
Console/Executor.cci
Console/Executor.ct [new file with mode: 0644]
Console/Executor.hh
Console/Executor.test.cc
Console/Node.cc
Console/Node.cci
Console/Node.ct
Console/Node.cti
Console/Node.hh
Console/Node.ih [new file with mode: 0644]
Mainpage.dox
SConstruct
Utils/TypeInfo.cc
Utils/TypeInfo.hh
Utils/hexdump.cc [new file with mode: 0644]
Utils/hexdump.cci [new file with mode: 0644]
Utils/hexdump.ct
Utils/hexdump.hh
Utils/hexdump.ih [new file with mode: 0644]
Utils/hexdump.test.cc
Utils/impl/demangle.h [deleted file]
Utils/type_traits.hh
Utils/type_traits.mpp
senfscons/senfutil.py

index fdbb850..3533a0e 100644 (file)
@@ -52,7 +52,7 @@ prefix_ void senf::console::Executor::execute(std::ostream & output,
     SENF_LOG(( "Executing: " << command ));
 
     if (cwd_.expired() || ! cwd().active())
-        cwd_ = root().thisptr();
+        cwd_ = root_;
 
     try {
         switch(command.builtin()) {
@@ -77,7 +77,7 @@ prefix_ void senf::console::Executor::execute(std::ostream & output,
                     && command.arguments().begin()->begin()->value() == "-") {
                     if (oldCwd_.expired() || ! oldCwd_.lock()->active()) {
                         oldCwd_ = cwd_;
-                        cwd_ = root().thisptr();
+                        cwd_ = root_;
                     } else
                         swap(cwd_, oldCwd_);
                 }
@@ -138,17 +138,18 @@ prefix_ void senf::console::Executor::execute(std::ostream & output,
     catch (InvalidCommandException &) {
         output << "invalid command" << std::endl;
     }
+    catch (IgnoreCommandException &) {}
 }
 
 prefix_ senf::console::GenericNode &
 senf::console::Executor::traverseNode(ParseCommandInfo::TokensRange const & path)
 {
     try {
-        return cwd().traverse(
+        return traverse(
+            cwd(),
             boost::make_iterator_range(
                 boost::make_transform_iterator(path.begin(), TraverseTokens()),
-                boost::make_transform_iterator(path.end(), TraverseTokens())),
-            autocomplete_);
+                boost::make_transform_iterator(path.end(), TraverseTokens())) );
     }
     catch (std::bad_cast &) {
         throw InvalidPathException();
@@ -162,7 +163,7 @@ prefix_ senf::console::GenericNode &
 senf::console::Executor::traverseCommand(ParseCommandInfo::CommandPathRange const & path)
 {
     try {
-        return cwd().traverse(path, autocomplete_);
+        return traverse(cwd(), path);
     }
     catch (std::bad_cast &) {
         throw InvalidPathException();
index 89e2501..744737e 100644 (file)
 // senf::console::Executor
 
 prefix_ senf::console::Executor::Executor()
-    : autocd_ (false), autocomplete_ (false)
-{
-    oldCwd_ = cwd_ = boost::static_pointer_cast<DirectoryNode>(
-        root().shared_from_this());
-}
+    : root_(senf::console::root().thisptr()), cwd_ (root_), oldCwd_ (cwd_),
+      autocd_ (false), autocomplete_ (false)
+{}
 
 prefix_ void senf::console::Executor::operator()(std::ostream & output,
                                                  ParseCommandInfo const & command)
@@ -76,6 +74,26 @@ prefix_ senf::console::Executor & senf::console::Executor::autocomplete(bool v)
     return *this;
 }
 
+prefix_ senf::console::DirectoryNode & senf::console::Executor::chroot()
+    const
+{
+    return *root_;
+}
+
+prefix_ senf::console::Executor & senf::console::Executor::chroot(DirectoryNode & node)
+{
+    root_ = node.thisptr();
+    cwd_ = root_;
+    oldCwd_ = root_;
+    return *this;
+}
+
+prefix_ senf::console::Executor & senf::console::Executor::policy(SecurityPolicy policy)
+{
+    policy_ = policy;
+    return *this;
+}
+
 ///////////////////////////////cci.e///////////////////////////////////////
 #undef prefix_
 
diff --git a/Console/Executor.ct b/Console/Executor.ct
new file mode 100644 (file)
index 0000000..4123d85
--- /dev/null
@@ -0,0 +1,64 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief Executor non-inline template implementation  */
+
+//#include "Executor.ih"
+
+// Custom includes
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::Executor
+
+template <class ForwardRange>
+prefix_ senf::console::GenericNode &
+senf::console::Executor::traverse(DirectoryNode & dir, ForwardRange const & range)
+{
+    typedef typename boost::range_const_iterator<ForwardRange>::type const_iterator;
+    detail::NodeTraverser traverser (*root_, dir, autocomplete_);
+    const_iterator i (boost::begin(range));
+    const_iterator const i_end (boost::end(range));
+    for (; i != i_end; ++i) {
+        if ( policy_ && (*i) != std::string("") && (*i) != std::string(".") )
+            policy_( dynamic_cast<DirectoryNode &>(traverser.node()), *i );
+        traverser( *i );
+    }
+    return traverser.node();
+}
+
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
index 86e54be..e126590 100644 (file)
@@ -66,6 +66,12 @@ namespace console {
         /// Thrown by built-in 'exit' command
         struct ExitException {};        
 
+        /// Executor policy function
+        typedef boost::function<void (DirectoryNode &,std::string const &)> SecurityPolicy;
+
+        /// Thrown by the SecurityPolicy to silently ignore a command
+        struct IgnoreCommandException {};
+
         ///////////////////////////////////////////////////////////////////////////
         //\/name Structors and default members
         ///\{
@@ -104,6 +110,20 @@ namespace console {
         Executor & autocomplete(bool v); ///< Set autocomplete status
                                         /**< \see autocomplete() */
 
+        DirectoryNode & chroot() const; ///< Get root node
+                                        /**< The root node defaults to senf::console::root(). If
+                                             changed, all path references are relative to this node
+                                             and objects outside that tree cannot be accessed. */ 
+        Executor & chroot(DirectoryNode & node); ///< chroot into given directory
+                                        /**< After this call, all path's are interpreted relative to
+                                             \a node and only nodes in the tree rooted at \a node
+                                             are accessible via the executor. This value defaults to
+                                             senf::console::root(). */
+
+        Executor & policy(SecurityPolicy policy); ///< Set security policy
+                                        /**< The security policy is called before traversing a node
+                                             to validate that access. */
+
     protected:
 
     private:
@@ -111,10 +131,15 @@ namespace console {
         GenericNode & traverseCommand(ParseCommandInfo::CommandPathRange const & path); 
         DirectoryNode & traverseDirectory(ParseCommandInfo::TokensRange const & path);
 
+        template <class ForwardRange>
+        GenericNode & traverse(DirectoryNode & dir, ForwardRange const & range);
+
         struct InvalidPathException {};
         struct InvalidDirectoryException {};
         struct InvalidCommandException {};
-
+        
+        DirectoryNode::ptr root_;
+        SecurityPolicy policy_;
         DirectoryNode::weak_ptr cwd_;
         DirectoryNode::weak_ptr oldCwd_;
         typedef std::vector<DirectoryNode::weak_ptr> DirStack;
@@ -129,7 +154,7 @@ namespace console {
 
 ///////////////////////////////hh.e////////////////////////////////////////
 #include "Executor.cci"
-//#include "Executor.ct"
+#include "Executor.ct"
 //#include "Executor.cti"
 #endif
 
index 7453af2..0e751f1 100644 (file)
@@ -163,6 +163,71 @@ BOOST_AUTO_UNIT_TEST(executor)
     senf::console::root().remove("dir2");
 }
 
+BOOST_AUTO_UNIT_TEST(executorChroot)
+{
+    senf::console::root().mkdir("dir1").mkdir("dir3");
+    senf::console::root().mkdir("dir2").doc("Helptext").add("test",&testCommand);
+
+    senf::console::Executor executor;
+    senf::console::CommandParser parser;
+
+    executor.chroot( senf::console::root()["dir2"] );
+
+    BOOST_CHECK( & executor.chroot() == & senf::console::root()["dir2"] );
+
+    {
+        std::stringstream os;
+        parser.parse("../test", &setCommand);
+        executor(os, commands.back());
+        BOOST_CHECK_EQUAL( commands.back().builtin(), senf::console::ParseCommandInfo::NoBuiltin );
+        BOOST_CHECK_EQUAL( os.str(), "testCommand\n" );
+    }
+
+    commands.clear();
+    senf::console::root().remove("dir1");
+    senf::console::root().remove("dir2");
+}
+
+namespace {
+    
+    void testPolicy(senf::console::DirectoryNode & dir, std::string const & entry)
+    {
+        if (dir == senf::console::root() && entry == "dir2")
+            throw senf::console::Executor::IgnoreCommandException();
+    }
+}
+
+BOOST_AUTO_UNIT_TEST(executorPolicy)
+{
+    senf::console::root().mkdir("dir1").mkdir("dir3");
+    senf::console::root().mkdir("dir2").doc("Helptext").add("test",&testCommand);
+
+    senf::console::Executor executor;
+    senf::console::CommandParser parser;
+
+    executor.policy(&testPolicy);
+
+    {
+        std::stringstream os;
+        parser.parse("ls dir1", &setCommand);
+        executor(os, commands.back());
+        BOOST_CHECK_EQUAL( commands.back().builtin(), senf::console::ParseCommandInfo::BuiltinLS );
+        BOOST_CHECK_EQUAL( os.str(), "dir3/\n" );
+    }
+
+    {
+        std::stringstream os;
+        parser.parse("dir2/test", &setCommand);
+        executor(os, commands.back());
+        BOOST_CHECK_EQUAL( commands.back().builtin(), senf::console::ParseCommandInfo::NoBuiltin );
+        BOOST_CHECK_EQUAL( os.str(), "" );
+    }
+
+    commands.clear();
+    senf::console::root().remove("dir1");
+    senf::console::root().remove("dir2");
+}
+
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_
 
index 4886b77..3e16667 100644 (file)
@@ -24,7 +24,7 @@
     \brief Node non-inline non-template implementation */
 
 #include "Node.hh"
-//#include "Node.ih"
+#include "Node.ih"
 
 // Custom includes
 
@@ -53,6 +53,23 @@ prefix_ std::string senf::console::GenericNode::path()
     return path.empty() ? "/" : path;
 }
 
+prefix_ std::string senf::console::GenericNode::path(DirectoryNode const & root)
+    const
+{
+    std::string path;
+    cptr node (thisptr());
+    while (node && node != root.thisptr()) {
+        if (! path.empty())
+            path = node->name() + "/" + path;
+        else
+            path = node->name();
+        node = node->parent();
+    }
+    if (path.empty() || path[0] != '/')
+        path = "/" + path;
+    return path;
+}
+
 prefix_ bool senf::console::GenericNode::active()
     const
 {
@@ -62,6 +79,15 @@ prefix_ bool senf::console::GenericNode::active()
     return node == root().thisptr();
 }
 
+prefix_ bool senf::console::GenericNode::isChildOf(DirectoryNode & parent)
+    const
+{
+    cptr node (thisptr());
+    while (node && node != parent.thisptr())
+        node = node->parent();
+    return node;
+}
+
 ///////////////////////////////////////////////////////////////////////////
 //senf::console::DirectoryNode
 
@@ -117,6 +143,53 @@ prefix_ void senf::console::DirectoryNode::v_help(std::ostream & output)
 }
 
 ///////////////////////////////////////////////////////////////////////////
+// senf::console::detail::NodeTraverser
+
+prefix_ void senf::console::detail::NodeTraverser::operator()(std::string const & name)
+{
+    if (! init_) {
+        init_ = true;
+        if (name == std::string("")) {
+            dir_ = root_.thisptr();
+            return;
+        }
+    }
+    if (! elt_.empty()) {
+        if (elt_ == "..") {
+            dir_ = dir_->parent();
+            if (! dir_ || ! dir_->isChildOf(root_))
+                dir_ = root_.thisptr();
+        }
+        else if (elt_ != "" && elt_ != ".") {
+            if (! dir_->hasChild(elt_) && autocomplete_) {
+                DirectoryNode::ChildrenRange completions (dir_->completions(elt_));
+                if (completions.size() == 1)
+                    elt_ = completions.begin()->first;
+            }
+            // Why does g++ give an error on this line ???? :
+            // dir = dynamic_cast<DirectoryNode&>( dir->get(name) ).thisptr();
+            DirectoryNode & d (dynamic_cast<DirectoryNode&>( dir_->get(elt_) ));
+            dir_ = d.thisptr();
+        }
+    }
+    elt_ = name;
+}
+
+prefix_ senf::console::GenericNode & senf::console::detail::NodeTraverser::node()
+{
+    if (elt_ != "" && elt_ != ".") {
+        if (! dir_->hasChild(elt_) && autocomplete_) {
+            DirectoryNode::ChildrenRange completions (dir_->completions(elt_));
+            if (completions.size() == 1)
+                elt_ = completions.begin()->first;
+        }
+        return dir_->get(elt_);
+    }
+    else
+        return * dir_;
+}
+
+///////////////////////////////////////////////////////////////////////////
 // senf::console::SyntaxErrorException
 
 prefix_ char const * senf::console::SyntaxErrorException::what()
index 0193989..108902a 100644 (file)
@@ -23,7 +23,7 @@
 /** \file
     \brief Node inline non-template implementation */
 
-//#include "Node.ih"
+#include "Node.ih"
 
 // Custom includes
 #include "../Utils/senfassert.hh"
@@ -84,6 +84,18 @@ prefix_ senf::console::GenericNode::cptr senf::console::GenericNode::thisptr()
     return shared_from_this();
 }
 
+prefix_ bool senf::console::GenericNode::operator==(GenericNode & other)
+    const
+{
+    return this == & other;
+}
+
+prefix_ bool senf::console::GenericNode::operator!=(GenericNode & other)
+    const
+{
+    return this != & other;
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // senf::console::DirectoryNode
 
@@ -175,6 +187,15 @@ prefix_ senf::console::DirectoryNode::cptr senf::console::DirectoryNode::thisptr
 }
 
 ///////////////////////////////////////////////////////////////////////////
+// senf::console::detail::NodeTraverser
+
+prefix_ senf::console::detail::NodeTraverser::NodeTraverser(DirectoryNode & root,
+                                                            DirectoryNode & dir,
+                                                            bool autocomplete)
+    : root_ (root), dir_ (dir.thisptr()), autocomplete_ (autocomplete), init_ (false)
+{}
+
+///////////////////////////////////////////////////////////////////////////
 // senf::console::SyntaxErrorException
 
 prefix_ senf::console::SyntaxErrorException::SyntaxErrorException(std::string const & msg)
index ddf17ac..c9516c0 100644 (file)
@@ -23,7 +23,7 @@
 /** \file
     \brief Node non-inline template implementation  */
 
-//#include "Node.ih"
+#include "Node.ih"
 
 // Custom includes
 #include <boost/range.hpp>
 
 template <class ForwardRange>
 prefix_ senf::console::GenericNode &
-senf::console::DirectoryNode::traverse(ForwardRange const & range, bool autocomplete)
+senf::console::DirectoryNode::traverse(ForwardRange const & range, bool autocomplete,
+                                       DirectoryNode & root)
 {
     typedef typename boost::range_const_iterator<ForwardRange>::type const_iterator;
-    DirectoryNode::ptr dir (thisptr());
+    detail::NodeTraverser traverser (root, *this, autocomplete);
     const_iterator i (boost::begin(range));
     const_iterator const i_end (boost::end(range));
-    if (i != i_end && *i == std::string("")) {
-        dir = root().thisptr();
-        ++ i;
-    }
-    while (i != i_end) {
-        const_iterator next_i (i);
-        ++ next_i;
-        if (*i == std::string("..")) {
-            dir = dir->parent();
-            if (! dir)
-                dir = root().thisptr();
-        }
-        else if (*i != std::string("") && *i != std::string(".")) {
-            std::string name (*i);
-            if (! dir->hasChild(name) && autocomplete) {
-                ChildrenRange completions (dir->completions(name));
-                if (completions.size() == 1)
-                    name = completions.begin()->first;
-            }
-            if (next_i == i_end)
-                return dir->get(name);
-            else {
-                // Why does g++ give an error on this line ???? :
-                // dir = dynamic_cast<DirectoryNode&>( dir->get(name) ).thisptr();
-                DirectoryNode & d (dynamic_cast<DirectoryNode&>( dir->get(name) ));
-                dir = d.thisptr();
-            }
-        }
-        i = next_i;
-    }
-    return *dir;
+    for (; i != i_end; ++i)
+        traverser( *i );
+    return traverser.node();
 }
 
 ///////////////////////////////ct.e////////////////////////////////////////
index a6e113f..b7f118b 100644 (file)
@@ -23,7 +23,7 @@
 /** \file
     \brief Node inline template implementation */
 
-//#include "Node.ih"
+#include "Node.ih"
 
 // Custom includes
 
index 0349831..0bfc594 100644 (file)
@@ -218,6 +218,8 @@ namespace console {
     class DirectoryNode;
     class CommandNode;
 
+    DirectoryNode & root();
+
     /** \brief Config/console node tree base-class
 
         GenericNode is the base class of all node objects. There are two basic node types derived
@@ -259,6 +261,10 @@ namespace console {
         std::string path() const;       ///< Node path
                                         /**< The node path is built by joining the names of all
                                              parent nodes with '/' chars. */
+        std::string path(DirectoryNode const & root) const;       
+                                        ///< Node path up to \a root
+                                        /**< The node path is built by joining the names of all
+                                             parent nodes up to \a root with '/' chars. */
 
         ptr unlink();                   ///< Remove node from it's parent directory
                                         /**< You may either discard the return value and thereby
@@ -272,6 +278,16 @@ namespace console {
         ptr thisptr();                  ///< Get smart pointer to node
         cptr thisptr() const;           ///< Get smart pointer to node (const)
 
+        bool isChildOf(DirectoryNode & parent) const;
+                                        ///< \c true, if node is a child of \a parent
+                                        /**< Will also return \c true, if \a parent is the current
+                                             node. */
+
+        bool operator== (GenericNode & other) const;
+                                        /// \c true, if this and \a other are the same node
+        bool operator!= (GenericNode & other) const;
+                                        /// \c true, if this and \a other are different nodes
+
     protected:
         GenericNode();
 
@@ -476,7 +492,8 @@ namespace console {
         ///////////////////////////////////////////////////////////////////////////
 
         template <class ForwardRange>
-        GenericNode & traverse(ForwardRange const & range, bool autocomplete=false);
+        GenericNode & traverse(ForwardRange const & range, bool autocomplete=false,
+                               DirectoryNode & root = root());
                                         ///< Traverse node path starting at this node
                                         /**< The <tt>ForwardRange::value_type</tt> must be
                                              (convertible to) std::string. Each range element
@@ -641,8 +658,6 @@ namespace console {
 
 #endif
 
-    DirectoryNode & root();
-
 }}
 
 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
diff --git a/Console/Node.ih b/Console/Node.ih
new file mode 100644 (file)
index 0000000..1a02bdd
--- /dev/null
@@ -0,0 +1,72 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief Node internal header */
+
+#ifndef IH_Node_
+#define IH_Node_ 1
+
+// Custom includes
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace senf {
+namespace console {
+namespace detail {
+
+#ifndef DOXYGEN
+
+    class NodeTraverser
+    {
+    public:
+        NodeTraverser(DirectoryNode & root, DirectoryNode & dir, bool autocomplete);
+        
+        void operator()(std::string const & name);
+        
+        GenericNode & node();
+      
+    private:
+        DirectoryNode & root_;
+        DirectoryNode::ptr dir_;
+        bool autocomplete_;
+        std::string elt_;
+        bool init_;
+    };
+
+#endif
+
+}}}
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
index f7ff985..049d80c 100644 (file)
 
     env = Environment(
 
-        LIBS     = [ 'senf', 'iberty', 'boost_regex', 'boost_iostreams' ],
+        LIBS     = [ 'senf', 'boost_regex', 'boost_iostreams' ],
         CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long' ],
 
     )
index d316b40..88dd14f 100644 (file)
@@ -142,7 +142,7 @@ def configFilesOpts(target, source, env, for_signature):
 
 env.Append(
    CPPPATH = [ '#/include' ],
-   LIBS = [ 'iberty', 'readline', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB' ],
+   LIBS = [ 'readline', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB' ],
    TEST_EXTRA_LIBS = [ '$BOOSTFSLIB' ],
    DOXY_XREF_TYPES = [ 'bug', 'fixme', 'todo', 'idea' ],
    DOXY_HTML_XSL = '#/doclib/html-munge.xsl',
index 1c18256..bed2876 100644 (file)
 //#include "TypeInfo.ih"
 
 // Custom includes
-#include "malloc.h"
-
-// Copied from the binutils sources 
-#define HAVE_DECL_BASENAME 1
-#define HAVE_DECL_ASPRINTF 1
-#define HAVE_DECL_VASPRINTF 1
-#include "impl/demangle.h"
+#include <cxxabi.h>
+#include <malloc.h>
 
 //#include "TypeInfo.mpp"
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-
-// WARNING: This is completely g++ and libiberty dependent. The demangling
-// interface isn't even explicitly exportet from libiberty. However, it is
-// *EXTREMELY* helpful for debugging ...
-
 prefix_ std::string senf::prettyName(std::type_info const & type)
 {
     char const * mangled = type.name();
-    char * demangled = ::cplus_demangle(mangled,DMGL_TYPES|DMGL_AUTO);
+    int status (0);
+    char * demangled ( abi::__cxa_demangle(mangled, 0, 0, &status) );
     std::string name (demangled ? demangled : mangled);
     if (demangled)
         ::free(demangled);
index 7244351..ef4b720 100644 (file)
@@ -41,12 +41,6 @@ namespace senf {
         given type_info object. If the demangling fails, the possibly
         mangled name (type->name()) will be returned.
 
-        This function depends on the liberty library provided by the
-        linux binutils or binutils-dev packages. It also depends on an
-        internal header file. If the API should change, this header
-        file (which resides in impl/demangle.h) must be updated from
-        the binutils sources.
-
         \param[in] type type_info object
         \returns type name, possibly demangled
      */
diff --git a/Utils/hexdump.cc b/Utils/hexdump.cc
new file mode 100644 (file)
index 0000000..9f08553
--- /dev/null
@@ -0,0 +1,81 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief hexdump non-inline non-template implementation */
+
+#include "hexdump.hh"
+#include "hexdump.ih"
+
+// Custom includes
+#include <iomanip> 
+
+//#include "hexdump.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ void senf::detail::HexDumper::operator()(unsigned ch)
+{
+    if ((offset_ % block_size_) == 0) {
+        if (!ascii_.empty()) {
+            os_ << "  " << ascii_ << "\n";
+            ascii_ = "";
+        }
+        os_ << "  "
+               << std::hex << std::setw(4) << std::setfill('0')
+               << offset_ << ' ';
+    } else if ((offset_ % block_size_) == block_size_/2) {
+        os_ << " ";
+        ascii_ += ' ';
+    }
+    os_ << ' ' << std::hex << std::setw(2) << std::setfill('0')
+           << ch;
+    ascii_ += (ch >= ' ' && ch < 126) ? ch : '.';
+    ++ offset_;
+}
+
+prefix_ senf::detail::HexDumper::~HexDumper()
+{
+    if (!ascii_.empty()) {
+        for (; (offset_ % block_size_) != 0; ++offset_) {
+            if ((offset_ % block_size_) == block_size_/2)
+                os_ << " ";
+            os_ << "   ";
+        }
+        os_ << "  " << ascii_ << "\n";
+    }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "hexdump.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Utils/hexdump.cci b/Utils/hexdump.cci
new file mode 100644 (file)
index 0000000..7544966
--- /dev/null
@@ -0,0 +1,53 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief hexdump inline non-template implementation */
+
+#include "hexdump.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+//senf::detail::HexDumper
+
+prefix_ senf::detail::HexDumper::HexDumper(std::ostream & os, unsigned block_size)
+    : os_ (os), ias_ (os_), block_size_ (block_size), offset_ (0)
+{}
+
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
index 513b1a4..76abf99 100644 (file)
 /** \file
     \brief hexdump non-inline template implementation */
 
-//#include "hexdump.ih"
+#include "hexdump.ih"
 
 // Custom includes
-#include <boost/io/ios_state.hpp>
-#include <iomanip> 
 
 //#include "hexdump.mpp"
 #define prefix_
@@ -37,34 +35,9 @@ template <class Iterator>
 prefix_ void senf::hexdump(Iterator i, Iterator i_end, std::ostream & stream,
                            unsigned block_size)
 {
-    boost::io::ios_all_saver ias (stream);
-    unsigned offset (0);
-    std::string ascii;
-    for (; i != i_end; ++i, ++offset) {
-        if ((offset % block_size) == 0) {
-            if (!ascii.empty()) {
-                stream << "  " << ascii << "\n";
-                ascii = "";
-            }
-            stream << "  "
-                   << std::hex << std::setw(4) << std::setfill('0')
-                   << offset << ' ';
-        } else if ((offset % block_size) == block_size/2) {
-            stream << " ";
-            ascii += ' ';
-        }
-        stream << ' ' << std::hex << std::setw(2) << std::setfill('0')
-               << unsigned(*i);
-        ascii += (*i >= ' ' && *i < 126) ? *i : '.';
-    }
-    if (!ascii.empty()) {
-        for (; (offset % block_size) != 0; ++offset) {
-            if ((offset % block_size) == block_size/2)
-                stream << " ";
-            stream << "   ";
-        }
-        stream << "  " << ascii << "\n";
-    }
+    detail::HexDumper dumper (stream, block_size);
+    for (; i != i_end; ++i)
+        dumper(*i);
 }
 
 ///////////////////////////////cc.e////////////////////////////////////////
index 9dc9458..4cd5062 100644 (file)
@@ -41,7 +41,7 @@ namespace senf {
 }
 
 ///////////////////////////////hh.e////////////////////////////////////////
-//#include "hexdump.cci"
+#include "hexdump.cci"
 #include "hexdump.ct"
 //#include "hexdump.cti"
 //#include "hexdump.mpp"
diff --git a/Utils/hexdump.ih b/Utils/hexdump.ih
new file mode 100644 (file)
index 0000000..2c530a8
--- /dev/null
@@ -0,0 +1,74 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief hexdump internal header */
+
+#ifndef IH_hexdump_
+#define IH_hexdump_ 1
+
+// Custom includes
+#include <string>
+#include <boost/io/ios_state.hpp>
+#include <boost/utility.hpp>
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace senf {
+namespace detail {
+
+#ifndef DOXYGEN
+
+    class HexDumper
+        : boost::noncopyable
+    {
+    public:
+        HexDumper(std::ostream & os, unsigned block_size);
+        ~HexDumper();
+
+        void operator()(unsigned ch);
+
+    private:
+        std::ostream & os_;
+        boost::io::ios_all_saver ias_;
+        unsigned block_size_;
+        unsigned offset_;
+        std::string ascii_;
+    };
+
+#endif
+
+}}
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
index 7e71797..8a17a40 100644 (file)
@@ -40,8 +40,8 @@ BOOST_AUTO_UNIT_TEST(hExDuMp)
 {
     char data[] = { 0x18, 0x19, 0x20, 0x21, 0x7c, 0x7d, 0x7e, 0x7f };
     std::stringstream s;
-    senf::hexdump(data, data+sizeof(data), s, 8);
-    BOOST_CHECK_EQUAL( s.str(), "  0000  18 19 20 21  7c 7d 7e 7f  .. ! |}..\n" );
+    senf::hexdump(data, data+sizeof(data), s, 10);
+    BOOST_CHECK_EQUAL( s.str(), "  0000  18 19 20 21 7c  7d 7e 7f        .. !| }..\n" );
 }
 
 ///////////////////////////////cc.e////////////////////////////////////////
diff --git a/Utils/impl/demangle.h b/Utils/impl/demangle.h
deleted file mode 100644 (file)
index a532366..0000000
+++ /dev/null
@@ -1,533 +0,0 @@
-/* Defs for interface to demanglers.
-   Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002,
-   2003, 2004 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program 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 General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-
-#if !defined (DEMANGLE_H)
-#define DEMANGLE_H
-
-#include "libiberty.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* Options passed to cplus_demangle (in 2nd parameter). */
-
-#define DMGL_NO_OPTS     0              /* For readability... */
-#define DMGL_PARAMS      (1 << 0)       /* Include function args */
-#define DMGL_ANSI        (1 << 1)       /* Include const, volatile, etc */
-#define DMGL_JAVA        (1 << 2)       /* Demangle as Java rather than C++. */
-#define DMGL_VERBOSE     (1 << 3)       /* Include implementation details.  */
-#define DMGL_TYPES       (1 << 4)       /* Also try to demangle type encodings.  */
-
-#define DMGL_AUTO        (1 << 8)
-#define DMGL_GNU         (1 << 9)
-#define DMGL_LUCID       (1 << 10)
-#define DMGL_ARM         (1 << 11)
-#define DMGL_HP          (1 << 12)       /* For the HP aCC compiler;
-                                            same as ARM except for
-                                            template arguments, etc. */
-#define DMGL_EDG         (1 << 13)
-#define DMGL_GNU_V3      (1 << 14)
-#define DMGL_GNAT        (1 << 15)
-
-/* If none of these are set, use 'current_demangling_style' as the default. */
-#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT)
-
-/* Enumeration of possible demangling styles.
-
-   Lucid and ARM styles are still kept logically distinct, even though
-   they now both behave identically.  The resulting style is actual the
-   union of both.  I.E. either style recognizes both "__pt__" and "__rf__"
-   for operator "->", even though the first is lucid style and the second
-   is ARM style. (FIXME?) */
-
-extern enum demangling_styles
-{
-  no_demangling = -1,
-  unknown_demangling = 0,
-  auto_demangling = DMGL_AUTO,
-  gnu_demangling = DMGL_GNU,
-  lucid_demangling = DMGL_LUCID,
-  arm_demangling = DMGL_ARM,
-  hp_demangling = DMGL_HP,
-  edg_demangling = DMGL_EDG,
-  gnu_v3_demangling = DMGL_GNU_V3,
-  java_demangling = DMGL_JAVA,
-  gnat_demangling = DMGL_GNAT
-} current_demangling_style;
-
-/* Define string names for the various demangling styles. */
-
-#define NO_DEMANGLING_STYLE_STRING            "none"
-#define AUTO_DEMANGLING_STYLE_STRING          "auto"
-#define GNU_DEMANGLING_STYLE_STRING           "gnu"
-#define LUCID_DEMANGLING_STYLE_STRING         "lucid"
-#define ARM_DEMANGLING_STYLE_STRING           "arm"
-#define HP_DEMANGLING_STYLE_STRING            "hp"
-#define EDG_DEMANGLING_STYLE_STRING           "edg"
-#define GNU_V3_DEMANGLING_STYLE_STRING        "gnu-v3"
-#define JAVA_DEMANGLING_STYLE_STRING          "java"
-#define GNAT_DEMANGLING_STYLE_STRING          "gnat"
-
-/* Some macros to test what demangling style is active. */
-
-#define CURRENT_DEMANGLING_STYLE current_demangling_style
-#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO)
-#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU)
-#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID)
-#define ARM_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_ARM)
-#define HP_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_HP)
-#define EDG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_EDG)
-#define GNU_V3_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU_V3)
-#define JAVA_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_JAVA)
-#define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT)
-
-/* Provide information about the available demangle styles. This code is
-   pulled from gdb into libiberty because it is useful to binutils also.  */
-
-extern const struct demangler_engine
-{
-  const char *const demangling_style_name;
-  const enum demangling_styles demangling_style;
-  const char *const demangling_style_doc;
-} libiberty_demanglers[];
-
-extern char *
-cplus_demangle PARAMS ((const char *mangled, int options));
-
-extern int
-cplus_demangle_opname PARAMS ((const char *opname, char *result, int options));
-
-extern const char *
-cplus_mangle_opname PARAMS ((const char *opname, int options));
-
-/* Note: This sets global state.  FIXME if you care about multi-threading. */
-
-extern void
-set_cplus_marker_for_demangling PARAMS ((int ch));
-
-extern enum demangling_styles
-cplus_demangle_set_style PARAMS ((enum demangling_styles style));
-
-extern enum demangling_styles
-cplus_demangle_name_to_style PARAMS ((const char *name));
-
-/* V3 ABI demangling entry points, defined in cp-demangle.c.  */
-extern char*
-cplus_demangle_v3 PARAMS ((const char* mangled, int options));
-
-extern char*
-java_demangle_v3 PARAMS ((const char* mangled));
-
-
-enum gnu_v3_ctor_kinds {
-  gnu_v3_complete_object_ctor = 1,
-  gnu_v3_base_object_ctor,
-  gnu_v3_complete_object_allocating_ctor
-};
-
-/* Return non-zero iff NAME is the mangled form of a constructor name
-   in the G++ V3 ABI demangling style.  Specifically, return an `enum
-   gnu_v3_ctor_kinds' value indicating what kind of constructor
-   it is.  */
-extern enum gnu_v3_ctor_kinds
-        is_gnu_v3_mangled_ctor PARAMS ((const char *name));
-
-
-enum gnu_v3_dtor_kinds {
-  gnu_v3_deleting_dtor = 1,
-  gnu_v3_complete_object_dtor,
-  gnu_v3_base_object_dtor
-};
-
-/* Return non-zero iff NAME is the mangled form of a destructor name
-   in the G++ V3 ABI demangling style.  Specifically, return an `enum
-   gnu_v3_dtor_kinds' value, indicating what kind of destructor
-   it is.  */
-extern enum gnu_v3_dtor_kinds
-        is_gnu_v3_mangled_dtor PARAMS ((const char *name));
-
-/* The V3 demangler works in two passes.  The first pass builds a tree
-   representation of the mangled name, and the second pass turns the
-   tree representation into a demangled string.  Here we define an
-   interface to permit a caller to build their own tree
-   representation, which they can pass to the demangler to get a
-   demangled string.  This can be used to canonicalize user input into
-   something which the demangler might output.  It could also be used
-   by other demanglers in the future.  */
-
-/* These are the component types which may be found in the tree.  Many
-   component types have one or two subtrees, referred to as left and
-   right (a component type with only one subtree puts it in the left
-   subtree).  */
-
-enum demangle_component_type
-{
-  /* A name, with a length and a pointer to a string.  */
-  DEMANGLE_COMPONENT_NAME,
-  /* A qualified name.  The left subtree is a class or namespace or
-     some such thing, and the right subtree is a name qualified by
-     that class.  */
-  DEMANGLE_COMPONENT_QUAL_NAME,
-  /* A local name.  The left subtree describes a function, and the
-     right subtree is a name which is local to that function.  */
-  DEMANGLE_COMPONENT_LOCAL_NAME,
-  /* A typed name.  The left subtree is a name, and the right subtree
-     describes that name as a function.  */
-  DEMANGLE_COMPONENT_TYPED_NAME,
-  /* A template.  The left subtree is a template name, and the right
-     subtree is a template argument list.  */
-  DEMANGLE_COMPONENT_TEMPLATE,
-  /* A template parameter.  This holds a number, which is the template
-     parameter index.  */
-  DEMANGLE_COMPONENT_TEMPLATE_PARAM,
-  /* A constructor.  This holds a name and the kind of
-     constructor.  */
-  DEMANGLE_COMPONENT_CTOR,
-  /* A destructor.  This holds a name and the kind of destructor.  */
-  DEMANGLE_COMPONENT_DTOR,
-  /* A vtable.  This has one subtree, the type for which this is a
-     vtable.  */
-  DEMANGLE_COMPONENT_VTABLE,
-  /* A VTT structure.  This has one subtree, the type for which this
-     is a VTT.  */
-  DEMANGLE_COMPONENT_VTT,
-  /* A construction vtable.  The left subtree is the type for which
-     this is a vtable, and the right subtree is the derived type for
-     which this vtable is built.  */
-  DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE,
-  /* A typeinfo structure.  This has one subtree, the type for which
-     this is the tpeinfo structure.  */
-  DEMANGLE_COMPONENT_TYPEINFO,
-  /* A typeinfo name.  This has one subtree, the type for which this
-     is the typeinfo name.  */
-  DEMANGLE_COMPONENT_TYPEINFO_NAME,
-  /* A typeinfo function.  This has one subtree, the type for which
-     this is the tpyeinfo function.  */
-  DEMANGLE_COMPONENT_TYPEINFO_FN,
-  /* A thunk.  This has one subtree, the name for which this is a
-     thunk.  */
-  DEMANGLE_COMPONENT_THUNK,
-  /* A virtual thunk.  This has one subtree, the name for which this
-     is a virtual thunk.  */
-  DEMANGLE_COMPONENT_VIRTUAL_THUNK,
-  /* A covariant thunk.  This has one subtree, the name for which this
-     is a covariant thunk.  */
-  DEMANGLE_COMPONENT_COVARIANT_THUNK,
-  /* A Java class.  This has one subtree, the type.  */
-  DEMANGLE_COMPONENT_JAVA_CLASS,
-  /* A guard variable.  This has one subtree, the name for which this
-     is a guard variable.  */
-  DEMANGLE_COMPONENT_GUARD,
-  /* A reference temporary.  This has one subtree, the name for which
-     this is a temporary.  */
-  DEMANGLE_COMPONENT_REFTEMP,
-  /* A standard substitution.  This holds the name of the
-     substitution.  */
-  DEMANGLE_COMPONENT_SUB_STD,
-  /* The restrict qualifier.  The one subtree is the type which is
-     being qualified.  */
-  DEMANGLE_COMPONENT_RESTRICT,
-  /* The volatile qualifier.  The one subtree is the type which is
-     being qualified.  */
-  DEMANGLE_COMPONENT_VOLATILE,
-  /* The const qualifier.  The one subtree is the type which is being
-     qualified.  */
-  DEMANGLE_COMPONENT_CONST,
-  /* The restrict qualifier modifying a member function.  The one
-     subtree is the type which is being qualified.  */
-  DEMANGLE_COMPONENT_RESTRICT_THIS,
-  /* The volatile qualifier modifying a member function.  The one
-     subtree is the type which is being qualified.  */
-  DEMANGLE_COMPONENT_VOLATILE_THIS,
-  /* The const qualifier modifying a member function.  The one subtree
-     is the type which is being qualified.  */
-  DEMANGLE_COMPONENT_CONST_THIS,
-  /* A vendor qualifier.  The left subtree is the type which is being
-     qualified, and the right subtree is the name of the
-     qualifier.  */
-  DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
-  /* A pointer.  The one subtree is the type which is being pointed
-     to.  */
-  DEMANGLE_COMPONENT_POINTER,
-  /* A reference.  The one subtree is the type which is being
-     referenced.  */
-  DEMANGLE_COMPONENT_REFERENCE,
-  /* A complex type.  The one subtree is the base type.  */
-  DEMANGLE_COMPONENT_COMPLEX,
-  /* An imaginary type.  The one subtree is the base type.  */
-  DEMANGLE_COMPONENT_IMAGINARY,
-  /* A builtin type.  This holds the builtin type information.  */
-  DEMANGLE_COMPONENT_BUILTIN_TYPE,
-  /* A vendor's builtin type.  This holds the name of the type.  */
-  DEMANGLE_COMPONENT_VENDOR_TYPE,
-  /* A function type.  The left subtree is the return type.  The right
-     subtree is a list of ARGLIST nodes.  Either or both may be
-     NULL.  */
-  DEMANGLE_COMPONENT_FUNCTION_TYPE,
-  /* An array type.  The left subtree is the dimension, which may be
-     NULL, or a string (represented as DEMANGLE_COMPONENT_NAME), or an
-     expression.  The right subtree is the element type.  */
-  DEMANGLE_COMPONENT_ARRAY_TYPE,
-  /* A pointer to member type.  The left subtree is the class type,
-     and the right subtree is the member type.  CV-qualifiers appear
-     on the latter.  */
-  DEMANGLE_COMPONENT_PTRMEM_TYPE,
-  /* An argument list.  The left subtree is the current argument, and
-     the right subtree is either NULL or another ARGLIST node.  */
-  DEMANGLE_COMPONENT_ARGLIST,
-  /* A template argument list.  The left subtree is the current
-     template argument, and the right subtree is either NULL or
-     another TEMPLATE_ARGLIST node.  */
-  DEMANGLE_COMPONENT_TEMPLATE_ARGLIST,
-  /* An operator.  This holds information about a standard
-     operator.  */
-  DEMANGLE_COMPONENT_OPERATOR,
-  /* An extended operator.  This holds the number of arguments, and
-     the name of the extended operator.  */
-  DEMANGLE_COMPONENT_EXTENDED_OPERATOR,
-  /* A typecast, represented as a unary operator.  The one subtree is
-     the type to which the argument should be cast.  */
-  DEMANGLE_COMPONENT_CAST,
-  /* A unary expression.  The left subtree is the operator, and the
-     right subtree is the single argument.  */
-  DEMANGLE_COMPONENT_UNARY,
-  /* A binary expression.  The left subtree is the operator, and the
-     right subtree is a BINARY_ARGS.  */
-  DEMANGLE_COMPONENT_BINARY,
-  /* Arguments to a binary expression.  The left subtree is the first
-     argument, and the right subtree is the second argument.  */
-  DEMANGLE_COMPONENT_BINARY_ARGS,
-  /* A trinary expression.  The left subtree is the operator, and the
-     right subtree is a TRINARY_ARG1.  */
-  DEMANGLE_COMPONENT_TRINARY,
-  /* Arguments to a trinary expression.  The left subtree is the first
-     argument, and the right subtree is a TRINARY_ARG2.  */
-  DEMANGLE_COMPONENT_TRINARY_ARG1,
-  /* More arguments to a trinary expression.  The left subtree is the
-     second argument, and the right subtree is the third argument.  */
-  DEMANGLE_COMPONENT_TRINARY_ARG2,
-  /* A literal.  The left subtree is the type, and the right subtree
-     is the value, represented as a DEMANGLE_COMPONENT_NAME.  */
-  DEMANGLE_COMPONENT_LITERAL,
-  /* A negative literal.  Like LITERAL, but the value is negated.
-     This is a minor hack: the NAME used for LITERAL points directly
-     to the mangled string, but since negative numbers are mangled
-     using 'n' instead of '-', we want a way to indicate a negative
-     number which involves neither modifying the mangled string nor
-     allocating a new copy of the literal in memory.  */
-  DEMANGLE_COMPONENT_LITERAL_NEG
-};
-
-/* Types which are only used internally.  */
-
-struct demangle_operator_info;
-struct demangle_builtin_type_info;
-
-/* A node in the tree representation is an instance of a struct
-   demangle_component.  Note that the field names of the struct are
-   not well protected against macros defined by the file including
-   this one.  We can fix this if it ever becomes a problem.  */
-
-struct demangle_component
-{
-  /* The type of this component.  */
-  enum demangle_component_type type;
-
-  union
-  {
-    /* For DEMANGLE_COMPONENT_NAME.  */
-    struct
-    {
-      /* A pointer to the name (which need not NULL terminated) and
-         its length.  */
-      const char *s;
-      int len;
-    } s_name;
-
-    /* For DEMANGLE_COMPONENT_OPERATOR.  */
-    struct
-    {
-      /* Operator.  */
-      const struct demangle_operator_info *op;
-    } s_operator;
-
-    /* For DEMANGLE_COMPONENT_EXTENDED_OPERATOR.  */
-    struct
-    {
-      /* Number of arguments.  */
-      int args;
-      /* Name.  */
-      struct demangle_component *name;
-    } s_extended_operator;
-
-    /* For DEMANGLE_COMPONENT_CTOR.  */
-    struct
-    {
-      /* Kind of constructor.  */
-      enum gnu_v3_ctor_kinds kind;
-      /* Name.  */
-      struct demangle_component *name;
-    } s_ctor;
-
-    /* For DEMANGLE_COMPONENT_DTOR.  */
-    struct
-    {
-      /* Kind of destructor.  */
-      enum gnu_v3_dtor_kinds kind;
-      /* Name.  */
-      struct demangle_component *name;
-    } s_dtor;
-
-    /* For DEMANGLE_COMPONENT_BUILTIN_TYPE.  */
-    struct
-    {
-      /* Builtin type.  */
-      const struct demangle_builtin_type_info *type;
-    } s_builtin;
-
-    /* For DEMANGLE_COMPONENT_SUB_STD.  */
-    struct
-    {
-      /* Standard substitution string.  */
-      const char* string;
-      /* Length of string.  */
-      int len;
-    } s_string;
-
-    /* For DEMANGLE_COMPONENT_TEMPLATE_PARAM.  */
-    struct
-    {
-      /* Template parameter index.  */
-      long number;
-    } s_number;
-
-    /* For other types.  */
-    struct
-    {
-      /* Left (or only) subtree.  */
-      struct demangle_component *left;
-      /* Right subtree.  */
-      struct demangle_component *right;
-    } s_binary;
-
-  } u;
-};
-
-/* People building mangled trees are expected to allocate instances of
-   struct demangle_component themselves.  They can then call one of
-   the following functions to fill them in.  */
-
-/* Fill in most component types with a left subtree and a right
-   subtree.  Returns non-zero on success, zero on failure, such as an
-   unrecognized or inappropriate component type.  */
-
-extern int
-cplus_demangle_fill_component PARAMS ((struct demangle_component *fill,
-                                       enum demangle_component_type,
-                                       struct demangle_component *left,
-                                       struct demangle_component *right));
-
-/* Fill in a DEMANGLE_COMPONENT_NAME.  Returns non-zero on success,
-   zero for bad arguments.  */
-
-extern int
-cplus_demangle_fill_name PARAMS ((struct demangle_component *fill,
-                                  const char *, int));
-
-/* Fill in a DEMANGLE_COMPONENT_BUILTIN_TYPE, using the name of the
-   builtin type (e.g., "int", etc.).  Returns non-zero on success,
-   zero if the type is not recognized.  */
-
-extern int
-cplus_demangle_fill_builtin_type PARAMS ((struct demangle_component *fill,
-                                          const char *type_name));
-
-/* Fill in a DEMANGLE_COMPONENT_OPERATOR, using the name of the
-   operator and the number of arguments which it takes (the latter is
-   used to disambiguate operators which can be both binary and unary,
-   such as '-').  Returns non-zero on success, zero if the operator is
-   not recognized.  */
-
-extern int
-cplus_demangle_fill_operator PARAMS ((struct demangle_component *fill,
-                                      const char *opname, int args));
-
-/* Fill in a DEMANGLE_COMPONENT_EXTENDED_OPERATOR, providing the
-   number of arguments and the name.  Returns non-zero on success,
-   zero for bad arguments.  */
-
-extern int
-cplus_demangle_fill_extended_operator PARAMS ((struct demangle_component *fill,
-                                               int numargs,
-                                               struct demangle_component *nm));
-
-/* Fill in a DEMANGLE_COMPONENT_CTOR.  Returns non-zero on success,
-   zero for bad arguments.  */
-
-extern int
-cplus_demangle_fill_ctor PARAMS ((struct demangle_component *fill,
-                                  enum gnu_v3_ctor_kinds kind,
-                                  struct demangle_component *name));
-
-/* Fill in a DEMANGLE_COMPONENT_DTOR.  Returns non-zero on success,
-   zero for bad arguments.  */
-
-extern int
-cplus_demangle_fill_dtor PARAMS ((struct demangle_component *fill,
-                                  enum gnu_v3_dtor_kinds kind,
-                                  struct demangle_component *name));
-
-/* This function translates a mangled name into a struct
-   demangle_component tree.  The first argument is the mangled name.
-   The second argument is DMGL_* options.  This returns a pointer to a
-   tree on success, or NULL on failure.  On success, the third
-   argument is set to a block of memory allocated by malloc.  This
-   block should be passed to free when the tree is no longer
-   needed.  */
-
-extern struct demangle_component *
-cplus_demangle_v3_components PARAMS ((const char *mangled,
-                                      int options,
-                                      void **mem));
-
-/* This function takes a struct demangle_component tree and returns
-   the corresponding demangled string.  The first argument is DMGL_*
-   options.  The second is the tree to demangle.  The third is a guess
-   at the length of the demangled string, used to initially allocate
-   the return buffer.  The fourth is a pointer to a size_t.  On
-   success, this function returns a buffer allocated by malloc(), and
-   sets the size_t pointed to by the fourth argument to the size of
-   the allocated buffer (not the length of the returned string).  On
-   failure, this function returns NULL, and sets the size_t pointed to
-   by the fourth argument to 0 for an invalid tree, or to 1 for a
-   memory allocation error.  */
-
-extern char *
-cplus_demangle_print PARAMS ((int options,
-                              const struct demangle_component *tree,
-                              int estimated_length,
-                              size_t *p_allocated_size));
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif  /* DEMANGLE_H */
index 8ee2429..34451b4 100644 (file)
@@ -117,7 +117,7 @@ namespace senf
         >::value ));
         \endcode
 
-        \tparam MemberPointer type to return member pointer from
+        \tparam MemberPointer type to remove member pointer from
      */
     template < class MemberPointer > struct remove_member_pointer
     {
index 9c483da..7681a97 100644 (file)
@@ -83,9 +83,8 @@ struct function_traits_arg_type<Traits, BOOST_PP_ITERATION(), true>
 // ////////////////////////////////////////////////////////////////////////
 // Undefine local Macros
 
-#undef mpp_Args
-#undef mpp_Args_
-
+#undef mpp_OtherArgs_
+#undef mpp_OtherArgs
 #undef mpp_Arg
 
 // ////////////////////////////////////////////////////////////////////////
index ad80d8b..c3ef1b2 100644 (file)
@@ -8,7 +8,9 @@ from SCons.Script import *
 # c) check for a local SENF, set options accordingly and update that SENF if needed
 
 def SetupForSENF(env):
-    env.Append( LIBS           = [ 'senf', 'iberty', 'boost_regex', 'boost_iostreams' ],
+    env.Append( LIBS           = [ 'senf', '$BOOSTREGEXLIB', '$BOOSTIOSTREAMSLIB' ],
+                BOOSTREGEXLIB  = 'boost_regex',
+                BOOSTIOSTREAMSLIB = 'boost_iostreams',
                 CXXFLAGS       = [ '-Wno-long-long',
                                    '${"$CXXFLAGS_"+(final and "final" or "debug")}' ],
                 LINKFLAGS      = [ '${"$LINKFLAGS_"+(final and "final" or "debug")}' ],