File indexing completed on 2024-05-19 04:25:03
0001 /* 0002 * SPDX-FileCopyrightText: 2013 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef __KIS_ASSERT_H 0008 #define __KIS_ASSERT_H 0009 0010 #include <QtGlobal> 0011 #include <kritaglobal_export.h> 0012 0013 KRITAGLOBAL_EXPORT void kis_assert_exception(const char *assertion, const char *file, int line); 0014 KRITAGLOBAL_EXPORT void kis_assert_recoverable(const char *assertion, const char *file, int line); 0015 KRITAGLOBAL_EXPORT void kis_assert_x_exception(const char *assertion, const char *where, const char *what, const char *file, int line); 0016 0017 KRITAGLOBAL_EXPORT void kis_safe_assert_recoverable(const char *assertion, const char *file, int line); 0018 0019 // NOLINTBEGIN(cppcoreguidelines-macro-usage, readability-simplify-boolean-expr) 0020 0021 /** 0022 * KIS_ASSERT family of macros allows the user to choose whether to 0023 * try to continue working in Krita or to abort an application and see 0024 * a backtrace. 0025 * 0026 * Note, the macro are present in Release mode by default! 0027 */ 0028 0029 /** 0030 * Checks the condition and depending on the user action either aborts 0031 * the program or throws an exception, which restarts event loop. 0032 */ 0033 #define KIS_ASSERT(cond) ((!(cond)) ? kis_assert_exception(#cond,__FILE__,__LINE__) : qt_noop()) 0034 0035 /** 0036 * Same as KIS_ASSERT, but allows to show more text to the user. 0037 * 0038 * \see KIS_ASSERT 0039 */ 0040 #define KIS_ASSERT_X(cond, where, what) ((!(cond)) ? kis_assert_x_exception(#cond,where, what,__FILE__,__LINE__) : qt_noop()) 0041 0042 0043 /** 0044 * This is a recoverable variant of KIS_ASSERT. It doesn't throw any 0045 * exceptions. It checks the condition, and either aborts the 0046 * application, or executes user-supplied code. The typical usecase is 0047 * the following: 0048 * 0049 * int fooBar = ...; 0050 * KIS_ASSERT_RECOVER (fooBar > 0) { 0051 * // the code which is executed in a case of emergency 0052 * } 0053 * 0054 */ 0055 #define KIS_ASSERT_RECOVER(cond) if (!(cond) && (kis_assert_recoverable(#cond,__FILE__,__LINE__), true)) 0056 0057 /** 0058 * Equivalent of the following: 0059 * 0060 * KIS_ASSERT_RECOVER(cond) { 0061 * break; 0062 * } 0063 * 0064 */ 0065 #define KIS_ASSERT_RECOVER_BREAK(cond) KIS_ASSERT_RECOVER(cond) { break; } 0066 0067 /** 0068 * Equivalent of the following: 0069 * 0070 * KIS_ASSERT_RECOVER(cond) { 0071 * return; 0072 * } 0073 * 0074 */ 0075 #define KIS_ASSERT_RECOVER_RETURN(cond) do { KIS_ASSERT_RECOVER(cond) { return; } } while (0) 0076 0077 /** 0078 * Equivalent of the following: 0079 * 0080 * KIS_ASSERT_RECOVER(cond) { 0081 * return val; 0082 * } 0083 * 0084 */ 0085 #define KIS_ASSERT_RECOVER_RETURN_VALUE(cond, val) do { KIS_ASSERT_RECOVER(cond) { return (val); } } while (0) 0086 0087 /** 0088 * Does nothing in case of a failure. Just continues execution. 0089 * 0090 * Equivalent of the following: 0091 * 0092 * KIS_ASSERT_RECOVER(cond) { 0093 * qt_noop(); 0094 * } 0095 * 0096 */ 0097 #define KIS_ASSERT_RECOVER_NOOP(cond) do { KIS_ASSERT_RECOVER(cond) { qt_noop(); } } while (0) 0098 0099 0100 /** 0101 * This set of macros work in exactly the same way as their non-safe 0102 * counterparts, but they are automatically converted into console 0103 * warnings in release builds. That is the user will not see any 0104 * message box, just a warning message will be printed in a terminal 0105 * and a recovery branch will be taken automatically. 0106 * 0107 * Rules when to use "safe" asserts. Use them if the following 0108 * conditions are met: 0109 * 0110 * 1) The condition in the assert shows that a real *bug* has 0111 * happened. It is not just a warning. It is a bug that should be 0112 * fixed. 0113 * 0114 * 2) The recovery branch will *workaround* the bug and the user will 0115 * be able to continue his work *as if nothing has 0116 * happened*. Again, please mark the assert "safe" if and only if 0117 * you are 100% sure Krita will not crash in a minute after you 0118 * faced that bug. The user is not notified about this bug, so he 0119 * is not going to take any emergency steps like saving his work 0120 * and restarting Krita! 0121 * 0122 * 3) If you think that Krita should be better restarted after this 0123 * bug, please use a usual KIS_ASSERT_RECOVER. 0124 */ 0125 0126 #define KIS_SAFE_ASSERT_RECOVER(cond) if (!(cond) && (kis_safe_assert_recoverable(#cond,__FILE__,__LINE__), true)) 0127 #define KIS_SAFE_ASSERT_RECOVER_BREAK(cond) KIS_SAFE_ASSERT_RECOVER(cond) { break; } 0128 #define KIS_SAFE_ASSERT_RECOVER_RETURN(cond) do { KIS_SAFE_ASSERT_RECOVER(cond) { return; } } while (0) 0129 #define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val) do { KIS_SAFE_ASSERT_RECOVER(cond) { return (val); } } while (0) 0130 #define KIS_SAFE_ASSERT_RECOVER_NOOP(cond) do { KIS_SAFE_ASSERT_RECOVER(cond) { qt_noop(); } } while (0) 0131 0132 // NOLINTEND(cppcoreguidelines-macro-usage, readability-simplify-boolean-expr) 0133 0134 #endif /* __KIS_ASSERT_H */