]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - tools/elftosb/common/Logging.h
merged tx6dl-devel into denx master branch
[karo-tx-uboot.git] / tools / elftosb / common / Logging.h
1 /*
2  * File:        Logging.h
3  *
4  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5  * See included license file for license details.
6  */
7 #if !defined(_Logging_h_)
8 #define _Logging_h_
9
10 #include <string>
11 #include <assert.h>
12 #include <stdarg.h>
13
14 /*!
15  * \brief Base logger class.
16  *
17  * There are two types of logging levels that are used by this class. First
18  * there is the filter level. Any log message that is assigned a level
19  * higher than the current filter level is discarded. Secondly there is the
20  * current output level. Log messages that do not have their own level
21  * use the current output level to determine if they should be shown or
22  * not.
23  *
24  * The two methods setFilterLevel() and setOutputLevel() set the filter
25  * and default output logging levels, respectively. There are corresponding
26  * getter methods as well. Both the filter and output levels are
27  * initialized to #INFO during object construction.
28  *
29  * Most use of the logger classes is expected to be through the Log
30  * class. It provides static logging methods that call through to a global
31  * singleton logger instance. There is also a Log::SetOutputLevel utility
32  * class that makes it extremely easiy to temporarily change the default
33  * output logging level.
34  *
35  * Of all the overloaded log() methods in this class, none of them are
36  * really expected to be reimplemented by subclasses. Instead, there is
37  * the single protected _log() method that takes a simple string pointer.
38  * The other log methods all wind up calling _log(), so it provides a
39  * single point to override. In fact, _log() is pure virtual, so subclasses
40  * must implement it.
41  *
42  * \see Log
43  */
44 class Logger
45 {
46 public:
47         //! \brief Logging levels.
48         enum log_level_t
49         {
50                 URGENT = 0,     //!< The lowest level, for messages that must always be logged.
51                 ERROR,          //!< For fatal error messages.
52                 WARNING,        //!< For non-fatal warning messages.
53                 INFO,           //!< The normal log level, for status messages.
54                 INFO2,          //!< For verbose status messages.
55                 DEBUG,          //!< For internal reporting.
56                 DEBUG2          //!< Highest log level; verbose debug logging.
57         };
58         
59 public:
60         //! \brief Default constructor.
61         Logger() : m_filter(INFO), m_level(INFO) {}
62         
63         //! \brief Destructor.
64         virtual ~Logger() {}
65         
66         //! \name Logging levels
67         //@{
68         //! \brief Changes the logging level to \a level.
69         inline void setFilterLevel(log_level_t level) { m_filter = level; }
70         
71         //! \brief Returns the current logging filter level.
72         inline log_level_t getFilterLevel() const { return m_filter; }
73         
74         //! \brief Changes the logging output level to \a level.
75         inline void setOutputLevel(log_level_t level) { m_level = level; }
76         
77         //! \brief Returns the current logging output level.
78         inline log_level_t getOutputLevel() const { return m_level; }
79         //@}
80         
81         //! \name Logging
82         //@{
83         //! \brief Log with format.
84         virtual void log(const char * fmt, ...);
85         
86         //! \brief Log a string object.
87         virtual void log(const std::string & msg) { log(msg.c_str()); }
88         
89         //! \brief Log with format at a specific output level.
90         virtual void log(log_level_t level, const char * fmt, ...);
91         
92         //! \brief Log a string output at a specific output level.
93         virtual void log(log_level_t level, const std::string & msg) { log(level, msg.c_str()); }
94         
95         //! \brief Log with format using an argument list.
96         virtual void log(const char * fmt, va_list args);
97         
98         //! \brief Log with format using an argument with a specific output level.
99         virtual void log(log_level_t level, const char * fmt, va_list args);
100         //@}
101                 
102 protected:
103         log_level_t m_filter;   //!< The current logging filter level.
104         log_level_t m_level;    //!< The current log output level.
105         
106 protected:
107         //! \brief The base pure virtual logging function implemented by subclasses.
108         virtual void _log(const char * msg)=0;
109 };
110
111 /*!
112  * \brief Wraps a set of static functions for easy global logging access.
113  *
114  * This class has a set of static methods that make it easy to access a global
115  * logger instance without having to worry about extern symbols. It does this
116  * by keeping a static member variable pointing at the singleton logger instance,
117  * which is set with the setLogger() static method.
118  *
119  * There is also an inner utility class called SetOutputLevel that uses
120  * C++ scoping rules to temporarily change the output logging level. When the
121  * SetOutputLevel instance falls out of scope the output level is restored
122  * to the previous value.
123  */
124 class Log
125 {
126 public:
127         //! \name Singleton logger access
128         //@{
129         //! \brief Returns the current global logger singleton.
130         static inline Logger * getLogger() { return s_logger; }
131         
132         //! \brief Sets the global logger singleton instance.
133         static inline void setLogger(Logger * logger) { s_logger = logger; }
134         //@}
135         
136         //! \name Logging
137         //@{
138         //! \brief Log with format.
139         static void log(const char * fmt, ...);
140         
141         //! \brief Log a string object.
142         static void log(const std::string & msg);
143         
144         //! \brief Log with format at a specific output level.
145         static void log(Logger::log_level_t level, const char * fmt, ...);
146         
147         //! \brief Log a string output at a specific output level.
148         static void log(Logger::log_level_t level, const std::string & msg);
149         //@}
150         
151 protected:
152         static Logger * s_logger;       //!< The single global logger instance.
153         
154 public:
155         /*!
156          * \brief Utility class to temporarily change the logging output level.
157          *
158          * This class will change the current logging output level of a given
159          * logger instance. Then when it falls out of scope it will set the
160          * level back to what it was originally.
161          *
162          * Use like this:
163          * \code
164          *              // output level is some value here
165          *              {
166          *                      Log::SetOutputLevel leveler(Logger::DEBUG);
167          *                      // now output level is DEBUG
168          *                      Log::log("my debug message 1");
169          *                      Log::log("my debug message 2");
170          *              }
171          *              // output level is restored to previous value
172          * \endcode
173          */
174         class SetOutputLevel
175         {
176         public:
177                 //! \brief Default constructor.
178                 //!
179                 //! Saves the current logging output level of the global logger,
180                 //! as managed by the Log class, and sets the new level to \a level.
181                 SetOutputLevel(Logger::log_level_t level)
182                 :       m_logger(Log::getLogger()), m_saved(Logger::INFO)
183                 {
184                         assert(m_logger);
185                         m_saved = m_logger->getOutputLevel();
186                         m_logger->setOutputLevel(level);
187                 }
188                 
189                 //! \brief Constructor.
190                 //!
191                 //! Saves the current logging output level of \a logger and sets
192                 //! the new level to \a level.
193                 SetOutputLevel(Logger * logger, Logger::log_level_t level)
194                 :       m_logger(logger), m_saved(logger->getOutputLevel())
195                 {
196                         assert(m_logger);
197                         m_logger->setOutputLevel(level);
198                 }
199                 
200                 //! \brief Destructor.
201                 //!
202                 //! Restores the saved logging output level.
203                 ~SetOutputLevel()
204                 {
205                         m_logger->setOutputLevel(m_saved);
206                 }
207                 
208         protected:
209                 Logger * m_logger;      //!< The logger instance we're controlling.
210                 Logger::log_level_t m_saved;    //!< Original logging output level.
211         };
212
213 };
214
215
216 /*!
217  * \brief Simple logger that writes to stdout.
218  */
219 class StdoutLogger : public Logger
220 {
221 protected:
222         //! \brief Logs the message to stdout.
223         virtual void _log(const char * msg);
224 };
225
226 #endif // _Logging_h_