src/cx/common.h

changeset 1093
bcbf6bf582fa
parent 1076
bb4da3255de3
equal deleted inserted replaced
1092:8a35119d1f01 1093:bcbf6bf582fa
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29 /** 29 /**
30 * \file common.h 30 * @file common.h
31 * 31 *
32 * \brief Common definitions and feature checks. 32 * @brief Common definitions and feature checks.
33 * 33 *
34 * \author Mike Becker 34 * @author Mike Becker
35 * \author Olaf Wintermann 35 * @author Olaf Wintermann
36 * \copyright 2-Clause BSD License 36 * @copyright 2-Clause BSD License
37 * 37 *
38 * \mainpage UAP Common Extensions 38 * @mainpage UAP Common Extensions
39 * Library with common and useful functions, macros and data structures. 39 * Library with common and useful functions, macros and data structures.
40 * <p> 40 * <p>
41 * Latest available source:<br> 41 * Latest available source:<br>
42 * <a href="https://sourceforge.net/projects/ucx/files/">https://sourceforge.net/projects/ucx/files/</a> 42 * <a href="https://sourceforge.net/projects/ucx/files/">https://sourceforge.net/projects/ucx/files/</a>
43 * </p> 43 * </p>
100 100
101 // --------------------------------------------------------------------------- 101 // ---------------------------------------------------------------------------
102 // Architecture Detection 102 // Architecture Detection
103 // --------------------------------------------------------------------------- 103 // ---------------------------------------------------------------------------
104 104
105 #ifndef INTPTR_MAX
106 #error Missing INTPTR_MAX definition
107 #endif
105 #if INTPTR_MAX == INT64_MAX 108 #if INTPTR_MAX == INT64_MAX
106 /** 109 /**
107 * The address width in bits on this platform. 110 * The address width in bits on this platform.
108 */ 111 */
109 #define CX_WORDSIZE 64 112 #define CX_WORDSIZE 64
120 // Missing Defines 123 // Missing Defines
121 // --------------------------------------------------------------------------- 124 // ---------------------------------------------------------------------------
122 125
123 #ifndef SSIZE_MAX // not defined in glibc since C23 and MSVC 126 #ifndef SSIZE_MAX // not defined in glibc since C23 and MSVC
124 #if CX_WORDSIZE == 64 127 #if CX_WORDSIZE == 64
128 /**
129 * The maximum representable value in ssize_t.
130 */
125 #define SSIZE_MAX 0x7fffffffffffffffll 131 #define SSIZE_MAX 0x7fffffffffffffffll
126 #else 132 #else
127 #define SSIZE_MAX 0x7fffffffl 133 #define SSIZE_MAX 0x7fffffffl
128 #endif 134 #endif
129 #endif 135 #endif
161 #define cx_attr_malloc __attribute__((__malloc__)) 167 #define cx_attr_malloc __attribute__((__malloc__))
162 168
163 #ifndef __clang__ 169 #ifndef __clang__
164 /** 170 /**
165 * The pointer returned by the attributed function is supposed to be freed 171 * The pointer returned by the attributed function is supposed to be freed
166 * by \p freefunc. 172 * by @p freefunc.
167 * 173 *
168 * @param freefunc the function that shall be used to free the memory 174 * @param freefunc the function that shall be used to free the memory
169 * @param freefunc_arg the index of the pointer argument in \p freefunc 175 * @param freefunc_arg the index of the pointer argument in @p freefunc
170 */ 176 */
171 #define cx_attr_dealloc(freefunc, freefunc_arg) \ 177 #define cx_attr_dealloc(freefunc, freefunc_arg) \
172 __attribute__((__malloc__(freefunc, freefunc_arg))) 178 __attribute__((__malloc__(freefunc, freefunc_arg)))
173 #else 179 #else
174 /** 180 /**
188 #define cx_attr_allocsize(...) __attribute__((__alloc_size__(__VA_ARGS__))) 194 #define cx_attr_allocsize(...) __attribute__((__alloc_size__(__VA_ARGS__)))
189 195
190 196
191 #ifdef __clang__ 197 #ifdef __clang__
192 /** 198 /**
193 * No support for \c null_terminated_string_arg in clang or GCC below 14. 199 * No support for @c null_terminated_string_arg in clang or GCC below 14.
194 */ 200 */
195 #define cx_attr_cstr_arg(idx) 201 #define cx_attr_cstr_arg(idx)
196 /** 202 /**
197 * No support for access attribute in clang. 203 * No support for access attribute in clang.
198 */ 204 */
209 */ 215 */
210 #define cx_attr_access(mode, ...) __attribute__((__access__(mode, __VA_ARGS__))) 216 #define cx_attr_access(mode, ...) __attribute__((__access__(mode, __VA_ARGS__)))
211 #endif // __GNUC__ < 10 217 #endif // __GNUC__ < 10
212 #if __GNUC__ < 14 218 #if __GNUC__ < 14
213 /** 219 /**
214 * No support for \c null_terminated_string_arg in clang or GCC below 14. 220 * No support for @c null_terminated_string_arg in clang or GCC below 14.
215 */ 221 */
216 #define cx_attr_cstr_arg(idx) 222 #define cx_attr_cstr_arg(idx)
217 #else 223 #else
218 /** 224 /**
219 * The specified argument is expected to be a zero-terminated string. 225 * The specified argument is expected to be a zero-terminated string.
286 typedef size_t (*cx_write_func)( 292 typedef size_t (*cx_write_func)(
287 const void *, 293 const void *,
288 size_t, 294 size_t,
289 size_t, 295 size_t,
290 void * 296 void *
291 ) cx_attr_nonnull; 297 );
292 298
293 /** 299 /**
294 * Function pointer compatible with fread-like functions. 300 * Function pointer compatible with fread-like functions.
295 */ 301 */
296 typedef size_t (*cx_read_func)( 302 typedef size_t (*cx_read_func)(
297 void *, 303 void *,
298 size_t, 304 size_t,
299 size_t, 305 size_t,
300 void * 306 void *
301 ) cx_attr_nonnull; 307 );
302 308
303 // --------------------------------------------------------------------------- 309 // ---------------------------------------------------------------------------
304 // Utility macros 310 // Utility macros
305 // --------------------------------------------------------------------------- 311 // ---------------------------------------------------------------------------
306 312
319 // szmul implementation 325 // szmul implementation
320 // --------------------------------------------------------------------------- 326 // ---------------------------------------------------------------------------
321 327
322 #if (__GNUC__ >= 5 || defined(__clang__)) && !defined(CX_NO_SZMUL_BUILTIN) 328 #if (__GNUC__ >= 5 || defined(__clang__)) && !defined(CX_NO_SZMUL_BUILTIN)
323 #define CX_SZMUL_BUILTIN 329 #define CX_SZMUL_BUILTIN
324 330 #define cx_szmul(a, b, result) __builtin_mul_overflow(a, b, result)
325 /** 331 #else // no GNUC or clang bultin
326 * Alias for \c __builtin_mul_overflow. 332 /**
327 *
328 * Performs a multiplication of size_t values and checks for overflow. 333 * Performs a multiplication of size_t values and checks for overflow.
334 *
335 * @param a (@c size_t) first operand
336 * @param b (@c size_t) second operand
337 * @param result (@c size_t*) a pointer to a variable, where the result should
338 * be stored
339 * @retval zero success
340 * @retval non-zero the multiplication would overflow
341 */
342 #define cx_szmul(a, b, result) cx_szmul_impl(a, b, result)
343
344 /**
345 * Implementation of cx_szmul() when no compiler builtin is available.
346 *
347 * Do not use in application code.
329 * 348 *
330 * @param a first operand 349 * @param a first operand
331 * @param b second operand 350 * @param b second operand
332 * @param result a pointer to a size_t, where the result should 351 * @param result a pointer to a variable, where the result should
333 * be stored 352 * be stored
334 * @return zero, if no overflow occurred and the result is correct, non-zero 353 * @retval zero success
335 * otherwise 354 * @retval non-zero the multiplication would overflow
336 */
337 #define cx_szmul(a, b, result) __builtin_mul_overflow(a, b, result)
338
339 #else // no GNUC or clang bultin
340
341 /**
342 * Performs a multiplication of size_t values and checks for overflow.
343 *
344 * @param a first operand
345 * @param b second operand
346 * @param result a pointer to a size_t, where the result should
347 * be stored
348 * @return zero, if no overflow occurred and the result is correct, non-zero
349 * otherwise
350 */
351 #define cx_szmul(a, b, result) cx_szmul_impl(a, b, result)
352
353 /**
354 * Performs a multiplication of size_t values and checks for overflow.
355 *
356 * This is a custom implementation in case there is no compiler builtin
357 * available.
358 *
359 * @param a first operand
360 * @param b second operand
361 * @param result a pointer to a size_t where the result should be stored
362 * @return zero, if no overflow occurred and the result is correct, non-zero
363 * otherwise
364 */ 355 */
365 #if __cplusplus 356 #if __cplusplus
366 extern "C" 357 extern "C"
367 #endif 358 #endif
368 int cx_szmul_impl(size_t a, size_t b, size_t *result); 359 int cx_szmul_impl(size_t a, size_t b, size_t *result);
369
370 #endif // cx_szmul 360 #endif // cx_szmul
371 361
372 362
373 // --------------------------------------------------------------------------- 363 // ---------------------------------------------------------------------------
374 // Fixes for MSVC incompatibilities 364 // Fixes for MSVC incompatibilities

mercurial