1 /*         ______   ___    ___
2  *        /\  _  \ /\_ \  /\_ \
3  *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
4  *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
5  *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
6  *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7  *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8  *                                           /\____/
9  *                                           \_/__/
10  *
11  *      Debug facilities.
12  *
13  *      By Shawn Hargreaves.
14  *
15  *      See readme.txt for copyright information.
16  */
17 
18 
19 #ifndef __al_included_allegro5_debug_h
20 #define __al_included_allegro5_debug_h
21 
22 #include <assert.h>
23 #include "allegro5/base.h"
24 
25 #ifdef __cplusplus
26    extern "C" {
27 #endif
28 
29 AL_FUNC(bool, _al_trace_prefix, (char const *channel, int level,
30    char const *file, int line, char const *function));
31 
32 AL_PRINTFUNC(void, _al_trace_suffix, (const char *msg, ...), 1, 2);
33 
34 #if defined(DEBUGMODE) || defined(ALLEGRO_CFG_RELEASE_LOGGING)
35    /* Must not be used with a trailing semicolon. */
36    #ifdef ALLEGRO_GCC
37       #define ALLEGRO_DEBUG_CHANNEL(x) \
38          static char const *__al_debug_channel __attribute__((unused)) = x;
39    #else
40       #define ALLEGRO_DEBUG_CHANNEL(x) \
41          static char const *__al_debug_channel = x;
42    #endif
43    #define ALLEGRO_TRACE_CHANNEL_LEVEL(channel, level)                        \
44       !_al_trace_prefix(channel, level, __FILE__, __LINE__, __func__)         \
45       ? (void)0 : _al_trace_suffix
46 #else
47    #define ALLEGRO_TRACE_CHANNEL_LEVEL(channel, x)  1 ? (void) 0 : _al_trace_suffix
48    #define ALLEGRO_DEBUG_CHANNEL(x)
49 #endif
50 
51 #define ALLEGRO_TRACE_LEVEL(x)   ALLEGRO_TRACE_CHANNEL_LEVEL(__al_debug_channel, x)
52 #define ALLEGRO_DEBUG            ALLEGRO_TRACE_LEVEL(0)
53 #define ALLEGRO_INFO             ALLEGRO_TRACE_LEVEL(1)
54 #define ALLEGRO_WARN             ALLEGRO_TRACE_LEVEL(2)
55 #define ALLEGRO_ERROR            ALLEGRO_TRACE_LEVEL(3)
56 
57 /* Run-time assertions. */
58 AL_FUNCPTR(void, _al_user_assert_handler, (char const *expr, char const *file,
59    int line, char const *func));
60 
61 AL_FUNC(void, al_register_assert_handler, (void (*handler)(char const *expr,
62    char const *file, int line, char const *func)));
63 
64 AL_FUNC(void, al_register_trace_handler, (void (*handler)(char const *)));
65 
66 #ifdef __clang_analyzer__
67    /* Clang doesn't understand _al_user_assert_handler, so we simplify the
68     * definition for analysis purposes. */
69    #define ALLEGRO_ASSERT(e) assert(e)
70 #else
71    #ifdef NDEBUG
72       #define ALLEGRO_ASSERT(e)	((void)(0 && (e)))
73    #else
74       #define ALLEGRO_ASSERT(e)                                                  \
75          ((e) ? (void) 0                                                         \
76          : (_al_user_assert_handler) ?                                           \
77             _al_user_assert_handler(#e, __FILE__, __LINE__, __func__)            \
78          : assert(e))
79    #endif
80 #endif
81 
82 /* Compile time assertions. */
83 #define ALLEGRO_ASSERT_CONCAT_(a, b)   a##b
84 #define ALLEGRO_ASSERT_CONCAT(a, b)    ALLEGRO_ASSERT_CONCAT_(a, b)
85 #define ALLEGRO_STATIC_ASSERT(module, e) \
86    struct ALLEGRO_ASSERT_CONCAT(static_assert_##module##_line_, __LINE__) \
87       { unsigned int bf : !!(e); }
88 
89 /* We are lazy and use just ASSERT while Allegro itself is compiled. */
90 #ifdef ALLEGRO_LIB_BUILD
91     #define ASSERT(x) ALLEGRO_ASSERT(x)
92 #endif
93 
94 #ifdef __cplusplus
95    }
96 #endif
97 
98 #endif
99 
100 /* vim: set sts=3 sw=3 et: */
101