publish final code
Fork of Pubnub_c_core by
pubnub_assert.h@3:9cb790d5df10, 2017-02-21 (annotated)
- Committer:
- cswiger
- Date:
- Tue Feb 21 22:23:28 2017 +0000
- Revision:
- 3:9cb790d5df10
- Parent:
- 0:d13755cfb705
Publish final project code
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sveljko | 0:d13755cfb705 | 1 | /* -*- c-file-style:"stroustrup"; indent-tabs-mode: nil -*- */ |
sveljko | 0:d13755cfb705 | 2 | #if !defined INC_PUBNUB_ASSERT |
sveljko | 0:d13755cfb705 | 3 | #define INC_PUBNUB_ASSERT |
sveljko | 0:d13755cfb705 | 4 | |
sveljko | 0:d13755cfb705 | 5 | #include <stdbool.h> |
sveljko | 0:d13755cfb705 | 6 | |
sveljko | 0:d13755cfb705 | 7 | |
sveljko | 0:d13755cfb705 | 8 | /** The Pubnub ASSERT macros. There are several layers: |
sveljko | 0:d13755cfb705 | 9 | - highest (PUBNUB_ASSERT_LEVEL_EX): all checks enabled, |
sveljko | 0:d13755cfb705 | 10 | even the long lasting ones |
sveljko | 0:d13755cfb705 | 11 | - regular (PUBNUB_ASSERT_LEVEL): only the long lasting |
sveljko | 0:d13755cfb705 | 12 | checks are disabled |
sveljko | 0:d13755cfb705 | 13 | - lowest (PUBNUB_ASSERT_LEVEL_OPT): only the checks with |
sveljko | 0:d13755cfb705 | 14 | negligible execution length are enabled |
sveljko | 0:d13755cfb705 | 15 | - none (PUBNUB_ASSERT_LEVEL_NONE): all checks disabled |
sveljko | 0:d13755cfb705 | 16 | |
sveljko | 0:d13755cfb705 | 17 | Define at most one of above mentioned macros before including this |
sveljko | 0:d13755cfb705 | 18 | header. If none is defined, the highest (_EX) level is assumed. |
sveljko | 0:d13755cfb705 | 19 | */ |
sveljko | 0:d13755cfb705 | 20 | |
sveljko | 0:d13755cfb705 | 21 | /* Let's make sure only one of @c PUBNUB_ASSERT_LEVEL_EX, @c |
sveljko | 0:d13755cfb705 | 22 | * PUBNUB_ASSERT_LEVEL, @c PUBNUB_ASSERT_LEVEL_OPT or @c |
sveljko | 0:d13755cfb705 | 23 | * PUBNUB_ASSERT_LEVEL_NONE is defined. |
sveljko | 0:d13755cfb705 | 24 | */ |
sveljko | 0:d13755cfb705 | 25 | |
sveljko | 0:d13755cfb705 | 26 | #if defined(PUBNUB_ASSERT_LEVEL_EX) && ( \ |
sveljko | 0:d13755cfb705 | 27 | defined(PUBNUB_ASSERT_LEVEL) || defined(PUBNUB_ASSERT_LEVEL_OPT) || \ |
sveljko | 0:d13755cfb705 | 28 | defined(PUBNUB_ASSERT_LEVEL_NONE) ) |
sveljko | 0:d13755cfb705 | 29 | #error Cannott define PUBNUB_ASSERT_LEVEL_EX and any lower level (regular, _OPT, _NONE) |
sveljko | 0:d13755cfb705 | 30 | #endif |
sveljko | 0:d13755cfb705 | 31 | |
sveljko | 0:d13755cfb705 | 32 | #if defined(PUBNUB_ASSERT_LEVEL) && ( \ |
sveljko | 0:d13755cfb705 | 33 | defined(PUBNUB_ASSERT_LEVEL_OPT) || defined(PUBNUB_ASSERT_LEVEL_NONE) ) |
sveljko | 0:d13755cfb705 | 34 | #error Cannott define PUBNUB_ASSERT_LEVEL and any lower level (_OPT, _NONE) |
sveljko | 0:d13755cfb705 | 35 | #endif |
sveljko | 0:d13755cfb705 | 36 | |
sveljko | 0:d13755cfb705 | 37 | |
sveljko | 0:d13755cfb705 | 38 | #if defined(PUBNUB_ASSERT_LEVEL_OPT) && defined(PUBNUB_ASSERT_LEVEL_NONE) |
sveljko | 0:d13755cfb705 | 39 | #error Cannott define PUBNUB_ASSERT_LEVEL_OPT and PUBNUB_ASSERT_LEVEL_NONE |
sveljko | 0:d13755cfb705 | 40 | #endif |
sveljko | 0:d13755cfb705 | 41 | |
sveljko | 0:d13755cfb705 | 42 | /* If none of ASSERT level defining macros is defined, let's assume |
sveljko | 0:d13755cfb705 | 43 | * the highest level. |
sveljko | 0:d13755cfb705 | 44 | */ |
sveljko | 0:d13755cfb705 | 45 | |
sveljko | 0:d13755cfb705 | 46 | #if !defined(PUBNUB_ASSERT_LEVEL_EX) && \ |
sveljko | 0:d13755cfb705 | 47 | !defined(PUBNUB_ASSERT_LEVEL) && \ |
sveljko | 0:d13755cfb705 | 48 | !defined(PUBNUB_ASSERT_LEVEL_OPT) && \ |
sveljko | 0:d13755cfb705 | 49 | !defined(PUBNUB_ASSERT_LEVEL_NONE) |
sveljko | 0:d13755cfb705 | 50 | #define PUBNUB_ASSERT_LEVEL_EX |
sveljko | 0:d13755cfb705 | 51 | #endif |
sveljko | 0:d13755cfb705 | 52 | |
sveljko | 0:d13755cfb705 | 53 | #ifdef _MSC_VER |
sveljko | 0:d13755cfb705 | 54 | #define PUBNUB_ANALYSIS_ASSUME(X) __analysis_assume(X) |
sveljko | 0:d13755cfb705 | 55 | #else |
sveljko | 0:d13755cfb705 | 56 | #define PUBNUB_ANALYSIS_ASSUME(X) |
sveljko | 0:d13755cfb705 | 57 | #endif |
sveljko | 0:d13755cfb705 | 58 | |
sveljko | 0:d13755cfb705 | 59 | /** The common ASSERT implementation */ |
sveljko | 0:d13755cfb705 | 60 | #define PUBNUB_ASSERT_IMPL(X) do { \ |
sveljko | 0:d13755cfb705 | 61 | PUBNUB_ANALYSIS_ASSUME(X); \ |
sveljko | 0:d13755cfb705 | 62 | (X) ? (void)0 : pubnub_assert_failed(#X, __FILE__, __LINE__); \ |
sveljko | 0:d13755cfb705 | 63 | } while (false) |
sveljko | 0:d13755cfb705 | 64 | |
sveljko | 0:d13755cfb705 | 65 | /** Should make the compiler not report "unused variable" |
sveljko | 0:d13755cfb705 | 66 | warnings. |
sveljko | 0:d13755cfb705 | 67 | */ |
sveljko | 0:d13755cfb705 | 68 | #define PUBNUB_UNUSED(x) do { (void)sizeof(x); } while (false) |
sveljko | 0:d13755cfb705 | 69 | |
sveljko | 0:d13755cfb705 | 70 | |
sveljko | 0:d13755cfb705 | 71 | /* Define the ASSERT macro for the highest (_EX) level. |
sveljko | 0:d13755cfb705 | 72 | */ |
sveljko | 0:d13755cfb705 | 73 | #if defined PUBNUB_ASSERT_LEVEL_EX |
sveljko | 0:d13755cfb705 | 74 | #define PUBNUB_ASSERT_EX(X) PUBNUB_ASSERT_IMPL(X) |
sveljko | 0:d13755cfb705 | 75 | #else |
sveljko | 0:d13755cfb705 | 76 | #define PUBNUB_ASSERT_EX(X) PUBNUB_UNUSED(X) |
sveljko | 0:d13755cfb705 | 77 | #endif |
sveljko | 0:d13755cfb705 | 78 | |
sveljko | 0:d13755cfb705 | 79 | /* Determine if regular level is to be used. |
sveljko | 0:d13755cfb705 | 80 | */ |
sveljko | 0:d13755cfb705 | 81 | #if defined(PUBNUB_ASSERT_LEVEL_EX) || defined(PUBNUB_ASSERT_LEVEL) |
sveljko | 0:d13755cfb705 | 82 | #define PUBNUB_ASSERT_IS_ACTIVE // also usable directly in client code |
sveljko | 0:d13755cfb705 | 83 | #endif |
sveljko | 0:d13755cfb705 | 84 | |
sveljko | 0:d13755cfb705 | 85 | /* Define the ASSERT macro for the regular level. |
sveljko | 0:d13755cfb705 | 86 | */ |
sveljko | 0:d13755cfb705 | 87 | #if defined(PUBNUB_ASSERT_IS_ACTIVE) |
sveljko | 0:d13755cfb705 | 88 | #define PUBNUB_ASSERT(X) PUBNUB_ASSERT_IMPL(X) |
sveljko | 0:d13755cfb705 | 89 | #else |
sveljko | 0:d13755cfb705 | 90 | #define PUBNUB_ASSERT(X) PUBNUB_UNUSED(X) |
sveljko | 0:d13755cfb705 | 91 | #endif |
sveljko | 0:d13755cfb705 | 92 | |
sveljko | 0:d13755cfb705 | 93 | |
sveljko | 0:d13755cfb705 | 94 | /* Define the ASSERT macro for the lowest level |
sveljko | 0:d13755cfb705 | 95 | */ |
sveljko | 0:d13755cfb705 | 96 | #if !defined(PUBNUB_ASSERT_LEVEL_NONE) |
sveljko | 0:d13755cfb705 | 97 | #define PUBNUB_ASSERT_OPT(X) PUBNUB_ASSERT_IMPL(X) |
sveljko | 0:d13755cfb705 | 98 | #else |
sveljko | 0:d13755cfb705 | 99 | #define PUBNUB_ASSERT_OPT(X) PUBNUB_UNUSED(X) |
sveljko | 0:d13755cfb705 | 100 | #endif |
sveljko | 0:d13755cfb705 | 101 | |
sveljko | 0:d13755cfb705 | 102 | |
sveljko | 0:d13755cfb705 | 103 | |
sveljko | 0:d13755cfb705 | 104 | /** This will invoke the installed assert handler. The default |
sveljko | 0:d13755cfb705 | 105 | behavior is pubnub_assert_handler_abort(). |
sveljko | 0:d13755cfb705 | 106 | */ |
sveljko | 0:d13755cfb705 | 107 | void pubnub_assert_failed(char const *s, char const *file, long line); |
sveljko | 0:d13755cfb705 | 108 | |
sveljko | 0:d13755cfb705 | 109 | /** Prototype of a Pubnub assertion failure handler. There are several |
sveljko | 0:d13755cfb705 | 110 | standard handlers, but you can also provide your own. |
sveljko | 0:d13755cfb705 | 111 | @param s The string that defines the failure condition |
sveljko | 0:d13755cfb705 | 112 | @param file The name of the source file with the condition |
sveljko | 0:d13755cfb705 | 113 | @param line Number of the line of @c file with the condition |
sveljko | 0:d13755cfb705 | 114 | */ |
sveljko | 0:d13755cfb705 | 115 | typedef void (*pubnub_assert_handler_t)(char const *s, char const *file, long line); |
sveljko | 0:d13755cfb705 | 116 | |
sveljko | 0:d13755cfb705 | 117 | /** This will install an assert handler. It can be one of the standard |
sveljko | 0:d13755cfb705 | 118 | ones, or your own. |
sveljko | 0:d13755cfb705 | 119 | |
sveljko | 0:d13755cfb705 | 120 | @param handler The handler to install. If NULL, will install |
sveljko | 0:d13755cfb705 | 121 | pubnub_assert_handler_abort() |
sveljko | 0:d13755cfb705 | 122 | */ |
sveljko | 0:d13755cfb705 | 123 | void pubnub_assert_set_handler(pubnub_assert_handler_t handler); |
sveljko | 0:d13755cfb705 | 124 | |
sveljko | 0:d13755cfb705 | 125 | /** This handler will print a message formed from the parameters and |
sveljko | 0:d13755cfb705 | 126 | then go to infinite loop. Useful for debugging. |
sveljko | 0:d13755cfb705 | 127 | */ |
sveljko | 0:d13755cfb705 | 128 | void pubnub_assert_handler_loop(char const *s, char const *file, long line); |
sveljko | 0:d13755cfb705 | 129 | |
sveljko | 0:d13755cfb705 | 130 | /** This handler will print a message formed from the parameters and |
sveljko | 0:d13755cfb705 | 131 | then abort (exit, end) the process. Useful for testing. |
sveljko | 0:d13755cfb705 | 132 | */ |
sveljko | 0:d13755cfb705 | 133 | void pubnub_assert_handler_abort(char const *s, char const *file, long line); |
sveljko | 0:d13755cfb705 | 134 | |
sveljko | 0:d13755cfb705 | 135 | /** This handler will print a message formed from the parameters and |
sveljko | 0:d13755cfb705 | 136 | that's it. Useful for getting data from a program execution "in |
sveljko | 0:d13755cfb705 | 137 | the field", where we must not stop or crash because of ASSERT |
sveljko | 0:d13755cfb705 | 138 | failure. |
sveljko | 0:d13755cfb705 | 139 | */ |
sveljko | 0:d13755cfb705 | 140 | void pubnub_assert_handler_printf(char const *s, char const *file, long line); |
sveljko | 0:d13755cfb705 | 141 | |
sveljko | 0:d13755cfb705 | 142 | |
sveljko | 0:d13755cfb705 | 143 | #define PUBNUB_CTASTR2(pre,post,lex) pre ## post ## lex |
sveljko | 0:d13755cfb705 | 144 | #define PUBNUB_CTASTR(pre,post,lex) PUBNUB_CTASTR2(pre,post,lex) |
sveljko | 0:d13755cfb705 | 145 | |
sveljko | 0:d13755cfb705 | 146 | #define PUBNUB_STATIC_ASSERT(cond) \ |
sveljko | 0:d13755cfb705 | 147 | typedef struct { int PUBNUB_CTASTR(static_assertion_failed_,msg) : !!(cond); } \ |
sveljko | 0:d13755cfb705 | 148 | PUBNUB_CTASTR(static_assertion_failed_,__FILE__,__LINE__) |
sveljko | 0:d13755cfb705 | 149 | |
sveljko | 0:d13755cfb705 | 150 | |
sveljko | 0:d13755cfb705 | 151 | #endif /* !defined INC_PUBNUB_ASSERT */ |