| 86 #define UCX_VERSION_MINOR 1 |
86 #define UCX_VERSION_MINOR 1 |
| 87 |
87 |
| 88 /** Version constant which ensures to increase monotonically. */ |
88 /** Version constant which ensures to increase monotonically. */ |
| 89 #define UCX_VERSION (((UCX_VERSION_MAJOR)<<16)|UCX_VERSION_MINOR) |
89 #define UCX_VERSION (((UCX_VERSION_MAJOR)<<16)|UCX_VERSION_MINOR) |
| 90 |
90 |
| 91 // Common Includes |
91 // --------------------------------------------------------------------------- |
| |
92 // Common includes |
| |
93 // --------------------------------------------------------------------------- |
| 92 |
94 |
| 93 #include <stdlib.h> |
95 #include <stdlib.h> |
| 94 #include <stddef.h> |
96 #include <stddef.h> |
| 95 #include <stdbool.h> |
97 #include <stdbool.h> |
| 96 #include <stdint.h> |
98 #include <stdint.h> |
| |
99 |
| |
100 // --------------------------------------------------------------------------- |
| |
101 // Attribute definitions |
| |
102 // --------------------------------------------------------------------------- |
| |
103 |
| |
104 #ifndef __GNUC__ |
| |
105 /** |
| |
106 * Removes GNU C attributes where they are not supported. |
| |
107 */ |
| |
108 #define __attribute__(x) |
| |
109 #endif |
| |
110 |
| |
111 /** |
| |
112 * All pointer arguments must be non-NULL. |
| |
113 */ |
| |
114 #define cx_attr_nonnull __attribute__((__nonnull__)) |
| |
115 |
| |
116 /** |
| |
117 * The specified pointer arguments must be non-NULL. |
| |
118 */ |
| |
119 #define cx_attr_nonnull_arg(...) __attribute__((__nonnull__(__VA_ARGS__))) |
| |
120 |
| |
121 /** |
| |
122 * The returned value is guaranteed to be non-NULL. |
| |
123 */ |
| |
124 #define cx_attr_returns_nonnull __attribute__((__returns_nonnull__)) |
| |
125 |
| |
126 /** |
| |
127 * The attributed function always returns freshly allocated memory. |
| |
128 */ |
| |
129 #define cx_attr_malloc __attribute__((__malloc__)) |
| |
130 |
| |
131 #ifndef __clang__ |
| |
132 /** |
| |
133 * The pointer returned by the attributed function is supposed to be freed |
| |
134 * by \p freefunc. |
| |
135 * |
| |
136 * @param freefunc the function that shall be used to free the memory |
| |
137 * @param freefunc_arg the index of the pointer argument in \p freefunc |
| |
138 */ |
| |
139 #define cx_attr_dealloc(freefunc, freefunc_arg) \ |
| |
140 __attribute__((__malloc__(freefunc, freefunc_arg))) |
| |
141 #else |
| |
142 /** |
| |
143 * Not supported in clang. |
| |
144 */ |
| |
145 #define cx_attr_dealloc(...) |
| |
146 #endif // __clang__ |
| |
147 |
| |
148 /** |
| |
149 * Shortcut to specify #cxFree() as deallocator. |
| |
150 */ |
| |
151 #define cx_attr_dealloc_ucx cx_attr_dealloc(cxFree, 2) |
| |
152 |
| |
153 /** |
| |
154 * Specifies the parameters from which the allocation size is calculated. |
| |
155 */ |
| |
156 #define cx_attr_allocsize(...) __attribute__((__alloc_size__(__VA_ARGS__))) |
| |
157 |
| |
158 |
| |
159 #ifdef __clang__ |
| |
160 /** |
| |
161 * No support for \c null_terminated_string_arg in clang or GCC below 14. |
| |
162 */ |
| |
163 #define cx_attr_cstr_arg(idx) |
| |
164 /** |
| |
165 * No support for access attribute in clang. |
| |
166 */ |
| |
167 #define cx_attr_access(mode, ...) |
| |
168 #else |
| |
169 #if __GNUC__ < 10 |
| |
170 /** |
| |
171 * No support for access attribute in GCC < 10. |
| |
172 */ |
| |
173 #define cx_attr_access(mode, ...) |
| |
174 #else |
| |
175 /** |
| |
176 * Helper macro to define access macros. |
| |
177 */ |
| |
178 #define cx_attr_access(mode, ...) __attribute__((__access__(mode, __VA_ARGS__))) |
| |
179 #endif // __GNUC__ < 10 |
| |
180 #if __GNUC__ < 14 |
| |
181 /** |
| |
182 * No support for \c null_terminated_string_arg in clang or GCC below 14. |
| |
183 */ |
| |
184 #define cx_attr_cstr_arg(idx) |
| |
185 #else |
| |
186 /** |
| |
187 * The specified argument is expected to be a zero-terminated string. |
| |
188 * |
| |
189 * @param idx the index of the argument |
| |
190 */ |
| |
191 #define cx_attr_cstr_arg(idx) \ |
| |
192 __attribute__((__null_terminated_string_arg__(idx))) |
| |
193 #endif // __GNUC__ < 14 |
| |
194 #endif // __clang__ |
| |
195 |
| |
196 |
| |
197 /** |
| |
198 * Specifies that the function will only read through the given pointer. |
| |
199 * |
| |
200 * Takes one or two arguments: the index of the pointer and (optionally) the |
| |
201 * index of another argument specifying the maximum number of accessed bytes. |
| |
202 */ |
| |
203 #define cx_attr_access_r(...) cx_attr_access(__read_only__, __VA_ARGS__) |
| |
204 |
| |
205 /** |
| |
206 * Specifies that the function will read and write through the given pointer. |
| |
207 * |
| |
208 * Takes one or two arguments: the index of the pointer and (optionally) the |
| |
209 * index of another argument specifying the maximum number of accessed bytes. |
| |
210 */ |
| |
211 #define cx_attr_access_rw(...) cx_attr_access(__read_write__, __VA_ARGS__) |
| |
212 |
| |
213 /** |
| |
214 * Specifies that the function will only write through the given pointer. |
| |
215 * |
| |
216 * Takes one or two arguments: the index of the pointer and (optionally) the |
| |
217 * index of another argument specifying the maximum number of accessed bytes. |
| |
218 */ |
| |
219 #define cx_attr_access_w(...) cx_attr_access(__write_only__, __VA_ARGS__) |
| |
220 |
| |
221 #if __STDC_VERSION__ >= 202300L |
| |
222 |
| |
223 /** |
| |
224 * Do not warn about unused variable. |
| |
225 */ |
| |
226 #define cx_attr_unused [[maybe_unused]] |
| |
227 |
| |
228 /** |
| |
229 * Warn about discarded return value. |
| |
230 */ |
| |
231 #define cx_attr_nodiscard [[nodiscard]] |
| |
232 |
| |
233 #else // no C23 |
| |
234 |
| |
235 /** |
| |
236 * Do not warn about unused variable. |
| |
237 */ |
| |
238 #define cx_attr_unused __attribute__((__unused__)) |
| |
239 |
| |
240 /** |
| |
241 * Warn about discarded return value. |
| |
242 */ |
| |
243 #define cx_attr_nodiscard __attribute__((__warn_unused_result__)) |
| |
244 |
| |
245 #endif // __STDC_VERSION__ |
| |
246 |
| |
247 // --------------------------------------------------------------------------- |
| |
248 // Useful function pointers |
| |
249 // --------------------------------------------------------------------------- |
| 97 |
250 |
| 98 /** |
251 /** |
| 99 * Function pointer compatible with fwrite-like functions. |
252 * Function pointer compatible with fwrite-like functions. |
| 100 */ |
253 */ |
| 101 typedef size_t (*cx_write_func)( |
254 typedef size_t (*cx_write_func)( |
| 102 const void *, |
255 const void *, |
| 103 size_t, |
256 size_t, |
| 104 size_t, |
257 size_t, |
| 105 void * |
258 void * |
| 106 ); |
259 ) cx_attr_nonnull; |
| 107 |
260 |
| 108 /** |
261 /** |
| 109 * Function pointer compatible with fread-like functions. |
262 * Function pointer compatible with fread-like functions. |
| 110 */ |
263 */ |
| 111 typedef size_t (*cx_read_func)( |
264 typedef size_t (*cx_read_func)( |
| 112 void *, |
265 void *, |
| 113 size_t, |
266 size_t, |
| 114 size_t, |
267 size_t, |
| 115 void * |
268 void * |
| 116 ); |
269 ) cx_attr_nonnull; |
| |
270 |
| |
271 // --------------------------------------------------------------------------- |
| |
272 // Utility macros |
| |
273 // --------------------------------------------------------------------------- |
| 117 |
274 |
| 118 /** |
275 /** |
| 119 * Determines the number of members in a static C array. |
276 * Determines the number of members in a static C array. |
| 120 * |
277 * |
| 121 * @attention never use this to determine the size of a dynamically allocated |
278 * @attention never use this to determine the size of a dynamically allocated |