1/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2/* If you are missing that file, acquire a complete release at teeworlds.com. */
3
4#ifndef BASE_DBG_H
5#define BASE_DBG_H
6
7#include <functional>
8
9/**
10 * Utilities for debugging.
11 *
12 * @defgroup Debug Debugging
13 */
14
15/**
16 * Breaks into the debugger based on a test.
17 *
18 * @ingroup Debug
19 *
20 * @param test Result of the test.
21 * @param fmt A printf styled format message that should be printed if the test fails.
22 *
23 * @remark Also works in release mode.
24 *
25 * @see dbg_break
26 */
27#define dbg_assert(test, fmt, ...) \
28 do \
29 { \
30 if(!(test)) \
31 { \
32 dbg_assert_imp(__FILE__, __LINE__, fmt, ##__VA_ARGS__); \
33 } \
34 } while(false)
35
36/**
37 * Breaks into the debugger with a message.
38 *
39 * @ingroup Debug
40 * @param fmt A printf styled format message that should be printed in case the
41 * code is reached.
42 *
43 * @remark Also works in release mode.
44 *
45 * @see dbg_break
46 */
47#define dbg_assert_failed(fmt, ...) dbg_assert_imp(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
48
49/**
50 * Use the @link dbg_assert @endlink function instead!
51 *
52 * This is also used from Rust, if you modify the signature, also look into
53 * src/base/dbg.rs.
54 *
55 * @ingroup Debug
56 *
57 * @see dbg_assert
58 */
59extern "C" [[gnu::format(printf, 3, 4)]] [[noreturn]] void
60dbg_assert_imp(const char *filename, int line, const char *fmt, ...);
61
62/**
63 * Checks whether the program is currently shutting down due to a failed
64 * assert.
65 *
66 * @ingroup Debug
67 *
68 * @return indication whether the program is currently shutting down due to a
69 * failed assert.
70 *
71 * @see dbg_assert
72 */
73bool dbg_assert_has_failed();
74
75/**
76 * Breaks into the debugger.
77 *
78 * @ingroup Debug
79 *
80 * @remark Also works in release mode.
81 *
82 * @see dbg_assert
83 */
84[[noreturn]] void dbg_break();
85
86/**
87 * Callback function type for @link dbg_assert_set_handler @endlink.
88 *
89 * @ingroup Debug
90 *
91 * @param message The message that a @link dbg_assert @endlink is failing with.
92 *
93 * @see dbg_assert_set_handler
94 */
95typedef std::function<void(const char *message)> DBG_ASSERT_HANDLER;
96
97/**
98 * Sets a callback function that will be invoked before breaking into the
99 * debugger in @link dbg_assert @endlink.
100 *
101 * @ingroup Debug
102 *
103 * @remark Also works in release mode.
104 *
105 * @see dbg_assert
106 */
107void dbg_assert_set_handler(DBG_ASSERT_HANDLER handler);
108
109/**
110 * Prints a debug message.
111 *
112 * @ingroup Debug
113 *
114 * @param sys A string that describes what system the message belongs to.
115 * @param fmt A printf styled format string.
116 *
117 * @remark Also works in release mode.
118 *
119 * @deprecated Use `log_*` functions with appropriate severity instead.
120 */
121[[gnu::format(printf, 2, 3)]] void dbg_msg(const char *sys, const char *fmt, ...);
122
123#endif
124