1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
#pragma once
#include <QtDebug>
static constexpr const char* kDebugAssertPrefix = "DEBUG ASSERT";
inline void mixxx_noop(void) {}
inline void mixxx_debug_assert(const char* assertion, const char* file, int line, const char* function) {
qCritical("%s: \"%s\" in function %s at %s:%d", kDebugAssertPrefix, assertion, function, file, line);
}
inline bool mixxx_maybe_debug_assert_return_true(const char* assertion, const char* file, int line, const char* function) {
#ifdef MIXXX_DEBUG_ASSERTIONS_ENABLED
mixxx_debug_assert(assertion, file, line, function);
#else
Q_UNUSED(assertion);
Q_UNUSED(file);
Q_UNUSED(line);
Q_UNUSED(function);
#endif
return true;
}
inline void mixxx_release_assert(const char* assertion, const char* file, int line, const char* function) {
qFatal("ASSERT: \"%s\" in function %s at %s:%d", assertion, function, file, line);
}
// These macros provide the demangled function name (including helpful template
// type information) and are supported on every version of GCC, Clang, and MSVC
// that Mixxx supports.
#if defined(_MSC_VER)
#define ASSERT_FUNCTION __FUNCSIG__
#else
#define ASSERT_FUNCTION __PRETTY_FUNCTION__
#endif
/// If cond is false, produces a fatal assertion and quits ungracefully. Think
/// very hard before using this -- this should only be for the most dire of
/// situations where we know Mixxx cannot take any action without potentially
/// corrupting user data. Handle errors gracefully whenever possible.
#define RELEASE_ASSERT(cond) ((!(cond)) ? mixxx_release_assert(#cond, __FILE__, __LINE__, ASSERT_FUNCTION) : mixxx_noop())
// Checks that cond is true in debug builds. If cond is false then prints a
// warning message to the console. If Mixxx is built with
// MIXXX_DEBUG_ASSERTIONS_FATAL then the warning message is fatal. Compiles
// to nothing in release builds.
//
// Be careful of the common mistake with assertions:
// DEBUG_ASSERT(doSomething());
//
// In release builds, doSomething() is never called!
#ifdef MIXXX_DEBUG_ASSERTIONS_ENABLED
#define DEBUG_ASSERT(cond) ((!(cond)) ? mixxx_debug_assert(#cond, __FILE__, __LINE__, ASSERT_FUNCTION) : mixxx_noop())
#else
#define DEBUG_ASSERT(cond)
#endif
/// Same as DEBUG_ASSERT, but if MIXXX_DEBUG_ASSERTIONS_FATAL is disabled run the specified fallback function.
/// In most cases you should probably use this rather than DEBUG_ASSERT. Only use DEBUG_ASSERT if there is no appropriate fallback.
#define VERIFY_OR_DEBUG_ASSERT(cond) if ((!(cond)) && mixxx_maybe_debug_assert_return_true(#cond, __FILE__, __LINE__, ASSERT_FUNCTION))
|