E-MailRelay
glog.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2023 Graeme Walker <graeme_walker@users.sourceforge.net>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// ===
17///
18/// \file glog.h
19///
20
21#ifndef G_LOG_H
22#define G_LOG_H
23
24#include "gdef.h"
25#include "glogstream.h"
26#include "gformat.h"
27#include <sstream>
28#include <string>
29
30namespace G
31{
32 class Log ;
33}
34
35//| \class G::Log
36/// A class for doing iostream-based logging. The G_LOG/G_DEBUG/G_WARNING/G_ERROR
37/// macros are provided as a convenient way of using this interface.
38///
39/// Usage:
40/// \code
41/// G::Log(G::Log::Severity::InfoSummary,__FILE__,__LINE__) << a << b ;
42/// \endcode
43/// or
44/// \code
45/// G_LOG( a << b ) ;
46/// \endcode
47/// or
48/// \code
49/// G_LOG( G::format("%1% %2%") % a % b ) ;
50/// \endcode
51///
52/// \see G::LogOutput
53///
54class G::Log
55{
56public:
57 enum class Severity
58 {
59 Debug ,
60 InfoMoreVerbose ,
61 InfoVerbose ,
62 InfoSummary ,
63 Warning ,
64 Error ,
65 Assertion
66 } ;
67
68 Log( Severity , const char * file , int line ) noexcept ;
69 ///< Constructor.
70
71 ~Log() ;
72 ///< Destructor. Writes the accumulated string to the log output.
73
74 LogStream & operator<<( const char * s ) noexcept ;
75 ///< Streams 's' and then returns a stream for streaming more stuff into.
76
77 LogStream & operator<<( const std::string & s ) noexcept ;
78 ///< Streams 's' and then returns a stream for streaming more stuff into.
79
80 LogStream & operator<<( const format & f ) ;
81 ///< Streams 'f' and then returns a stream for streaming more stuff into.
82
83 static bool at( Severity ) noexcept ;
84 ///< Returns true if G::LogOutput::output() would log at the given level.
85 ///< This can be used as an optimisation to short-ciruit the stream-out
86 ///< expression evaluation.
87
88 static bool atDebug() noexcept ;
89 ///< Returns at(Severity::Debug).
90
91 static bool atVerbose() noexcept ;
92 ///< Returns at(Severity::InfoVerbose).
93
94 static bool atMoreVerbose() noexcept ;
95 ///< Returns at(Severity::InfoMoreVerbose).
96
97public:
98 Log( const Log & ) = delete ;
99 Log( Log && ) = delete ;
100 Log & operator=( const Log & ) = delete ;
101 Log & operator=( Log && ) = delete ;
102
103private:
104 void flush() ;
105
106private:
107 Severity m_severity ;
108 const char * m_file ;
109 int m_line ;
110 LogStream & m_logstream ;
111} ;
112
113inline bool G::Log::atDebug() noexcept
114{
115 return at( Log::Severity::Debug ) ;
116}
117
118inline bool G::Log::atVerbose() noexcept
119{
120 return at( Log::Severity::InfoVerbose ) ;
121}
122
123inline bool G::Log::atMoreVerbose() noexcept
124{
125 return at( Log::Severity::InfoMoreVerbose ) ;
126}
127
128// Macros: G_LOG_S, G_LOG, G_LOG_MORE, G_DEBUG, G_WARNING, G_ERROR
129// The G_DEBUG macro is for debugging during development, the G_LOG macro
130// generates informational logging in verbose mode only, the 'summary'
131// G_LOG_S macro generates informational logging even when not verbose,
132// and the G_WARNING and G_ERROR macros are used for error warning/error
133// messages although in programs where logging can be disabled completely (see
134// G::LogOutput) error conditions should be made visible by some other means
135// (such as stderr).
136
137#define G_LOG_IMP( expr , severity ) do { if(G::Log::at(severity)) G::Log((severity),__FILE__,__LINE__) << expr ; } while(0) /* NOLINT bugprone-macro-parentheses */
138#define G_LOG_IMP_IF( cond , expr , severity ) do { if(G::Log::at(severity)&&(cond)) G::Log((severity),__FILE__,__LINE__) << expr ; } while(0) /* NOLINT bugprone-macro-parentheses */
139#define G_LOG_IMP_ONCE( expr , severity ) do { static bool done__ = false ; if(!done__&&G::Log::at(severity)) { G::Log((severity),__FILE__,__LINE__) << expr ; done__ = true ; } } while(0) /* NOLINT bugprone-macro-parentheses */
140
141#if defined(G_WITH_DEBUG) || ( defined(_DEBUG) && ! defined(G_NO_DEBUG) )
142#define G_DEBUG( expr ) G_LOG_IMP( expr , G::Log::Severity::Debug )
143#define G_DEBUG_IF( cond , expr ) G_LOG_IMP_IF( cond , expr , G::Log::Severity::Debug )
144#define G_DEBUG_ONCE( expr ) G_LOG_IMP_ONCE( expr , G::Log::Severity::Debug )
145#else
146#define G_DEBUG( expr )
147#define G_DEBUG_IF( cond , expr )
148#define G_DEBUG_ONCE( group , expr )
149#endif
150
151#if ! defined(G_NO_LOG)
152#define G_LOG( expr ) G_LOG_IMP( expr , G::Log::Severity::InfoVerbose )
153#define G_LOG_IF( cond , expr ) G_LOG_IMP_IF( cond , expr , G::Log::Severity::InfoVerbose )
154#define G_LOG_ONCE( expr ) G_LOG_IMP_ONCE( expr , G::Log::Severity::InfoVerbose )
155#else
156#define G_LOG( expr )
157#define G_LOG_IF( cond , expr )
158#define G_LOG_ONCE( expr )
159#endif
160
161#if ! defined(G_NO_LOG_MORE)
162#define G_LOG_MORE( expr ) G_LOG_IMP( expr , G::Log::Severity::InfoMoreVerbose )
163#define G_LOG_MORE_IF( cond , expr ) G_LOG_IMP_IF( cond , expr , G::Log::Severity::InfoMoreVerbose )
164#define G_LOG_MORE_ONCE( expr ) G_LOG_IMP_ONCE( expr , G::Log::Severity::InfoMoreVerbose )
165#else
166#define G_LOG_MORE( expr )
167#define G_LOG_MORE_IF( cond , expr )
168#define G_LOG_MORE_ONCE( expr )
169#endif
170
171#if ! defined(G_NO_LOG_S)
172#define G_LOG_S( expr ) G_LOG_IMP( expr , G::Log::Severity::InfoSummary )
173#define G_LOG_S_IF( cond , expr ) G_LOG_IMP_IF( cond , expr , G::Log::Severity::InfoSummary )
174#define G_LOG_S_ONCE( expr ) G_LOG_IMP_ONCE( expr , G::Log::Severity::InfoSummary )
175#else
176#define G_LOG_S( expr )
177#define G_LOG_S_IF( cond , expr )
178#define G_LOG_S_ONCE( expr )
179#endif
180
181#if ! defined(G_NO_WARNING)
182#define G_WARNING( expr ) G_LOG_IMP( expr , G::Log::Severity::Warning )
183#define G_WARNING_IF( cond , expr ) G_LOG_IMP_IF( cond , expr , G::Log::Severity::Warning )
184#define G_WARNING_ONCE( expr ) G_LOG_IMP_ONCE( expr , G::Log::Severity::Warning )
185#else
186#define G_WARNING( expr )
187#define G_WARNING_IF( cond , expr )
188#define G_WARNING_ONCE( expr )
189#endif
190
191#if ! defined(G_NO_ERROR)
192#define G_ERROR( expr ) G_LOG_IMP( expr , G::Log::Severity::Error )
193#else
194#define G_ERROR( expr )
195#endif
196
197#endif
A class for doing iostream-based logging.
Definition: glog.h:55
~Log()
Destructor. Writes the accumulated string to the log output.
Definition: glog.cpp:35
Log(Severity, const char *file, int line) noexcept
Constructor.
Definition: glog.cpp:26
static bool atDebug() noexcept
Returns at(Severity::Debug).
Definition: glog.h:113
LogStream & operator<<(const char *s) noexcept
Streams 's' and then returns a stream for streaming more stuff into.
Definition: glog.cpp:50
static bool atMoreVerbose() noexcept
Returns at(Severity::InfoMoreVerbose).
Definition: glog.h:123
static bool at(Severity) noexcept
Returns true if G::LogOutput::output() would log at the given level.
Definition: glog.cpp:41
static bool atVerbose() noexcept
Returns at(Severity::InfoVerbose).
Definition: glog.h:118
A simple version of boost::format for formatting strings in an i18n-friendly way.
Definition: gformat.h:46
Low-level classes.
Definition: garg.h:30
A non-throwing wrapper for std::ostream, used by G::Log.
Definition: glogstream.h:37