--- /dev/null
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// 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 Area inline non-template implementation */
+
+#include "Area.ih"
+
+// Custom includes
+#include "../TypeInfo.hh"
+#include "Levels.hh"
+#include "Stream.hh"
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::log::AreaRegistry
+
+prefix_ std::string const &
+senf::log::AreaRegistry::SelectName::operator()(Registry::value_type const & v)
+ const
+{
+ return v.first;
+}
+
+prefix_ senf::log::AreaRegistry::AreaRegistry()
+{}
+
+prefix_ senf::log::AreaRegistry::iterator senf::log::AreaRegistry::begin()
+{
+ return boost::make_transform_iterator(registry_.begin(), SelectName());
+}
+
+prefix_ senf::log::AreaRegistry::iterator senf::log::AreaRegistry::end()
+{
+ return boost::make_transform_iterator(registry_.end(), SelectName());
+}
+
+prefix_ void senf::log::AreaRegistry::registerArea(detail::AreaBase const & area)
+{
+ registry_.insert( std::make_pair(area.v_name(), &area) );
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::log::detail::AreaBase
+
+prefix_ std::string senf::log::detail::AreaBase::fullName()
+ const
+{
+ return prettyName(typeid(*this));
+}
+
+prefix_ std::string senf::log::detail::AreaBase::v_name()
+ const
+{
+ return fullName();
+}
+
+prefix_ void senf::log::detail::AreaBase::init()
+{
+ senf::log::AreaRegistry::instance().registerArea(*this);
+}
+
+prefix_ unsigned senf::log::detail::AreaBase::streamLimit(StreamBase const & stream)
+ const
+{
+ return stream.index >= streamLimits_.size() ? DISABLED::value : streamLimits_[stream.index];
+}
+
+prefix_ void senf::log::detail::AreaBase::setStreamLimit(StreamBase const & stream, unsigned value)
+ const
+{
+ if (stream.index >= streamLimits_.size())
+ streamLimits_.resize(stream.index+1,0u);
+ streamLimits_[stream.index] = value;
+}
+
+///////////////////////////////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:
#define HH_Area_ 1
// Custom includes
+#include <map>
+#include <functional>
+#include <boost/iterator/transform_iterator.hpp>
+#include "../singleton.hh"
//#include "Area.mpp"
-#include "Area.ih"
///////////////////////////////hh.p////////////////////////////////////////
/** \brief Define log area
\hideinitializer
*/
-#define SENF_LOG_DEF_AREA(area) \
- struct area \
- : public senf::log::detail::AreaBase \
- {}
+#define SENF_LOG_DEF_AREA(area) SENF_LOG_DEF_AREA_I(area, ; )
+
+namespace senf {
+namespace log {
+
+ namespace detail { struct AreaBase; }
+
+ class AreaRegistry
+ : public senf::singleton<AreaRegistry>
+ {
+ typedef std::map<std::string, detail::AreaBase const *> Registry;
+
+ struct SelectName
+ {
+ typedef std::string result_type;
+ std::string const & operator()(Registry::value_type const & v) const;
+ };
+
+ public:
+ typedef boost::transform_iterator<SelectName, Registry::const_iterator> iterator;
+
+ using senf::singleton<AreaRegistry>::instance;
+
+ iterator begin();
+ iterator end();
+
+ private:
+ AreaRegistry();
+
+ void registerArea(detail::AreaBase const & area);
+
+ Registry registry_;
+
+ friend class senf::singleton<AreaRegistry>;
+ friend class detail::AreaBase;
+ friend class Target;
+ };
+
+}}
///////////////////////////////hh.e////////////////////////////////////////
-//#include "Area.cci"
+#include "Area.cci"
//#include "Area.ct"
//#include "Area.cti"
#endif
#define IH_Area_ 1
// Custom includes
+#include <string>
+#include <vector>
///////////////////////////////ih.p////////////////////////////////////////
namespace log {
namespace detail {
+ class StreamBase;
+
struct AreaBase
- {};
+ {
+ virtual ~AreaBase() {};
+
+ std::string fullName() const;
+ virtual std::string v_name() const;
+
+ void init();
+
+ unsigned streamLimit(StreamBase const & stream) const;
+ void setStreamLimit(StreamBase const & stream, unsigned value) const;
+
+ private:
+ typedef std::vector<unsigned> StreamLimits;
+ // mutable since this is a cache and may therefore change at unexpected places ...
+ mutable StreamLimits streamLimits_;
+ };
}}}
+#define SENF_LOG_DEF_AREA_I(area, decls) \
+ struct area \
+ : public senf::log::detail::AreaBase, public senf::singleton<area> \
+ { \
+ static std::string name() { return instance().v_name(); } \
+ decls \
+ private: \
+ area() { init(); } \
+ friend class senf::singleton<area>; \
+ }
+
///////////////////////////////ih.e////////////////////////////////////////
#endif
#include <boost/preprocessor/expand.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/to_tuple.hpp>
-#include "Defaults.hh"
+#include <boost/preprocessor/seq/fold_right.hpp>
+#include <boost/preprocessor/seq/pop_back.hpp>
+#include <boost/preprocessor/if.hpp>
+#include "../preprocessor.hh"
///////////////////////////////ih.p////////////////////////////////////////
typedef typename Stream::compileLimit compileLimit;
};
-# define SENF_LOG_CONF_DEFINE(stream, area, level) \
- template <> \
- struct Config<stream, area> \
- { typedef senf::log::level compileLimit; };
+}}}
-# ifdef SENF_LOG_CONF
+#define SENF_LOG_SEQ_TO_NAME_(s,data,elem) ::elem
-# define _ void
-# define SLC_elt(r, data, elt) \
- BOOST_PP_EXPAND(SENF_LOG_CONF_DEFINE BOOST_PP_SEQ_TO_TUPLE(elt))
+#define SENF_LOG_SEQ_TO_NAME(seq) \
+ BOOST_PP_SEQ_FOR_EACH(SENF_LOG_SEQ_TO_NAME_, none, seq)
- BOOST_PP_SEQ_FOR_EACH(SLC_elt, x, SENF_LOG_CONF)
+#define SENF_LOG_PREDECL_(s, state, elem) \
+ namespace elem { state }
-# undef SLC_elt
-# undef _
+#define SENF_LOG_PREDECL(seq) \
+ BOOST_PP_SEQ_FOLD_RIGHT( SENF_LOG_PREDECL_, \
+ class SENF_PP_SEQ_BACK(seq);, \
+ BOOST_PP_SEQ_POP_BACK(seq) )
-# endif
+#define SENF_LOG_NIL(x)
+
+#define SENF_LOG_CONF_DEFINE(stream, area, level) \
+ SENF_LOG_PREDECL(stream) \
+ BOOST_PP_IF(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(area)), \
+ SENF_LOG_PREDECL, \
+ SENF_LOG_NIL)(area) \
+ namespace senf { namespace log { namespace detail { \
+ template <> \
+ struct Config< SENF_LOG_SEQ_TO_NAME(stream), \
+ BOOST_PP_IF(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(area)), \
+ SENF_LOG_SEQ_TO_NAME(area), \
+ void) > \
+ { typedef senf::log::level compileLimit; }; \
+ }}}
+
+#ifdef SENF_LOG_CONF
+
+# define SLC_elt(s, state, elt) \
+ SENF_LOG_CONF_DEFINE elt
+
+ // Need to use fold here to not exhaust the maximum FOR nesting depth ...
+ BOOST_PP_SEQ_FOLD_LEFT(SLC_elt, none, SENF_LOG_CONF)
+
+# undef SLC_elt
+
+#endif
-}}}
namespace log {
SENF_LOG_DEF_STREAM(Debug, MESSAGE, DISABLED, DISABLED);
- SENF_LOG_DEF_AREA(DefaultArea);
+
+ SENF_LOG_DEF_AREA_I(DefaultArea,
+ std::string v_name() const { return ""; });
}}
// Custom includes
#include <sstream>
+// We need to put all tests into this single file to not violate the ODR
+
#define _senf_LOG_STREAM logstream
namespace {
std::stringstream logstream;
}
-#define SENF_LOG_CONF ((senf::log::Debug)(_)(VERBOSE))
+#define SENF_LOG_CONF (( (senf)(log)(Debug), (_), NOTICE ))
#include "Log.hh"
#include "Defaults.hh"
typedef int value;
};
- SENF_LOG_DEF_ALIAS( LogFoo, (senf::log::Debug) (senf::log::CRITICAL) );
+ SENF_LOG_DEF_ALIAS( LogCritical, (senf::log::Debug) (senf::log::CRITICAL) );
SENF_LOG_DEF_STREAM( myStream, senf::log::MESSAGE, senf::log::MESSAGE, senf::log::MESSAGE );
SENF_LOG_DEF_AREA( myArea );
{
SENF_LOG_DEFAULT_STREAM(senf::log::Debug);
SENF_LOG_DEFAULT_AREA(senf::log::DefaultArea);
- SENF_LOG_DEFAULT_LEVEL(senf::log::NOTICE);
+ SENF_LOG_DEFAULT_LEVEL(senf::log::VERBOSE);
+ // should be disabled
SENF_LOG(("Log message"));
-
- SENF_LOG((LogFoo) ("Another log message: " << 10));
+ SENF_LOG((senf::log::VERBOSE)("Log message 2"));
+ // should be enabled
+ SENF_LOG((senf::log::IMPORTANT)("Important message"));
+ SENF_LOG((LogCritical) ("Another log message: " << 10));
SENF_LOG_BLOCK((senf::log::Debug) (senf::log::IMPORTANT) ({
log << "Last message";
}));
BOOST_CHECK_EQUAL( logstream.str(),
- "Log message\nAnother log message: 10\nLast message continued here\n" );
+ "Important message\n"
+ "Another log message: 10\n"
+ "Last message continued here\n" );
+}
+
+BOOST_AUTO_UNIT_TEST(streamRegistry)
+{
+ char const * streams[] = { "(anonymous namespace)::myStream", "senf::log::Debug" };
+
+ BOOST_CHECK_EQUAL_COLLECTIONS( senf::log::StreamRegistry::instance().begin(),
+ senf::log::StreamRegistry::instance().end(),
+ streams, streams+sizeof(streams)/sizeof(streams[0]) );
+ BOOST_CHECK_EQUAL( senf::log::detail::StreamBase::nStreams, 2u );
+}
+
+BOOST_AUTO_UNIT_TEST(areaRegistry)
+{
+ char const * areas[] = { "", "(anonymous namespace)::myArea" };
+
+ BOOST_CHECK_EQUAL_COLLECTIONS( senf::log::AreaRegistry::instance().begin(),
+ senf::log::AreaRegistry::instance().end(),
+ areas, areas+sizeof(areas)/sizeof(areas[0]) );
+
}
///////////////////////////////cc.e////////////////////////////////////////
#define HH_Parameters_ 1
// Custom includes
+#include "Area.hh"
//#include "Parameters.mpp"
#include "Parameters.ih"
}; \
}
+#define SENF_LOG_CLASS_AREA() \
+ SENF_LOG_DEF_AREA_I(SenfLogArea, \
+ std::string v_name() const \
+ { std::string s (fullName()); return std::string(s,s.size()-13); }); \
+ SENF_LOG_DEFAULT_AREA(SenfLogArea)
+
+
///////////////////////////////hh.e////////////////////////////////////////
//#include "Parameters.cci"
//#include "Parameters.ct"
SENFSCons.AllIncludesHH(env, [ f for f in glob.glob("*.hh")
if f not in ('all_includes.hh','INet.hh') and not f.endswith('.test.hh') ])
sources = SENFSCons.GlobSources()
-objects = SENFSCons.Objects( env, sources = sources )
+objects = SENFSCons.Objects( env, sources = sources, LIBS = [ 'Utils' ] )
SENFSCons.Doxygen(env)
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// 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 Stream non-inline non-template implementation */
+
+#include "Stream.hh"
+#include "Stream.ih"
+
+// Custom includes
+
+//#include "Stream.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+unsigned senf::log::detail::StreamBase::nStreams = 0;
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "Stream.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:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// 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 Stream inline non-template implementation */
+
+#include "Stream.ih"
+
+// Custom includes
+#include "../TypeInfo.hh"
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::log::StreamRegistry
+
+prefix_ std::string const &
+senf::log::StreamRegistry::SelectName::operator()(Registry::value_type const & v)
+ const
+{
+ return v.first;
+}
+
+prefix_ senf::log::StreamRegistry::StreamRegistry()
+{}
+
+prefix_ senf::log::StreamRegistry::iterator senf::log::StreamRegistry::begin()
+{
+ return boost::make_transform_iterator(registry_.begin(), SelectName());
+}
+
+prefix_ senf::log::StreamRegistry::iterator senf::log::StreamRegistry::end()
+{
+ return boost::make_transform_iterator(registry_.end(), SelectName());
+}
+
+prefix_ void senf::log::StreamRegistry::registerStream(detail::StreamBase const & stream)
+{
+ registry_.insert( std::make_pair(stream.v_name(), &stream) );
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::log::detail::StreamBase
+
+prefix_ senf::log::detail::StreamBase::StreamBase()
+ : index( nStreams++ )
+{}
+
+prefix_ std::string senf::log::detail::StreamBase::fullName()
+ const
+{
+ return prettyName(typeid(*this));
+}
+
+prefix_ std::string senf::log::detail::StreamBase::v_name()
+ const
+{
+ return fullName();
+}
+
+prefix_ void senf::log::detail::StreamBase::init()
+{
+ senf::log::StreamRegistry::instance().registerStream(*this);
+}
+
+///////////////////////////////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:
#define HH_Stream_ 1
// Custom includes
+#include <map>
+#include <functional>
+#include <boost/iterator/transform_iterator.hpp>
#include "Levels.hh"
+#include "../singleton.hh"
//#include "Stream.mpp"
-#include "Stream.ih"
///////////////////////////////hh.p////////////////////////////////////////
/** \brief Define log stream
*/
#define SENF_LOG_DEF_STREAM(stream, defaultLevel_, runtimeLimit_, compileLimit_) \
struct stream \
- : public senf::log::detail::StreamBase \
+ : public senf::log::detail::StreamBase, public senf::singleton<stream> \
{ \
typedef defaultLevel_ defaultLevel; \
typedef runtimeLimit_ runtimeLimit; \
typedef compileLimit_ compileLimit; \
- \
- static char const * name() { return #stream ; } \
- virtual char const * v_name() { return name(); } \
+ static std::string name() { return instance().v_name(); } \
+ private: \
+ stream() { init(); } \
+ friend class senf::singleton<stream>; \
}
-///////////////////////////////hh.e////////////////////////////////////////
-//#include "Stream.cci"
+namespace senf {
+namespace log {
+
+ namespace detail { struct StreamBase; }
+
+ class StreamRegistry
+ : public senf::singleton<StreamRegistry>
+ {
+ typedef std::map<std::string, detail::StreamBase const *> Registry;
+
+ struct SelectName
+ {
+ typedef std::string result_type;
+ std::string const & operator()(Registry::value_type const & v) const;
+ };
+
+ public:
+ typedef boost::transform_iterator<SelectName, Registry::const_iterator> iterator;
+
+ using senf::singleton<StreamRegistry>::instance;
+
+ iterator begin();
+ iterator end();
+
+ private:
+ StreamRegistry();
+
+ void registerStream(detail::StreamBase const & stream);
+
+ Registry registry_;
+
+ friend class senf::singleton<StreamRegistry>;
+ friend class detail::StreamBase;
+ friend class Target;
+ };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////#
+#include "Stream.cci"
//#include "Stream.ct"
//#include "Stream.cti"
#endif
#define IH_Stream_ 1
// Custom includes
+#include <string>
///////////////////////////////ih.p////////////////////////////////////////
struct StreamBase
{
+ StreamBase();
virtual ~StreamBase() {};
- virtual char const * v_name() = 0;
+
+ std::string fullName() const;
+ virtual std::string v_name() const;
+
+ void init();
+
+ unsigned index;
+ static unsigned nStreams;
};
}}}
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// 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 Target non-inline non-template implementation */
+
+#include "Target.hh"
+//#include "Target.ih"
+
+// Custom includes
+
+//#include "Target.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::log::Target
+
+prefix_ senf::log::Target::~Target()
+{}
+
+prefix_ void senf::log::Target::write(detail::StreamBase const & stream,
+ detail::AreaBase const & area,
+ unsigned level, std::string const & message)
+{
+ RIB::iterator i (rib_.begin());
+ RIB::iterator const i_end (rib_.end());
+ for (; i != i_end; ++i)
+ if ( ( ! i->stream || i->stream == &stream ) &&
+ ( ! i->area || i->area == &area ) &&
+ i->level <= level ) {
+ v_write(stream.v_name(), area.v_name(), level, message);
+ return;
+ }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "Target.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:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// 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 Target inline non-template implementation */
+
+//#include "Target.ih"
+
+// Custom includes
+#include <algorithm>
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::log::Target
+
+prefix_ void senf::log::Target::route(detail::StreamBase const * stream,
+ detail::AreaBase const * area, unsigned level)
+{
+ rib_.push_back(RoutingEntry(stream, area, level));
+
+ // Update the area/stream routing cache
+ if (area)
+ updateAreaCache(*area, stream, level);
+ else {
+ AreaRegistry::Registry::iterator i (AreaRegistry::instance().registry_.begin());
+ AreaRegistry::Registry::iterator const i_end (AreaRegistry::instance().registry_.end());
+ for (; i != i_end; ++i)
+ updateAreaCache(*(i->second), stream, level);
+ }
+
+}
+
+prefix_ void
+senf::log::Target::updateAreaCache(detail::AreaBase const & area,
+ detail::StreamBase const * stream, unsigned level)
+{
+ if (stream) {
+ if (level < area.streamLimit(*stream))
+ area.setStreamLimit(*stream, level);
+ } else {
+ StreamRegistry::Registry::iterator i (StreamRegistry::instance().registry_.begin());
+ StreamRegistry::Registry::iterator const i_end (StreamRegistry::instance().registry_.end());
+ for(; i != i_end; ++i)
+ if (level < area.streamLimit(*(i->second)))
+ area.setStreamLimit(*(i->second),level);
+ }
+}
+
+prefix_ void senf::log::Target::unroute(detail::StreamBase const * stream,
+ detail::AreaBase const * area, unsigned level)
+{
+ rib_.erase(std::remove(rib_.begin(), rib_.end(), RoutingEntry(stream, area, level)),
+ rib_.end());
+
+ ///\fixme Update area/stream routing cache
+ // Not doing anything here does not produce incorrect behavior, since removing a route
+ // can never lower the logging limit. Not updating the cache just reduces the performance.
+}
+
+/////////////////////////////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) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// 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 Target public header */
+
+#ifndef HH_Target_
+#define HH_Target_ 1
+
+// Custom includes
+#include "../singleton.hh"
+#include "Stream.hh"
+#include "Area.hh"
+
+//#include "Target.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace log {
+
+ /** \brief
+ */
+ class Target
+ : public senf::singleton<Target>
+ {
+ public:
+ ///////////////////////////////////////////////////////////////////////////
+ // Types
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///\name Structors and default members
+ ///@{
+
+ virtual ~Target();
+
+ // default default constructor
+ // default copy constructor
+ // default copy assignment
+ // default destructor
+
+ // no conversion constructors
+
+ ///@}
+
+ protected:
+
+ private:
+
+ void route(detail::StreamBase const * stream, detail::AreaBase const * area,
+ unsigned level);
+ void unroute(detail::StreamBase const * stream, detail::AreaBase const * area,
+ unsigned level);
+
+ void updateAreaCache(detail::AreaBase const & area, detail::StreamBase const * stream,
+ unsigned level);
+
+ void write(detail::StreamBase const & stream, detail::AreaBase const & area,
+ unsigned level, std::string const & message);
+
+ virtual void v_write(std::string const & stream, std::string const & area, unsigned level,
+ std::string const & message) = 0;
+
+ struct RoutingEntry
+ {
+ RoutingEntry(detail::StreamBase const * stream_, detail::AreaBase const * area_,
+ unsigned level_)
+ : stream(stream_), area(area_), level(level_) {}
+ RoutingEntry()
+ : stream(0), area(0), level(0) {}
+
+ bool operator==(RoutingEntry const & other)
+ { return stream == other.stream && area == other.area && level == other.level; }
+
+ detail::StreamBase const * stream;
+ detail::AreaBase const * area;
+ unsigned level;
+ };
+
+ typedef std::vector<RoutingEntry> RIB;
+
+ RIB rib_;
+ };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "Target.cci"
+//#include "Target.ct"
+//#include "Target.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:
SENFSCons.StandardTargets(env)
sources, testSources = SENFSCons.GlobSources()
-objects = SENFSCons.Objects( env, sources = sources )
+objects = SENFSCons.Objects( env, sources = sources, testSources=testSources )
for sc in glob.glob("*/SConscript"):
ob = SConscript(sc)
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// 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 preprocessor public header */
+
+#ifndef HH_preprocessor_
+#define HH_preprocessor_ 1
+
+// Custom includes
+#include <boost/preprocessor/seq/size.hpp>
+#include <boost/preprocessor/seq/elem.hpp>
+#include <boost/preprocessor/dec.hpp>
+
+//#include "preprocessor.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+#define SENF_PP_SEQ_BACK(seq) BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq)),seq)
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "preprocessor.cci"
+//#include "preprocessor.ct"
+//#include "preprocessor.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: