orx  1.14
Portable Game Engine
orxDebug.h
Go to the documentation of this file.
1 /* Orx - Portable Game Engine
2  *
3  * Copyright (c) 2008-2022 Orx-Project
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  *
18  * 2. Altered source versions must be plainly marked as such, and must not be
19  * misrepresented as being the original software.
20  *
21  * 3. This notice may not be removed or altered from any source
22  * distribution.
23  */
24 
45 #ifndef _orxDEBUG_H_
46 #define _orxDEBUG_H_
47 
48 #include "orxInclude.h"
49 
50 
51 /* *** orxDEBUG flags *** */
52 
53 #define orxDEBUG_KU32_STATIC_FLAG_NONE 0x00000000
54 
55 #define orxDEBUG_KU32_STATIC_FLAG_TIMESTAMP 0x00000001
56 #define orxDEBUG_KU32_STATIC_FLAG_FULL_TIMESTAMP 0x00000002
57 #define orxDEBUG_KU32_STATIC_FLAG_TYPE 0x00000004
58 #define orxDEBUG_KU32_STATIC_FLAG_TAGGED 0x00000008
59 
60 #define orxDEBUG_KU32_STATIC_FLAG_FILE 0x00000010
61 #define orxDEBUG_KU32_STATIC_FLAG_TERMINAL 0x00000020
62 #define orxDEBUG_KU32_STATIC_FLAG_CONSOLE 0x00000040
63 #define orxDEBUG_KU32_STATIC_FLAG_CALLBACK 0x00000080
64 
65 #define orxDEBUG_KU32_STATIC_MASK_DEFAULT 0x000000F5
66 
67 #define orxDEBUG_KU32_STATIC_MASK_DEBUG 0x000000BD
68 
69 #define orxDEBUG_KU32_STATIC_MASK_USER_ALL 0x0FFFFFFF
70 
71 
72 /* *** Misc *** */
73 
74 #define orxDEBUG_KZ_DEFAULT_DEBUG_FILE "orx-debug.log"
75 #define orxDEBUG_KZ_DEFAULT_LOG_FILE "orx.log"
76 #define orxDEBUG_KZ_DEFAULT_LOG_SUFFIX ".log"
77 #define orxDEBUG_KZ_DEFAULT_DEBUG_SUFFIX "-debug.log"
78 
79 
80 /* Debug levels */
81 typedef enum __orxDEBUG_LEVEL_t
82 {
112 
114 
115  orxDEBUG_LEVEL_ALL = 0xFFFFFFFE,
117  orxDEBUG_LEVEL_NONE = orxENUM_NONE
118 
120 
121 
122 /* Log callback function */
123 typedef orxSTATUS (orxFASTCALL *orxDEBUG_CALLBACK_FUNCTION)(orxDEBUG_LEVEL _eLevel, const orxSTRING _zFunction, const orxSTRING _zFile, orxU32 _u32Line, const orxSTRING _zLog);
124 
125 
126 /* *** Debug Macros *** */
127 
128 /* Log message, compiler specific */
129 #if defined(__orxGCC__) || defined(__orxLLVM__)
130 
131  #define orxLOG(STRING, ...) \
132  do \
133  { \
134  _orxDebug_Log(orxDEBUG_LEVEL_LOG, (const orxSTRING)__FUNCTION__, __FILE__, __LINE__, STRING, ##__VA_ARGS__); \
135  } while(orxFALSE)
136 
137  #define orxLOG_TERMINAL(STRING, ...) \
138  do \
139  { \
140  orxU32 u32DebugFlags; \
141  u32DebugFlags = _orxDebug_GetFlags(); \
142  _orxDebug_SetFlags(orxDEBUG_KU32_STATIC_FLAG_TERMINAL, \
143  orxDEBUG_KU32_STATIC_FLAG_FILE \
144  |orxDEBUG_KU32_STATIC_FLAG_CONSOLE); \
145  _orxDebug_Log(orxDEBUG_LEVEL_LOG, (const orxSTRING)__FUNCTION__, __FILE__, __LINE__, STRING, ##__VA_ARGS__); \
146  _orxDebug_SetFlags(u32DebugFlags, orxDEBUG_KU32_STATIC_MASK_USER_ALL); \
147  } while(orxFALSE)
148 
149  #define orxLOG_FILE(STRING, ...) \
150  do \
151  { \
152  orxU32 u32DebugFlags; \
153  u32DebugFlags = _orxDebug_GetFlags(); \
154  _orxDebug_SetFlags(orxDEBUG_KU32_STATIC_FLAG_FILE, \
155  orxDEBUG_KU32_STATIC_FLAG_CONSOLE \
156  |orxDEBUG_KU32_STATIC_FLAG_TERMINAL); \
157  _orxDebug_Log(orxDEBUG_LEVEL_LOG, (const orxSTRING)__FUNCTION__, __FILE__, __LINE__, STRING, ##__VA_ARGS__); \
158  _orxDebug_SetFlags(u32DebugFlags, orxDEBUG_KU32_STATIC_MASK_USER_ALL); \
159  } while(orxFALSE)
160 
161  #define orxLOG_CONSOLE(STRING, ...) \
162  do \
163  { \
164  orxU32 u32DebugFlags; \
165  u32DebugFlags = _orxDebug_GetFlags(); \
166  _orxDebug_SetFlags(orxDEBUG_KU32_STATIC_FLAG_CONSOLE, \
167  orxDEBUG_KU32_STATIC_FLAG_FILE \
168  |orxDEBUG_KU32_STATIC_FLAG_TERMINAL); \
169  _orxDebug_Log(orxDEBUG_LEVEL_LOG, (const orxSTRING)__FUNCTION__, __FILE__, __LINE__, STRING, ##__VA_ARGS__); \
170  _orxDebug_SetFlags(u32DebugFlags, orxDEBUG_KU32_STATIC_MASK_USER_ALL); \
171  } while(orxFALSE)
172 
173 #else /* __orxGCC__ || __orxLLVM__ */
174  #ifdef __orxMSVC__
175 
176  #define orxLOG(STRING, ...) \
177  do \
178  { \
179  _orxDebug_Log(orxDEBUG_LEVEL_LOG, (const orxSTRING)__FUNCTION__, __FILE__, __LINE__, STRING, __VA_ARGS__); \
180  } while(orxFALSE)
181 
182  #define orxLOG_TERMINAL(STRING, ...) \
183  do \
184  { \
185  orxU32 u32DebugFlags; \
186  u32DebugFlags = _orxDebug_GetFlags(); \
187  _orxDebug_SetFlags(orxDEBUG_KU32_STATIC_FLAG_TERMINAL, \
188  orxDEBUG_KU32_STATIC_FLAG_FILE \
189  |orxDEBUG_KU32_STATIC_FLAG_CONSOLE); \
190  _orxDebug_Log(orxDEBUG_LEVEL_LOG, (const orxSTRING)__FUNCTION__, __FILE__, __LINE__, STRING, __VA_ARGS__); \
191  _orxDebug_SetFlags(u32DebugFlags, orxDEBUG_KU32_STATIC_MASK_USER_ALL); \
192  } while(orxFALSE)
193 
194  #define orxLOG_FILE(STRING, ...) \
195  do \
196  { \
197  orxU32 u32DebugFlags; \
198  u32DebugFlags = _orxDebug_GetFlags(); \
199  _orxDebug_SetFlags(orxDEBUG_KU32_STATIC_FLAG_FILE, \
200  orxDEBUG_KU32_STATIC_FLAG_CONSOLE \
201  |orxDEBUG_KU32_STATIC_FLAG_TERMINAL); \
202  _orxDebug_Log(orxDEBUG_LEVEL_LOG, (const orxSTRING)__FUNCTION__, __FILE__, __LINE__, STRING, __VA_ARGS__); \
203  _orxDebug_SetFlags(u32DebugFlags, orxDEBUG_KU32_STATIC_MASK_USER_ALL); \
204  } while(orxFALSE)
205 
206  #define orxLOG_CONSOLE(STRING, ...) \
207  do \
208  { \
209  orxU32 u32DebugFlags; \
210  u32DebugFlags = _orxDebug_GetFlags(); \
211  _orxDebug_SetFlags(orxDEBUG_KU32_STATIC_FLAG_CONSOLE, \
212  orxDEBUG_KU32_STATIC_FLAG_FILE \
213  |orxDEBUG_KU32_STATIC_FLAG_TERMINAL); \
214  _orxDebug_Log(orxDEBUG_LEVEL_LOG, (const orxSTRING)__FUNCTION__, __FILE__, __LINE__, STRING, __VA_ARGS__); \
215  _orxDebug_SetFlags(u32DebugFlags, orxDEBUG_KU32_STATIC_MASK_USER_ALL); \
216  } while(orxFALSE)
217 
218  #endif /* __orxMSVC__ */
219 #endif /* __orcGCC__ || __orxLLVM__ */
220 
221 #define orxDEBUG_INIT() \
222 do \
223 { \
224  orxU32 u32DebugFlags; \
225  _orxDebug_Init(); \
226  u32DebugFlags = _orxDebug_GetFlags(); \
227  _orxDebug_SetFlags(orxDEBUG_KU32_STATIC_MASK_DEBUG, orxDEBUG_KU32_STATIC_MASK_USER_ALL); \
228  if(orxSystem_GetVersionNumeric() < __orxVERSION__) \
229  { \
230  orxLOG("The version of the runtime library [" orxANSI_KZ_COLOR_FG_GREEN "%s" \
231  orxANSI_KZ_COLOR_FG_DEFAULT "] is " orxANSI_KZ_COLOR_FG_RED orxANSI_KZ_COLOR_BLINK_ON "older" \
232  orxANSI_KZ_COLOR_FG_DEFAULT orxANSI_KZ_COLOR_BLINK_OFF " than the version used when compiling this program [" \
233  orxANSI_KZ_COLOR_FG_GREEN "%s" orxANSI_KZ_COLOR_FG_DEFAULT "]." \
234  orxANSI_KZ_COLOR_FG_RED orxANSI_KZ_COLOR_BLINK_ON " Problems will likely ensue!", \
235  orxSystem_GetVersionFullString(), __orxVERSION_FULL_STRING__); \
236  } \
237  else if(orxSystem_GetVersionNumeric() > __orxVERSION__) \
238  { \
239  orxLOG("The version of the runtime library [" orxANSI_KZ_COLOR_FG_GREEN "%s" \
240  orxANSI_KZ_COLOR_FG_DEFAULT "] is " orxANSI_KZ_COLOR_FG_YELLOW orxANSI_KZ_COLOR_BLINK_ON "more recent" \
241  orxANSI_KZ_COLOR_FG_DEFAULT orxANSI_KZ_COLOR_BLINK_OFF " than the version used when compiling this program [" \
242  orxANSI_KZ_COLOR_FG_GREEN "%s" orxANSI_KZ_COLOR_FG_DEFAULT "]." \
243  orxANSI_KZ_COLOR_FG_YELLOW orxANSI_KZ_COLOR_BLINK_ON " Problems may arise due to possible incompatibilities!",\
244  orxSystem_GetVersionFullString(), __orxVERSION_FULL_STRING__); \
245  } \
246  _orxDebug_SetFlags(u32DebugFlags, orxDEBUG_KU32_STATIC_MASK_USER_ALL); \
247 } \
248 while(orxFALSE)
249 #define orxDEBUG_EXIT() _orxDebug_Exit()
250 
251 #ifdef __orxDEBUG__
252 
253  /* Debug print, compiler specific */
254  #if defined(__orxGCC__) || defined(__orxLLVM__)
255  #define orxDEBUG_PRINT(LEVEL, STRING, ...) \
256  do \
257  { \
258  orxU32 u32DebugFlags; \
259  u32DebugFlags = _orxDebug_GetFlags(); \
260  _orxDebug_SetFlags(orxDEBUG_KU32_STATIC_MASK_DEBUG, orxDEBUG_KU32_STATIC_MASK_USER_ALL); \
261  _orxDebug_Log(LEVEL, (const orxSTRING)__FUNCTION__, __FILE__, __LINE__, STRING, ##__VA_ARGS__); \
262  _orxDebug_SetFlags(u32DebugFlags, orxDEBUG_KU32_STATIC_MASK_USER_ALL); \
263  } while(orxFALSE)
264  #else /* __orxGCC__ || __orxLLVM__ */
265  #ifdef __orxMSVC__
266  #define orxDEBUG_PRINT(LEVEL, STRING, ...) \
267  do \
268  { \
269  orxU32 u32DebugFlags; \
270  u32DebugFlags = _orxDebug_GetFlags(); \
271  _orxDebug_SetFlags(orxDEBUG_KU32_STATIC_MASK_DEBUG, orxDEBUG_KU32_STATIC_MASK_USER_ALL); \
272  _orxDebug_Log(LEVEL, (const orxSTRING)__FUNCTION__, __FILE__, __LINE__, STRING, __VA_ARGS__); \
273  _orxDebug_SetFlags(u32DebugFlags, orxDEBUG_KU32_STATIC_MASK_USER_ALL); \
274  } while(orxFALSE)
275  #endif /* __orxMSVC__ */
276  #endif /* __orcGCC__ || __orxLLVM__ */
277 
278  /* End platform specific */
279 
280  #define orxDEBUG_ENABLE_LEVEL(LEVEL, ENABLE)_orxDebug_EnableLevel(LEVEL, ENABLE)
281  #define orxDEBUG_IS_LEVEL_ENABLED(LEVEL) _orxDebug_IsLevelEnabled(LEVEL)
282 
283  #define orxDEBUG_SET_FLAGS(SET, UNSET) _orxDebug_SetFlags(SET, UNSET)
284  #define orxDEBUG_GET_FLAGS() _orxDebug_GetFlags()
285 
286  #define orxDEBUG_SET_LOG_CALLBACK(CALLBACK) _orxDebug_SetLogCallback(CALLBACK)
287 
288  /* Break */
289  #define orxBREAK() _orxDebug_Break()
290 
291  /* Files */
292  #define orxDEBUG_SETDEBUGFILE(FILE) _orxDebug_SetDebugFile(FILE)
293  #define orxDEBUG_SETLOGFILE(FILE) _orxDebug_SetLogFile(FILE)
294  #define orxDEBUG_SETBASEFILENAME(FILE) \
295  do \
296  { \
297  if((FILE != orxNULL) && (FILE != orxSTRING_EMPTY)) \
298  { \
299  orxCHAR zBuffer[512]; \
300  zBuffer[511] = orxCHAR_NULL; \
301  /* The redundant check is a workaround for some buggy compilers that don't realize FILE is not null here */ \
302  strncpy(zBuffer, FILE ? FILE : orxSTRING_EMPTY, 256); \
303  strncat(zBuffer, orxDEBUG_KZ_DEFAULT_DEBUG_SUFFIX, 255); \
304  _orxDebug_SetDebugFile(zBuffer); \
305  /* The redundant check is a workaround for some buggy compilers that don't realize FILE is not null here */ \
306  strncpy(zBuffer, FILE ? FILE : orxSTRING_EMPTY, 256); \
307  strncat(zBuffer, orxDEBUG_KZ_DEFAULT_LOG_SUFFIX, 255); \
308  _orxDebug_SetLogFile(zBuffer); \
309  } \
310  else \
311  { \
312  _orxDebug_SetDebugFile(FILE); \
313  _orxDebug_SetLogFile(FILE); \
314  } \
315  } while(orxFALSE)
316 
317  /* Assert */
318  #if defined(__orxGCC__) || defined(__orxLLVM__)
319  #define orxASSERT(TEST, ...) \
320  if(!(TEST)) \
321  { \
322  orxDEBUG_PRINT(orxDEBUG_LEVEL_ASSERT, orxANSI_KZ_COLOR_BG_RED orxANSI_KZ_COLOR_FG_WHITE orxANSI_KZ_COLOR_BLINK_ON "FAILED ASSERTION [" #TEST "]", ##__VA_ARGS__); \
323  orxBREAK(); \
324  }
325  #else /* __orxGCC__ || __orxLLVM__ */
326  #ifdef __orxMSVC__
327  #define orxASSERT(TEST, ...) \
328  if(!(TEST)) \
329  { \
330  orxDEBUG_PRINT(orxDEBUG_LEVEL_ASSERT, orxANSI_KZ_COLOR_BG_RED orxANSI_KZ_COLOR_FG_WHITE orxANSI_KZ_COLOR_BLINK_ON "FAILED ASSERTION [" #TEST "]", __VA_ARGS__); \
331  orxBREAK(); \
332  }
333  #endif /* __orxMSVC__ */
334  #endif /* __orcGCC__ || __orxLLVM__ */
335 
336 #else /* __orxDEBUG__ */
337 
338  #define orxDEBUG_PRINT(LEVEL, STRING, ...)
339 
340  #define orxDEBUG_ENABLE_LEVEL(LEVEL, ENABLE)_orxDebug_EnableLevel(LEVEL, ENABLE)
341  #define orxDEBUG_IS_LEVEL_ENABLED(LEVEL) _orxDebug_IsLevelEnabled(LEVEL)
342 
343  #define orxDEBUG_SET_FLAGS(SET, UNSET) _orxDebug_SetFlags(SET, UNSET)
344  #define orxDEBUG_GET_FLAGS() _orxDebug_GetFlags()
345 
346  #define orxDEBUG_SET_LOG_CALLBACK(CALLBACK) _orxDebug_SetLogCallback(CALLBACK)
347 
348  /* Break */
349  #define orxBREAK()
350 
351  /* File */
352  #define orxDEBUG_SETDEBUGFILE(FILE)
353  #define orxDEBUG_SETLOGFILE(FILE) _orxDebug_SetLogFile(FILE)
354  #define orxDEBUG_SETBASEFILENAME(FILE) \
355  do \
356  { \
357  if((FILE != orxNULL) && (FILE != orxSTRING_EMPTY)) \
358  { \
359  orxCHAR zBuffer[512]; \
360  zBuffer[511] = orxCHAR_NULL; \
361  /* The redundant check is a workaround for some buggy compilers that don't realize FILE is not null here */ \
362  strncpy(zBuffer, FILE ? FILE : orxSTRING_EMPTY, 256); \
363  strncat(zBuffer, orxDEBUG_KZ_DEFAULT_LOG_SUFFIX, 255); \
364  _orxDebug_SetLogFile(zBuffer); \
365  } \
366  else \
367  { \
368  _orxDebug_SetLogFile(FILE); \
369  } \
370  } while(orxFALSE)
371 
372  #define orxASSERT(TEST, ...)
373 
374 #endif /* __orxDEBUG__ */
375 
376 
377 
378 /*****************************************************************************/
379 
380 /* *** Debug defines. *** */
381 
382 #define orxDEBUG_KS32_BUFFER_OUTPUT_SIZE 2048
383 
384 #define orxDEBUG_KZ_DATE_FORMAT orxANSI_KZ_COLOR_FG_CYAN "[%H:%M:%S]" orxANSI_KZ_COLOR_RESET
385 #define orxDEBUG_KZ_DATE_FULL_FORMAT orxANSI_KZ_COLOR_FG_CYAN "[%Y-%m-%d %H:%M:%S]" orxANSI_KZ_COLOR_RESET
386 
387 #define orxDEBUG_KZ_TYPE_LOG_FORMAT orxANSI_KZ_COLOR_FG_GREEN "[%s]" orxANSI_KZ_COLOR_RESET
388 #define orxDEBUG_KZ_TYPE_WARNING_FORMAT orxANSI_KZ_COLOR_FG_YELLOW "[%s]" orxANSI_KZ_COLOR_RESET
389 #define orxDEBUG_KZ_TYPE_ERROR_FORMAT orxANSI_KZ_COLOR_FG_RED "[%s]" orxANSI_KZ_COLOR_RESET
390 
391 #define orxDEBUG_KZ_FILE_FORMAT orxANSI_KZ_COLOR_FG_MAGENTA "[%s:%s(%u)]" orxANSI_KZ_COLOR_RESET
392 
393 
394 /*****************************************************************************/
395 
396 /* *** Functions *** */
397 
401 extern orxDLLAPI orxSTATUS orxFASTCALL _orxDebug_Init();
402 
404 extern orxDLLAPI void orxFASTCALL _orxDebug_Exit();
405 
413 extern orxDLLAPI void orxCDECL _orxDebug_Log(orxDEBUG_LEVEL _eLevel, const orxSTRING _zFunction, const orxSTRING _zFile, orxU32 _u32Line, const orxSTRING _zFormat, ...);
414 
419 extern orxDLLAPI void orxFASTCALL _orxDebug_EnableLevel(orxDEBUG_LEVEL _eLevel, orxBOOL _bEnable);
420 
424 extern orxDLLAPI orxBOOL orxFASTCALL _orxDebug_IsLevelEnabled(orxDEBUG_LEVEL _eLevel);
425 
430 extern orxDLLAPI void orxFASTCALL _orxDebug_SetFlags(orxU32 _u32Add, orxU32 _u32Remove);
431 
435 extern orxDLLAPI orxU32 orxFASTCALL _orxDebug_GetFlags();
436 
438 extern orxDLLAPI void orxFASTCALL _orxDebug_Break();
439 
443 extern orxDLLAPI void orxFASTCALL _orxDebug_SetDebugFile(const orxSTRING _zFileName);
444 
448 extern orxDLLAPI void orxFASTCALL _orxDebug_SetLogFile(const orxSTRING _zFileName);
449 
453 extern orxDLLAPI void orxFASTCALL _orxDebug_SetLogCallback(const orxDEBUG_CALLBACK_FUNCTION _pfnLogCallback);
454 
455 #endif /* __orxDEBUG_H_ */
456 
orxDLLAPI void orxFASTCALL _orxDebug_SetDebugFile(const orxSTRING _zFileName)
orxSTATUS(orxFASTCALL * orxDEBUG_CALLBACK_FUNCTION)(orxDEBUG_LEVEL _eLevel, const orxSTRING _zFunction, const orxSTRING _zFile, orxU32 _u32Line, const orxSTRING _zLog)
Definition: orxDebug.h:123
orxDLLAPI void orxFASTCALL _orxDebug_EnableLevel(orxDEBUG_LEVEL _eLevel, orxBOOL _bEnable)
orxDLLAPI void orxFASTCALL _orxDebug_SetLogCallback(const orxDEBUG_CALLBACK_FUNCTION _pfnLogCallback)
orxDLLAPI void orxFASTCALL _orxDebug_SetLogFile(const orxSTRING _zFileName)
orxDLLAPI void orxCDECL _orxDebug_Log(orxDEBUG_LEVEL _eLevel, const orxSTRING _zFunction, const orxSTRING _zFile, orxU32 _u32Line, const orxSTRING _zFormat,...)
orxDLLAPI void orxFASTCALL _orxDebug_Break()
orxDLLAPI orxBOOL orxFASTCALL _orxDebug_IsLevelEnabled(orxDEBUG_LEVEL _eLevel)
orxDLLAPI void orxFASTCALL _orxDebug_Exit()
orxSTATUS
Definition: orxType.h:256
orxDLLAPI orxSTATUS orxFASTCALL _orxDebug_Init()
orxDLLAPI orxU32 orxFASTCALL _orxDebug_GetFlags()
#define orxDLLAPI
Definition: orxDecl.h:370
orxDLLAPI void orxFASTCALL _orxDebug_SetFlags(orxU32 _u32Add, orxU32 _u32Remove)
orxDEBUG_LEVEL
Definition: orxDebug.h:81

Generated for orx by doxygen 1.8.11