1 //
2 // Copyright (C) 2001-2013 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 glogoutput.h
19 ///
20 
21 #ifndef G_LOG_OUTPUT_H
22 #define G_LOG_OUTPUT_H
23 
24 #include "gdef.h"
25 #include "glog.h"
26 #include <string>
27 #include <ctime>
28 
29 /// \namespace G
30 namespace G
31 {
32 	class LogOutput ;
33 }
34 
35 /// \class G::LogOutput
36 /// Controls and implements low-level logging output, as
37 /// used by the Log interface. Applications should instantiate a LogOutput
38 /// object in main() to enable log output.
39 /// \see G::Log
40 ///
41 class G::LogOutput
42 {
43 public:
44  	enum SyslogFacility { User , Daemon , Mail , Cron } ; // etc.
45 
46 	LogOutput( const std::string & prefix , bool output , bool with_logging ,
47 		bool with_verbose_logging , bool with_debug , bool with_level ,
48 		bool with_timestamp , bool strip_context , bool use_syslog ,
49 		const std::string & stderr_replacement = std::string() ,
50 		SyslogFacility syslog_facility = User ) ;
51 			///< Constructor. If there is no LogOutput object, or if 'output'
52 			///< is false, then there is no output of any sort. Otherwise at
53 			///< least warning and error messages are generated.
54 			///<
55 			///< If 'with-logging' is true then log[summary] messages are
56 			///< output. If 'with-verbose-logging' is true then log[verbose]
57 			///< messages are output. If 'with_debug' is true then debug
58 			///< messages will also be generated (but only if compiled in).
59 			///<
60 			///< More than one LogOutput object may be created, but only
61 			///< the first one controls output.
62 
63 	explicit LogOutput( bool output_with_logging , bool verbose_and_debug = true ,
64 		const std::string & stderr_replacement = std::string() ) ;
65 			///< Constructor for test programs. Only generates output if the
66 			///< first parameter is true. Never uses syslog.
67 
68 	virtual ~LogOutput() ;
69 		///< Destructor.
70 
71 	virtual void rawOutput( std::ostream & , G::Log::Severity , const std::string & ) ;
72 		///< Overridable. Used to do the final message
73 		///< output (with OutputDebugString() or stderr).
74 
75 	static LogOutput * instance() ;
76 		///< Returns a pointer to the controlling LogOutput object. Returns
77 		///< NULL if none.
78 
79 	bool enable( bool enabled = true ) ;
80 		///< Enables or disables output. Returns the previous setting.
81 
82 	static void output( G::Log::Severity , const char * file , int line , const std::string & ) ;
83 		///< Generates output if there is an existing
84 		///< LogOutput object which is enabled. Uses rawOutput().
85 
86 	static void assertion( const char * file , int line , bool test , const std::string & ) ;
87 		///< Makes an assertion check (regardless of any LogOutput
88 		///< object). Calls output() if the 'file' parameter is not null.
89 
90 	virtual void onAssert() ;
91 		///< Called during an assertion failure. This allows Windows
92 		///< applications to stop timers etc. (Timers can cause reentrancy
93 		///< problems and infinitely recursive dialog box creation.)
94 
95 private:
96 	typedef size_t size_type ;
97 	LogOutput( const LogOutput & ) ; // not implemented
98 	void operator=( const LogOutput & ) ; // not implemented
99 	void init() ;
100 	void cleanup() ;
101 	std::string timestampString() ;
102 	static std::string dateString() ;
103 	void doOutput( G::Log::Severity , const std::string & ) ;
104 	void doOutput( G::Log::Severity s , const char * , int , const std::string & ) ;
105 	void doAssertion( const char * , int , const std::string & ) ;
106 	static std::string levelString( Log::Severity s ) ;
107 	static std::string itoa( int ) ;
108 	static std::string fileAndLine( const char * , int ) ;
109 	static void halt() ;
110 	static LogOutput * & pthis() ;
111 	static std::ostream & err( const std::string & ) ;
112 	static void getLocalTime( time_t , struct std::tm * ) ; // dont make logging dependent on G::DateTime
113 
114 private:
115 	std::string m_prefix ;
116 	bool m_enabled ;
117 	bool m_summary_log ;
118 	bool m_verbose_log ;
119 	bool m_debug ;
120 	bool m_level ;
121 	bool m_strip ;
122 	bool m_syslog ;
123 	std::ostream & m_std_err ;
124 	SyslogFacility m_facility ;
125 	time_t m_time ;
126 	char m_time_buffer[40U] ;
127 	bool m_timestamp ;
128 	HANDLE m_handle ; // windows
129 	bool m_handle_set ;
130 } ;
131 
132 #endif
133