Home | History | Annotate | Line # | Download | only in utilities
      1 /*
      2  * Copyright (c) 2022 Apple Inc. All rights reserved.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     https://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef DNS_ASSERT_MACROS_H
     18 #define DNS_ASSERT_MACROS_H
     19 
     20 //======================================================================================================================
     21 // MARK: - Platform Dependent Assert Macros
     22 
     23 #ifdef __APPLE__
     24 
     25 // MARK: - Apple
     26 
     27 #include <AssertMacros.h>
     28 #else
     29 
     30 // MARK: - Other
     31 
     32 #include <stdbool.h>
     33 
     34 #ifndef DEBUG_ASSERT_MESSAGE
     35 	#define DEBUG_ASSERT_MESSAGE
     36 #endif
     37 
     38 #ifndef require
     39 	#define require(assertion, exception_label)			\
     40 		do {											\
     41 			if (__builtin_expect(!(assertion), 0)) {	\
     42 				goto exception_label;					\
     43 			}											\
     44 		} while (false)
     45 #endif
     46 
     47 #ifndef require_quiet
     48 	#define require_quiet require
     49 #endif
     50 
     51 #ifndef require_action
     52 	#define require_action(assertion, exception_label, action)	\
     53 		do {													\
     54 			if (__builtin_expect(!(assertion), 0)) {			\
     55 				{												\
     56 					action;										\
     57 				}												\
     58 				goto exception_label;							\
     59 			}													\
     60 		} while (false)
     61 #endif
     62 
     63 #ifndef require_action_quiet
     64 	#define require_action_quiet require_action
     65 #endif
     66 
     67 #ifndef require_noerr
     68 	#define require_noerr(error_code, exceptional_label)		\
     69 		do {													\
     70 			long error_code_long = (error_code);				\
     71 			if (__builtin_expect(0 != error_code_long, 0)) {	\
     72 				goto exceptional_label;							\
     73 			}													\
     74 		} while (false)
     75 #endif
     76 
     77 #ifndef require_noerr_action
     78 	#define require_noerr_action(error_code, exceptional_label, action)	\
     79 		do {															\
     80 			long error_code_long = (error_code);						\
     81 			if (__builtin_expect(0 != error_code_long, 0)) {			\
     82 				{														\
     83 					action;												\
     84 				}														\
     85 				goto exceptional_label;									\
     86 			}															\
     87 		} while (false)
     88 #endif
     89 
     90 #ifndef verify_action
     91 	#define verify_action(assertion, action)		\
     92 		if (__builtin_expect(!(assertion), 0)) {	\
     93 			action;									\
     94 		} else do {} while (0)
     95 #endif
     96 
     97 #endif // __APPLE__
     98 
     99 //======================================================================================================================
    100 // MARK: - Common Assert Macros
    101 
    102 #ifndef check_compile_time
    103 	#define check_compile_time(expr)	extern int compile_time_assert_failed[(expr) ? 1 : -1]
    104 #endif
    105 
    106 #ifndef check_compile_time_code
    107 	#define check_compile_time_code(X)	do {switch(0) {case 0: case X:;}} while( 0 )
    108 #endif
    109 
    110 #ifndef require_return
    111 	#define require_return(assertion)											\
    112 	do {																		\
    113 		if(__builtin_expect(!(assertion), 0)) {									\
    114 			DEBUG_ASSERT_MESSAGE("", #assertion, 0, 0, __FILE__, __LINE__, 0);	\
    115 			return;																\
    116 		}																		\
    117 	} while(false)
    118 #endif
    119 
    120 #ifndef require_return_quiet
    121 	#define require_return_quiet(assertion)										\
    122 	do {																		\
    123 		if(__builtin_expect(!(assertion), 0)) {									\
    124 			return;																\
    125 		}																		\
    126 	} while(false)
    127 #endif
    128 
    129 #ifndef require_return_value
    130 	#define require_return_value(assertion, value)								\
    131 	do {																		\
    132 		if(__builtin_expect(!(assertion), 0)) {									\
    133 			DEBUG_ASSERT_MESSAGE("", #assertion, 0, 0, __FILE__, __LINE__, 0);	\
    134 			return (value);														\
    135 		}																		\
    136 	} while(false)
    137 #endif
    138 
    139 #ifndef require_return_value_quiet
    140 	#define require_return_value_quiet(assertion, value)						\
    141 	do {																		\
    142 		if(__builtin_expect(!(assertion), 0)) {									\
    143 			return (value);														\
    144 		}																		\
    145 	} while(false)
    146 #endif
    147 
    148 #ifndef require_noerr_return
    149 	#define require_noerr_return(error_code)																\
    150 		do {																								\
    151 			long error_code_long = (error_code);															\
    152 			if (__builtin_expect(0 != error_code_long, 0)) {												\
    153 				DEBUG_ASSERT_MESSAGE("", #error_code " == 0", 0, 0, __FILE__, __LINE__, error_code_long);	\
    154 				return;																						\
    155 			}																								\
    156 		} while (false)
    157 #endif
    158 
    159 #ifndef require_noerr_return_quiet
    160 	#define require_noerr_return_quiet(error_code)															\
    161 		do {																								\
    162 			long error_code_long = (error_code);															\
    163 			if (__builtin_expect(0 != error_code_long, 0)) {												\
    164 				return;																						\
    165 			}																								\
    166 		} while (false)
    167 #endif
    168 
    169 #ifndef require_noerr_return_value
    170 	#define require_noerr_return_value(error_code, value)													\
    171 		do {																								\
    172 			long error_code_long = (error_code);															\
    173 			if (__builtin_expect(0 != error_code_long, 0)) {												\
    174 				DEBUG_ASSERT_MESSAGE("", #error_code " == 0", 0, 0, __FILE__, __LINE__, error_code_long);	\
    175 				return (value);																				\
    176 			}																								\
    177 		} while (false)
    178 #endif
    179 
    180 #ifndef require_noerr_return_value_quiet
    181 	#define require_noerr_return_value_quiet(error_code, value)												\
    182 		do {																								\
    183 			long error_code_long = (error_code);															\
    184 			if (__builtin_expect(0 != error_code_long, 0)) {												\
    185 				return (value);																				\
    186 			}																								\
    187 		} while (false)
    188 #endif
    189 
    190 #endif // DNS_ASSERT_MACROS_H
    191