src/ucx/cx/common.h

changeset 579
e10457d74fe1
parent 490
d218607f5a7e
equal deleted inserted replaced
578:eb48f716b31c 579:e10457d74fe1
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 * \version 3.0 36 * @copyright 2-Clause BSD License
37 * \copyright 2-Clause BSD License 37 *
38 * 38 * @mainpage UAP Common Extensions
39 * \mainpage UAP Common Extensions
40 * Library with common and useful functions, macros and data structures. 39 * Library with common and useful functions, macros and data structures.
41 * <p> 40 * <p>
42 * Latest available source:<br> 41 * Latest available source:<br>
43 * <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>
44 * </p> 43 * </p>
45 * 44 *
46 * <p> 45 * <p>
47 * Repositories:<br> 46 * Repositories:<br>
48 * <a href="https://sourceforge.net/p/ucx/code">https://sourceforge.net/p/ucx/code</a> 47 * <a href="https://sourceforge.net/p/ucx/code">https://sourceforge.net/p/ucx/code</a>
49 * -&nbsp;or&nbsp;- 48 * -&nbsp;or&nbsp;-
50 * <a href="https://develop.uap-core.de/hg/ucx">https://develop.uap-core.de/hg/ucx</a> 49 * <a href="https://uap-core.de/hg/ucx">https://uap-core.de/hg/ucx</a>
51 * </p> 50 * </p>
52 * 51 *
53 * <h2>LICENCE</h2> 52 * <h2>LICENCE</h2>
54 * 53 *
55 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. 54 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
82 81
83 /** Major UCX version as integer constant. */ 82 /** Major UCX version as integer constant. */
84 #define UCX_VERSION_MAJOR 3 83 #define UCX_VERSION_MAJOR 3
85 84
86 /** Minor UCX version as integer constant. */ 85 /** Minor UCX version as integer constant. */
87 #define UCX_VERSION_MINOR 0 86 #define UCX_VERSION_MINOR 1
88 87
89 /** Version constant which ensures to increase monotonically. */ 88 /** Version constant which ensures to increase monotonically. */
90 #define UCX_VERSION (((UCX_VERSION_MAJOR)<<16)|UCX_VERSION_MINOR) 89 #define UCX_VERSION (((UCX_VERSION_MAJOR)<<16)|UCX_VERSION_MINOR)
91 90
92 // Common Includes 91 // ---------------------------------------------------------------------------
92 // Common includes
93 // ---------------------------------------------------------------------------
93 94
94 #include <stdlib.h> 95 #include <stdlib.h>
95 #include <stddef.h> 96 #include <stddef.h>
96 #include <stdbool.h> 97 #include <stdbool.h>
97 #include <stdint.h> 98 #include <stdint.h>
98 #include <sys/types.h> 99 #include <sys/types.h>
99 100
101 // ---------------------------------------------------------------------------
102 // Architecture Detection
103 // ---------------------------------------------------------------------------
104
105 #ifndef INTPTR_MAX
106 #error Missing INTPTR_MAX definition
107 #endif
108 #if INTPTR_MAX == INT64_MAX
109 /**
110 * The address width in bits on this platform.
111 */
112 #define CX_WORDSIZE 64
113 #elif INTPTR_MAX == INT32_MAX
114 /**
115 * The address width in bits on this platform.
116 */
117 #define CX_WORDSIZE 32
118 #else
119 #error Unknown pointer size or missing size macros!
120 #endif
121
122 // ---------------------------------------------------------------------------
123 // Attribute definitions
124 // ---------------------------------------------------------------------------
125
126 #ifndef __GNUC__
127 /**
128 * Removes GNU C attributes where they are not supported.
129 */
130 #define __attribute__(x)
131 #endif
132
133 /**
134 * All pointer arguments must be non-NULL.
135 */
136 #define cx_attr_nonnull __attribute__((__nonnull__))
137
138 /**
139 * The specified pointer arguments must be non-NULL.
140 */
141 #define cx_attr_nonnull_arg(...) __attribute__((__nonnull__(__VA_ARGS__)))
142
143 /**
144 * The returned value is guaranteed to be non-NULL.
145 */
146 #define cx_attr_returns_nonnull __attribute__((__returns_nonnull__))
147
148 /**
149 * The attributed function always returns freshly allocated memory.
150 */
151 #define cx_attr_malloc __attribute__((__malloc__))
152
153 #ifndef __clang__
154 /**
155 * The pointer returned by the attributed function is supposed to be freed
156 * by @p freefunc.
157 *
158 * @param freefunc the function that shall be used to free the memory
159 * @param freefunc_arg the index of the pointer argument in @p freefunc
160 */
161 #define cx_attr_dealloc(freefunc, freefunc_arg) \
162 __attribute__((__malloc__(freefunc, freefunc_arg)))
163 #else
164 /**
165 * Not supported in clang.
166 */
167 #define cx_attr_dealloc(...)
168 #endif // __clang__
169
170 /**
171 * Shortcut to specify #cxFree() as deallocator.
172 */
173 #define cx_attr_dealloc_ucx cx_attr_dealloc(cxFree, 2)
174
175 /**
176 * Specifies the parameters from which the allocation size is calculated.
177 */
178 #define cx_attr_allocsize(...) __attribute__((__alloc_size__(__VA_ARGS__)))
179
180
181 #ifdef __clang__
182 /**
183 * No support for @c null_terminated_string_arg in clang or GCC below 14.
184 */
185 #define cx_attr_cstr_arg(idx)
186 /**
187 * No support for access attribute in clang.
188 */
189 #define cx_attr_access(mode, ...)
190 #else
191 #if __GNUC__ < 10
192 /**
193 * No support for access attribute in GCC < 10.
194 */
195 #define cx_attr_access(mode, ...)
196 #else
197 /**
198 * Helper macro to define access macros.
199 */
200 #define cx_attr_access(mode, ...) __attribute__((__access__(mode, __VA_ARGS__)))
201 #endif // __GNUC__ < 10
202 #if __GNUC__ < 14
203 /**
204 * No support for @c null_terminated_string_arg in clang or GCC below 14.
205 */
206 #define cx_attr_cstr_arg(idx)
207 #else
208 /**
209 * The specified argument is expected to be a zero-terminated string.
210 *
211 * @param idx the index of the argument
212 */
213 #define cx_attr_cstr_arg(idx) \
214 __attribute__((__null_terminated_string_arg__(idx)))
215 #endif // __GNUC__ < 14
216 #endif // __clang__
217
218
219 /**
220 * Specifies that the function will only read through the given pointer.
221 *
222 * Takes one or two arguments: the index of the pointer and (optionally) the
223 * index of another argument specifying the maximum number of accessed bytes.
224 */
225 #define cx_attr_access_r(...) cx_attr_access(__read_only__, __VA_ARGS__)
226
227 /**
228 * Specifies that the function will read and write through the given pointer.
229 *
230 * Takes one or two arguments: the index of the pointer and (optionally) the
231 * index of another argument specifying the maximum number of accessed bytes.
232 */
233 #define cx_attr_access_rw(...) cx_attr_access(__read_write__, __VA_ARGS__)
234
235 /**
236 * Specifies that the function will only write through the given pointer.
237 *
238 * Takes one or two arguments: the index of the pointer and (optionally) the
239 * index of another argument specifying the maximum number of accessed bytes.
240 */
241 #define cx_attr_access_w(...) cx_attr_access(__write_only__, __VA_ARGS__)
242
243 #if __STDC_VERSION__ >= 202300L
244
245 /**
246 * Do not warn about unused variable.
247 */
248 #define cx_attr_unused [[maybe_unused]]
249
250 /**
251 * Warn about discarded return value.
252 */
253 #define cx_attr_nodiscard [[nodiscard]]
254
255 #else // no C23
256
257 /**
258 * Do not warn about unused variable.
259 */
260 #define cx_attr_unused __attribute__((__unused__))
261
262 /**
263 * Warn about discarded return value.
264 */
265 #define cx_attr_nodiscard __attribute__((__warn_unused_result__))
266
267 #endif // __STDC_VERSION__
268
269
270 // ---------------------------------------------------------------------------
271 // MSVC specifics
272 // ---------------------------------------------------------------------------
273
274 #ifdef _MSC_VER
275 // fix missing _Thread_local support
276 #define _Thread_local __declspec(thread)
277 #endif // _MSC_VER
278
279 #if defined(CX_WINDLL_EXPORT)
280 #define cx_attr_export __declspec(dllexport)
281 #elif defined(CX_WINDLL)
282 #define cx_attr_export __declspec(dllimport)
283 #else
284 /** Only used for building Windows DLLs. */
285 #define cx_attr_export
286 #endif // CX_WINDLL / CX_WINDLL_EXPORT
287
288 // ---------------------------------------------------------------------------
289 // Useful function pointers
290 // ---------------------------------------------------------------------------
291
100 /** 292 /**
101 * Function pointer compatible with fwrite-like functions. 293 * Function pointer compatible with fwrite-like functions.
102 */ 294 */
103 typedef size_t (*cx_write_func)( 295 typedef size_t (*cx_write_func)(
104 void const *, 296 const void *,
105 size_t, 297 size_t,
106 size_t, 298 size_t,
107 void * 299 void *
108 ); 300 );
109 301
115 size_t, 307 size_t,
116 size_t, 308 size_t,
117 void * 309 void *
118 ); 310 );
119 311
120 312 // ---------------------------------------------------------------------------
121 // Compiler specific stuff 313 // Utility macros
122 314 // ---------------------------------------------------------------------------
123 #ifndef __GNUC__ 315
124 /** 316 /**
125 * Removes GNU C attributes where they are not supported. 317 * Determines the number of members in a static C array.
126 */ 318 *
127 #define __attribute__(x) 319 * @attention never use this to determine the size of a dynamically allocated
320 * array.
321 *
322 * @param arr the array identifier
323 * @return the number of elements
324 */
325 #define cx_nmemb(arr) (sizeof(arr)/sizeof((arr)[0]))
326
327 // ---------------------------------------------------------------------------
328 // szmul implementation
329 // ---------------------------------------------------------------------------
330
331 #if (__GNUC__ >= 5 || defined(__clang__)) && !defined(CX_NO_SZMUL_BUILTIN)
332 #define CX_SZMUL_BUILTIN
333 #define cx_szmul(a, b, result) __builtin_mul_overflow(a, b, result)
334 #else // no GNUC or clang bultin
335 /**
336 * Performs a multiplication of size_t values and checks for overflow.
337 *
338 * @param a (@c size_t) first operand
339 * @param b (@c size_t) second operand
340 * @param result (@c size_t*) a pointer to a variable, where the result should
341 * be stored
342 * @retval zero success
343 * @retval non-zero the multiplication would overflow
344 */
345 #define cx_szmul(a, b, result) cx_szmul_impl(a, b, result)
346
347 /**
348 * Implementation of cx_szmul() when no compiler builtin is available.
349 *
350 * Do not use in application code.
351 *
352 * @param a first operand
353 * @param b second operand
354 * @param result a pointer to a variable, where the result should
355 * be stored
356 * @retval zero success
357 * @retval non-zero the multiplication would overflow
358 */
359 #if __cplusplus
360 extern "C"
128 #endif 361 #endif
129 362 cx_attr_export int cx_szmul_impl(size_t a, size_t b, size_t *result);
130 #ifdef _MSC_VER 363 #endif // cx_szmul
131 364
132 // fix missing ssize_t definition 365
133 #include <BaseTsd.h>
134 typedef SSIZE_T ssize_t;
135
136 // fix missing _Thread_local support
137 #define _Thread_local __declspec(thread)
138
139 #endif
140 366
141 #endif // UCX_COMMON_H 367 #endif // UCX_COMMON_H

mercurial