Chuck Swiger / Pubnub_c_core2

Fork of Pubnub_c_core by Srdjan Veljkovic

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pubnub_assert.h Source File

pubnub_assert.h

00001 /* -*- c-file-style:"stroustrup"; indent-tabs-mode: nil -*- */
00002 #if !defined INC_PUBNUB_ASSERT
00003 #define      INC_PUBNUB_ASSERT
00004 
00005 #include <stdbool.h>
00006 
00007 
00008 /** The Pubnub ASSERT macros. There are several layers:
00009     - highest (PUBNUB_ASSERT_LEVEL_EX): all checks enabled, 
00010     even the long lasting ones
00011     - regular (PUBNUB_ASSERT_LEVEL): only the long lasting
00012     checks are disabled
00013     - lowest (PUBNUB_ASSERT_LEVEL_OPT): only the checks with
00014     negligible execution length are enabled
00015     - none (PUBNUB_ASSERT_LEVEL_NONE): all checks disabled
00016 
00017     Define at most one of above mentioned macros before including this
00018     header.  If none is defined, the highest (_EX) level is assumed.
00019  */
00020 
00021 /* Let's make sure only one of @c PUBNUB_ASSERT_LEVEL_EX, @c
00022  * PUBNUB_ASSERT_LEVEL, @c PUBNUB_ASSERT_LEVEL_OPT or @c
00023  * PUBNUB_ASSERT_LEVEL_NONE is defined.
00024  */
00025 
00026 #if defined(PUBNUB_ASSERT_LEVEL_EX) && (                                \
00027     defined(PUBNUB_ASSERT_LEVEL) || defined(PUBNUB_ASSERT_LEVEL_OPT) || \
00028     defined(PUBNUB_ASSERT_LEVEL_NONE) ) 
00029 #error Cannott define PUBNUB_ASSERT_LEVEL_EX and any lower level (regular, _OPT, _NONE)
00030 #endif
00031 
00032 #if defined(PUBNUB_ASSERT_LEVEL) && (                                   \
00033     defined(PUBNUB_ASSERT_LEVEL_OPT) || defined(PUBNUB_ASSERT_LEVEL_NONE) ) 
00034 #error Cannott define PUBNUB_ASSERT_LEVEL and any lower level (_OPT, _NONE)
00035 #endif
00036 
00037 
00038 #if defined(PUBNUB_ASSERT_LEVEL_OPT) && defined(PUBNUB_ASSERT_LEVEL_NONE) 
00039 #error Cannott define PUBNUB_ASSERT_LEVEL_OPT and PUBNUB_ASSERT_LEVEL_NONE
00040 #endif
00041 
00042 /* If none of ASSERT level defining macros is defined, let's assume
00043  * the highest level.
00044  */
00045 
00046 #if !defined(PUBNUB_ASSERT_LEVEL_EX) &&             \
00047     !defined(PUBNUB_ASSERT_LEVEL) &&                \
00048     !defined(PUBNUB_ASSERT_LEVEL_OPT) &&                        \
00049     !defined(PUBNUB_ASSERT_LEVEL_NONE)
00050 #define PUBNUB_ASSERT_LEVEL_EX
00051 #endif
00052 
00053 #ifdef _MSC_VER
00054 #define PUBNUB_ANALYSIS_ASSUME(X) __analysis_assume(X)
00055 #else
00056 #define PUBNUB_ANALYSIS_ASSUME(X)
00057 #endif
00058 
00059 /** The common ASSERT implementation */
00060 #define PUBNUB_ASSERT_IMPL(X) do {                                      \
00061         PUBNUB_ANALYSIS_ASSUME(X);                                      \
00062         (X) ? (void)0 : pubnub_assert_failed(#X, __FILE__, __LINE__);   \
00063     } while (false)
00064 
00065 /** Should make the compiler not report "unused variable"
00066     warnings.
00067 */
00068 #define PUBNUB_UNUSED(x) do { (void)sizeof(x); } while (false)
00069 
00070 
00071 /* Define the ASSERT macro for the highest (_EX) level.
00072  */
00073 #if defined PUBNUB_ASSERT_LEVEL_EX
00074 #define PUBNUB_ASSERT_EX(X) PUBNUB_ASSERT_IMPL(X)
00075 #else
00076 #define PUBNUB_ASSERT_EX(X) PUBNUB_UNUSED(X)
00077 #endif
00078 
00079 /* Determine if regular level is to be used. 
00080  */
00081 #if defined(PUBNUB_ASSERT_LEVEL_EX) || defined(PUBNUB_ASSERT_LEVEL)
00082 #define PUBNUB_ASSERT_IS_ACTIVE       // also usable directly in client code
00083 #endif
00084 
00085 /* Define the ASSERT macro for the regular level.
00086  */
00087 #if defined(PUBNUB_ASSERT_IS_ACTIVE)
00088 #define PUBNUB_ASSERT(X) PUBNUB_ASSERT_IMPL(X)
00089 #else
00090 #define PUBNUB_ASSERT(X) PUBNUB_UNUSED(X)
00091 #endif
00092 
00093 
00094 /* Define the ASSERT macro for the lowest level
00095  */
00096 #if !defined(PUBNUB_ASSERT_LEVEL_NONE)
00097 #define PUBNUB_ASSERT_OPT(X) PUBNUB_ASSERT_IMPL(X)
00098 #else
00099 #define PUBNUB_ASSERT_OPT(X) PUBNUB_UNUSED(X)
00100 #endif
00101 
00102 
00103 
00104 /** This will invoke the installed assert handler.  The default
00105     behavior is pubnub_assert_handler_abort().
00106  */
00107 void pubnub_assert_failed(char const *s, char const *file, long line);
00108 
00109 /** Prototype of a Pubnub assertion failure handler. There are several
00110     standard handlers, but you can also provide your own.
00111     @param s The string that defines the failure condition
00112     @param file The name of the source file with the condition
00113     @param line Number of the line of @c file with the condition
00114  */
00115 typedef void (*pubnub_assert_handler_t)(char const *s, char const *file, long line);
00116 
00117 /** This will install an assert handler. It can be one of the standard
00118     ones, or your own.
00119 
00120     @param handler The handler to install. If NULL, will install
00121     pubnub_assert_handler_abort()
00122  */
00123 void pubnub_assert_set_handler(pubnub_assert_handler_t handler);
00124 
00125 /** This handler will print a message formed from the parameters and
00126     then go to infinite loop. Useful for debugging.
00127 */
00128 void pubnub_assert_handler_loop(char const *s, char const *file, long line);
00129 
00130 /** This handler will print a message  formed from the parameters and
00131     then abort (exit, end) the process. Useful for testing.
00132  */
00133 void pubnub_assert_handler_abort(char const *s, char const *file, long line);
00134 
00135 /** This handler will print a message formed from the parameters and
00136     that's it. Useful for getting data from a program execution "in
00137     the field", where we must not stop or crash because of ASSERT
00138     failure.
00139  */
00140 void pubnub_assert_handler_printf(char const *s, char const *file, long line);
00141 
00142 
00143 #define PUBNUB_CTASTR2(pre,post,lex) pre ## post ## lex
00144 #define PUBNUB_CTASTR(pre,post,lex) PUBNUB_CTASTR2(pre,post,lex)
00145 
00146 #define PUBNUB_STATIC_ASSERT(cond) \
00147     typedef struct { int PUBNUB_CTASTR(static_assertion_failed_,msg) : !!(cond); } \
00148         PUBNUB_CTASTR(static_assertion_failed_,__FILE__,__LINE__)
00149 
00150 
00151 #endif /* !defined INC_PUBNUB_ASSERT */