From: g0dil Date: Thu, 11 Oct 2007 08:07:14 +0000 (+0000) Subject: Utils/Logger: Implement Area and Stream registry X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=9ff976ea47b175355a1f7ef4d05f14edb98a82e4;p=senf.git Utils/Logger: Implement Area and Stream registry Utils/Logger: New SENF_LOG_CONF syntax supporting not-yet-declared areas and streams Utils/Logger: Target baseclass git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@461 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Utils/Logger/Area.cci b/Utils/Logger/Area.cci new file mode 100644 index 0000000..58a59cb --- /dev/null +++ b/Utils/Logger/Area.cci @@ -0,0 +1,110 @@ +// $Id$ +// +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// 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 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_ + + +// 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/Area.hh b/Utils/Logger/Area.hh index 20ff5db..648bd8c 100644 --- a/Utils/Logger/Area.hh +++ b/Utils/Logger/Area.hh @@ -27,9 +27,12 @@ #define HH_Area_ 1 // Custom includes +#include +#include +#include +#include "../singleton.hh" //#include "Area.mpp" -#include "Area.ih" ///////////////////////////////hh.p//////////////////////////////////////// /** \brief Define log area @@ -38,13 +41,48 @@ \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 + { + typedef std::map Registry; + + struct SelectName + { + typedef std::string result_type; + std::string const & operator()(Registry::value_type const & v) const; + }; + + public: + typedef boost::transform_iterator iterator; + + using senf::singleton::instance; + + iterator begin(); + iterator end(); + + private: + AreaRegistry(); + + void registerArea(detail::AreaBase const & area); + + Registry registry_; + + friend class senf::singleton; + friend class detail::AreaBase; + friend class Target; + }; + +}} ///////////////////////////////hh.e//////////////////////////////////////// -//#include "Area.cci" +#include "Area.cci" //#include "Area.ct" //#include "Area.cti" #endif diff --git a/Utils/Logger/Area.ih b/Utils/Logger/Area.ih index d5ddbf3..168ecb0 100644 --- a/Utils/Logger/Area.ih +++ b/Utils/Logger/Area.ih @@ -27,6 +27,8 @@ #define IH_Area_ 1 // Custom includes +#include +#include ///////////////////////////////ih.p//////////////////////////////////////// @@ -34,11 +36,39 @@ namespace senf { 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 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 \ + { \ + static std::string name() { return instance().v_name(); } \ + decls \ + private: \ + area() { init(); } \ + friend class senf::singleton; \ + } + ///////////////////////////////ih.e//////////////////////////////////////// #endif diff --git a/Utils/Logger/Config.ih b/Utils/Logger/Config.ih index dae740d..10b9e4a 100644 --- a/Utils/Logger/Config.ih +++ b/Utils/Logger/Config.ih @@ -30,7 +30,10 @@ #include #include #include -#include "Defaults.hh" +#include +#include +#include +#include "../preprocessor.hh" ///////////////////////////////ih.p//////////////////////////////////////// @@ -50,25 +53,49 @@ namespace detail { typedef typename Stream::compileLimit compileLimit; }; -# define SENF_LOG_CONF_DEFINE(stream, area, level) \ - template <> \ - struct Config \ - { 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 -}}} diff --git a/Utils/Logger/Defaults.hh b/Utils/Logger/Defaults.hh index 833f8f0..a6d6340 100644 --- a/Utils/Logger/Defaults.hh +++ b/Utils/Logger/Defaults.hh @@ -37,7 +37,9 @@ namespace senf { 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 ""; }); }} diff --git a/Utils/Logger/Log.test.cc b/Utils/Logger/Log.test.cc index d57d625..cc31c61 100644 --- a/Utils/Logger/Log.test.cc +++ b/Utils/Logger/Log.test.cc @@ -29,12 +29,14 @@ // Custom includes #include +// 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" @@ -55,7 +57,7 @@ namespace { 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 ); @@ -65,11 +67,14 @@ BOOST_AUTO_UNIT_TEST(logger) { 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"; @@ -77,7 +82,29 @@ BOOST_AUTO_UNIT_TEST(logger) })); 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//////////////////////////////////////// diff --git a/Utils/Logger/Parameters.hh b/Utils/Logger/Parameters.hh index c34d308..e811cb1 100644 --- a/Utils/Logger/Parameters.hh +++ b/Utils/Logger/Parameters.hh @@ -27,6 +27,7 @@ #define HH_Parameters_ 1 // Custom includes +#include "Area.hh" //#include "Parameters.mpp" #include "Parameters.ih" @@ -64,6 +65,13 @@ }; \ } +#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" diff --git a/Utils/Logger/SConscript b/Utils/Logger/SConscript index bd53fae..138b282 100644 --- a/Utils/Logger/SConscript +++ b/Utils/Logger/SConscript @@ -10,7 +10,7 @@ SENFSCons.StandardTargets(env) 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) diff --git a/Utils/Logger/Stream.cc b/Utils/Logger/Stream.cc new file mode 100644 index 0000000..e3c37e0 --- /dev/null +++ b/Utils/Logger/Stream.cc @@ -0,0 +1,50 @@ +// $Id$ +// +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// 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 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" + + +// 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/Stream.cci b/Utils/Logger/Stream.cci new file mode 100644 index 0000000..f106291 --- /dev/null +++ b/Utils/Logger/Stream.cci @@ -0,0 +1,98 @@ +// $Id$ +// +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// 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 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_ + + +// 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/Stream.hh b/Utils/Logger/Stream.hh index b4bab97..d30d2ca 100644 --- a/Utils/Logger/Stream.hh +++ b/Utils/Logger/Stream.hh @@ -27,10 +27,13 @@ #define HH_Stream_ 1 // Custom includes +#include +#include +#include #include "Levels.hh" +#include "../singleton.hh" //#include "Stream.mpp" -#include "Stream.ih" ///////////////////////////////hh.p//////////////////////////////////////// /** \brief Define log stream @@ -47,18 +50,57 @@ */ #define SENF_LOG_DEF_STREAM(stream, defaultLevel_, runtimeLimit_, compileLimit_) \ struct stream \ - : public senf::log::detail::StreamBase \ + : public senf::log::detail::StreamBase, public senf::singleton \ { \ 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; \ } -///////////////////////////////hh.e//////////////////////////////////////// -//#include "Stream.cci" +namespace senf { +namespace log { + + namespace detail { struct StreamBase; } + + class StreamRegistry + : public senf::singleton + { + typedef std::map Registry; + + struct SelectName + { + typedef std::string result_type; + std::string const & operator()(Registry::value_type const & v) const; + }; + + public: + typedef boost::transform_iterator iterator; + + using senf::singleton::instance; + + iterator begin(); + iterator end(); + + private: + StreamRegistry(); + + void registerStream(detail::StreamBase const & stream); + + Registry registry_; + + friend class senf::singleton; + friend class detail::StreamBase; + friend class Target; + }; + +}} + +///////////////////////////////hh.e////////////////////////////////////////# +#include "Stream.cci" //#include "Stream.ct" //#include "Stream.cti" #endif diff --git a/Utils/Logger/Stream.ih b/Utils/Logger/Stream.ih index 55b2dd2..a2db435 100644 --- a/Utils/Logger/Stream.ih +++ b/Utils/Logger/Stream.ih @@ -27,6 +27,7 @@ #define IH_Stream_ 1 // Custom includes +#include ///////////////////////////////ih.p//////////////////////////////////////// @@ -36,8 +37,16 @@ namespace detail { 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; }; }}} diff --git a/Utils/Logger/Target.cc b/Utils/Logger/Target.cc new file mode 100644 index 0000000..651671e --- /dev/null +++ b/Utils/Logger/Target.cc @@ -0,0 +1,69 @@ +// $Id$ +// +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// 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 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" + + +// 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/Target.cci b/Utils/Logger/Target.cci new file mode 100644 index 0000000..07db6d6 --- /dev/null +++ b/Utils/Logger/Target.cci @@ -0,0 +1,93 @@ +// $Id$ +// +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// 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 Target inline non-template implementation */ + +//#include "Target.ih" + +// Custom includes +#include + +#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_ + + +// 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/Target.hh b/Utils/Logger/Target.hh new file mode 100644 index 0000000..43ae954 --- /dev/null +++ b/Utils/Logger/Target.hh @@ -0,0 +1,120 @@ +// $Id$ +// +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// 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 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 + { + 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 RIB; + + RIB rib_; + }; + +}} + +///////////////////////////////hh.e//////////////////////////////////////// +#include "Target.cci" +//#include "Target.ct" +//#include "Target.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/SConscript b/Utils/SConscript index 8d67e70..561137b 100644 --- a/Utils/SConscript +++ b/Utils/SConscript @@ -8,7 +8,7 @@ import SENFSCons, glob 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) diff --git a/Utils/preprocessor.hh b/Utils/preprocessor.hh new file mode 100644 index 0000000..c51605a --- /dev/null +++ b/Utils/preprocessor.hh @@ -0,0 +1,54 @@ +// $Id$ +// +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// 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 preprocessor public header */ + +#ifndef HH_preprocessor_ +#define HH_preprocessor_ 1 + +// Custom includes +#include +#include +#include + +//#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 + + +// 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: