logger.hh

Go to the documentation of this file.
00001 /*
00002    The lestes compiler suite
00003    Copyright (C) 2002, 2003, 2004, 2005 Miroslav Tichy
00004    Copyright (C) 2002, 2003, 2004, 2005 Petr Zika
00005    Copyright (C) 2002, 2003, 2004, 2005 Vojtech Hala
00006    Copyright (C) 2002, 2003, 2004, 2005 Jiri Kosina
00007    Copyright (C) 2002, 2003, 2004, 2005 Pavel Sanda
00008    Copyright (C) 2002, 2003, 2004, 2005 Jan Zouhar
00009    Copyright (C) 2002, 2003, 2004, 2005 Rudolf Thomas
00010 
00011    This program is free software; you can redistribute it and/or modify
00012    it under the terms of the GNU General Public License as published by
00013    the Free Software Foundation; version 2 of the License.
00014 
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019 
00020    See the full text of the GNU General Public License version 2, and
00021    the limitations in the file doc/LICENSE.
00022 
00023    By accepting the license the licensee waives any and all claims
00024    against the copyright holder(s) related in whole or in part to the
00025    work, its use, and/or the inability to use it.
00026  
00027  */
00028 #ifndef lestes__msg___logger_hh___included
00029 #define lestes__msg___logger_hh___included
00030 
00031 /*! \file
00032  * Logger and the llog macro.
00033  * \author Rudo
00034  */
00035 
00036 /*!
00037  * The llog macro calls fullname_formatter on given logger, which prints full
00038  * name of the logger followed by ": ". You can use the << operator in the result.
00039  */
00040 #define llog( logger )  ((*(logger)) << ::lestes::msg::fullname_formatter::instance())
00041 
00042 /*!
00043  * The llog_plain macro calls plain_formatter on given logger. The plain_formatter does
00044  * nothing except returning the logger's ostream.
00045  */
00046 #define llog_plain( logger )    ((*(logger)) << ::lestes::msg::plain_formatter::instance())
00047 
00048 /*!
00049  * The llog_xml_open macro outputs opening xml tag with given name to given
00050  * logger. The tag contains attribute named 'by' filled with full path of the
00051  * logger. xml_formatter is used to achieve this.
00052  *
00053  * Note: To avoid the 'by' attribute, simply use llog_plain.
00054  */
00055 #define llog_xml_open( logger, tag )                                    \
00056         (::lestes::msg::xml_formatter::instance()->tag_name_set(tag),   \
00057         *(logger) << ::lestes::msg::xml_formatter::instance())
00058 /*!
00059  * The llog_xml_close prints closing tag with specified name to given logger.
00060  * It is just a simple wrapper around llog_plain.
00061  */
00062 #define llog_xml_close( logger, tag )   \
00063         ((*(logger)) << ::lestes::msg::plain_formatter::instance() << "</" << (tag) << '>')
00064 
00065 /*!
00066  * \brief declares logger with specified name, used in namespace scope
00067  * 
00068  * The declare_logger macro declares [extern] variable with given name, its type is
00069  * ptr<logger>; the variable is ready to be passed to llog family of macros.
00070  * The actual definition of the variable is handled by initialize_top_logger
00071  * and initialize_logger macros.
00072  *
00073  * The macro can only be used in namespace scope. It can be used in a header file.
00074  *
00075  * Note: The macro also declares a function named variable_name##_init (i.e.
00076  * passed name suffixed with _init) which is used to initialize the pointer.
00077  */
00078 #define declare_logger( variable_name ) \
00079         extern ::lestes::std::ptr< ::lestes::msg::logger > variable_name; \
00080         const ::lestes::std::ptr< ::lestes::msg::logger > & variable_name##_init();
00081 
00082 /*!
00083  * \brief declares the logger variable with correct initializer
00084  *
00085  * The initialize_logger macro declares the logger variable and initializes it.
00086  * Name of the logger instance and name of variable with a pointer to parent
00087  * logger are passed as arguments. The parent variable must be declared and
00088  * initialized using declare_logger and initialize_logger (or
00089  * initialize_top_logger) macros.
00090  *
00091  * The macro can only be used in namespace scope. It MUST NOT be used in a header file.
00092  *
00093  * Note: The macro also defines a function used to initialize the pointer.
00094  * Such function of the parent logger is called from it. By analogy, this
00095  * function is used when the logger is used as a parent in different
00096  * initialize_logger macro invocation.
00097  */
00098 #define initialize_logger( variable_name, logger_name, parent_variable ) \
00099         ptr< ::lestes::msg::logger > variable_name = variable_name##_init(); \
00100         \
00101         const ptr< ::lestes::msg::logger > & variable_name##_init() \
00102         { \
00103                 if (!variable_name) \
00104                         variable_name = ::lestes::msg::logger::create( \
00105                                         logger_name, parent_variable##_init() ); \
00106                 return variable_name; \
00107         }
00108 
00109 /*!
00110  * \brief similar to initialize_logger, just the logger will be a child of the root one
00111  */
00112 #define initialize_top_logger( variable_name, logger_name ) \
00113         ptr< ::lestes::msg::logger > variable_name = variable_name##_init(); \
00114         \
00115         const ptr< ::lestes::msg::logger > & variable_name##_init() \
00116         { \
00117                 if (!variable_name) \
00118                         variable_name = ::lestes::msg::logger::create( \
00119                                 logger_name, ::lestes::msg::logger::root_instance() ); \
00120                 return variable_name; \
00121         }
00122 
00123 #include <lestes/common.hh>
00124 #include <lestes/std/map.hh>
00125 #include <lestes/std/objectize_macros.hh>
00126 #include <lestes/std/ostream_wrapper.hh>
00127 #include <lestes/msg/logger_formatters.hh>
00128 
00129 #include <iosfwd>
00130 
00131 package(lestes);
00132 package(msg);
00133 
00134 class logger_formatter;
00135 
00136 /*!
00137  * ...
00138  * One should only instantiate this class by hand when they know what they are doing.
00139  */
00140 class logger : public ::lestes::std::object {
00141         friend class logger_configurator;
00142 public:
00143         //! Map that maps lstrings to loggers, used to store children of a logger.
00144         typedef map< lstring, srp<logger> > children_map_type;
00145 
00146         //! Factory method, creates logger with given name. Also adds it to 'children' of given parent.
00147         static ptr<logger> create( const lstring & a_name, const ptr<logger> & a_parent );
00148         //! Returns pointer to the root "grandparent" logger.
00149         static ptr<logger> root_instance();
00150         //! Configures the logger tree by applying the settings found in given xml file.
00151         static bool init( const lstring & filename );
00152         //! Closes all files open during init().
00153         static void finish();
00154         //! Traverses the logger tree starting at root_instance(), outputs xml configuration file with corresponding elements.
00155         static ::std::ostream & dump_skeleton( ::std::ostream & );
00156         ptr<logger> parent_get() const;
00157         lstring name_get() const;
00158         ptr<children_map_type> children_get() const;
00159         ptr < logger_formatter > formatter_get() const;
00160         void formatter_set(ptr < logger_formatter > x);
00161 #ifdef ALL_LOGGER_GETTERS_NEEDED
00162         bool logging_get() const;
00163         bool logging_changed_get() const;
00164 #endif
00165         ::std::ostream & operator << ( const ptr<logger_formatter> & );
00166 private:
00167         //! Whether this logger is supposed to actually do something.
00168         bool logging;
00169         //! True when logging field has already been changed.
00170         bool logging_changed;
00171         //! Pointer to a stream used for the actual logging.
00172         srp<ostream_wrapper> ostr;
00173 
00174         //! Name of this logger. This does not include names of parents.
00175         const lstring name;
00176         //! Pointer to parent logger, the root logger points to self; checked.
00177         const srp<logger> parent;
00178         const srp<children_map_type> children;
00179 
00180         //! the default formatter
00181         srp < logger_formatter > formatter;
00182 
00183         //! Hold pointer to the root logger instance.
00184         static ptr<logger> the_root_instance;
00185 
00186         typedef map< lstring, srp<ostream_wrapper> > files_map_type;
00187         static ptr<files_map_type> files_map;
00188 
00189         //! Dumps all children (including "transitive" ones:) as xml to given ostream; used internally by dump_skeleton method.
00190         static void subtree_dump( const ptr<logger> &, ::std::ostream & );
00191 
00192         static ptr<ostream_wrapper> null_ostream;
00193         static ptr<ostream_wrapper> cerr_wrapper;
00194         //! This ctor is only used to construct the root logger.
00195         logger();
00196 protected:
00197         //! Constructor run from the 'create' factory method.
00198         logger( const lstring & a_name, const ptr<logger> a_parent );
00199         void gc_mark();
00200 };
00201 
00202 end_package(msg);
00203 end_package(lestes);
00204 
00205 #endif  // lestes__msg___logger_hh___included

Generated on Mon Feb 12 18:27:09 2007 for lestes by doxygen 1.5.1-20070107