From: g0dil Date: Wed, 14 May 2008 18:01:51 +0000 (+0000) Subject: Utils: Refactor hexdump() helper to move code out of template function X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=0734de7b0f8616d5f2454289d1c686ba1d2c625b;hp=fa5eaa97c8593e3587c87f25adb14f7f91f31f37;p=senf.git Utils: Refactor hexdump() helper to move code out of template function 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 --- diff --git a/Console/Executor.cc b/Console/Executor.cc index fdbb850..3533a0e 100644 --- a/Console/Executor.cc +++ b/Console/Executor.cc @@ -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(); diff --git a/Console/Executor.cci b/Console/Executor.cci index 89e2501..744737e 100644 --- a/Console/Executor.cci +++ b/Console/Executor.cci @@ -34,11 +34,9 @@ // senf::console::Executor prefix_ senf::console::Executor::Executor() - : autocd_ (false), autocomplete_ (false) -{ - oldCwd_ = cwd_ = boost::static_pointer_cast( - 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 index 0000000..4123d85 --- /dev/null +++ b/Console/Executor.ct @@ -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 +// +// 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 +prefix_ senf::console::GenericNode & +senf::console::Executor::traverse(DirectoryNode & dir, ForwardRange const & range) +{ + typedef typename boost::range_const_iterator::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(traverser.node()), *i ); + traverser( *i ); + } + return traverser.node(); +} + +///////////////////////////////ct.e//////////////////////////////////////// +#undef prefix_ + + +// 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/Console/Executor.hh b/Console/Executor.hh index 86e54be..e126590 100644 --- a/Console/Executor.hh +++ b/Console/Executor.hh @@ -66,6 +66,12 @@ namespace console { /// Thrown by built-in 'exit' command struct ExitException {}; + /// Executor policy function + typedef boost::function 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 + 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 DirStack; @@ -129,7 +154,7 @@ namespace console { ///////////////////////////////hh.e//////////////////////////////////////// #include "Executor.cci" -//#include "Executor.ct" +#include "Executor.ct" //#include "Executor.cti" #endif diff --git a/Console/Executor.test.cc b/Console/Executor.test.cc index 7453af2..0e751f1 100644 --- a/Console/Executor.test.cc +++ b/Console/Executor.test.cc @@ -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_ diff --git a/Console/Node.cc b/Console/Node.cc index 4886b77..3e16667 100644 --- a/Console/Node.cc +++ b/Console/Node.cc @@ -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( dir->get(name) ).thisptr(); + DirectoryNode & d (dynamic_cast( 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() diff --git a/Console/Node.cci b/Console/Node.cci index 0193989..108902a 100644 --- a/Console/Node.cci +++ b/Console/Node.cci @@ -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) diff --git a/Console/Node.ct b/Console/Node.ct index ddf17ac..c9516c0 100644 --- a/Console/Node.ct +++ b/Console/Node.ct @@ -23,7 +23,7 @@ /** \file \brief Node non-inline template implementation */ -//#include "Node.ih" +#include "Node.ih" // Custom includes #include @@ -36,43 +36,16 @@ template 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::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( dir->get(name) ).thisptr(); - DirectoryNode & d (dynamic_cast( dir->get(name) )); - dir = d.thisptr(); - } - } - i = next_i; - } - return *dir; + for (; i != i_end; ++i) + traverser( *i ); + return traverser.node(); } ///////////////////////////////ct.e//////////////////////////////////////// diff --git a/Console/Node.cti b/Console/Node.cti index a6e113f..b7f118b 100644 --- a/Console/Node.cti +++ b/Console/Node.cti @@ -23,7 +23,7 @@ /** \file \brief Node inline template implementation */ -//#include "Node.ih" +#include "Node.ih" // Custom includes diff --git a/Console/Node.hh b/Console/Node.hh index 0349831..0bfc594 100644 --- a/Console/Node.hh +++ b/Console/Node.hh @@ -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 - 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 ForwardRange::value_type 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 index 0000000..1a02bdd --- /dev/null +++ b/Console/Node.ih @@ -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 +// +// 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 + + +// 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/Mainpage.dox b/Mainpage.dox index f7ff985..049d80c 100644 --- a/Mainpage.dox +++ b/Mainpage.dox @@ -155,7 +155,7 @@ env = Environment( - LIBS = [ 'senf', 'iberty', 'boost_regex', 'boost_iostreams' ], + LIBS = [ 'senf', 'boost_regex', 'boost_iostreams' ], CXXFLAGS = [ '-Wall', '-Woverloaded-virtual', '-Wno-long-long' ], ) diff --git a/SConstruct b/SConstruct index d316b40..88dd14f 100644 --- a/SConstruct +++ b/SConstruct @@ -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', diff --git a/Utils/TypeInfo.cc b/Utils/TypeInfo.cc index 1c18256..bed2876 100644 --- a/Utils/TypeInfo.cc +++ b/Utils/TypeInfo.cc @@ -27,27 +27,18 @@ //#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 +#include //#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); diff --git a/Utils/TypeInfo.hh b/Utils/TypeInfo.hh index 7244351..ef4b720 100644 --- a/Utils/TypeInfo.hh +++ b/Utils/TypeInfo.hh @@ -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 index 0000000..9f08553 --- /dev/null +++ b/Utils/hexdump.cc @@ -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 +// +// 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 + +//#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" + + +// 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 index 0000000..7544966 --- /dev/null +++ b/Utils/hexdump.cci @@ -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 +// +// 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_ + + +// 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.ct b/Utils/hexdump.ct index 513b1a4..76abf99 100644 --- a/Utils/hexdump.ct +++ b/Utils/hexdump.ct @@ -23,11 +23,9 @@ /** \file \brief hexdump non-inline template implementation */ -//#include "hexdump.ih" +#include "hexdump.ih" // Custom includes -#include -#include //#include "hexdump.mpp" #define prefix_ @@ -37,34 +35,9 @@ template 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//////////////////////////////////////// diff --git a/Utils/hexdump.hh b/Utils/hexdump.hh index 9dc9458..4cd5062 100644 --- a/Utils/hexdump.hh +++ b/Utils/hexdump.hh @@ -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 index 0000000..2c530a8 --- /dev/null +++ b/Utils/hexdump.ih @@ -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 +// +// 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 +#include +#include + +///////////////////////////////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 + + +// 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.test.cc b/Utils/hexdump.test.cc index 7e71797..8a17a40 100644 --- a/Utils/hexdump.test.cc +++ b/Utils/hexdump.test.cc @@ -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 index a532366..0000000 --- a/Utils/impl/demangle.h +++ /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 */ diff --git a/Utils/type_traits.hh b/Utils/type_traits.hh index 8ee2429..34451b4 100644 --- a/Utils/type_traits.hh +++ b/Utils/type_traits.hh @@ -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 { diff --git a/Utils/type_traits.mpp b/Utils/type_traits.mpp index 9c483da..7681a97 100644 --- a/Utils/type_traits.mpp +++ b/Utils/type_traits.mpp @@ -83,9 +83,8 @@ struct function_traits_arg_type // //////////////////////////////////////////////////////////////////////// // Undefine local Macros -#undef mpp_Args -#undef mpp_Args_ - +#undef mpp_OtherArgs_ +#undef mpp_OtherArgs #undef mpp_Arg // //////////////////////////////////////////////////////////////////////// diff --git a/senfscons/senfutil.py b/senfscons/senfutil.py index ad80d8b..c3ef1b2 100644 --- a/senfscons/senfutil.py +++ b/senfscons/senfutil.py @@ -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")}' ],