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