1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #ifndef _RADIOLOGGER_H_ |
|
19 #define _RADIOLOGGER_H_ |
|
20 |
|
21 // System includes |
|
22 #include <QObject> |
|
23 |
|
24 // User includes |
|
25 #include "radiowrapperexport.h" |
|
26 |
|
27 class WRAPPER_DLL_EXPORT RadioLogger |
|
28 { |
|
29 public: |
|
30 |
|
31 enum Mode { Normal, MethodEnter, MethodExit, DecIndent }; |
|
32 |
|
33 static void initCombinedLogger(); |
|
34 static void releaseCombinedLogger(); |
|
35 |
|
36 static void logMsg( const char* msg, Mode mode = Normal ); |
|
37 |
|
38 private: |
|
39 RadioLogger(); |
|
40 ~RadioLogger(); |
|
41 }; |
|
42 |
|
43 // ============================================================================ |
|
44 // START TIMESTAMP LOGGING |
|
45 // ============================================================================ |
|
46 |
|
47 #ifdef TIMESTAMP_LOGGING_ENABLED |
|
48 |
|
49 #include <QTime> |
|
50 #include <QDebug> |
|
51 |
|
52 /** |
|
53 * Timestamp logging macro. |
|
54 * When the macro is defined, timestamp logging is on |
|
55 * |
|
56 * Example. These lines in the code... |
|
57 * LOG_TIMESTAMP( "Start operation" ); |
|
58 * ... |
|
59 * LOG_TIMESTAMP( "End operation" ); |
|
60 * |
|
61 * ... print the following log lines |
|
62 * FMRadio: Start operation "14:13:09.042" |
|
63 * FMRadio: End operation "14:13:09.250" |
|
64 */ |
|
65 //#define LOG_TIMESTAMP(comment) do{ qDebug() << LOGMARKER << comment << QTime::currentTime().toString("hh:mm:ss.zzz"); }while(0) |
|
66 #define LOG_TIMESTAMP(comment) LOG_FORMAT( comment ## " %s", GETSTRING( QTime::currentTime().toString("hh:mm:ss.zzz") ) ) |
|
67 |
|
68 #else |
|
69 |
|
70 #define LOG_TIMESTAMP(comment) |
|
71 |
|
72 #endif // TIMESTAMP_LOGGING_ENABLED |
|
73 |
|
74 // ============================================================================ |
|
75 // END TIMESTAMP LOGGING |
|
76 // ============================================================================ |
|
77 |
|
78 // ============================================================================ |
|
79 // START FULL LOGGING |
|
80 // ============================================================================ |
|
81 |
|
82 #ifdef LOGGING_ENABLED |
|
83 |
|
84 #include <QtGlobal> |
|
85 #include <QDebug> |
|
86 |
|
87 // UI logs can be combined with engine logs by making the UI feed its log prints into |
|
88 // the engine logger. This requires that we initialize the radio engine utils right here |
|
89 // because the engine won't start up until much later. This is a bit ugly since the macros |
|
90 // call Symbian code directly, but it was considered to be worth it to see UI and engine |
|
91 // traces in the same file. |
|
92 #if defined COMBINE_WITH_ENGINE_LOGGER && defined LOGGING_ENABLED && !defined BUILD_WIN32 |
|
93 # include "../../../radioengine/utils/api/mradioenginelogger.h" |
|
94 # include "../../../radioengine/utils/api/radioengineutils.h" |
|
95 # define WRITELOG(msg) RadioLogger::logMsg( msg ); |
|
96 # define WRITELOG_METHOD_ENTER(msg) RadioLogger::logMsg( GETSTRING( msg ), RadioLogger::MethodEnter ); |
|
97 # define WRITELOG_METHOD_EXIT(msg) RadioLogger::logMsg( GETSTRING( msg ), RadioLogger::MethodExit ); |
|
98 # define LOGGER_DEC_INDENT RadioLogger::logMsg( "", RadioLogger::DecIndent ); |
|
99 # define WRITELOG_GETSTRING(msg) WRITELOG( GETSTRING( msg ) ) |
|
100 # define INIT_COMBINED_LOGGER RadioLogger::initCombinedLogger(); |
|
101 # define RELEASE_COMBINED_LOGGER RadioLogger::releaseCombinedLogger(); |
|
102 #else |
|
103 # define WRITELOG(msg) qDebug() << LOGMARKER << msg; |
|
104 # define WRITELOG_METHOD_ENTER(msg) WRITELOG(msg) |
|
105 # define WRITELOG_METHOD_EXIT(msg) WRITELOG(msg) |
|
106 # define WRITELOG_GETSTRING(msg) WRITELOG(msg) |
|
107 # define LOGGER_INC_INDENT |
|
108 # define LOGGER_DEC_INDENT |
|
109 # define INIT_COMBINED_LOGGER |
|
110 # define RELEASE_COMBINED_LOGGER |
|
111 #endif |
|
112 |
|
113 // Macro that simply logs a string |
|
114 // Example: |
|
115 // LOG( "This is a test" ); |
|
116 #define LOG(string) do{ WRITELOG( string ) }while(0) |
|
117 |
|
118 // Helper macro to get a const char* out of a QString so that it can be logged. Can be used with LOG_FORMAT() |
|
119 #define GETSTRING(qstring) qstring.toAscii().constData() |
|
120 |
|
121 // Macro that logs a string with multiple parameters |
|
122 // Examples: |
|
123 // LOG_FORMAT( "This is an integer %d, and this is a float with two digits %.2f", 42, 3.14 ); |
|
124 // LOG_FORMAT( "This is a QString %s", GETSTRING(someQString) ); |
|
125 #define LOG_FORMAT(fmt,args...) do{ QString tmp; WRITELOG_GETSTRING( tmp.sprintf(fmt,args) ) }while(0) |
|
126 |
|
127 // Macro that logs function enter, exit and exception |
|
128 // Example (Simply put it in the beginning of a function): |
|
129 // LOG_METHOD; |
|
130 // Output: |
|
131 // -> SomeFunction(int,const char*) |
|
132 // <- SomeFunction(int,const char*) |
|
133 // <- SomeFunction(int,const char*): Exception raised! |
|
134 #define LOG_METHOD MethodLogger ___methodLogger( __PRETTY_FUNCTION__, "" ) |
|
135 |
|
136 // Same as the previous function logging macro with the addition of logging the return value |
|
137 // Note! The return value can only be retrieved in the emulator. |
|
138 // Example (Simply put it in the beginning of a function): |
|
139 // LOG_METHOD_RET( "%d" ); |
|
140 // Output: |
|
141 // -> SomeFunction(int,const char*) |
|
142 // <- SomeFunction(int,const char*) returning 42 |
|
143 #define LOG_METHOD_RET(fmt) MethodLogger ___methodLogger( __PRETTY_FUNCTION__, fmt ) |
|
144 |
|
145 // Logs function enter but does not log exit or leave. This is meant to be lighter than LOG_METHOD macro |
|
146 #define LOG_METHOD_ENTER LOG_FORMAT( "Enter: %s", __PRETTY_FUNCTION__ ) |
|
147 |
|
148 // Assert macro for logging. If the condition is false, the expression is performed |
|
149 // Example: |
|
150 // LOG_ASSERT( thisMustBeTrue, LOG_FORMAT( "OMG! That was not true: %d", thisMustBeTrue ) ); |
|
151 #define LOG_ASSERT(cond,expr) do{ if (!cond) { expr; } }while(0) |
|
152 |
|
153 // Macro to hide a function variable that is used only when debugging is enabled. |
|
154 // Expands to the variable name when debugging is enabled and to nothing when it is not |
|
155 #define DEBUGVAR(a) a |
|
156 |
|
157 // Macro to log slot function caller by its class name. |
|
158 #define LOG_SLOT_CALLER do { \ |
|
159 QObject* caller = sender(); \ |
|
160 if ( caller ) { \ |
|
161 LOG_FORMAT( "SLOT %s called by %s. Objectname: %s", __PRETTY_FUNCTION__, \ |
|
162 caller->metaObject()->className(), GETSTRING( caller->objectName() ) ); \ |
|
163 } else { \ |
|
164 LOG_FORMAT( "SLOT %s called as regular function. ", __PRETTY_FUNCTION__ ); \ |
|
165 } \ |
|
166 } while (0) |
|
167 |
|
168 // Class declaration |
|
169 class WRAPPER_DLL_EXPORT MethodLogger |
|
170 { |
|
171 public: |
|
172 |
|
173 MethodLogger( const char* function, const char* format ); |
|
174 ~MethodLogger(); |
|
175 |
|
176 private: |
|
177 |
|
178 const char* mFunction; |
|
179 const char* mFormat; |
|
180 |
|
181 }; |
|
182 |
|
183 #else // LOGGING_ENABLED |
|
184 |
|
185 # define LOG(string) |
|
186 # define GETSTRING(qstring) |
|
187 # define LOG_FORMAT(fmt,args...) |
|
188 # define LOG_METHOD |
|
189 # define LOG_METHOD_RET(fmt) |
|
190 # define LOG_METHOD_ENTER |
|
191 # define LOG_ASSERT(cond,expr) |
|
192 # define DEBUGVAR(a) |
|
193 # define LOG_SLOT_CALLER |
|
194 # define INIT_COMBINED_LOGGER |
|
195 # define RELEASE_COMBINED_LOGGER |
|
196 |
|
197 |
|
198 // Dummy class |
|
199 class WRAPPER_DLL_EXPORT MethodLogger |
|
200 { |
|
201 public: |
|
202 MethodLogger( const char*, const char* ); |
|
203 ~MethodLogger(); |
|
204 }; |
|
205 |
|
206 #endif // LOGGING_ENABLED |
|
207 |
|
208 #ifdef TRACE_TO_FILE |
|
209 |
|
210 # define INSTALL_MESSAGE_HANDLER FileLogger::installMessageHandler(QString(TRACE_OUTPUT_FILE), FILTER_BY_LOGMARKER); |
|
211 # define UNINSTALL_MESSAGE_HANDLER FileLogger::uninstallMessageHandler(); |
|
212 |
|
213 // Class declaration |
|
214 class WRAPPER_DLL_EXPORT FileLogger |
|
215 { |
|
216 public: |
|
217 |
|
218 static void installMessageHandler( const QString& fileName, bool filterByMarker = true ); |
|
219 static void uninstallMessageHandler(); |
|
220 |
|
221 private: |
|
222 |
|
223 static void handleMessage( QtMsgType type, const char* msg ); |
|
224 |
|
225 }; |
|
226 |
|
227 #else |
|
228 # define INSTALL_MESSAGE_HANDLER |
|
229 # define UNINSTALL_MESSAGE_HANDLER |
|
230 #endif // TRACE_TO_FILE |
|
231 |
|
232 // ============================================================================ |
|
233 // END FULL LOGGING |
|
234 // ============================================================================ |
|
235 |
|
236 // ============================================================================ |
|
237 // SIGNAL/SLOT CONNECTION CHECKER |
|
238 // ============================================================================ |
|
239 static bool connectAndTest( const QObject* sender, const char* signal, |
|
240 const QObject* receiver, const char* member, |
|
241 Qt::ConnectionType type = Qt::AutoConnection ) |
|
242 { |
|
243 bool connected = QObject::connect( sender, signal, receiver, member, type ); |
|
244 |
|
245 # ifdef CONNECT_TEST_MODE |
|
246 |
|
247 if ( !connected ) |
|
248 { |
|
249 LOG( "Failed to make a signal-slot connection!" ); |
|
250 LOG_FORMAT( "sender: %s", sender->metaObject()->className() ); |
|
251 LOG_FORMAT( "signal: %s", signal ); |
|
252 LOG_FORMAT( "receiver: %s", receiver->metaObject()->className() ); |
|
253 LOG_FORMAT( "slot/signal: %s", signal ); |
|
254 |
|
255 #if CONNECT_TEST_MODE == 2 |
|
256 Q_ASSERT( false ); |
|
257 #endif |
|
258 |
|
259 // ---------------------------------------------------------------- |
|
260 // SIGNAL-SLOT CONNECTION FAILED! |
|
261 // ---------------------------------------------------------------- |
|
262 } |
|
263 |
|
264 # endif |
|
265 |
|
266 return connected; |
|
267 } |
|
268 |
|
269 #ifdef ENABLE_ASSERTS |
|
270 |
|
271 #define RADIO_ASSERT(cond,where,what) Q_ASSERT_X(cond,where,what) |
|
272 |
|
273 #else |
|
274 # ifdef LOGGING_ENABLED |
|
275 # define RADIO_ASSERT(cond,where,what) \ |
|
276 do { \ |
|
277 if ( !cond ) { \ |
|
278 LOG_FORMAT( "ASSERT Failed! %s, %s", where, what ); \ |
|
279 } \ |
|
280 } while ( false ) |
|
281 # else |
|
282 # define RADIO_ASSERT(cond,where,what) |
|
283 # endif // LOGGING_ENABLED |
|
284 #endif // ENABLE_ASSERTS |
|
285 |
|
286 #endif // _RADIOLOGGER_H_ |
|