Utils/Logger: Complete unit testing
g0dil [Tue, 30 Oct 2007 13:24:19 +0000 (13:24 +0000)]
Utils/Logger: Fix routing API ambiguities

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@481 270642c3-0616-0410-b53a-bc976706d245

13 files changed:
Utils/Logger/AreaRegistry.test.cc [new file with mode: 0644]
Utils/Logger/Config.hh
Utils/Logger/Config.test.cc [new file with mode: 0644]
Utils/Logger/Log.test.cc
Utils/Logger/Parameters.ih
Utils/Logger/Parameters.test.cc [new file with mode: 0644]
Utils/Logger/StreamRegistry.test.cc [new file with mode: 0644]
Utils/Logger/Target.cc
Utils/Logger/Target.cci
Utils/Logger/Target.cti
Utils/Logger/Target.hh
Utils/Logger/Target.test.cc [new file with mode: 0644]
Utils/Logger/main.test.hh [new file with mode: 0644]

diff --git a/Utils/Logger/AreaRegistry.test.cc b/Utils/Logger/AreaRegistry.test.cc
new file mode 100644 (file)
index 0000000..a299cf3
--- /dev/null
@@ -0,0 +1,60 @@
+// $Id$
+//
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+//     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 AreaRegistry.test unit tests */
+
+//#include "AreaRegistry.test.hh"
+//#include "AreaRegistry.test.ih"
+
+// Custom includes
+#include "main.test.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(areaRegistry)
+{
+    char const * areas[] = { "", "senf::log::test::Foo", "senf::log::test::myArea" };
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( senf::log::AreaRegistry::instance().begin(),
+                                   senf::log::AreaRegistry::instance().end(),
+                                   areas, areas+sizeof(areas)/sizeof(areas[0]) );
+
+}
+
+///////////////////////////////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:
index cd0186a..9725f04 100644 (file)
@@ -45,7 +45,8 @@
 
     <em>Runtime</em> configuration on the other hand deals with routing all those messages, which
     are enabled at compile time to the logging targets. If a message is not routed, it will be
-    discarded. This allows to additionally disable messages at run-time.
+    discarded. This allows to additionally disable messages at run-time. Message routing is managed
+    via the \ref Target interface.
  */
 
 namespace senf {
@@ -62,7 +63,7 @@ namespace log {
         be set on the compiler command line:
         <pre>
         g++ ... -DSENF_LOG_CONF="(( (senf)(log)(Debug),(_),DISABLED ))
-                                 (( (senf)(log)(Debug),(foo)(SomeClass),(VERBOSE) ))
+                                 (( (senf)(log)(Debug),(foo)(SomeClass),VERBOSE ))
                                  (( (foo)(Transactions),(_),NOTICE ))" ...
         </pre>
         (As this option can get quite long, you might want to use the '-imacros' option instead)
diff --git a/Utils/Logger/Config.test.cc b/Utils/Logger/Config.test.cc
new file mode 100644 (file)
index 0000000..5371e66
--- /dev/null
@@ -0,0 +1,70 @@
+// $Id$
+//
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+//     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 Config.test unit tests */
+
+//#include "Config.test.hh"
+//#include "Config.test.ih"
+
+// Custom includes
+#include "main.test.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(logConfig)
+{
+    BOOST_CHECK((   senf::log::Enabled< senf::log::Debug, 
+                                        senf::log::DefaultArea, 
+                                        senf::log::NOTICE >::value ));
+
+    BOOST_CHECK(( ! senf::log::Enabled< senf::log::Debug, 
+                                        senf::log::DefaultArea, 
+                                        senf::log::VERBOSE >::value ));
+
+    BOOST_CHECK(( ! senf::log::Enabled< senf::log::test::myStream, 
+                                        senf::log::DefaultArea, 
+                                        senf::log::VERBOSE >::value ));
+
+
+    BOOST_CHECK((   senf::log::Enabled< senf::log::test::myStream, 
+                                        senf::log::test::Foo, 
+                                        senf::log::VERBOSE >::value ));
+}
+
+///////////////////////////////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:
index 0bec6da..a79397a 100644 (file)
 //#include "Log.test.hh"
 //#include "Log.test.ih"
 
-// We need to put all tests into this single file to not violate the ODR
-
-#define SENF_LOG_CONF (( (senf)(log)(Debug), (_), NOTICE )) \
-                      (( (not_anonymous)(myStream), (not_anonymous)(Foo), VERBOSE ))
-
 // Custom includes
-#include "Logger.hh"
 #include <boost/test/auto_unit_test.hpp>
 #include <boost/test/test_tools.hpp>
+#include "main.test.hh"
 
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-namespace not_anonymous {
-    
-    struct Foo
-    {
-        SENF_LOG_CLASS_AREA();
-
-        static void log() {
-            SENF_LOG(("Foo::log"));
-        }
-    };
-
-    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 );
-
-}
-using namespace not_anonymous;
-
 BOOST_AUTO_UNIT_TEST(logger)
 {
     senf::log::StringTarget target;
 
     target.route<senf::log::Debug>();
-    target.route("not_anonymous::myStream", "not_anonymous::Foo");
 
     // We cannot easily check the exact log string since that includes the current date/time
     
@@ -82,7 +58,7 @@ BOOST_AUTO_UNIT_TEST(logger)
     BOOST_CHECK( ! target.str().empty() );
     target.clear();
 
-    SENF_LOG((LogCritical) ("Another log message: " << 10));
+    SENF_LOG((senf::log::test::LogCritical) ("Another log message: " << 10));
     BOOST_CHECK( ! target.str().empty() );
     target.clear();
 
@@ -93,35 +69,15 @@ BOOST_AUTO_UNIT_TEST(logger)
     BOOST_CHECK( ! target.str().empty() );
     target.clear();
 
-    Foo::log();
+    senf::log::test::Foo::log();
     BOOST_CHECK( ! target.str().empty() );
     target.clear();
 
-    SENF_LOG((Foo)("Foo area"));
+    SENF_LOG((senf::log::test::Foo)("Foo area"));
     BOOST_CHECK( target.str().empty() );
     target.clear();
 }
 
-BOOST_AUTO_UNIT_TEST(streamRegistry)
-{
-    char const * streams[] = { "not_anonymous::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[] = { "", "not_anonymous::Foo", "not_anonymous::myArea" };
-
-    BOOST_CHECK_EQUAL_COLLECTIONS( senf::log::AreaRegistry::instance().begin(),
-                                   senf::log::AreaRegistry::instance().end(),
-                                   areas, areas+sizeof(areas)/sizeof(areas[0]) );
-
-}
-
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_
 
index 2c17541..5370f97 100644 (file)
@@ -34,6 +34,8 @@
 #include <boost/mpl/vector.hpp>
 #include <boost/mpl/fold.hpp>
 #include <boost/mpl/if.hpp>
+#include <boost/utility.hpp>
+#include <boost/type_traits/is_convertible.hpp>
 #include "../mpl.hh"
 #include "Config.hh"
 
diff --git a/Utils/Logger/Parameters.test.cc b/Utils/Logger/Parameters.test.cc
new file mode 100644 (file)
index 0000000..ed2d8c6
--- /dev/null
@@ -0,0 +1,52 @@
+// $Id$
+//
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+//     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 Parameters.test unit tests */
+
+//#include "Parameters.test.hh"
+//#include "Parameters.test.ih"
+
+// Custom includes
+#include "main.test.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+// Tested in Log.test.cc
+
+///////////////////////////////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:
diff --git a/Utils/Logger/StreamRegistry.test.cc b/Utils/Logger/StreamRegistry.test.cc
new file mode 100644 (file)
index 0000000..21901a0
--- /dev/null
@@ -0,0 +1,60 @@
+// $Id$
+//
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+//     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 StreamRegistry.test unit tests */
+
+//#include "StreamRegistry.test.hh"
+//#include "StreamRegistry.test.ih"
+
+// Custom includes
+#include "main.test.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(streamRegistry)
+{
+    char const * streams[] = { "senf::log::Debug", "senf::log::test::myStream" };
+
+    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 );
+}
+
+///////////////////////////////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:
index a7b734b..c07ba21 100644 (file)
@@ -67,6 +67,21 @@ prefix_ void senf::log::Target::route(std::string const & stream, std::string co
     route(s, a, level, action, index);
 }
 
+prefix_ void senf::log::Target::unroute(std::string const & stream, std::string const & area,
+                                        unsigned level, action_t action)
+{
+    detail::StreamBase const * s (StreamRegistry::instance().lookup(stream));
+    if (!s)
+        throw InvalidStreamException();
+    detail::AreaBase const * a (0);
+    if (! area.empty()) {
+        a = AreaRegistry::instance().lookup(area);
+        if (!a)
+            throw InvalidAreaException();
+    }
+    unroute(s, a, level, action);
+}
+
 prefix_ void senf::log::Target::unroute(int index)
 {
     RIB::iterator i;
@@ -105,7 +120,7 @@ prefix_ void senf::log::Target::route(detail::StreamBase const * stream,
             i = rib_.begin();
         else {
             i = rib_.end();
-            std::advance(i, -index - 1);
+            std::advance(i, index + 1 );
         }
     } else {
         if (RIB::size_type(index) >= rib_.size())
index 1aa5b77..1d6f6d9 100644 (file)
@@ -70,13 +70,13 @@ prefix_ bool senf::log::Target::RoutingEntry::operator==(RoutingEntry const & ot
 prefix_ std::string senf::log::Target::RoutingEntry::stream()
     const
 {
-    return stream_->v_name();
+    return stream_ ? stream_->v_name() : "";
 }
 
 prefix_ std::string senf::log::Target::RoutingEntry::area()
     const
 {
-    return area_->v_name();
+    return area_ ? area_->v_name() : "";
 }
 
 prefix_ unsigned senf::log::Target::RoutingEntry::level()
index 30a4523..2312dc6 100644 (file)
 ///////////////////////////////////////////////////////////////////////////
 // senf::log::Target
 
+// senf::log::Target::route
+
 template <class Stream>
 prefix_ void senf::log::Target::route(action_t action, int index)
 {
     route(&Stream::instance(), 0, NONE::value, action, index);
 }
 
-template <class Stream, class Arg>
-prefix_ void senf::log::Target::route(action_t action, int index)
+template <class Stream, class Level>
+prefix_ void senf::log::Target::
+route(action_t action, int index,
+      typename boost::enable_if< boost::is_convertible<Level*, detail::LevelBase *> >::type *)
+{
+    route(&Stream::instance(), 0, Level::value, action, index);
+}
+
+template <class Stream, class Area>
+prefix_ void senf::log::Target::
+route(action_t action, int index,
+      typename boost::enable_if< boost::is_convertible<Area*, detail::AreaBase *> >::type *)
 {
-    route<Arg>(&Stream::instance(), static_cast<Arg*>(0), action, index);
+    route(&Stream::instance(), &Area::instance(), NONE::value, action, index);
+}
+
+template <class Stream, class AreaClass>
+prefix_ void senf::log::Target::
+route(action_t action, int index,
+      typename boost::enable_if< boost::is_convertible<typename AreaClass::SENFLogArea *, detail::AreaBase *> >::type *)
+{
+    route(&Stream::instance(), &AreaClass::SENFLogArea::instance(), NONE::value, action, index);
 }
 
 template <class Stream, class Area, class Level>
-prefix_ void senf::log::Target::route(action_t action, int index)
+prefix_ void senf::log::Target::
+route(action_t action, int index,
+      typename boost::enable_if< boost::is_convertible<Area *, detail::AreaBase *> >::type *)
 {
     route(&Stream::instance(), &Area::instance(), Level::value, action, index);
 }
 
-template <class Stream>
-prefix_ void senf::log::Target::unroute(action_t action)
+template <class Stream, class AreaClass, class Level>
+prefix_ void senf::log::Target::
+route(action_t action, int index,
+      typename boost::enable_if< boost::is_convertible<typename AreaClass::SENFLogArea *, detail::AreaBase *> >::type *)
 {
-    unroute(&Stream::instance(), 0, NONE::value, action);
+    route(&Stream::instance(), &AreaClass::SENFLogArea::instance(), Level::value, action, index);
 }
 
-template <class Stream, class Arg>
+// senf::log::target::ununroute
+
+template <class Stream>
 prefix_ void senf::log::Target::unroute(action_t action)
 {
-    unroute<Arg>(&Stream::instance(), static_cast<Arg*>(0), action);
+    unroute(&Stream::instance(), 0, NONE::value, action);
 }
 
-template <class Stream, class Area, class Level>
-prefix_ void senf::log::Target::unroute(action_t action)
+template <class Stream, class Level>
+prefix_ void senf::log::Target::
+unroute(action_t action,
+      typename boost::enable_if< boost::is_convertible<Level*, detail::LevelBase *> >::type *)
 {
-    unroute(&Stream::instance(), &Area::instance(), Level::value, action);
+    unroute(&Stream::instance(), 0, Level::value, action);
 }
 
-////////////////////////////////////////
-// private members
-
-template <class Area>
-prefix_ void senf::log::Target::route(detail::StreamBase const * stream,
-                                      detail::AreaBase const *, action_t action, int index)
+template <class Stream, class Area>
+prefix_ void senf::log::Target::
+unroute(action_t action,
+      typename boost::enable_if< boost::is_convertible<Area*, detail::AreaBase *> >::type *)
 {
-    route(stream, &Area::instance(), NONE::value, action, index);
+    unroute(&Stream::instance(), &Area::instance(), NONE::value, action);
 }
 
-template <class Level>
-prefix_ void senf::log::Target::route(detail::StreamBase const * stream,
-                                      detail::LevelBase const *, action_t action, int index)
+template <class Stream, class AreaClass>
+prefix_ void senf::log::Target::
+unroute(action_t action,
+      typename boost::enable_if< boost::is_convertible<typename AreaClass::SENFLogArea *, detail::AreaBase *> >::type *)
 {
-    route(stream, 0, Level::value, action, index);
+    unroute(&Stream::instance(), &AreaClass::SENFLogArea::instance(), NONE::value, action);
 }
 
-template <class Area>
-prefix_ void senf::log::Target::unroute(detail::StreamBase const * stream,
-                                        detail::AreaBase const *, action_t action)
+template <class Stream, class Area, class Level>
+prefix_ void senf::log::Target::
+unroute(action_t action,
+      typename boost::enable_if< boost::is_convertible<Area *, detail::AreaBase *> >::type *)
 {
-    unroute(stream, &Area::instance(), NONE::value, action);
+    unroute(&Stream::instance(), &Area::instance(), Level::value, action);
 }
 
-template <class Level>
-prefix_ void senf::log::Target::unroute(detail::StreamBase const * stream,
-                                        detail::LevelBase const *, action_t action)
+template <class Stream, class AreaClass, class Level>
+prefix_ void senf::log::Target::
+unroute(action_t action,
+      typename boost::enable_if< boost::is_convertible<typename AreaClass::SENFLogArea *, detail::AreaBase *> >::type *)
 {
-    unroute(stream, 0, Level::value, action);
+    unroute(&Stream::instance(), &AreaClass::SENFLogArea::instance(), Level::value, action);
 }
 
 ///////////////////////////////////////////////////////////////////////////
index 777e546..b4137d6 100644 (file)
@@ -30,6 +30,7 @@
 #include <set>
 #include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/utility.hpp>
+#include <boost/type_traits/is_convertible.hpp>
 #include "../singleton.hh"
 #include "../mpl.hh"
 #include "StreamRegistry.hh"
@@ -99,17 +100,54 @@ namespace log {
 
         ///@}
 
-        template <class Stream> void route(action_t action = ACCEPT, int index = -1);
-        template <class Stream, class Arg> void route(action_t action = ACCEPT, int index = -1);
-        template <class Stream, class Area, class Level> void route(action_t action = ACCEPT, 
-                                                                    int index = -1);
+        template <class Stream> void route(
+            action_t action = ACCEPT, int index = -1);
+        template <class Stream, class Level> void route(
+            action_t action = ACCEPT, int index = -1,
+            typename boost::enable_if< boost::is_convertible<Level*,
+                                                             detail::LevelBase *> >::type * = 0);
+        template <class Stream, class Area> void route(
+            action_t action = ACCEPT, int index = -1,
+            typename boost::enable_if< boost::is_convertible<Area*,
+                                                             detail::AreaBase *> >::type * = 0);
+        template <class Stream, class AreaClass> void route(
+            action_t action = ACCEPT, int index = -1,
+            typename boost::enable_if< boost::is_convertible<typename AreaClass::SENFLogArea *,
+                                                             detail::AreaBase *> >::type * = 0);
+        template <class Stream, class Area, class Level> void route(
+            action_t action = ACCEPT, int index = -1,
+            typename boost::enable_if< boost::is_convertible<Area *,
+                                                             detail::AreaBase *> >::type * = 0);
+        template <class Stream, class AreaClass, class Level> void route(
+            action_t action = ACCEPT, int index = -1,
+            typename boost::enable_if< boost::is_convertible<typename AreaClass::SENFLogArea *,
+                                                             detail::AreaBase *> >::type * = 0);
 
         void route(std::string const & stream, std::string const & area = "", 
                    unsigned level = NONE::value, action_t action = ACCEPT, int index = -1);
 
-        template <class Stream> void unroute(action_t action = ACCEPT);
-        template <class Stream, class Arg> void unroute(action_t action = ACCEPT);
-        template <class Stream, class Area, class Level> void unroute(action_t action = ACCEPT);
+        template <class Stream> void unroute(
+            action_t action = ACCEPT);
+        template <class Stream, class Level> void unroute(
+            action_t action = ACCEPT,
+            typename boost::enable_if< boost::is_convertible<Level*,
+                                                             detail::LevelBase *> >::type * = 0);
+        template <class Stream, class Area> void unroute(
+            action_t action = ACCEPT,
+            typename boost::enable_if< boost::is_convertible<Area*,
+                                                             detail::AreaBase *> >::type * = 0);
+        template <class Stream, class AreaClass> void unroute(
+            action_t action = ACCEPT,
+            typename boost::enable_if< boost::is_convertible<typename AreaClass::SENFLogArea *,
+                                                             detail::AreaBase *> >::type * = 0);
+        template <class Stream, class Area, class Level> void unroute(
+            action_t action = ACCEPT,
+            typename boost::enable_if< boost::is_convertible<Area*,
+                                                             detail::AreaBase *> >::type * = 0);
+        template <class Stream, class AreaClass, class Level> void unroute(
+            action_t action = ACCEPT,
+            typename boost::enable_if< boost::is_convertible<typename AreaClass::SENFLogArea *,
+                                                             detail::AreaBase *> >::type * = 0);
 
         void unroute(std::string const & stream, std::string const & area = "", 
                      unsigned level = NONE::value, action_t action = ACCEPT);
@@ -132,16 +170,6 @@ namespace log {
         void unroute(detail::StreamBase const * stream, detail::AreaBase const * area, 
                      unsigned level, action_t action);
 
-        template <class Area> void route(detail::StreamBase const * stream, 
-                                         detail::AreaBase const *, action_t action, int index);
-        template <class Level> void route(detail::StreamBase const * stream, 
-                                          detail::LevelBase const *, action_t action, int index);
-
-        template <class Area> void unroute(detail::StreamBase const * stream, 
-                                           detail::AreaBase const *, action_t action);
-        template <class Level> void unroute(detail::StreamBase const * stream, 
-                                          detail::LevelBase const *, action_t action);
-        
         void updateRoutingCache(detail::StreamBase const * stream, detail::AreaBase const * area);
 
         void write(boost::posix_time::ptime timestamp, detail::StreamBase const & stream,
diff --git a/Utils/Logger/Target.test.cc b/Utils/Logger/Target.test.cc
new file mode 100644 (file)
index 0000000..b41ead9
--- /dev/null
@@ -0,0 +1,114 @@
+// $Id$
+//
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+//     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.test unit tests */
+
+//#include "Target.test.hh"
+//#include "Target.test.ih"
+
+// Custom includes
+#include <sstream>
+#include "main.test.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+    
+    struct RouteCheck
+    {
+        typedef std::string result_type;
+        std::string operator()(senf::log::Target::RoutingEntry const & entry) const
+            {
+                static char const * levels[] = { "NONE", "VERBOSE", "NOTICE", "MESSAGE",
+                                                 "IMPORTANT", "CRITICAL","DISABLED" };
+                static char const * actions[] = { "ACCEPT", "REJECT" };
+                std::stringstream s;
+                s << entry.stream() << "-" << entry.area() << "-" << levels[entry.level()] << "-" 
+                  << actions[entry.action()];
+                return s.str();
+            }
+    };
+
+}
+
+BOOST_AUTO_UNIT_TEST(target)
+{
+    senf::log::StringTarget target;
+
+    target.route<senf::log::Debug>();
+    target.route<senf::log::test::myStream, senf::log::DefaultArea>(senf::log::Target::REJECT);
+    target.route<senf::log::test::myStream, senf::log::VERBOSE>(senf::log::Target::ACCEPT, 0);
+    target.route<senf::log::test::myStream, senf::log::test::Foo, senf::log::VERBOSE>(
+        senf::log::Target::ACCEPT, 2);
+    target.route("senf::log::test::myStream", "", senf::log::IMPORTANT::value, 
+                 senf::log::Target::REJECT, 4);
+    target.route("senf::log::Debug", "senf::log::test::Foo", senf::log::VERBOSE::value,
+                 senf::log::Target::REJECT, -5);
+    target.route("senf::log::Debug", "", senf::log::MESSAGE::value, 
+                 senf::log::Target::ACCEPT, -7);
+
+    typedef boost::transform_iterator<RouteCheck, senf::log::Target::iterator> iterator;
+    iterator i (boost::make_transform_iterator(target.begin(), RouteCheck()));
+    iterator const i_end (boost::make_transform_iterator(target.end(), RouteCheck()));
+
+    char const * data[] = { 
+        "senf::log::Debug--MESSAGE-ACCEPT",
+        "senf::log::test::myStream--VERBOSE-ACCEPT",
+        "senf::log::Debug-senf::log::test::Foo-VERBOSE-REJECT",
+        "senf::log::Debug--NONE-ACCEPT",
+        "senf::log::test::myStream-senf::log::test::Foo-VERBOSE-ACCEPT",
+        "senf::log::test::myStream--NONE-REJECT",
+        "senf::log::test::myStream--IMPORTANT-REJECT",
+    };
+
+    BOOST_CHECK_EQUAL_COLLECTIONS( i, i_end, data, data + sizeof(data)/sizeof(data[0]) );
+
+    target.unroute<senf::log::Debug>();
+    target.unroute<senf::log::test::myStream, senf::log::VERBOSE>();
+    target.unroute<senf::log::test::myStream, senf::log::DefaultArea>(senf::log::Target::REJECT);
+    target.unroute<senf::log::test::myStream, senf::log::test::Foo, senf::log::VERBOSE>();
+    target.unroute("senf::log::test::myStream", "", senf::log::IMPORTANT::value, 
+                   senf::log::Target::REJECT);
+    target.unroute(1);
+    target.unroute(0);
+
+    BOOST_CHECK( target.begin() == target.end() );
+}
+
+///////////////////////////////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:
diff --git a/Utils/Logger/main.test.hh b/Utils/Logger/main.test.hh
new file mode 100644 (file)
index 0000000..799d529
--- /dev/null
@@ -0,0 +1,73 @@
+// $Id$
+//
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer NETwork research (NET)
+//     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 main.test public header */
+
+#ifndef HH_main_test_
+#define HH_main_test_ 1
+
+// Custom includes
+
+#define SENF_LOG_CONF (( (senf)(log)(Debug), (_), NOTICE )) \
+                      (( (senf)(log)(test)(myStream), (senf)(log)(test)(Foo), VERBOSE ))
+
+#include "Logger.hh"
+
+//#include "main.test.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace log {
+namespace test {
+    
+    struct Foo
+    {
+        SENF_LOG_CLASS_AREA();
+
+        static void log() {
+            SENF_LOG(("Foo::log"));
+        }
+    };
+
+    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 );
+
+}}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "main.test.cci"
+//#include "main.test.ct"
+//#include "main.test.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: