switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Utils / Logger / Log.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief Log public header */
30
31 #ifndef HH_SENF_Utils_Logger_Log_
32 #define HH_SENF_Utils_Logger_Log_ 1
33
34 // Custom includes
35 #include <boost/preprocessor/seq/size.hpp>
36 #include <boost/preprocessor/dec.hpp>
37 #include <boost/preprocessor/seq/elem.hpp>
38 #include <boost/preprocessor/seq/pop_back.hpp>
39 #include "Parameters.hh"
40
41 //#include "Log.mpp"
42 #include "Log.ih"
43 //-/////////////////////////////////////////////////////////////////////////////////////////////////
44
45 /** \defgroup logging Logging commands
46
47     The logging library provides several commands to create %log messages. All these macro commands
48     take a variable number of arguments. Since this is not supported in a usable way by the C++
49     preprocessor, the arguments are encoded into a <a
50     href="http://www.boost.org/doc/libs/release/libs/preprocessor/doc/index.html">Boost.Preprocessor</a>
51     like sequence:
52
53     \code
54     SENF_LOG( (senf::log::Debug)(senf::log::NOTICE)(FroblizerArea)("The log message") );
55     \endcode
56
57     The argument is comprised of a sequence of parameters and the %log message itself.
58     The parameters are
59     - the <em>%log stream</em>,
60     - the <em>%log area</em>,
61     - the <em>%log level</em>.
62
63     These parameters are optional and may be specified <i>in arbitrary order</i> (with the %log
64     message always being the last sequence element) and even multiple times in the parameter
65     sequence. If some argument type occurs multiple times, the last occurrence wins. If any one of
66     the parameters is not specified, it's current default value will be used.
67
68     This current default value is set using \ref SENF_LOG_DEFAULT_STREAM, \ref SENF_LOG_DEFAULT_AREA
69     and \ref SENF_LOG_DEFAULT_LEVEL respectively. These macros set the default stream, area and/or
70     level <em>of the current scope</em>. They may be used with a class declaration to set defaults
71     for all class members or within a function or member body to set the default for that member
72     only. They may be used only \e once within each scope.
73
74     The logging library defines the global defaults for stream, area and level to be \c
75     senf::log::Debug, senf::log::DefaultArea, and senf::log::NONE respectively.
76
77     The %log level senf::log::NONE is special. If the %log level is set to this value, the %log level
78     will be set from the stream provided default value.
79
80     All these parameters must be <em>compile time constants</em> (they are all types, so it's
81     difficult for them to be something else).
82
83     \section logging_aliases Aliases
84
85     To further simplify logging commands, aliases may be defined within any scope. An alias is an
86     arbitrary collection of %log parameters:
87     \code
88     SENF_LOG_DEFINE_ALIAS( VerboseDebug, (senf::log::Debug)(senf::log::VERBOSE) );
89     \endcode
90     Within %log statements, aliases may be used like normal parameters. They will be substituted for
91     the parameter sequence they represent:
92     \code
93     SENF_LOG( (VerboseDebug)("Debug message") )
94     // is equivalent to
95     SENF_LOG( (senf::log::Debug)(senf::log::VERBOSE)("Debug message") )
96     \endcode
97     Aliases may be used together with other parameters, even with further aliases in any order.
98  */
99
100 ///\addtogroup logging
101 //\{
102
103 ///\name Generating log messages
104 //\{
105
106 /** \brief Write log message
107
108     This macro will write it's last argument to the log stream. The last argument must be an
109     expression which will be placed after a streaming \c operator<< (like
110     <i>some-log-stream</i> \c << <i>last-macro-arg</i>).
111     \code
112     SENF_LOG((parameters...)("log message " << args << ...));
113     \endcode
114
115     \hideinitializer
116  */
117 #define SENF_LOG(args)                                                                            \
118     SENF_LOG_BLOCK_( SENF_LOG_MERGE_PARAMETERS(BOOST_PP_SEQ_POP_BACK(args)),                      \
119                      { log << BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args); })
120
121 /** \brief Write log message (template context)
122
123     This macro is used like \ref SENF_LOG() if called from a template context
124
125     \hideinitializer
126  */
127 #define SENF_LOG_TPL(args)                                                                        \
128     SENF_LOG_BLOCK_TPL_( SENF_LOG_MERGE_PARAMETERS_TPL(BOOST_PP_SEQ_POP_BACK(args)),              \
129                          { log << BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args); })
130
131 /** \brief Enable block based on logging parameters
132
133     This macro is like SENF_LOG, however instead of writing a simple message, this macro allows
134     to specify a complete block of code to be executed if the log message is enabled.
135     \code
136     SENF_LOG_BLOCK((parameters...)({
137        // arbitrary code using 'log' for logging
138        log << "log message";
139     }));
140     \endcode
141
142     \hideinitializer
143  */
144 #define SENF_LOG_BLOCK(args)                                                                      \
145     SENF_LOG_BLOCK_( SENF_LOG_MERGE_PARAMETERS(BOOST_PP_SEQ_POP_BACK(args)),                      \
146                      BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args))
147
148 /** \brief Write log message (template context)
149
150     This macro is used like \ref SENF_LOG_BLOCK() if called from a template context
151
152     \hideinitializer
153  */
154 #define SENF_LOG_BLOCK_TPL(args)                                                                  \
155     SENF_LOG_BLOCK_TPL_( SENF_LOG_MERGE_PARAMETERS_TPL(BOOST_PP_SEQ_POP_BACK(args)),              \
156                          BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args))
157
158 //\}
159 //\}
160
161 //-/////////////////////////////////////////////////////////////////////////////////////////////////
162 //#include "Log.cci"
163 //#include "Log.ct"
164 //#include "Log.cti"
165 #endif
166
167 \f
168 // Local Variables:
169 // mode: c++
170 // fill-column: 100
171 // comment-column: 40
172 // c-file-style: "senf"
173 // indent-tabs-mode: nil
174 // ispell-local-dictionary: "american"
175 // compile-command: "scons -u test"
176 // End: