Utils: Moved Logger into 'Logger/' submodule
g0dil [Wed, 10 Oct 2007 07:08:36 +0000 (07:08 +0000)]
Logger: Implemented compile-time configuration support

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

27 files changed:
PPI/DebugModules.cti
PPI/DebugModules.hh
PPI/DebugModules.test.cc
Socket/Protocols/SConscript
Utils/Logger.hh
Utils/Logger/Area.hh [copied from Utils/Logger.test.cc with 52% similarity]
Utils/Logger/Area.ih [copied from Utils/Logger.test.cc with 52% similarity]
Utils/Logger/Config.hh [copied from Utils/Logger.test.cc with 52% similarity]
Utils/Logger/Config.ih [new file with mode: 0644]
Utils/Logger/Defaults.hh [copied from Utils/Logger.test.cc with 52% similarity]
Utils/Logger/Doxyfile [new file with mode: 0644]
Utils/Logger/Levels.hh [new file with mode: 0644]
Utils/Logger/Levels.ih [copied from Utils/Logger.test.cc with 52% similarity]
Utils/Logger/Log.hh [new file with mode: 0644]
Utils/Logger/Log.test.cc [copied from Utils/Logger.test.cc with 68% similarity]
Utils/Logger/Logger.hh [new file with mode: 0644]
Utils/Logger/Mainpage.dox [new file with mode: 0644]
Utils/Logger/Parameters.hh [new file with mode: 0644]
Utils/Logger/Parameters.ih [new file with mode: 0644]
Utils/Logger/SConscript [new file with mode: 0644]
Utils/Logger/Stream.hh [new file with mode: 0644]
Utils/Logger/Stream.ih [copied from Utils/Logger.test.cc with 52% similarity]
Utils/Logger/main.test.cc [moved from Utils/Logger.test.cc with 60% similarity]
Utils/Mainpage.dox
Utils/SConscript
doclib/SConscript
senf.dict

index b2b2c33..e9c7309 100644 (file)
@@ -34,8 +34,8 @@
 ///////////////////////////////////////////////////////////////////////////
 // senf::ppi::module::debug::LogSink<Stream,Area,level>
 
-template <class Stream, class Area, senf::log::Level level>
-prefix_ senf::ppi::module::debug::LogSink<Stream,Area,level>::LogSink()
+template <class Stream, class Area, class Level>
+prefix_ senf::ppi::module::debug::LogSink<Stream,Area,Level>::LogSink()
 {
     noroute(input);
     input.onRequest(&LogSink::request);
@@ -44,11 +44,11 @@ prefix_ senf::ppi::module::debug::LogSink<Stream,Area,level>::LogSink()
 ////////////////////////////////////////
 // private members
 
-template <class Stream, class Area, senf::log::Level level>
-prefix_ void senf::ppi::module::debug::LogSink<Stream,Area,level>::request()
+template <class Stream, class Area, class Level>
+prefix_ void senf::ppi::module::debug::LogSink<Stream,Area,Level>::request()
 {
     Packet packet (input());
-    SENF_LOG_BLOCK((Stream)(Area)(level)({
+    SENF_LOG_BLOCK((Stream)(Area)(Level)({
         packet.dump(log);
         hexdump(packet.last().data().begin(), packet.last().data().end(),log);
     }));
index 7611442..58e52c6 100644 (file)
@@ -266,9 +266,9 @@ namespace debug {
         This module will log all packets sent to it's input using SENF_LOG to the given log
         \a Stream, \a Area and \a level.
      */
-    template < class Stream           = log::Debug, 
-               class Area             = log::DefaultArea, 
-               senf::log::Level level = log::VERBOSE >
+    template < class Stream = log::Debug, 
+               class Area   = log::DefaultArea, 
+               class Level  = log::VERBOSE >
     class LogSink
         : public module::Module
     {
index e04fb70..a088012 100644 (file)
@@ -36,6 +36,8 @@ namespace {
     std::stringstream logstream;
 }
 
+#define SENF_LOG_CONF ((senf::log::Debug)(_)(VERBOSE))
+
 #include "../Packets/Packets.hh"
 #include "DebugModules.hh"
 #include "Setup.hh"
index c5ca1ad..bbf7262 100644 (file)
@@ -5,17 +5,15 @@ import SENFSCons, glob
 
 ###########################################################################
 
-sources = SENFSCons.GlobSources()
-
-allob = []
+SENFSCons.StandardTargets(env)
 
-allob.extend(
-    SENFSCons.Objects( env, sources = sources, LIBS = [ 'Socket', 'Utils' ] ) )
+sources = SENFSCons.GlobSources()
+objects = SENFSCons.Objects( env, sources = sources, LIBS = [ 'Socket', 'Utils' ] )
 
 for sc in glob.glob("*/SConscript"):
     ob = SConscript(sc)
-    if ob : allob.extend(ob)
+    if ob : objects.extend(ob)
 
 SENFSCons.InstallIncludeFiles(env, [ 'INet.hh', 'Raw.hh' ])
 
-Return('allob')
+Return('objects')
index c766392..c904f46 100644 (file)
 /** \file
     \brief Logger public header */
 
-/** \defgroup logger The SENF Logger
-
-    The Loggger infrastructure shall implement a highly flexible compile- and run-time configurable
-    logging infrastructure supporting multiple streams, user definable log areas and fine grained
-    log levels. Logging can be configured at compile and runtime on any combination of above
-    parameters. The library supports a host of log targets and messages can be routed into multiple
-    targets at the same time. To allow concise usage of the library, a utility to define logging
-    defaults for any scope is provided.
-
-    An important basic concept of the library is, that most of the macros take a variable number of
-    arguments. Since this is not supported in the needed manner by the C++ preprocessor, the
-    arguments are encoded into a <a
-    href="http://www.boost.org/libs/preprocessor/doc/index.html">Boost.Preprocessor</a> like
-    sequence:
-
-    \code
-    SENF_LOG( (senf::log::Debug)(senf::log::NOTICE)(FroblizerArea)("The log message") );
-    \endcode
-
-    The last sequence element always is the log message. Before that we have a number of log
-    parameters <i>in arbitrary order</i>. Since giving all the parameters in every log message is
-    to verbose, there are two helpful constructs to reduce the verbosity. Using \ref SENF_LOG_DEFAULTS it
-    is possible to define the default logging parameters to be used within a given scope. Using
-    \ref SENF_LOG_DEF_ALIAS you can define an alias (which is a scoped symbol) as an arbitrary
-    combination of parameters.
-
-    \code
-    SENF_LOG_DEF_STREAM(userLog);
-
-    class Froblizer
-    {
-        // Define a new log area
-        SENF_LOG_DEF_AREA(FroblizerArea);
-
-        // Set default log parameters for this scope
-        SENF_LOG_DEFAULTS( (senf::log::Debug) (senf::log::NOTICE) (FroblizerArea) );
-
-        // Define an alias for emergency messages to the sysadmin.
-        // The log area is inherited from the default at the place, where this
-        // alias is used *not* where it is defined
-        SENF_LOG_DEF_ALIAS(LogEmerg, (userLog) (senf::log::CRITICAL));
-
-        void test();
-
-    public:
-        void froblize();
-    };
-
-    void Froblizer::froblize()
-    {
-        SENF_LOG(("This is the Debug stream at level NOTICE in the FroblizeArea"));
-        SENF_LOG((senf::log::WARNING) ("Same stream and area but at warning level"));
-        SENF_LOG((LogEmerg) ("This goes to the userLog at level CRITICAL in the FroblizerArea"));
-    }
-
-    void Froblizer::test()
-    {
-        // Change the default log level for this method. stream and area are taken
-        // from the next scope up
-        SENF_LOG_DEFAULTS((senf::log::DEBUG));
-
-        SENF_LOG(("Log to Debug stream in Froblizer area however at DEBUG level"));
-    }
-    \endcode
-
-    Currently, the library is not implemented in any way. The interface has been defined up to a
-    point and we have dummy implementations of the 'in-code' part of the interface. This is the
-    part, which is called throughout the code. The configuration API is defined but we don't even
-    have a template implementation. However, this allows starting to use the SENF Logger in newly
-    developed code. Even though this code will unconditionally log everything to \c std::cerr for
-    now and errors in the parameter specification will not be caught (since they are just ignored)
-    the logging should work automatically as advertised as soon as the logger is completely
-    implemented.
-
-    \implementation I would have much preferred a more C++ like implementation. However given the
-    design goals
-    \li Flexible configuration at compile and runtime
-    \li Concise usage and simple interface
-    \li Zero overhead for compile-time disabled log messages
-
-    I did not find any implementation which was not either completely convoluted, unusable or
-    slow. So I turned to a macro based implementation which can provide all the design goals stated
-    above.
- */
-
-#ifndef HH_Logger_
-#define HH_Logger_ 1
-
-// Custom includes
-#include <iostream>
-#include <boost/preprocessor/seq/size.hpp>
-#include <boost/preprocessor/dec.hpp>
-#include <boost/preprocessor/seq/elem.hpp>
-
-//#include "Logger.mpp"
-///////////////////////////////hh.p////////////////////////////////////////
-
-namespace senf {
-namespace log {
-
-#   ifndef _senf_LOG_STREAM
-#     define _senf_LOG_STREAM std::cerr
-#   endif
-
-    /// \addtogroup logger
-    /// @{
-
-    /** \brief Write log message
-
-        This macro will write it's last argument to the log stream. The last argument must be an
-        expression which will be placed after a streaming \c operator<< (like
-        <i>some-log-sttream</i> \c << <i>last-macro-arg</i>).
-        \code
-        SENF_LOG((parameters...)("log message " << args << ...));
-        \endcode
-
-        \hideinitializer
-     */
-#   define SENF_LOG(args)                                                                       \
-        _senf_LOG_STREAM << BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args)       \
-                         << std::endl;
-
-    /** \brief Enable block based on logging parameters
-
-        This macro is like SENF_LOG, however instead of writing a simple message, this macro allows
-        to specify a complete block of code to be executed if the log message is enabled.
-        \code
-        SENF_LOG_BLOCK((parameters...)({
-           // arbitrary code using 'log' for logging
-           log << "log message";
-        }));
-        \endcode
-
-        \hideinitializer
-     */
-#   define SENF_LOG_BLOCK(args)                                                 \
-        do {                                                                    \
-            std::ostream & log (_senf_LOG_STREAM);                              \
-            BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args)       \
-            log << std::endl;                                                   \
-        } while (0)
-
-    /** \brief Set scope default log parameters
-
-        Sets the default log parameters for the current scope
-        \code
-        SENF_LOG_DEFAULTS((parameters...));
-        \endcode
-
-        \hideinitializer
-     */
-#   define SENF_LOG_DEFAULTS(args)
-
-    /** \brief Define log area
-
-        Defines a new log area named \a area. The area is defined as a symbol in the current scope.
-
-        \hideinitializer
-     */
-#   define SENF_LOG_DEF_AREA(area) struct area {}
-
-    /** \brief Define log stream
-
-        Defines a new log stream named \a stream. The stream is defined as a symbol in the current
-        scope.
-
-        \hideinitializer
-     */
-#   define SENF_LOG_DEF_STREAM(stream) struct stream {}
-
-    /** \brief Define log parameter alias
-
-        Defines a new parameter alias named \a alias as an alias for the parameters in \a args. The
-        alias is defined as a symbol in the current scope.
-
-        \hideinitializer
-     */
-#   define SENF_LOG_DEF_ALIAS(alias,args) struct alias {}
-
-    /// @}
-
-    enum Level { VERBOSE, NOTICE, MESSAGE, IMPORTANT, CRITICAL };
-    
-    SENF_LOG_DEF_STREAM(Debug);
-    SENF_LOG_DEF_AREA(DefaultArea);
-
-}}
-
-///////////////////////////////hh.e////////////////////////////////////////
-//#include "Logger.cci"
-//#include "Logger.ct"
-//#include "Logger.cti"
-#endif
+#include "Logger/Logger.hh"
 
 \f
 // Local Variables:
similarity index 52%
copy from Utils/Logger.test.cc
copy to Utils/Logger/Area.hh
index 5478e90..20ff5db 100644 (file)
@@ -1,6 +1,6 @@
 // $Id$
 //
-// Copyright (C) 2007
+// Copyright (C) 2007 
 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
 //     Stefan Bund <g0dil@berlios.de>
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief Logger.test unit tests */
+    \brief Area public header */
 
-//#include "Logger.test.hh"
-//#include "Logger.test.ih"
+#ifndef HH_Area_
+#define HH_Area_ 1
 
 // Custom includes
-#include <sstream>
-#define _senf_LOG_STREAM logstream
-#include "Logger.hh"
 
-#include <boost/test/auto_unit_test.hpp>
-#include <boost/test/test_tools.hpp>
+//#include "Area.mpp"
+#include "Area.ih"
+///////////////////////////////hh.p////////////////////////////////////////
 
-#define prefix_
-///////////////////////////////cc.p////////////////////////////////////////
+/** \brief Define log area
 
-BOOST_AUTO_UNIT_TEST(logger)
-{
-    std::stringstream logstream;
+    Defines a new log area named \a area. The area is defined as a symbol in the current scope.
 
-    SENF_LOG_DEFAULTS( (senf::log::Debug) (senf::log::NOTICE) );
-    SENF_LOG_DEF_ALIAS( LogFoo, (senf::log::Debug) (senf::log::CRITICAL) );
-    SENF_LOG_DEF_STREAM( myStream );
-    SENF_LOG_DEF_AREA( myArea );
+    \hideinitializer
+ */
+#define SENF_LOG_DEF_AREA(area)                                                                   \
+    struct area                                                                                   \
+        : public senf::log::detail::AreaBase                                                      \
+    {}
 
-    SENF_LOG(("Log message"));
-
-    SENF_LOG((LogFoo) ("Another log message: " << 10));
-
-    SENF_LOG_BLOCK((senf::log::Debug) (senf::log::WARNING) ({
-        log << "Last message";
-        log << " continued here";
-    }));
-
-    BOOST_CHECK_EQUAL( logstream.str(), "Log message\nAnother log message: 10\nLast message continued here\n" );
-}
-
-///////////////////////////////cc.e////////////////////////////////////////
-#undef prefix_
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "Area.cci"
+//#include "Area.ct"
+//#include "Area.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"
-// comment-column: 40
 // End:
similarity index 52%
copy from Utils/Logger.test.cc
copy to Utils/Logger/Area.ih
index 5478e90..d5ddbf3 100644 (file)
@@ -1,6 +1,6 @@
 // $Id$
 //
-// Copyright (C) 2007
+// Copyright (C) 2007 
 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
 //     Stefan Bund <g0dil@berlios.de>
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief Logger.test unit tests */
+    \brief Area internal header */
 
-//#include "Logger.test.hh"
-//#include "Logger.test.ih"
+#ifndef IH_Area_
+#define IH_Area_ 1
 
 // Custom includes
-#include <sstream>
-#define _senf_LOG_STREAM logstream
-#include "Logger.hh"
 
-#include <boost/test/auto_unit_test.hpp>
-#include <boost/test/test_tools.hpp>
+///////////////////////////////ih.p////////////////////////////////////////
 
-#define prefix_
-///////////////////////////////cc.p////////////////////////////////////////
+namespace senf {
+namespace log {
+namespace detail {
 
-BOOST_AUTO_UNIT_TEST(logger)
-{
-    std::stringstream logstream;
+    struct AreaBase
+    {};
 
-    SENF_LOG_DEFAULTS( (senf::log::Debug) (senf::log::NOTICE) );
-    SENF_LOG_DEF_ALIAS( LogFoo, (senf::log::Debug) (senf::log::CRITICAL) );
-    SENF_LOG_DEF_STREAM( myStream );
-    SENF_LOG_DEF_AREA( myArea );
+}}}
 
-    SENF_LOG(("Log message"));
-
-    SENF_LOG((LogFoo) ("Another log message: " << 10));
-
-    SENF_LOG_BLOCK((senf::log::Debug) (senf::log::WARNING) ({
-        log << "Last message";
-        log << " continued here";
-    }));
-
-    BOOST_CHECK_EQUAL( logstream.str(), "Log message\nAnother log message: 10\nLast message continued here\n" );
-}
-
-///////////////////////////////cc.e////////////////////////////////////////
-#undef prefix_
+///////////////////////////////ih.e////////////////////////////////////////
+#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"
-// comment-column: 40
 // End:
similarity index 52%
copy from Utils/Logger.test.cc
copy to Utils/Logger/Config.hh
index 5478e90..0cc8362 100644 (file)
@@ -1,6 +1,6 @@
 // $Id$
 //
-// Copyright (C) 2007
+// Copyright (C) 2007 
 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
 //     Stefan Bund <g0dil@berlios.de>
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief Logger.test unit tests */
+    \brief Config public header */
 
-//#include "Logger.test.hh"
-//#include "Logger.test.ih"
+#ifndef HH_Config_
+#define HH_Config_ 1
 
 // Custom includes
-#include <sstream>
-#define _senf_LOG_STREAM logstream
-#include "Logger.hh"
+#include "Levels.hh"
 
-#include <boost/test/auto_unit_test.hpp>
-#include <boost/test/test_tools.hpp>
+//#include "Config.mpp"
+#include "Config.ih"
+///////////////////////////////hh.p////////////////////////////////////////
 
-#define prefix_
-///////////////////////////////cc.p////////////////////////////////////////
+namespace senf {
+namespace log {
 
-BOOST_AUTO_UNIT_TEST(logger)
-{
-    std::stringstream logstream;
+    template <class Stream, class Area, class Level>
+    struct Enabled
+    {
+        static const bool value = (
+            (Level::value == senf::log::NONE::value ? Stream::defaultLevel::value : Level::value)
+                >= detail::Config<Stream,Area>::compileLimit::value );
+    };
 
-    SENF_LOG_DEFAULTS( (senf::log::Debug) (senf::log::NOTICE) );
-    SENF_LOG_DEF_ALIAS( LogFoo, (senf::log::Debug) (senf::log::CRITICAL) );
-    SENF_LOG_DEF_STREAM( myStream );
-    SENF_LOG_DEF_AREA( myArea );
+}}
 
-    SENF_LOG(("Log message"));
-
-    SENF_LOG((LogFoo) ("Another log message: " << 10));
-
-    SENF_LOG_BLOCK((senf::log::Debug) (senf::log::WARNING) ({
-        log << "Last message";
-        log << " continued here";
-    }));
-
-    BOOST_CHECK_EQUAL( logstream.str(), "Log message\nAnother log message: 10\nLast message continued here\n" );
-}
-
-///////////////////////////////cc.e////////////////////////////////////////
-#undef prefix_
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "Config.cci"
+//#include "Config.ct"
+//#include "Config.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"
-// comment-column: 40
 // End:
diff --git a/Utils/Logger/Config.ih b/Utils/Logger/Config.ih
new file mode 100644 (file)
index 0000000..dae740d
--- /dev/null
@@ -0,0 +1,87 @@
+// $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 Config internal header */
+
+#ifndef IH_Config_
+#define IH_Config_ 1
+
+// Custom includes
+#include <boost/preprocessor/expand.hpp>
+#include <boost/preprocessor/seq/for_each.hpp>
+#include <boost/preprocessor/seq/to_tuple.hpp>
+#include "Defaults.hh"
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace senf {
+namespace log {
+namespace detail {
+
+    template <class Stream, class Area>
+    struct Config
+    {
+        typedef typename Config<Stream,void>::compileLimit compileLimit;
+    };
+
+    template <class Stream>
+    struct Config<Stream, void>
+    {
+        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 _ void
+#       define SLC_elt(r, data, elt) \
+            BOOST_PP_EXPAND(SENF_LOG_CONF_DEFINE BOOST_PP_SEQ_TO_TUPLE(elt))
+
+        BOOST_PP_SEQ_FOR_EACH(SLC_elt, x, SENF_LOG_CONF)
+
+#       undef SLC_elt
+#       undef _
+
+#   endif
+
+}}}
+
+
+
+///////////////////////////////ih.e////////////////////////////////////////
+#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:
similarity index 52%
copy from Utils/Logger.test.cc
copy to Utils/Logger/Defaults.hh
index 5478e90..833f8f0 100644 (file)
@@ -1,6 +1,6 @@
 // $Id$
 //
-// Copyright (C) 2007
+// Copyright (C) 2007 
 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
 //     Stefan Bund <g0dil@berlios.de>
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief Logger.test unit tests */
+    \brief Defaults public header */
 
-//#include "Logger.test.hh"
-//#include "Logger.test.ih"
+#ifndef HH_Defaults_
+#define HH_Defaults_ 1
 
 // Custom includes
-#include <sstream>
-#define _senf_LOG_STREAM logstream
-#include "Logger.hh"
+#include "Stream.hh"
+#include "Area.hh"
 
-#include <boost/test/auto_unit_test.hpp>
-#include <boost/test/test_tools.hpp>
+//#include "Defaults.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
 
-#define prefix_
-///////////////////////////////cc.p////////////////////////////////////////
+namespace senf {
+namespace log {
 
-BOOST_AUTO_UNIT_TEST(logger)
-{
-    std::stringstream logstream;
+    SENF_LOG_DEF_STREAM(Debug, MESSAGE, DISABLED, DISABLED);
+    SENF_LOG_DEF_AREA(DefaultArea);
 
-    SENF_LOG_DEFAULTS( (senf::log::Debug) (senf::log::NOTICE) );
-    SENF_LOG_DEF_ALIAS( LogFoo, (senf::log::Debug) (senf::log::CRITICAL) );
-    SENF_LOG_DEF_STREAM( myStream );
-    SENF_LOG_DEF_AREA( myArea );
+}}
 
-    SENF_LOG(("Log message"));
-
-    SENF_LOG((LogFoo) ("Another log message: " << 10));
-
-    SENF_LOG_BLOCK((senf::log::Debug) (senf::log::WARNING) ({
-        log << "Last message";
-        log << " continued here";
-    }));
-
-    BOOST_CHECK_EQUAL( logstream.str(), "Log message\nAnother log message: 10\nLast message continued here\n" );
-}
-
-///////////////////////////////cc.e////////////////////////////////////////
-#undef prefix_
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "Defaults.cci"
+//#include "Defaults.ct"
+//#include "Defaults.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"
-// comment-column: 40
 // End:
diff --git a/Utils/Logger/Doxyfile b/Utils/Logger/Doxyfile
new file mode 100644 (file)
index 0000000..580c29f
--- /dev/null
@@ -0,0 +1,5 @@
+@INCLUDE = "$(TOPDIR)/doclib/Doxyfile.global"
+
+PROJECT_NAME = libLogger
+GENERATE_TAGFILE = doc/Logger.tag
+ALPHABETICAL_INDEX = NO
diff --git a/Utils/Logger/Levels.hh b/Utils/Logger/Levels.hh
new file mode 100644 (file)
index 0000000..35aa048
--- /dev/null
@@ -0,0 +1,73 @@
+// $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 Levels public header */
+
+#ifndef HH_Levels_
+#define HH_Levels_ 1
+
+// Custom includes
+
+//#include "Levels.mpp"
+#include "Levels.ih"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace log {
+
+    /** \brief Log levels
+        
+        These are the valid log levels with some additional special values:
+
+        \c DISABLED is a special value used as level limit to disable all messages.
+
+        \c NONE is used to in some special places to inherit the default log level.
+     */
+
+    struct VERBOSE   : public detail::LevelBase { static unsigned const value = 1; };
+    struct NOTICE    : public detail::LevelBase { static unsigned const value = 2; };
+    struct MESSAGE   : public detail::LevelBase { static unsigned const value = 3; };
+    struct IMPORTANT : public detail::LevelBase { static unsigned const value = 4; };
+    struct CRITICAL  : public detail::LevelBase { static unsigned const value = 5; };
+
+    struct DISABLED  : public detail::LevelBase { static unsigned const value = 6; };
+    struct NONE      : public detail::LevelBase { static unsigned const value = 0; };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "Levels.cci"
+//#include "Levels.ct"
+//#include "Levels.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:
similarity index 52%
copy from Utils/Logger.test.cc
copy to Utils/Logger/Levels.ih
index 5478e90..442efd1 100644 (file)
@@ -1,6 +1,6 @@
 // $Id$
 //
-// Copyright (C) 2007
+// Copyright (C) 2007 
 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
 //     Stefan Bund <g0dil@berlios.de>
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief Logger.test unit tests */
+    \brief Levels internal header */
 
-//#include "Logger.test.hh"
-//#include "Logger.test.ih"
+#ifndef IH_Levels_
+#define IH_Levels_ 1
 
 // Custom includes
-#include <sstream>
-#define _senf_LOG_STREAM logstream
-#include "Logger.hh"
 
-#include <boost/test/auto_unit_test.hpp>
-#include <boost/test/test_tools.hpp>
+///////////////////////////////ih.p////////////////////////////////////////
 
-#define prefix_
-///////////////////////////////cc.p////////////////////////////////////////
+namespace senf {
+namespace log {
+namespace detail {
 
-BOOST_AUTO_UNIT_TEST(logger)
-{
-    std::stringstream logstream;
+    struct LevelBase {};
 
-    SENF_LOG_DEFAULTS( (senf::log::Debug) (senf::log::NOTICE) );
-    SENF_LOG_DEF_ALIAS( LogFoo, (senf::log::Debug) (senf::log::CRITICAL) );
-    SENF_LOG_DEF_STREAM( myStream );
-    SENF_LOG_DEF_AREA( myArea );
+}}}
 
-    SENF_LOG(("Log message"));
-
-    SENF_LOG((LogFoo) ("Another log message: " << 10));
-
-    SENF_LOG_BLOCK((senf::log::Debug) (senf::log::WARNING) ({
-        log << "Last message";
-        log << " continued here";
-    }));
-
-    BOOST_CHECK_EQUAL( logstream.str(), "Log message\nAnother log message: 10\nLast message continued here\n" );
-}
-
-///////////////////////////////cc.e////////////////////////////////////////
-#undef prefix_
+///////////////////////////////ih.e////////////////////////////////////////
+#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"
-// comment-column: 40
 // End:
diff --git a/Utils/Logger/Log.hh b/Utils/Logger/Log.hh
new file mode 100644 (file)
index 0000000..efb5143
--- /dev/null
@@ -0,0 +1,95 @@
+// $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 Log public header */
+
+#ifndef HH_Log_
+#define HH_Log_ 1
+
+// Custom includes
+#include <boost/preprocessor/seq/size.hpp>
+#include <boost/preprocessor/dec.hpp>
+#include <boost/preprocessor/seq/elem.hpp>
+#include <boost/preprocessor/seq/pop_back.hpp>
+#include "Parameters.hh"
+
+//#include "Log.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+/** \brief Write log message
+
+    This macro will write it's last argument to the log stream. The last argument must be an
+    expression which will be placed after a streaming \c operator<< (like
+    <i>some-log-sttream</i> \c << <i>last-macro-arg</i>).
+    \code
+    SENF_LOG((parameters...)("log message " << args << ...));
+    \endcode
+
+    \hideinitializer
+ */
+#define SENF_LOG(args)                                                                            \
+    SENF_LOG_BLOCK_( SENF_LOG_MERGE_PARAMETERS(BOOST_PP_SEQ_POP_BACK(args)),                      \
+                     { log << BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args); })
+
+/** \brief Enable block based on logging parameters
+
+    This macro is like SENF_LOG, however instead of writing a simple message, this macro allows
+    to specify a complete block of code to be executed if the log message is enabled.
+    \code
+    SENF_LOG_BLOCK((parameters...)({
+       // arbitrary code using 'log' for logging
+       log << "log message";
+    }));
+    \endcode
+
+    \hideinitializer
+ */
+#define SENF_LOG_BLOCK(args)                                                                      \
+    SENF_LOG_BLOCK_( SENF_LOG_MERGE_PARAMETERS(BOOST_PP_SEQ_POP_BACK(args)),                      \
+                     BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args))
+
+#define SENF_LOG_BLOCK_(parameters, block)                                                        \
+    do {                                                                                          \
+        if (parameters::compile_enabled && parameters::enabled()) {                               \
+            std::ostream & log (parameters::log_stream());                                         \
+            do block while(0);                                                                    \
+            log << std::endl;                                                                     \
+        }                                                                                         \
+    } while(0) 
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "Log.cci"
+//#include "Log.ct"
+//#include "Log.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:
similarity index 68%
copy from Utils/Logger.test.cc
copy to Utils/Logger/Log.test.cc
index 5478e90..d57d625 100644 (file)
@@ -1,4 +1,4 @@
-// $Id$
+// $Id: Log.test.cc 369 2007-08-01 07:51:36Z tho $
 //
 // Copyright (C) 2007
 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief Logger.test unit tests */
+    \brief Log.test unit tests */
 
-//#include "Logger.test.hh"
-//#include "Logger.test.ih"
+//#include "Log.test.hh"
+//#include "Log.test.ih"
 
 // Custom includes
 #include <sstream>
+
 #define _senf_LOG_STREAM logstream
-#include "Logger.hh"
+namespace {
+    std::stringstream logstream;
+}
+
+#define SENF_LOG_CONF ((senf::log::Debug)(_)(VERBOSE))
+
+#include "Log.hh"
+#include "Defaults.hh"
+#include "Parameters.hh"
+#include "Levels.hh"
 
 #include <boost/test/auto_unit_test.hpp>
 #include <boost/test/test_tools.hpp>
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-BOOST_AUTO_UNIT_TEST(logger)
-{
-    std::stringstream logstream;
+namespace {
+    
+    template <class T>
+    struct Foo
+    {
+        typedef int value;
+    };
 
-    SENF_LOG_DEFAULTS( (senf::log::Debug) (senf::log::NOTICE) );
     SENF_LOG_DEF_ALIAS( LogFoo, (senf::log::Debug) (senf::log::CRITICAL) );
-    SENF_LOG_DEF_STREAM( myStream );
+    SENF_LOG_DEF_STREAM( myStream, senf::log::MESSAGE, senf::log::MESSAGE, senf::log::MESSAGE );
     SENF_LOG_DEF_AREA( myArea );
 
+}
+
+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(("Log message"));
 
     SENF_LOG((LogFoo) ("Another log message: " << 10));
 
-    SENF_LOG_BLOCK((senf::log::Debug) (senf::log::WARNING) ({
+    SENF_LOG_BLOCK((senf::log::Debug) (senf::log::IMPORTANT) ({
         log << "Last message";
         log << " continued here";
     }));
 
-    BOOST_CHECK_EQUAL( logstream.str(), "Log message\nAnother log message: 10\nLast message continued here\n" );
+    BOOST_CHECK_EQUAL( logstream.str(), 
+                       "Log message\nAnother log message: 10\nLast message continued here\n" );
 }
 
 ///////////////////////////////cc.e////////////////////////////////////////
diff --git a/Utils/Logger/Logger.hh b/Utils/Logger/Logger.hh
new file mode 100644 (file)
index 0000000..5b49ffe
--- /dev/null
@@ -0,0 +1,42 @@
+// $Id: Logger.hh 407 2007-08-23 22:40:59Z g0dil $
+//
+// 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 Logger public header */
+
+#ifndef HH_Logger_
+#define HH_Logger_ 1
+
+#include "all_includes.hh"
+
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
+// End:
diff --git a/Utils/Logger/Mainpage.dox b/Utils/Logger/Mainpage.dox
new file mode 100644 (file)
index 0000000..9bd6118
--- /dev/null
@@ -0,0 +1,135 @@
+// $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.
+
+/** \mainpage The SENF Logging library
+
+    The Loggger infrastructure implements a highly flexible compile- and run-time configurable
+    logging infrastructure supporting multiple streams, user definable log areas and fine grained
+    log levels. Logging can be configured at compile and runtime on any combination of above
+    parameters. The library supports a host of log targets and messages can be routed into multiple
+    targets at the same time. To allow concise usage of the library, a utility to define logging
+    defaults for any scope is provided.
+
+    An important basic concept of the library is, that most of the macros take a variable number of
+    arguments. Since this is not supported in the needed manner by the C++ preprocessor, the
+    arguments are encoded into a <a
+    href="http://www.boost.org/libs/preprocessor/doc/index.html">Boost.Preprocessor</a> like
+    sequence:
+
+    \code
+    SENF_LOG( (senf::log::Debug)(senf::log::NOTICE)(FroblizerArea)("The log message") );
+    \endcode
+
+    The last sequence element always is the log message. Before that we have a number of log
+    parameters <i>in arbitrary order</i>. Since giving all the parameters in every log message is to
+    verbose, there are two helpful constructs to reduce the verbosity. Using \ref
+    SENF_LOG_DEFAULT_STREAM, \ref SENF_LOG_DEFAULT_AREA and \ref SENF_LOG_DEFAULT_LEVEL it is
+    possible to define the default logging parameters to be used within a given scope. Using \ref
+    SENF_LOG_DEF_ALIAS you can define an alias (which is a scoped symbol) as an arbitrary
+    combination of parameters.
+
+    \code
+    SENF_LOG_DEF_STREAM( userLog, senf::log::MESSAGE, senf::log::MESSAGE );
+
+    class Froblizer
+    {
+        // Define a new log area
+        SENF_LOG_DEF_AREA(FroblizerArea);
+
+        // Set default log parameters for this scope
+        SENF_LOG_DEFAULTS((senf::log::Debug)(senf::log::NOTICE)(FroblizerArea));
+
+        // Define an alias for emergency messages to the sysadmin.
+        // The log area is inherited from the default at the place, where this
+        // alias is used *not* where it is defined
+        SENF_LOG_DEF_ALIAS(LogEmerg, (userLog)(senf::log::CRITICAL));
+
+        void test();
+
+    public:
+        void froblize();
+    };
+
+    void Froblizer::froblize()
+    {
+        SENF_LOG(("This is the Debug stream at level NOTICE in the FroblizeArea"));
+        SENF_LOG((senf::log::WARNING) ("Same stream and area but at warning level"));
+        SENF_LOG((LogEmerg) ("This goes to the userLog at level CRITICAL in the FroblizerArea"));
+    }
+
+    void Froblizer::test()
+    {
+        // Change the default log level for this method. stream and area are taken
+        // from the next scope up
+        SENF_LOG_DEFAULTS((senf::log::VERBOSE));
+
+        SENF_LOG(("Log to Debug stream in Froblizer area however at VERBOSE level"));
+    }
+    \endcode
+
+    Currently, the library is not implemented in any way. The interface has been defined up to a
+    point and we have dummy implementations of the 'in-code' part of the interface. This is the
+    part, which is called throughout the code. The configuration API is defined but we don't even
+    have a template implementation. However, this allows starting to use the SENF Logger in newly
+    developed code. Even though this code will unconditionally log everything to \c std::cerr for
+    now and errors in the parameter specification will not be caught (since they are just ignored)
+    the logging should work automatically as advertised as soon as the logger is completely
+    implemented.
+
+    I did not find any implementation which was not either completely convoluted, unusable or
+    slow. So I turned to a macro based implementation which can provide all the design goals stated
+    above.
+
+    \section logger_compile_conf Compile time configuration
+
+    The logger infrastructure allows to enable or disable log levels or areas at compile
+    time. Levels or areas disabled at compile time do not generate any code. The compile time
+    configuration is done in two parts: When defining log streams, default log levels and log level
+    limits are defined. Additionally the \c SENF_LOG_CONF symbol can be defined to customize this
+    default configuration.
+
+    The \c SENF_LOG_CONF symbol is a Boost.Preprocessor style sequence of sequences:
+    <pre>
+    g++ ... -DSENF_LOG_CONF="((senf::log::Debug)(_)(DISABLED)) \
+                             ((senf::log::Debug)(foo::FooArea)(VERBOSE))" ...
+    </pre>
+    Each element defines the compile time limit for a stream and optional area.
+    \implementation I would have much preferred a more C++ like implementation. However given the
+    design goals
+    \li Flexible configuration at compile and runtime
+    \li Concise usage and simple interface
+    \li Zero overhead for compile-time disabled log messages
+ */
+
+\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"
+// mode: flyspell
+// mode: auto-fill
+// End:
diff --git a/Utils/Logger/Parameters.hh b/Utils/Logger/Parameters.hh
new file mode 100644 (file)
index 0000000..c34d308
--- /dev/null
@@ -0,0 +1,82 @@
+// $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 Parameters public header */
+
+#ifndef HH_Parameters_
+#define HH_Parameters_ 1
+
+// Custom includes
+
+//#include "Parameters.mpp"
+#include "Parameters.ih"
+///////////////////////////////hh.p////////////////////////////////////////
+
+/** \brief Set scope default log stream
+    \hideinitializer
+ */
+#define SENF_LOG_DEFAULT_STREAM(stream) typedef stream SENFLogDefaultStream
+
+/** \brief Set scope default log area
+    \hideinitializer
+ */
+#define SENF_LOG_DEFAULT_AREA(area) typedef area SENFLogDefaultArea
+
+/** \brief Set scope default log level
+    \hideinitializer
+ */
+#define SENF_LOG_DEFAULT_LEVEL(level) typedef level SENFLogDefaultLevel
+
+/** \brief Define log parameter alias
+
+    Defines a new parameter alias named \a alias as an alias for the parameters in \a args. The
+    alias is defined as a symbol in the current scope.
+
+    \hideinitializer
+ */
+#define SENF_LOG_DEF_ALIAS(alias,args)                                                            \
+    struct alias : public senf::log::detail::AliasBase                                            \
+    {                                                                                             \
+        template <class Base>                                                                     \
+        struct apply                                                                              \
+        {                                                                                         \
+            typedef typename SENF_LOG_MERGE_PARAMETERS_I(Base,args) type;                         \
+        };                                                                                        \
+    }
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "Parameters.cci"
+//#include "Parameters.ct"
+//#include "Parameters.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:
diff --git a/Utils/Logger/Parameters.ih b/Utils/Logger/Parameters.ih
new file mode 100644 (file)
index 0000000..55d2aba
--- /dev/null
@@ -0,0 +1,141 @@
+// $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 Parameters internal header */
+
+#ifndef IH_Parameters_
+#define IH_Parameters_ 1
+
+// Custom includes
+#include <iostream>
+#include <boost/preprocessor/seq/for_each_i.hpp>
+#include <boost/preprocessor/facilities/apply.hpp>
+#include <boost/preprocessor/punctuation/comma_if.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/fold.hpp>
+#include "Defaults.hh"
+#include "../mpl.hh"
+#include "Stream.hh"
+#include "Area.hh"
+#include "Levels.hh"
+#include "Config.hh"
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+#ifndef _senf_LOG_STREAM
+#   define _senf_LOG_STREAM std::cerr
+#endif
+
+typedef senf::log::Debug       SENFLogDefaultStream;
+typedef senf::log::DefaultArea SENFLogDefaultArea;
+typedef senf::log::NONE        SENFLogDefaultLevel;
+
+namespace senf {
+namespace log {
+namespace detail {
+
+    struct AliasBase {};
+
+    template <class Base, class Param, unsigned N>
+    struct Parameters_ {};
+
+    senf::mpl::rv<1> Parameters_select_(StreamBase *);
+    template <class Base, class Param>
+    struct Parameters_<Base,Param,1> : public Base
+    { typedef Param stream; };
+
+    senf::mpl::rv<2> Parameters_select_(AreaBase *);
+    template <class Base, class Param>
+    struct Parameters_<Base,Param,2> : public Base
+    { typedef Param area; };
+
+    senf::mpl::rv<3> Parameters_select_(LevelBase *);
+    template <class Base, class Param>
+    struct Parameters_<Base,Param,3> : public Base
+    { typedef Param level; };
+
+    senf::mpl::rv<4> Parameters_select_(void *);
+    template <class Base>
+    struct Parameters_<Base,void,4> : public Base
+    {};
+
+    senf::mpl::rv<5> Parameters_select_(AliasBase *);
+    template <class Base, class Param>
+    struct Parameters_<Base,Param,5> 
+        : public Param::template apply<Base>::type
+    {};
+
+    template <class Base>
+    struct Parameters : public Base
+    {
+
+        static bool const compile_enabled = senf::log::Enabled<
+            typename Base::stream, 
+            typename Base::area, 
+            typename Base::level>::value;
+
+        static bool enabled() { return compile_enabled; }
+        static std::ostream & log_stream() { return _senf_LOG_STREAM; }
+    };
+
+    struct empty {};
+
+    struct Parameters_Merge_
+    {
+        template <class Base, class Param>
+        struct apply {
+            typedef Parameters_<
+                Base, 
+                Param, 
+                SENF_MPL_RV(Parameters_select_(static_cast<Param*>(0)))> type;
+        };
+    };
+
+}}}
+
+#define SENF_LOG_MERGE_ARG(r, data, i, elem) BOOST_PP_COMMA_IF(i) elem
+
+#define SENF_LOG_MERGE_PARAMETERS_I(base, args)                                                   \
+    boost::mpl::fold<                                                                             \
+        boost::mpl::vector< BOOST_PP_SEQ_FOR_EACH_I(SENF_LOG_MERGE_ARG, _, args) >,               \
+        base,                                                                                     \
+        senf::log::detail::Parameters_Merge_ >::type
+
+#define SENF_LOG_MERGE_PARAMETERS(args)                                                           \
+    senf::log::detail::Parameters< SENF_LOG_MERGE_PARAMETERS_I(                                   \
+        senf::log::detail::empty,                                                                 \
+        (SENFLogDefaultStream)(SENFLogDefaultArea)(SENFLogDefaultLevel)args) >
+
+///////////////////////////////ih.e////////////////////////////////////////
+#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:
diff --git a/Utils/Logger/SConscript b/Utils/Logger/SConscript
new file mode 100644 (file)
index 0000000..bd53fae
--- /dev/null
@@ -0,0 +1,17 @@
+# -*- python -*-
+
+Import('env')
+import SENFSCons, glob
+
+###########################################################################
+
+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 )
+
+SENFSCons.Doxygen(env)
+
+Return('objects')
diff --git a/Utils/Logger/Stream.hh b/Utils/Logger/Stream.hh
new file mode 100644 (file)
index 0000000..b4bab97
--- /dev/null
@@ -0,0 +1,75 @@
+// $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 public header */
+
+#ifndef HH_Stream_
+#define HH_Stream_ 1
+
+// Custom includes
+#include "Levels.hh"
+
+//#include "Stream.mpp"
+#include "Stream.ih"
+///////////////////////////////hh.p////////////////////////////////////////
+
+/** \brief Define log stream
+
+    Defines a new log stream named \a stream. The stream is defined as a symbol in the current
+    scope.
+
+    \a defaultLevel defines the default log level for messages posted to this stream. \a
+    runtimeLimit defines the default log limit. Messages with a level below this will not be
+    output.  \a compileLimit defines the default log level limit at compile time: Messages
+    posted with a level below \a compileLimit will be discarded at compile time.
+
+    \hideinitializer
+ */
+#define SENF_LOG_DEF_STREAM(stream, defaultLevel_, runtimeLimit_, compileLimit_)                  \
+    struct stream                                                                                 \
+        : public senf::log::detail::StreamBase                                                    \
+    {                                                                                             \
+        typedef defaultLevel_ defaultLevel;                                                       \
+        typedef runtimeLimit_ runtimeLimit;                                                       \
+        typedef compileLimit_ compileLimit;                                                       \
+                                                                                                  \
+        static char const * name() { return #stream ; }                                           \
+        virtual char const * v_name() { return name(); }                                          \
+    }
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "Stream.cci"
+//#include "Stream.ct"
+//#include "Stream.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:
similarity index 52%
copy from Utils/Logger.test.cc
copy to Utils/Logger/Stream.ih
index 5478e90..55b2dd2 100644 (file)
@@ -1,6 +1,6 @@
 // $Id$
 //
-// Copyright (C) 2007
+// Copyright (C) 2007 
 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
 //     Stefan Bund <g0dil@berlios.de>
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief Logger.test unit tests */
+    \brief Stream internal header */
 
-//#include "Logger.test.hh"
-//#include "Logger.test.ih"
+#ifndef IH_Stream_
+#define IH_Stream_ 1
 
 // Custom includes
-#include <sstream>
-#define _senf_LOG_STREAM logstream
-#include "Logger.hh"
 
-#include <boost/test/auto_unit_test.hpp>
-#include <boost/test/test_tools.hpp>
+///////////////////////////////ih.p////////////////////////////////////////
 
-#define prefix_
-///////////////////////////////cc.p////////////////////////////////////////
+namespace senf {
+namespace log {
+namespace detail {
 
-BOOST_AUTO_UNIT_TEST(logger)
-{
-    std::stringstream logstream;
+    struct StreamBase 
+    {
+        virtual ~StreamBase() {};
+        virtual char const * v_name() = 0;
+    };
 
-    SENF_LOG_DEFAULTS( (senf::log::Debug) (senf::log::NOTICE) );
-    SENF_LOG_DEF_ALIAS( LogFoo, (senf::log::Debug) (senf::log::CRITICAL) );
-    SENF_LOG_DEF_STREAM( myStream );
-    SENF_LOG_DEF_AREA( myArea );
+}}}
 
-    SENF_LOG(("Log message"));
-
-    SENF_LOG((LogFoo) ("Another log message: " << 10));
-
-    SENF_LOG_BLOCK((senf::log::Debug) (senf::log::WARNING) ({
-        log << "Last message";
-        log << " continued here";
-    }));
-
-    BOOST_CHECK_EQUAL( logstream.str(), "Log message\nAnother log message: 10\nLast message continued here\n" );
-}
-
-///////////////////////////////cc.e////////////////////////////////////////
-#undef prefix_
+///////////////////////////////ih.e////////////////////////////////////////
+#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"
-// comment-column: 40
 // End:
similarity index 60%
rename from Utils/Logger.test.cc
rename to Utils/Logger/main.test.cc
index 5478e90..2e4e387 100644 (file)
@@ -1,9 +1,9 @@
-// $Id$
+// $Id: main.test.cc 369 2007-08-01 07:51:36Z tho $
 //
-// Copyright (C) 2007
+// Copyright (C) 2006
 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
-//     Stefan Bund <g0dil@berlios.de>
+//     Stefan Bund <stefan.bund@fokus.fraunhofer.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
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-/** \file
-    \brief Logger.test unit tests */
+// Definition of non-inline non-template functions
 
-//#include "Logger.test.hh"
-//#include "Logger.test.ih"
+//#include "test.hh"
+//#include "test.ih"
 
 // Custom includes
-#include <sstream>
-#define _senf_LOG_STREAM logstream
-#include "Logger.hh"
-
+#define BOOST_AUTO_TEST_MAIN
 #include <boost/test/auto_unit_test.hpp>
 #include <boost/test/test_tools.hpp>
 
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-BOOST_AUTO_UNIT_TEST(logger)
-{
-    std::stringstream logstream;
-
-    SENF_LOG_DEFAULTS( (senf::log::Debug) (senf::log::NOTICE) );
-    SENF_LOG_DEF_ALIAS( LogFoo, (senf::log::Debug) (senf::log::CRITICAL) );
-    SENF_LOG_DEF_STREAM( myStream );
-    SENF_LOG_DEF_AREA( myArea );
-
-    SENF_LOG(("Log message"));
-
-    SENF_LOG((LogFoo) ("Another log message: " << 10));
-
-    SENF_LOG_BLOCK((senf::log::Debug) (senf::log::WARNING) ({
-        log << "Last message";
-        log << " continued here";
-    }));
-
-    BOOST_CHECK_EQUAL( logstream.str(), "Log message\nAnother log message: 10\nLast message continued here\n" );
-}
 
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_
index 822c40b..7472bda 100644 (file)
@@ -6,8 +6,6 @@ namespace senf {
 
     <dl>
 
-    <dt>\ref logger</dt><dd>highly flexible logging infrastructure</dd>
-
     <dt>SystemException</dt><dd>standard exception for system errors (errno)</dd>
 
     <dt>\ref process</dt><dd>Some simple process management and daemon helpers<?dd>
index baa117a..8d67e70 100644 (file)
@@ -1,11 +1,21 @@
 # -*- python -*-
 
 Import('env')
-import SENFSCons
+import SENFSCons, glob
 
 ###########################################################################
 
-sources = SENFSCons.GlobSources()
 SENFSCons.StandardTargets(env)
-SENFSCons.Lib(env, 'Utils', sources)
+
+sources, testSources = SENFSCons.GlobSources()
+objects = SENFSCons.Objects( env, sources = sources )
+
+for sc in glob.glob("*/SConscript"):
+    ob = SConscript(sc)
+    if ob : objects.extend(ob)
+
+SENFSCons.Lib(env,
+              library = 'Utils',
+              sources = objects)
+
 SENFSCons.Doxygen(env)
index cdb9cd6..a162731 100644 (file)
@@ -188,3 +188,4 @@ env.Alias('install_all',
                                                   'senf.css' ] ))
 
 env.Clean('all', 'doxy-header.html') # I should not need this but I do ...
+env.Clean('all_docs', 'doxy-header.html') # I should not need this but I do ...
index c6705d0..080ca89 100644 (file)
--- a/senf.dict
+++ b/senf.dict
@@ -37,6 +37,8 @@ CloneSource
 CommunicationPolicy
 CommunicationPolicyBase
 ConcretePacket
+conf
+CONFIG
 ConnectedCommunicationPolicy
 ConnectedUDPv
 const