From: g0dil Date: Mon, 23 Feb 2009 19:37:18 +0000 (+0000) Subject: Utils: Add DiscardStream X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=7f1c36ac78c8aec05f857d7594ea70e865c822ef;p=senf.git Utils: Add DiscardStream Utils/Console: Allow adding additional config sources to a config bundle while parsing Utils/Console: Redirect non error console output during configuration to a DiscardStream Utils/Console: Add more information to path/directory console errors Utils/Logger: Fix reference to destroyed areas in global destructors git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1133 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Utils/Console/Config.cc b/Utils/Console/Config.cc index 77d712a..e6723aa 100644 --- a/Utils/Console/Config.cc +++ b/Utils/Console/Config.cc @@ -120,9 +120,8 @@ prefix_ void senf::console::ConfigBundle::parse(DirectoryNode & restrict) prefix_ void senf::console::ConfigBundle::parseInternal() { - Sources::const_iterator i (sources_.begin()); - Sources::const_iterator const i_end (sources_.end()); - for (; i != i_end; ++i) + // It is valid to add additional sources at the end while parsing ... + for (Sources::const_iterator i (sources_.begin()); i != sources_.end(); ++i) (*i)->parse(executor_); } diff --git a/Utils/Console/Config.cci b/Utils/Console/Config.cci index 46cb12f..99bccc8 100644 --- a/Utils/Console/Config.cci +++ b/Utils/Console/Config.cci @@ -53,6 +53,11 @@ prefix_ senf::console::DirectoryNode & senf::console::detail::RestrictedExecutor return executor_.chroot(); } +prefix_ std::ostream & senf::console::detail::RestrictedExecutor::stream() +{ + return stream_; +} + /////////////////////////////////////////////////////////////////////////// // senf::console::ConfigBundle diff --git a/Utils/Console/Config.hh b/Utils/Console/Config.hh index 4ef6fb0..64d9802 100644 --- a/Utils/Console/Config.hh +++ b/Utils/Console/Config.hh @@ -28,6 +28,7 @@ // Custom includes #include +#include #include "Parse.hh" #include "Executor.hh" @@ -94,7 +95,7 @@ namespace console { private: void parseInternal(); - typedef std::vector Sources; + typedef std::list Sources; Sources sources_; detail::RestrictedExecutor executor_; diff --git a/Utils/Console/Config.ih b/Utils/Console/Config.ih index bb0e55e..3c9ec54 100644 --- a/Utils/Console/Config.ih +++ b/Utils/Console/Config.ih @@ -31,6 +31,7 @@ #include #include "Executor.hh" #include "../../Utils/intrusive_refcount.hh" +#include "../../Utils/DiscardStream.hh" ///////////////////////////////ih.p//////////////////////////////////////// @@ -77,6 +78,8 @@ namespace detail { DirectoryNode & root() const; + std::ostream & stream(); + class RestrictGuard; protected: @@ -90,6 +93,7 @@ namespace detail { Executor executor_; ParsedNodes parsedNodes_; DirectoryNode::ptr restrict_; + DiscardStream stream_; friend class RestrictGuard; }; diff --git a/Utils/Console/ConfigFile.cc b/Utils/Console/ConfigFile.cc index bbe3b3f..6674c4c 100644 --- a/Utils/Console/ConfigFile.cc +++ b/Utils/Console/ConfigFile.cc @@ -39,7 +39,7 @@ prefix_ void senf::console::detail::ConfigFileSource::v_parse(RestrictedExecutor { try { parser_.parseFile(filename_, boost::bind( boost::ref(executor), - boost::ref(std::cerr), + boost::ref(executor.stream()), _1 )); } catch (SystemException & ex) { diff --git a/Utils/Console/Executor.cc b/Utils/Console/Executor.cc index 7733e07..e464906 100644 --- a/Utils/Console/Executor.cc +++ b/Utils/Console/Executor.cc @@ -41,7 +41,7 @@ namespace { - struct TraverseTokens { + struct TraversTokens { typedef std::string const & result_type; result_type operator()(senf::console::Token const & token) const { return token.value(); @@ -140,11 +140,11 @@ prefix_ void senf::console::Executor::execute(std::ostream & output, } } - catch (InvalidPathException &) { - throw SyntaxErrorException("invalid path"); + catch (InvalidPathException & ex) { + throw SyntaxErrorException("invalid path") << " '" << ex.path << "'"; } - catch (InvalidDirectoryException &) { - throw SyntaxErrorException("invalid directory"); + catch (InvalidDirectoryException & ex) { + throw SyntaxErrorException("invalid directory") << " '" << ex.path << "'"; } catch (InvalidCommandException &) { throw SyntaxErrorException("invalid command"); @@ -297,7 +297,12 @@ senf::console::Executor::traverseNode(ParseCommandInfo::TokensRange const & path return dir.back().lock()->get(name); } catch (UnknownNodeNameException &) { - throw InvalidPathException(); + throw InvalidPathException( + senf::stringJoin( + senf::make_transform_range( + boost::make_iterator_range(path.begin(), path.end()), + boost::bind(&Token::value, _1)), + "/")); } } @@ -305,10 +310,14 @@ prefix_ void senf::console::Executor::traverseDirectory(ParseCommandInfo::TokensRange const & path, Path & dir) { + std::string errorPath; try { ParseCommandInfo::TokensRange::const_iterator i (path.begin()); ParseCommandInfo::TokensRange::const_iterator const i_end (path.end()); for (; i != i_end; ++i) { + if (i != path.begin()) + errorPath += "/"; + errorPath += i->value(); if (*i == NoneToken()) { if (i == path.begin()) { dir.clear(); diff --git a/Utils/Console/Executor.hh b/Utils/Console/Executor.hh index 6a950f0..9341ded 100644 --- a/Utils/Console/Executor.hh +++ b/Utils/Console/Executor.hh @@ -148,8 +148,17 @@ namespace console { Path & dir); std::string complete(DirectoryNode & dir, std::string const & name); - struct InvalidPathException {}; - struct InvalidDirectoryException {}; + struct InvalidPathException { + std::string path; + InvalidPathException() : path() {} + InvalidPathException(std::string path_) : path(path_) {} + + }; + struct InvalidDirectoryException { + std::string path; + InvalidDirectoryException() : path() {} + InvalidDirectoryException(std::string path_) : path(path_) {} + }; struct InvalidCommandException {}; DirectoryNode::ptr root_; diff --git a/Utils/Console/Parse.test.cc b/Utils/Console/Parse.test.cc index 7f85ac7..57fb988 100644 --- a/Utils/Console/Parse.test.cc +++ b/Utils/Console/Parse.test.cc @@ -85,7 +85,7 @@ BOOST_AUTO_UNIT_TEST(commandGrammar) { static char text[] = "# Comment\n" - "doo / bii / doo arg" + "doo/bii/doo arg/two/three" " flab::blub" " 123.434>a" " (a,b;c (huhu/{haha}))" @@ -99,7 +99,7 @@ BOOST_AUTO_UNIT_TEST(commandGrammar) grammar.use_parser() ) . full ); BOOST_CHECK_EQUAL( ss.str(), "beginCommand( Word('doo')/Word('bii')/Word('doo') )\n" - "pushToken( Word('arg') )\n" + "pushToken( Word('arg/two/three') )\n" "pushToken( Word('flab::blub') )\n" "pushToken( Word('123.434>a') )\n" "pushToken( ArgumentGroupOpen('(') )\n" diff --git a/Utils/Console/ProgramOptions.cc b/Utils/Console/ProgramOptions.cc index 0efbd7e..245cce3 100644 --- a/Utils/Console/ProgramOptions.cc +++ b/Utils/Console/ProgramOptions.cc @@ -152,7 +152,7 @@ senf::console::detail::ProgramOptionsSource::parseLongOption(std::string const & cmd.command(path); parser_.parseArguments(value, cmd); - executor(std::cerr, cmd); + executor(executor.stream(), cmd); } prefix_ void diff --git a/Utils/Console/Server.ih b/Utils/Console/Server.ih index 5e110fa..d97c1c9 100644 --- a/Utils/Console/Server.ih +++ b/Utils/Console/Server.ih @@ -70,11 +70,6 @@ namespace detail { : public boost::iostreams::sink { public: - typedef ClientSocketHandle< - senf::MakeSocketPolicy::policy > Handle; - NonblockingSocketSink(Client & client); std::streamsize write(const char * s, std::streamsize n); diff --git a/Utils/DiscardStream.cci b/Utils/DiscardStream.cci new file mode 100644 index 0000000..dcdd535 --- /dev/null +++ b/Utils/DiscardStream.cci @@ -0,0 +1,55 @@ +// $Id$ +// +// Copyright (C) 2009 +// 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 DiscardStream inline non-template implementation */ + +//#include "DiscardStream.ih" + +// Custom includes + +#define prefix_ inline +///////////////////////////////cci.p/////////////////////////////////////// + +prefix_ std::streamsize senf::DiscardSink::write(char const * s, std::streamsize n) +{ + return n; +} + +prefix_ senf::DiscardStream::DiscardStream() +{ + open(DiscardSink()); +} + +///////////////////////////////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/DiscardStream.hh b/Utils/DiscardStream.hh new file mode 100644 index 0000000..de4823b --- /dev/null +++ b/Utils/DiscardStream.hh @@ -0,0 +1,69 @@ +// $Id$ +// +// Copyright (C) 2009 +// 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 DiscardStream public header */ + +#ifndef HH_SENF_Utils_DiscardStream_ +#define HH_SENF_Utils_DiscardStream_ 1 + +// Custom includes +#include +#include + +//#include "DiscardStream.mpp" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace senf { + + class DiscardSink + : public boost::iostreams::sink + { + public: + std::streamsize write(char const * s, std::streamsize n); + }; + + class DiscardStream + : public boost::iostreams::stream + { + public: + DiscardStream(); + }; + +} + +///////////////////////////////hh.e//////////////////////////////////////// +#include "DiscardStream.cci" +//#include "DiscardStream.ct" +//#include "DiscardStream.cti" +#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/DiscardStream.test.cc b/Utils/DiscardStream.test.cc new file mode 100644 index 0000000..8214457 --- /dev/null +++ b/Utils/DiscardStream.test.cc @@ -0,0 +1,56 @@ +// $Id$ +// +// Copyright (C) 2009 +// 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 DiscardStream.test unit tests */ + +//#include "DiscardStream.test.hh" +//#include "DiscardStream.test.ih" + +// Custom includes +#include "DiscardStream.hh" + +#include "../Utils/auto_unit_test.hh" +#include + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +BOOST_AUTO_UNIT_TEST(discardStream) +{ + senf::DiscardStream stream; + SENF_CHECK_NO_THROW( stream << "discard me" ); +} + +///////////////////////////////cc.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/Logger/AreaRegistry.cc b/Utils/Logger/AreaRegistry.cc index 7a6a988..11bec47 100644 --- a/Utils/Logger/AreaRegistry.cc +++ b/Utils/Logger/AreaRegistry.cc @@ -36,9 +36,15 @@ /////////////////////////////////////////////////////////////////////////// // senf::log::detail::AreaBase -prefix_ senf::log::detail::AreaBase::~AreaBase() +prefix_ senf::log::detail::AreaBase::AreaBase() + : alive_ (true) {} +prefix_ senf::log::detail::AreaBase::~AreaBase() +{ + alive_ = false; +} + prefix_ void senf::log::detail::AreaBase::updateRoutingCache(Target & target, StreamBase const & stream, unsigned limit) diff --git a/Utils/Logger/AreaRegistry.cci b/Utils/Logger/AreaRegistry.cci index 76e6e51..158c007 100644 --- a/Utils/Logger/AreaRegistry.cci +++ b/Utils/Logger/AreaRegistry.cci @@ -88,6 +88,12 @@ prefix_ void senf::log::detail::AreaBase::init() senf::log::AreaRegistry::instance().registerArea(*this); } +prefix_ bool senf::log::detail::AreaBase::alive() + const +{ + return alive_; +} + prefix_ unsigned senf::log::detail::AreaBase::limit(StreamBase const & stream) const { diff --git a/Utils/Logger/AreaRegistry.ih b/Utils/Logger/AreaRegistry.ih index 53b3d10..d5cd809 100644 --- a/Utils/Logger/AreaRegistry.ih +++ b/Utils/Logger/AreaRegistry.ih @@ -47,12 +47,14 @@ namespace detail { /** \brief Internal: Area base class */ struct AreaBase { + AreaBase(); virtual ~AreaBase(); std::string fullName() const; virtual std::string v_name() const; void init(); + bool alive() const; unsigned limit(StreamBase const & stream) const; void updateRoutingCache(Target & target, StreamBase const & stream, unsigned limit) const; @@ -74,6 +76,7 @@ namespace detail { }; typedef std::vector RoutingCache; mutable RoutingCache routingCache_; + bool alive_; }; }}} diff --git a/Utils/Logger/Target.cc b/Utils/Logger/Target.cc index 16b00ff..7896bf0 100644 --- a/Utils/Logger/Target.cc +++ b/Utils/Logger/Target.cc @@ -272,6 +272,9 @@ prefix_ void senf::log::Target::updateRoutingCache(detail::StreamBase const * st updateRoutingCache(stream, i->second); return; } + if (! area->alive()) + // We are globally destructing and the area is gone already ... + return; unsigned limit (DISABLED::value); RIB::iterator i (rib_.begin()); RIB::iterator const i_end (rib_.end()); @@ -415,7 +418,7 @@ prefix_ senf::log::detail::TargetRegistry::TargetRegistry() " \n" "\n" "Route all messages to the currently connected client\n" - " $ /sys/log/self { route (); }"); + " $ /sys/log/self { route (); }"); } prefix_ senf::log::detail::TargetRegistry::~TargetRegistry() diff --git a/Utils/auto_unit_test.hh b/Utils/auto_unit_test.hh index 8b0e1bb..c12bb7d 100644 --- a/Utils/auto_unit_test.hh +++ b/Utils/auto_unit_test.hh @@ -37,6 +37,7 @@ #define HH_SENF_Utils_auto_unit_test_ 1 // Custom includes +#include #include //#include "auto_unit_test.mpp"