X11workbench Toolkit  1.0
debug_helper.h
1 // //
3 // _ _ _ _ _ //
4 // __| | ___ | |__ _ _ __ _ | |__ ___ | | _ __ ___ _ __ | |__ //
5 // / _` | / _ \| '_ \ | | | | / _` | | '_ \ / _ \| || '_ \ / _ \| '__|| '_ \ //
6 // | (_| || __/| |_) || |_| || (_| | | | | || __/| || |_) || __/| | _ | | | | //
7 // \__,_| \___||_.__/ \__,_| \__, |_____|_| |_| \___||_|| .__/ \___||_|(_)|_| |_| //
8 // |___/|_____| |_| //
9 // //
11 // //
12 // This header file contains debug-related functionality, some of which will be //
13 // in the release version of the library, and expanded in the debug version. //
14 // //
16 
17 /*****************************************************************************
18 
19  X11workbench - X11 programmer's 'work bench' application and toolkit
20  Copyright (c) 2010-2019 by Bob Frazier (aka 'Big Bad Bombastic Bob')
21 
22  DISCLAIMER: The X11workbench application and toolkit software are supplied
23  'as-is', with no warranties, either implied or explicit.
24  Any claims to alleged functionality or features should be
25  considered 'preliminary', and might not function as advertised.
26 
27  MIT-like license:
28 
29  There is no restriction as to what you can do with this software, so long
30  as you include the above copyright notice and DISCLAIMER for any distributed
31  work that is equal to or derived from this one, along with this paragraph
32  that explains the terms of the license if the source is also being made
33  available. A "derived work" describes a work that uses a significant portion
34  of the source files or algorithms that are included with this one.
35  Specifically excluded from this are files that were generated by the software,
36  or anything that is included with the software that is part of another package
37  (such as files that were created or added during the 'configure' process).
38  Specifically included is the use of part or all of any of the X11 workbench
39  toolkit source or header files in your distributed application. If you do not
40  ship the source, the above copyright statement is still required to be placed
41  in a reasonably prominent place, such as documentation, splash screens, and/or
42  'about the application' dialog boxes.
43 
44  Use and distribution are in accordance with GPL, LGPL, and/or the above
45  MIT-like license. See COPYING and README files for more information.
46 
47 
48  Additional information at http://sourceforge.net/projects/X11workbench
49 
50 ******************************************************************************/
51 
52 #ifndef _DEBUG_HELPER_H_INCLUDED_
53 #define _DEBUG_HELPER_H_INCLUDED_
54 
55 #ifndef __DOXYGEN__ /* exclude these so I don't mess up the docs */
56 #include "platform_helper.h" // always make sure, I need some definitions from here
57 #endif // __DOXYGEN__ /* exclude these so I don't mess up the docs */
58 
59 #ifdef __cplusplus
60 extern "C" {
61 #endif // __cplusplus
62 
63 #ifndef __DOXYGEN__ /* exclude these so I don't mess up the docs */
64 typedef struct s_WBGC * WBGC; // forward declaration - see window_helper.h
65 #endif // __DOXYGEN__ /* exclude these so I don't mess up the docs */
66 
67 
69 // ____ _____ ____ _ _ ____ _ _ _____ _ ____ _____ ____ ____ //
70 // | _ \ | ____|| __ ) | | | | / ___| | | | || ____|| | | _ \ | ____|| _ \ / ___| //
71 // | | | || _| | _ \ | | | || | _ | |_| || _| | | | |_) || _| | |_) |\___ \ //
72 // | |_| || |___ | |_) || |_| || |_| | | _ || |___ | |___ | __/ | |___ | _ < ___) | //
73 // |____/ |_____||____/ \___/ \____| |_| |_||_____||_____||_| |_____||_| \_\|____/ //
74 // //
76 
77 
94 {
95  DebugLevel_None = 0,
96  DebugLevel_ERROR = 0,
97  DebugLevel_WARN = 1,
98 
99  // criteria for selecting debug output
100  DebugLevel_Minimal = 1,
101  DebugLevel_Light = 2,
102  DebugLevel_Medium = 3,
103  DebugLevel_Heavy = 4,
104  DebugLevel_Chatty = 5,
105  DebugLevel_Verbose = 6,
106  DebugLevel_Excessive = 7,
107  DebugLevel_MAXIMUM = 7,
108  DebugLevel_MASK = 7,
109 
110  // next are subsystem masks for additional debugging for the toolkit.
111  // Also, see 'aszDebugSubSys' in WBParseStandardArguments(), platform_helper.c (it must match)
112  DebugSubSystem_ALL = 0,
113  DebugSubSystem_RESTRICT = 0x80000000,
114  DebugSubSystem_BITSHIFT = 3,
115  DebugSubSystem_Init = 0x00000008,
116  DebugSubSystem_Application = 0x00000010,
117  DebugSubSystem_Window = 0x00000020,
118  DebugSubSystem_Menu = 0x00000040,
119  DebugSubSystem_Event = 0x00000080,
120  DebugSubSystem_Dialog = 0x00000100,
121  DebugSubSystem_DialogCtrl = 0x00000200,
122  DebugSubSystem_Frame = 0x00000400,
123  DebugSubSystem_Keyboard = 0x00000800,
124  DebugSubSystem_Mouse = 0x00001000,
125  DebugSubSystem_Font = 0x00002000,
126  DebugSubSystem_Settings = 0x00004000,
127  DebugSubSystem_Selection = 0x00008000,
128  DebugSubSystem_Pixmap = 0x00010000,
129  DebugSubSystem_Expose = 0x00020000,
130  DebugSubSystem_EditWindow = 0x00040000,
131  DebugSubSystem_ScrollBar = 0x00080000,
132  DebugSubSystem_DrawText = 0x00100000,
133  DebugSubSystem_Clipboard = 0x00200000,
134  DebugSubSystem_TextObject = 0x00400000,
135 
136  // remaining subsystem bits are reserved - please do not use them
137  DebugSubSystem_RESERVED2 = 0x00800000,
138  DebugSubSystem_RESERVED3 = 0x01000000,
139  DebugSubSystem_RESERVED4 = 0x02000000,
140  DebugSubSystem_RESERVED5 = 0x04000000,
141  DebugSubSystem_RESERVED6 = 0x08000000,
142  DebugSubSystem_RESERVED7 = 0x10000000,
143  DebugSubSystem_RESERVED8 = 0x20000000,
144  DebugSubSystem_RESERVED9 = 0x40000000,
145  DebugSubSystem_MAX = 0x40000000,
146 
147  DebugSubSystem_MASK = ~7L
148 
149  // user bits are the high 32-bits of a long-long value for the debug level. They can be
150  // used for any purpose without any restriction.
151 };
152 
153 
154 
155 
167 void WBSetDebugLevel(unsigned int iLevel);
168 
169 
184 #if defined(__GNUC__) || defined(_MSVC_VER)
185 static __inline__ WB_UINT64 WBGetDebugLevel(void)
186 {
187 extern WB_UINT64 iWBDebugLevel;
188 
189  return iWBDebugLevel;
190 }
191 #else // !defined(__GNUC__) && !defined(_MSVC_VER)
193 #endif // defined(__GNUC__) || defined(_MSVC_VER)
194 
211 #ifdef __GNUC__
212 void WBDebugPrint(const char *pFmt, ...) __attribute__ ((format(printf, 1, 2)));
213 #else // __GNUC__
214 void WBDebugPrint(const char *pFmt, ...);
215 #endif // __GNUC__
216 
233 void WBDebugDump(const char *szTitle, void *pData, int cbData); // dump binary data
234 
250 void WBDebugDumpGC(Display *pDisplay, WBGC hGC);
251 
266 void WBDebugDumpRegion(Region hRgn, int bRotate);
267 
268 
283 void WBDebugDumpEvent(XEvent *pEvent);
284 
285 
299 #if defined(__GNUC__) || defined(_MSVC_VER)
300 static __inline__ int WBCheckDebugLevel(WB_UINT64 dwLevel)
301 {
302 extern WB_UINT64 iWBDebugLevel;
303 
304  if(WB_LIKELY((iWBDebugLevel & DebugLevel_MASK) < (dwLevel & DebugLevel_MASK)))
305  {
306  return 0;
307  }
308 
309  if(!WB_UNLIKELY( WBGetDebugLevel() & DebugSubSystem_RESTRICT )) // RESTRICT not specified
310  {
311  if(!(dwLevel & DebugSubSystem_MASK) ) // no subsystem specified in debug output
312  {
313  return 1; // this is acceptable - since no subsystem specified, allow debug output if not 'RESTRICT'
314  }
315  }
316 
317  // at this point I have a debug subsystem 'RESTRICT' specified
318 
319  if(((dwLevel & DebugSubSystem_MASK) & (iWBDebugLevel & DebugSubSystem_MASK))
320  != 0) // check to see that subsystem bits in 'dwLevel' match bits in 'iWBDebugLevel'
321  {
322  // at least one subsystem bit matches from 'dwLevel' and iWBDebugLevel
323  return 1;
324  }
325 
326  return 0;
327 }
328 #else // !defined(__GNUC__) && !defined(_MSVC_VER)
329 int WBCheckDebugLevel(WB_UINT64 dwLevel);
330 #endif // defined(__GNUC__) || defined(_MSVC_VER)
331 
332 
333 
334 // NOTE: The debug code will be included when NO_DEBUG is *NOT* defined
335 
336 #ifdef NO_DEBUG /* assign this to disable debugging - most likely a -D in Makefile */
337 #define WB_DEBUG_PRINT(...)
338 #define WB_DEBUG_DUMP(L,X,Y,Z)
339 #define WB_IF_DEBUG_LEVEL(L) if(0) /* TODO: turn off the warning? */
340 #define WB_DEFINE_PROFILE(__name)
341 #define WB_ENABLE_PROFILE(__name,__desc)
342 #define WB_START_PROFILE(__name)
343 #define WB_STOP_PROFILE(__name)
344 #else // NO_DEBUG
345 
346 // NOTE: this macro is the preferred method of implementing debug output.
364 #define WB_DEBUG_PRINT(L, ...) \
365  WB_IF_DEBUG_LEVEL(L) { WBDebugPrint(__VA_ARGS__); }
366 
385 #define WB_DEBUG_DUMP(L,X,Y,Z) \
386  WB_IF_DEBUG_LEVEL(L) { WBDebugDump(X,Y,Z); }
387 
404 #define WB_IF_DEBUG_LEVEL(L) if(WBCheckDebugLevel((L)))
405 
406 
414 #define WB_DEFINE_PROFILE(__name) static int __wb_profile_##__name = -1
415 
426 #define WB_ENABLE_PROFILE(__name,__desc) { if(__wb_profile_##__name < 0) \
427  __wb_profile_##__name = WBRegisterProfileVar(__FILE__, __LINE__, __FUNCTION__, \
428  WB_STRINGIZE(__name), __desc); }
429 
430 
439 #define WB_START_PROFILE(__name) WBStartProfile(__wb_profile_##__name)
440 
441 
450 #define WB_STOP_PROFILE(__name) WBStopProfile(__wb_profile_##__name)
451 
452 
453 // internally defined functions to support profiling - debug builds only. do not call these directly.
454 int WBRegisterProfileVar(const char *szFile, WB_INT32 nLine, const char *szFunction, const char *szName, const char *szDesc);
455 void WBStartProfile(int nProfileID);
456 void WBStopProfile(int nProfileID);
457 void WBDumpProfileData(void);
458 
459 #endif // NO_DEBUG
460 
461 
467 #define WB_WARN_PRINT(...) WB_DEBUG_PRINT(DebugLevel_WARN, __VA_ARGS__)
468 
474 #define WB_ERROR_PRINT(...) WB_DEBUG_PRINT(DebugLevel_ERROR, __VA_ARGS__)
475 
485 #define WB_WARN_DUMP(X,Y,Z) WB_DEBUG_DUMP(DebugLevel_WARN, X,Y,Z)
486 
496 #define WB_ERROR_DUMP(X,Y,Z) WB_DEBUG_DUMP(DebugLevel_ERROR, X,Y,Z)
497 
498 
499 
500 
501 #ifdef __cplusplus
502 };
503 #endif // __cplusplus
504 
505 #endif // _DEBUG_HELPER_H_INCLUDED_
506 
507 
#define WB_LIKELY(x)
optimization for code branching when condition is 'likely'. use within conditionals
int WB_INT32
Platform abstract 32-bit integer.
DebugLevel
Debug level enumeration.
Definition: debug_helper.h:93
static __inline__ int WBCheckDebugLevel(WB_UINT64 dwLevel)
Check specified debug level against the value returned by WBGetDebugLevel() and return non-zero for a...
Definition: debug_helper.h:300
void void WBDebugDump(const char *szTitle, void *pData, int cbData)
conditionally dumps binary data to debug message output
unsigned long long WB_UINT64
Platform abstract unsigned 64-bit integer.
void WBSetDebugLevel(unsigned int iLevel)
set debug level
void WBDebugDumpEvent(XEvent *pEvent)
dumps the contents of an XEvent
void WBDebugDumpGC(Display *pDisplay, WBGC hGC)
dumps a GC's settings
struct s_WBGC * WBGC
internal wrapper struct for GC with local cache
void WBDebugPrint(const char *pFmt,...) __attribute__((format(printf
conditional debug message output
Definition file for platform-specific utility functions.
internal wrapper struct for GC with local cache
void WBDebugDumpRegion(Region hRgn, int bRotate)
dumps contents of a region
#define WB_UNLIKELY(x)
optimization for code branching when condition is 'unlikely'. use within conditionals
static __inline__ WB_UINT64 WBGetDebugLevel(void)
Returns the current debug level assigned by WBSetDebugLevel.
Definition: debug_helper.h:185