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