1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | /* |
3 | * This file is part of the LibreOffice project. |
4 | * |
5 | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | * |
9 | * This file incorporates work covered by the following license notice: |
10 | * |
11 | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | * contributor license agreements. See the NOTICE file distributed |
13 | * with this work for additional information regarding copyright |
14 | * ownership. The ASF licenses this file to you under the Apache |
15 | * License, Version 2.0 (the "License"); you may not use this file |
16 | * except in compliance with the License. You may obtain a copy of |
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | */ |
19 | #ifndef INCLUDED_TOOLS_DEBUG_HXX |
20 | #define INCLUDED_TOOLS_DEBUG_HXX |
21 | |
22 | #include <tools/toolsdllapi.h> |
23 | |
24 | #include <sal/detail/log.h> |
25 | #include <sal/types.h> |
26 | #include <tools/solar.h> |
27 | |
28 | /** The facilities provided by this header are deprecated. True assertions |
29 | (that detect broken program logic) should use standard assert (which aborts |
30 | if an assertion fails, and is controlled by the standard NDEBUG macro). |
31 | Logging of warnings (e.g., about malformed input) and traces (e.g., about |
32 | steps taken while executing some protocol) should use the facilities |
33 | provided by sal/log.hxx. |
34 | |
35 | Because the assertion macro (DBG_ASSERT) has been used for |
36 | true assertions as well as to log warnings, it maps to SAL_WARN instead of |
37 | standard assert. The warning and error macros (DBG_ASSERTWARNING, |
38 | DBG_WARNING, DBG_WARNING1, ..., DBG_WARNING3, DBG_ERRORFILE) all map to |
39 | SAL_INFO. |
40 | */ |
41 | |
42 | #ifdef DBG_UTIL |
43 | |
44 | typedef void (*DbgPrintLine)( const sal_Char* pLine ); |
45 | typedef const sal_Char* (*DbgUsr)(const void* pThis ); |
46 | typedef void (*DbgTestSolarMutexProc)(); |
47 | |
48 | #define DBG_BUF_MAXLEN 16384 |
49 | |
50 | #define DBG_TEST_XTOR (0x00000FFF) |
51 | #define DBG_TEST_XTOR_THIS (0x00000001) |
52 | #define DBG_TEST_XTOR_FUNC (0x00000002) |
53 | #define DBG_TEST_XTOR_EXIT (0x00000004) |
54 | #define DBG_TEST_XTOR_REPORT (0x00000008) |
55 | #define DBG_TEST_XTOR_TRACE (0x00000010) |
56 | |
57 | #define DBG_TEST_PROFILING (0x01000000) |
58 | #define DBG_TEST_RESOURCE (0x02000000) |
59 | #define DBG_TEST_DIALOG (0x04000000) |
60 | #define DBG_TEST_BOLDAPPFONT (0x08000000) |
61 | |
62 | #define DBG_OUT_NULL 0 |
63 | #define DBG_OUT_FILE 1 |
64 | #define DBG_OUT_WINDOW 2 |
65 | #define DBG_OUT_SHELL 3 |
66 | #define DBG_OUT_MSGBOX 4 |
67 | #define DBG_OUT_TESTTOOL 5 |
68 | #define DBG_OUT_DEBUGGER 6 |
69 | #define DBG_OUT_ABORT 7 |
70 | |
71 | #define DBG_OUT_COUNT 8 |
72 | |
73 | // user (runtime) defined output channels |
74 | #define DBG_OUT_USER_CHANNEL_0 100 |
75 | |
76 | struct DbgData |
77 | { |
78 | sal_uIntPtr nTestFlags; |
79 | bool bOverwrite; |
80 | sal_uIntPtr nTraceOut; |
81 | sal_uIntPtr nWarningOut; |
82 | sal_uIntPtr nErrorOut; |
83 | bool bHookOSLAssert; |
84 | sal_Char aDebugName[260]; |
85 | sal_Char aInclFilter[512]; |
86 | sal_Char aExclFilter[512]; |
87 | sal_Char aInclClassFilter[512]; |
88 | sal_Char aExclClassFilter[512]; |
89 | sal_Char aDbgWinState[50]; // DbgGUIData for VCL |
90 | }; |
91 | |
92 | struct DbgDataType |
93 | { |
94 | void* pData; |
95 | sal_Char const * pName; |
96 | }; |
97 | |
98 | // Dbg prototypes |
99 | #define DBG_FUNC_DEBUGSTART 1 |
100 | #define DBG_FUNC_DEBUGEND 2 |
101 | #define DBG_FUNC_GLOBALDEBUGEND 3 |
102 | #define DBG_FUNC_GETDATA 4 |
103 | #define DBG_FUNC_SAVEDATA 5 |
104 | #define DBG_FUNC_SETPRINTMSGBOX 6 |
105 | #define DBG_FUNC_SETPRINTWINDOW 7 |
106 | #define DBG_FUNC_SETPRINTTESTTOOL 8 |
107 | #define DBG_FUNC_XTORINFO 10 |
108 | #define DBG_FUNC_COREDUMP 12 |
109 | #define DBG_FUNC_ALLERROROUT 13 |
110 | #define DBG_FUNC_SETTESTSOLARMUTEX 14 |
111 | #define DBG_FUNC_TESTSOLARMUTEX 15 |
112 | #define DBG_FUNC_PRINTFILE 16 |
113 | #define DBG_FUNC_GETPRINTMSGBOX 17 |
114 | #define DBG_FUNC_FILTERMESSAGE 18 // new for #i38967 |
115 | #define DBG_FUNC_UPDATEOSLHOOK 19 |
116 | #define DBG_FUNC_SET_ABORT 20 |
117 | |
118 | TOOLS_DLLPUBLIC void* DbgFunc( sal_uInt16 nAction, void* pData = NULL ); |
119 | |
120 | inline void DbgUpdateOslHook( DbgData* pData ) |
121 | { |
122 | DbgFunc( DBG_FUNC_UPDATEOSLHOOK, pData ); |
123 | } |
124 | |
125 | inline void DbgDebugStart() |
126 | { |
127 | DbgFunc( DBG_FUNC_DEBUGSTART ); |
128 | } |
129 | |
130 | inline void DbgDebugEnd() |
131 | { |
132 | DbgFunc( DBG_FUNC_DEBUGEND ); |
133 | } |
134 | |
135 | inline void DbgGlobalDebugEnd() |
136 | { |
137 | DbgFunc( DBG_FUNC_GLOBALDEBUGEND ); |
138 | } |
139 | |
140 | inline void DbgSetPrintMsgBox( DbgPrintLine pProc ) |
141 | { |
142 | DbgFunc( DBG_FUNC_SETPRINTMSGBOX, (void*)(long)pProc ); |
143 | } |
144 | |
145 | inline DbgPrintLine DbgGetPrintMsgBox() |
146 | { |
147 | return (DbgPrintLine)(long)DbgFunc( DBG_FUNC_GETPRINTMSGBOX ); |
148 | } |
149 | |
150 | inline void DbgSetPrintWindow( DbgPrintLine pProc ) |
151 | { |
152 | DbgFunc( DBG_FUNC_SETPRINTWINDOW, (void*)(long)pProc ); |
153 | } |
154 | |
155 | inline void DbgSetPrintTestTool( DbgPrintLine pProc ) |
156 | { |
157 | DbgFunc( DBG_FUNC_SETPRINTTESTTOOL, (void*)(long)pProc ); |
158 | } |
159 | |
160 | inline void DbgSetAbort( DbgPrintLine pProc ) |
161 | { |
162 | DbgFunc( DBG_FUNC_SET_ABORT, (void*)(long)pProc ); |
163 | } |
164 | |
165 | typedef sal_uInt16 DbgChannelId; |
166 | |
167 | /** registers a user-defined channel for emitting the diagnostic messages |
168 | |
169 | Note that such a user-defined channel cannot be revoked during the lifetime |
170 | of the process. Thus, it's the caller's responsibility to ensure that the |
171 | procedure to which ->pProc points remains valid. |
172 | |
173 | @param pProc |
174 | the function for emitting the diagnostic messages |
175 | @return |
176 | a unique number for this channel, which can be used for ->DbgData::nErrorOut, |
177 | ->DbgData::nWarningOut and ->DbgData::nTraceOut |
178 | @see DBG_OUT_USER_CHANNEL_0 |
179 | |
180 | (In theory, this function could replace the other hard-coded channels. Well, at least |
181 | the ones for MsgBox, Window, Shell, TestTool. Perhaps in the next life ...) |
182 | */ |
183 | TOOLS_DLLPUBLIC DbgChannelId DbgRegisterUserChannel( DbgPrintLine pProc ); |
184 | |
185 | inline bool DbgFilterMessage( const char* pMsg ) |
186 | { |
187 | return (bool)(long) DbgFunc( DBG_FUNC_FILTERMESSAGE, (void*)pMsg ); |
188 | } |
189 | |
190 | inline bool DbgIsAllErrorOut() |
191 | { |
192 | return (DbgFunc( DBG_FUNC_ALLERROROUT ) != 0); |
193 | } |
194 | |
195 | inline DbgData* DbgGetData() |
196 | { |
197 | return (DbgData*)DbgFunc( DBG_FUNC_GETDATA ); |
198 | } |
199 | |
200 | inline void DbgSaveData( const DbgData& rData ) |
201 | { |
202 | DbgFunc( DBG_FUNC_SAVEDATA, (void*)&rData ); |
203 | } |
204 | |
205 | inline bool DbgIsTraceOut() |
206 | { |
207 | DbgData* pData = DbgGetData(); |
208 | return pData && pData->nTraceOut != DBG_OUT_NULL; |
209 | } |
210 | |
211 | inline bool DbgIsWarningOut() |
212 | { |
213 | DbgData* pData = DbgGetData(); |
214 | return pData && pData->nWarningOut != DBG_OUT_NULL; |
215 | } |
216 | |
217 | inline bool DbgIsErrorOut() |
218 | { |
219 | DbgData* pData = DbgGetData(); |
220 | return pData && pData->nErrorOut != DBG_OUT_NULL; |
221 | } |
222 | |
223 | inline sal_uIntPtr DbgGetErrorOut() // Testtool: test whether to collect OSL_ASSERTions as well |
224 | { |
225 | DbgData* pData = DbgGetData(); |
226 | if ( pData ) |
227 | return pData->nErrorOut; |
228 | else |
229 | return DBG_OUT_NULL; |
230 | } |
231 | |
232 | inline bool DbgIsAssertWarning() |
233 | { |
234 | return DbgIsWarningOut(); |
235 | } |
236 | |
237 | inline bool DbgIsAssert() |
238 | { |
239 | return DbgIsErrorOut(); |
240 | } |
241 | |
242 | inline sal_uIntPtr DbgIsResource() |
243 | { |
244 | DbgData* pData = DbgGetData(); |
245 | if ( pData ) |
246 | return pData->nTestFlags & DBG_TEST_RESOURCE; |
247 | else |
248 | return sal_False; |
249 | } |
250 | |
251 | inline sal_uIntPtr DbgIsDialog() |
252 | { |
253 | DbgData* pData = DbgGetData(); |
254 | if ( pData ) |
255 | return pData->nTestFlags & DBG_TEST_DIALOG; |
256 | else |
257 | return sal_False; |
258 | } |
259 | |
260 | inline sal_uIntPtr DbgIsBoldAppFont() |
261 | { |
262 | DbgData* pData = DbgGetData(); |
263 | if ( pData ) |
264 | return pData->nTestFlags & DBG_TEST_BOLDAPPFONT; |
265 | else |
266 | return sal_False; |
267 | } |
268 | |
269 | inline void DbgXtorInfo( sal_Char* pBuf ) |
270 | { |
271 | DbgFunc( DBG_FUNC_XTORINFO, (void*)pBuf ); |
272 | } |
273 | |
274 | inline void DbgCoreDump() |
275 | { |
276 | DbgFunc( DBG_FUNC_COREDUMP ); |
277 | } |
278 | |
279 | inline void DbgSetTestSolarMutex( DbgTestSolarMutexProc pProc ) |
280 | { |
281 | DbgFunc( DBG_FUNC_SETTESTSOLARMUTEX, (void*)(long)pProc ); |
282 | } |
283 | |
284 | inline void DbgTestSolarMutex() |
285 | { |
286 | DbgFunc( DBG_FUNC_TESTSOLARMUTEX ); |
287 | } |
288 | |
289 | inline void DbgPrintFile( const sal_Char* pLine ) |
290 | { |
291 | DbgFunc( DBG_FUNC_PRINTFILE, (void*)(sal_Char*)pLine ); |
292 | } |
293 | |
294 | // Dbg output |
295 | #define DBG_OUT_TRACE 1 |
296 | #define DBG_OUT_WARNING 2 |
297 | #define DBG_OUT_ERROR 3 |
298 | |
299 | TOOLS_DLLPUBLIC void DbgOut( const sal_Char* pMsg, sal_uInt16 nOutType = DBG_OUT_TRACE, |
300 | const sal_Char* pFile = NULL, sal_uInt16 nLine = 0 ); |
301 | TOOLS_DLLPUBLIC void DbgPrintShell(char const * message); |
302 | TOOLS_DLLPUBLIC void DbgOutTypef( sal_uInt16 nOutType, const sal_Char* pFStr, ... ); |
303 | TOOLS_DLLPUBLIC void DbgOutf( const sal_Char* pFStr, ... ); |
304 | TOOLS_DLLPUBLIC void ImpDbgOutfBuf( sal_Char* pBuf, const sal_Char* pFStr, ... ); |
305 | |
306 | // Dbg test functions |
307 | |
308 | #define DBG_PROF_START 1 |
309 | #define DBG_PROF_STOP 2 |
310 | #define DBG_PROF_CONTINUE 3 |
311 | #define DBG_PROF_PAUSE 4 |
312 | |
313 | TOOLS_DLLPUBLIC void DbgProf( sal_uInt16 nAction, DbgDataType* ); |
314 | |
315 | #define DBG_XTOR_CTOR 1 |
316 | #define DBG_XTOR_DTOR 2 |
317 | #define DBG_XTOR_CHKTHIS 3 |
318 | #define DBG_XTOR_CHKOBJ 4 |
319 | #define DBG_XTOR_DTOROBJ 0x8000 |
320 | |
321 | TOOLS_DLLPUBLIC void DbgXtor( DbgDataType* pDbgData, |
322 | sal_uInt16 nAction, const void* pThis, DbgUsr fDbgUsr ); |
323 | |
324 | class DbgXtorObj |
325 | { |
326 | private: |
327 | DbgDataType* pDbgData; |
328 | const void* pThis; |
329 | DbgUsr fDbgUsr; |
330 | sal_uInt16 nAction; |
331 | |
332 | public: |
333 | DbgXtorObj( DbgDataType* pData, |
334 | sal_uInt16 nAct, const void* pThs, DbgUsr fUsr ) |
335 | { |
336 | DbgXtor( pData, nAct, pThs, fUsr ); |
337 | pDbgData = pData; |
338 | nAction = nAct; |
339 | pThis = pThs; |
340 | fDbgUsr = fUsr; |
341 | } |
342 | |
343 | ~DbgXtorObj() |
344 | { |
345 | DbgXtor( pDbgData, nAction | DBG_XTOR_DTOROBJ, |
346 | pThis, fDbgUsr ); |
347 | } |
348 | }; |
349 | |
350 | // (internally used) defines |
351 | |
352 | #define DBG_FUNC( aName ) DbgName_##aName() |
353 | #define DBG_NAME( aName ) static DbgDataType aImpDbgData_##aName = { 0, #aName }; \ |
354 | DbgDataType* DBG_FUNC( aName ) { return &aImpDbgData_##aName; } |
355 | #define DBG_NAMEEX_VISIBILITY( aName, vis ) vis DbgDataType* DBG_FUNC( aName ); |
356 | #define DBG_NAMEEX( aName ) DBG_NAMEEX_VISIBILITY( aName, ) |
357 | |
358 | // (externally used) defines |
359 | |
360 | #define DBG_DEBUGSTART() DbgDebugStart() |
361 | #define DBG_DEBUGEND() DbgDebugEnd() |
362 | #define DBG_GLOBALDEBUGEND() DbgGlobalDebugEnd() |
363 | |
364 | #define DBG_PROFSTART( aName ) \ |
365 | DbgProf( DBG_PROF_START, DBG_FUNC( aName ) ) |
366 | |
367 | #define DBG_PROFSTOP( aName ) \ |
368 | DbgProf( DBG_PROF_STOP, DBG_FUNC( aName ) ) |
369 | |
370 | #define DBG_PROFCONTINUE( aName ) \ |
371 | DbgProf( DBG_PROF_CONTINUE, DBG_FUNC( aName ) ) |
372 | |
373 | #define DBG_PROFPAUSE( aName ) \ |
374 | DbgProf( DBG_PROF_PAUSE, DBG_FUNC( aName ) ) |
375 | |
376 | #define DBG_CTOR( aName, fTest ) \ |
377 | DbgXtorObj aDbgXtorObj( DBG_FUNC( aName ), \ |
378 | DBG_XTOR_CTOR, \ |
379 | (const void*)this, \ |
380 | fTest ) |
381 | |
382 | #define DBG_DTOR( aName, fTest ) \ |
383 | DbgXtorObj aDbgXtorObj( DBG_FUNC( aName ), \ |
384 | DBG_XTOR_DTOR, \ |
385 | (const void*)this, \ |
386 | fTest ) |
387 | |
388 | #define DBG_CHKTHIS( aName, fTest ) \ |
389 | DbgXtorObj aDbgXtorObj( DBG_FUNC( aName ), \ |
390 | DBG_XTOR_CHKTHIS, \ |
391 | (const void*)this, \ |
392 | fTest ) |
393 | |
394 | #define DBG_CHKOBJ( pObj, aName, fTest ) \ |
395 | DbgXtor( DBG_FUNC( aName ), DBG_XTOR_CHKOBJ, \ |
396 | (const void*)pObj, (DbgUsr)fTest ) |
397 | |
398 | #define DBG_ASSERTWARNING( sCon, aWarning ) \ |
399 | SAL_DETAIL_INFO_IF_FORMAT(!(sCon), "legacy.tools", aWarning) |
400 | |
401 | #define DBG_ASSERT( sCon, aError ) \ |
402 | SAL_DETAIL_WARN_IF_FORMAT(!(sCon), "legacy.tools", aError) |
403 | |
404 | #define DBG_WARNING( aWarning ) \ |
405 | SAL_DETAIL_INFO_IF_FORMAT(true, "legacy.tools", aWarning) |
406 | #define DBG_WARNING1( aWarning, x1 ) \ |
407 | SAL_DETAIL_INFO_IF_FORMAT(true, "legacy.tools", aWarning, x1) |
408 | #define DBG_WARNING2( aWarning, x1, x2 ) \ |
409 | SAL_DETAIL_INFO_IF_FORMAT(true, "legacy.tools", aWarning, x1, x2) |
410 | #define DBG_WARNING3( aWarning, x1, x2, x3 ) \ |
411 | SAL_DETAIL_INFO_IF_FORMAT(true, "legacy.tools", aWarning, x1, x2, x3) |
412 | |
413 | #define DBG_ERRORFILE( aError ) \ |
414 | SAL_DETAIL_INFO_IF_FORMAT(true, "legacy.tools", aError, __FILE__, __LINE__) |
415 | |
416 | #define DBG_TESTSOLARMUTEX() \ |
417 | do \ |
418 | { \ |
419 | DbgTestSolarMutex(); \ |
420 | } while(false) |
421 | |
422 | // en-/disable debug defines |
423 | |
424 | #define DBG_INSTOUTTRACE( nOut ) \ |
425 | do \ |
426 | { \ |
427 | DbgGetData()->nTraceOut = nOut; \ |
428 | } while(false) |
429 | |
430 | #define DBG_INSTOUTWARNING( nOut ) \ |
431 | do \ |
432 | { \ |
433 | DbgGetData()->nWarningOut = nOut; \ |
434 | } while(false) |
435 | |
436 | #define DBG_INSTOUTERROR( nOut ) \ |
437 | do \ |
438 | { \ |
439 | DbgGetData()->nErrorOut = nOut; \ |
440 | } while(false) |
441 | |
442 | #else |
443 | // NO DBG_UITL |
444 | |
445 | struct DbgData; |
446 | struct DbgDataType; |
447 | |
448 | typedef void (*DbgPrintLine)( const sal_Char* pLine ); |
449 | typedef const sal_Char* (*DbgUsr)(const void* pThis ); |
450 | |
451 | #define DBG_DEBUGSTART() ((void)0) |
452 | #define DBG_DEBUGEND() ((void)0) |
453 | #define DBG_GLOBALDEBUGEND() ((void)0) |
454 | |
455 | #define DBG_NAME( aName ) |
456 | #define DBG_NAMEEX( aName ) |
457 | #define DBG_NAMEEX_VISIBILITY( aName, vis ) |
458 | |
459 | #define DBG_PROFSTART( aName ) ((void)0) |
460 | #define DBG_PROFSTOP( aName ) ((void)0) |
461 | #define DBG_PROFCONTINUE( aName ) ((void)0) |
462 | #define DBG_PROFPAUSE( aName ) ((void)0) |
463 | |
464 | #define DBG_CTOR( aName, fTest ) ((void)0) |
465 | #define DBG_DTOR( aName, fTest ) ((void)0) |
466 | #define DBG_CHKTHIS( aName, fTest ) ((void)0) |
467 | #define DBG_CHKOBJ( pObj, aName, fTest ) ((void)0) |
468 | |
469 | #define DBG_ASSERTWARNING( sCon, aWarning ) ((void)0) |
470 | #define DBG_ASSERT( sCon, aError ) ((void)0) |
471 | #define DBG_WARNING( aWarning ) ((void)0) |
472 | #define DBG_WARNING1( aWarning, x1 ) ((void)0) |
473 | #define DBG_WARNING2( aWarning, x1, x2 ) ((void)0) |
474 | #define DBG_WARNING3( aWarning, x1, x2, x3 ) ((void)0) |
475 | #define DBG_ERRORFILE( aError ) ((void)0) |
476 | |
477 | #define DBG_TESTSOLARMUTEX() ((void)0) |
478 | |
479 | #define DBG_INSTOUTTRACE( nOut ) ((void)0) |
480 | #define DBG_INSTOUTWARNING( nOut ) ((void)0) |
481 | #define DBG_INSTOUTERROR( nOut ) ((void)0) |
482 | |
483 | #endif |
484 | |
485 | #endif |
486 | |
487 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
488 | |