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_);
}
return executor_.chroot();
}
+prefix_ std::ostream & senf::console::detail::RestrictedExecutor::stream()
+{
+ return stream_;
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::console::ConfigBundle
// Custom includes
#include <boost/utility.hpp>
+#include <list>
#include "Parse.hh"
#include "Executor.hh"
private:
void parseInternal();
- typedef std::vector<detail::ConfigSource::ptr> Sources;
+ typedef std::list<detail::ConfigSource::ptr> Sources;
Sources sources_;
detail::RestrictedExecutor executor_;
#include <boost/intrusive_ptr.hpp>
#include "Executor.hh"
#include "../../Utils/intrusive_refcount.hh"
+#include "../../Utils/DiscardStream.hh"
///////////////////////////////ih.p////////////////////////////////////////
DirectoryNode & root() const;
+ std::ostream & stream();
+
class RestrictGuard;
protected:
Executor executor_;
ParsedNodes parsedNodes_;
DirectoryNode::ptr restrict_;
+ DiscardStream stream_;
friend class RestrictGuard;
};
{
try {
parser_.parseFile(filename_, boost::bind( boost::ref(executor),
- boost::ref(std::cerr),
+ boost::ref(executor.stream()),
_1 ));
}
catch (SystemException & ex) {
namespace {
- struct TraverseTokens {
+ struct TraversTokens {
typedef std::string const & result_type;
result_type operator()(senf::console::Token const & token) const {
return token.value();
}
}
- 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");
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)),
+ "/"));
}
}
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();
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_;
{
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}))"
grammar.use_parser<Grammar::SkipParser>() ) . 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"
cmd.command(path);
parser_.parseArguments(value, cmd);
- executor(std::cerr, cmd);
+ executor(executor.stream(), cmd);
}
prefix_ void
: public boost::iostreams::sink
{
public:
- typedef ClientSocketHandle<
- senf::MakeSocketPolicy<StreamFramingPolicy,
- WriteablePolicy,
- ConnectedCommunicationPolicy>::policy > Handle;
-
NonblockingSocketSink(Client & client);
std::streamsize write(const char * s, std::streamsize n);
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2009
+// 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 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_
+
+\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:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2009
+// 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 DiscardStream public header */
+
+#ifndef HH_SENF_Utils_DiscardStream_
+#define HH_SENF_Utils_DiscardStream_ 1
+
+// Custom includes
+#include <boost/iostreams/concepts.hpp>
+#include <boost/iostreams/stream.hpp>
+
+//#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<DiscardSink>
+ {
+ public:
+ DiscardStream();
+ };
+
+}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "DiscardStream.cci"
+//#include "DiscardStream.ct"
+//#include "DiscardStream.cti"
+#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:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2009
+// 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 DiscardStream.test unit tests */
+
+//#include "DiscardStream.test.hh"
+//#include "DiscardStream.test.ih"
+
+// Custom includes
+#include "DiscardStream.hh"
+
+#include "../Utils/auto_unit_test.hh"
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(discardStream)
+{
+ senf::DiscardStream stream;
+ SENF_CHECK_NO_THROW( stream << "discard me" );
+}
+
+///////////////////////////////cc.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:
///////////////////////////////////////////////////////////////////////////
// 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)
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
{
/** \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;
};
typedef std::vector<CacheEntry> RoutingCache;
mutable RoutingCache routingCache_;
+ bool alive_;
};
}}}
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());
" <Directory '/sys/log/client-xxx.xxx.xxx.xxx:xxx'>\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()
#define HH_SENF_Utils_auto_unit_test_ 1
// Custom includes
+#include <iostream>
#include <boost/version.hpp>
//#include "auto_unit_test.mpp"