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 |