2 * Include file with general macros and typedefs used through Captive project
3 * Copyright (C) 2002 Jan Kratochvil <project-captive@jankratochvil.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; exactly version 2 of June 1991 is required
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #ifndef _CAPTIVE_MACROS_H
21 #define _CAPTIVE_MACROS_H 1
24 #include <glib/gmacros.h>
25 #include <glib/gmem.h>
27 #include <string.h> /* for memset() */
28 #include <glib/galloca.h>
29 #include <glib/gmessages.h>
30 #include <glib/gutils.h> /* for g_snprintf(); glib-2.2.x+ it also has in <glib/gprintf.h> */
38 * Prevent 'might be used uninitialized' warning.
39 * Macro will fakes the use of the variable as sometimes GCC can't code flow
40 * analyse #C correctly.
44 * g_some_type some_variable CAPTIVE_FAKEUSE;
48 #define CAPTIVE_FAKEUSE =0
53 * @objp: Variable with the pointer to the objects wished to be allocated.
54 * Original value is discarded.
55 * @n: Numbers of objects to be allocated. Value %0 is permitted (%NULL assignment effect).
57 * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp.
58 * Allocated memory may contain garbage.
60 * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp))*n.
61 * Value %NULL is returned iff @n==%0;
63 #define captive_newn(objp,n) ((objp)=g_new(typeof(*(objp)),(n)))
68 * @objp: Variable with the pointer to the objects wished to be allocated and precleared.
69 * Original value is discarded.
70 * @n: Numbers of objects to be allocated. Value %0 is permitted (%NULL assignment effect).
72 * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp.
73 * Allocated memory is precleared.
75 * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp))*n.
76 * Value %NULL is returned iff @n==%0;
78 #define captive_new0n(objp,n) ((objp)=g_new0(typeof(*(objp)),(n)))
83 * @objp: Variable with the pointer to the objects wished to be reallocated.
84 * Value %NULL is permitted (g_malloc() effect).
85 * @n: Numbers of objects to be allocated. Value %0 is permitted (g_free() effect).
87 * Macro to reallocate the original memory stored in @objp
88 * to the size @n objects of type *@objp and to assign the resulting pointer to @objp.
89 * New allocated space may contain garbage. Both @objp and @n can be nonexclusively
92 * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp))*n.
93 * Value %NULL is returned iff @n==%0;
95 #define captive_renewn(objp,n) ({ \
96 typeof(&(objp)) _captive_renewn_objpp=&(objp); \
97 *_captive_renewn_objpp=g_renew(typeof(*(objp)),*_captive_renewn_objpp,(n)); \
98 (*_captive_renewn_objpp); \
104 * @objp: Variable with the pointer to the object wished to be allocated.
105 * Original value is discarded.
107 * Macro to allocate one object of type *@objp and to assign the resulting pointer to @objp.
108 * Allocated memory may contain garbage. Equivalent to captive_newn(objp,1) call.
110 * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp)).
111 * Value %NULL is never returned.
113 #define captive_new(objp) (captive_newn((objp),1))
118 * @objp: Variable with the pointer to the object wished to be allocated and precleared.
119 * Original value is discarded.
121 * Macro to allocate one object of type *@objp and to assign the resulting pointer to @objp.
122 * Allocated memory is precleared. Equivalent to captive_new0n(objp,1) call.
124 * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp)).
125 * Value %NULL is never returned.
127 #define captive_new0(objp) (captive_new0n((objp),1))
131 * captive_newn_alloca:
132 * @objp: Variable with the pointer to the objects wished to be allocated.
133 * Original value is discarded.
134 * @n: Numbers of objects to be allocated. Value %0 is permitted (%NULL assignment effect).
136 * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp.
137 * Allocated memory may contain garbage.
139 * Memory is allocated on the stack frame by g_alloca() and it will be automatically deallocated
140 * during exit of current function (or current block if variable sized variables present there).
141 * You cannot deallocate or reallocate such memory in any other way.
143 * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp))*n.
144 * Value %NULL is returned iff @n==%0;
146 #define captive_newn_alloca(objp,n) ({ \
147 gsize _captive_newn_alloca_n=(n); \
148 /* Fix 'g_alloca(0)!=NULL': */ \
149 ((objp)=(!_captive_newn_alloca_n ? NULL : g_alloca(sizeof(*(objp))*_captive_newn_alloca_n))); \
154 * captive_new0n_alloca:
155 * @objp: Variable with the pointer to the objects wished to be allocated and precleared.
156 * Original value is discarded.
157 * @n: Numbers of objects to be allocated. Value %0 is permitted (%NULL assignment effect).
159 * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp.
160 * Allocated memory is precleared.
162 * Memory is allocated on the stack frame by g_alloca() and it will be automatically deallocated
163 * during exit of current function (or current block if variable sized variables present there).
164 * You cannot deallocate or reallocate such memory in any other way.
166 * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp))*n.
167 * Value %NULL is returned iff @n==%0;
169 #define captive_new0n_alloca(objp,n) ({ \
170 typeof(&(objp)) _captive_new0n_alloca_objpp=&(objp); \
171 captive_newn_alloca(*_captive_new0n_alloca_objpp,(n)); \
172 CAPTIVE_MEMZERO(*_captive_new0n_alloca_objpp); \
173 (*_captive_new0n_alloca_objpp); \
178 * captive_new_alloca:
179 * @objp: Variable with the pointer to the object wished to be allocated.
180 * Original value is discarded.
182 * Macro to allocate one object of type *@objp and to assign the resulting pointer to @objp.
183 * Allocated memory may contain garbage. Equivalent to captive_newn_alloca(objp,1) call.
185 * Memory is allocated on the stack frame by g_alloca() and it will be automatically deallocated
186 * during exit of current function (or current block if variable sized variables present there).
187 * You cannot deallocate or reallocate such memory in any other way.
189 * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp)).
190 * Value %NULL is never returned.
192 #define captive_new_alloca(objp) (captive_newn_alloca((objp),1))
196 * captive_new0_alloca:
197 * @objp: Variable with the pointer to the object wished to be allocated and precleared.
198 * Original value is discarded.
200 * Macro to allocate one object of type *@objp and to assign the resulting pointer to @objp.
201 * Allocated memory is precleared. Equivalent to captive_new0n_alloca(objp,1) call.
203 * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp)).
205 #define captive_new0_alloca(objp) (captive_new0n_alloca((objp),1))
210 * @destp: Variable with the pointer to the target object wished to be allocated.
211 * Original value is discarded.
212 * @srcp: Pointer to the source object to be copied to @destp.
214 * Macro to similiar to g_memdup() but the object size is detected automatically.
215 * Size of @destp object and @srcp object must be the same.
217 * You must free the allocated memory of @destp by g_free().
219 * @Returns: Initialized @destp value as the copied memory of size #sizeof(typeof(*srcp)).
221 #define captive_memdup(destp,srcp) ({ \
222 typeof(&(destp)) _captive_captive_memdup_destpp=&(destp); \
223 g_assert(sizeof(*(destp))==sizeof(*(srcp))); \
224 captive_new(*_captive_captive_memdup_destpp); \
225 memcpy(*_captive_captive_memdup_destpp,(srcp),sizeof(*(srcp))); \
226 (*_captive_captive_memdup_destpp); \
232 * @objp: Variable to be filled from the next argument of @ap.
233 * @ap: Initialized #va_list type.
235 * Automatically determines the size of @objp.
236 * Equivalent to objp=va_arg(ap,typeof(objp)) call.
238 * @Returns: Initialized @objp value.
240 #define captive_va_arg(objp,ap) ((objp)=va_arg((ap),typeof(objp)))
245 * @objp: Pointer to the variable to be cleared.
247 * Clears the sizeof(*@objp) bytes of the given pointer with memset().
248 * Pass _pointer_ to the object to be cleared.
250 #define CAPTIVE_MEMZERO(objp) (memset((objp),0,sizeof(*(objp))))
254 * captive_printf_alloca:
255 * @format: Format string. See the sprintf() documentation.
256 * @args...: Arguments for @format. See the sprintf() documentation.
258 * Format the given format string @format as in sprintf().
259 * Output buffer is allocated automatically and it does not need to be deallocated
260 * manually as it is managed by g_alloca().
262 * @Returns: Formatted output string located in g_alloca() memory.
264 #define captive_printf_alloca(format,args...) ({ \
265 gsize _captive_printf_alloca_size=captive_nv_printf_string_upper_bound((format) , ## args); \
266 gchar *_captive_printf_alloca_r=g_alloca(_captive_printf_alloca_size); \
267 g_snprintf(_captive_printf_alloca_r,_captive_printf_alloca_size,(format) , ## args); \
268 (const gchar *)_captive_printf_alloca_r; \
270 static inline gsize captive_nv_printf_string_upper_bound(const gchar *format,...) G_GNUC_PRINTF(1,0) G_GNUC_UNUSED;
271 static inline gsize captive_nv_printf_string_upper_bound(const gchar *format,...)
277 r=g_printf_string_upper_bound(format,ap);
284 * captive_strdup_alloca:
285 * @string: #const #gchar * string to duplicate.
287 * Macro to do g_strdup() equivalent in g_alloca() style.
289 * Memory is allocated on the stack frame by g_alloca() and it will be automatically deallocated
290 * during exit of current function (or current block if variable sized variables present there).
291 * You cannot deallocate or reallocate such memory in any other way.
293 * @Returns: Duplicated @string. You may modify its items if the length is not changed.
295 #define captive_strdup_alloca(string) ({ \
296 const gchar *_captive_strdup_alloca_string=(string); \
297 const gchar *_captive_strdup_alloca_r=g_alloca(strlen(_captive_strdup_alloca_string)+1); \
298 strcpy((gchar *)_captive_strdup_alloca_r,_captive_strdup_alloca_string); \
299 (const gchar *)(_captive_strdup_alloca_r); \
304 * CAPTIVE_ROUND_DOWN:
305 * @pointer: Arbitrary pointer type.
306 * @fragment: Amount of 'sizeof(char)' to align @pointer down to.
307 * This size will be typically a power of 2.
308 * Value less or equal to %0 is forbidden.
310 * General pointer down-rounding macro. Already aligned pointer is left as is.
312 * glib NOTE: YOU MAY NOT STORE POINTERS IN INTEGERS.
314 * @Returns: Down-rounded @pointer to the integer multiple of @fragment.
315 * Resulting pointer has the same type as @pointer.
317 #define CAPTIVE_ROUND_DOWN(pointer,fragment) \
318 ((typeof(pointer))(((guint32)(pointer))-CAPTIVE_ROUND_DOWN_EXCEEDING((pointer),(fragment))))
319 #define CAPTIVE_ROUND_DOWN64(pointer,fragment) \
320 ((typeof(pointer))(((guint64)(pointer))-CAPTIVE_ROUND_DOWN_EXCEEDING64((pointer),(fragment))))
324 * CAPTIVE_ROUND_DOWN_EXCEEDING:
325 * @pointer: Arbitrary pointer type.
326 * @fragment: Amount of 'sizeof(char)' to detect down-alignment amount of @pointer for.
327 * This size will be typically a power of 2.
328 * Value less or equal to %0 is forbidden.
330 * Detects current non-aligned amount of data exceeding over integer multiple of @fragment.
331 * It will return value %0 for an aligned pointer.
333 * glib NOTE: YOU MAY NOT STORE POINTERS IN INTEGERS.
335 * @Returns: #gsize typed number of bytes exceeding over integer multiple of @fragment.
337 #define CAPTIVE_ROUND_DOWN_EXCEEDING(pointer,fragment) \
338 ((gsize)(((guint32)(pointer))%(fragment)))
339 #define CAPTIVE_ROUND_DOWN_EXCEEDING64(pointer,fragment) \
340 ((gsize)(((guint64)(pointer))%(fragment)))
345 * @pointer: Arbitrary pointer type.
346 * @fragment: Amount of 'sizeof(char)' to align @pointer up to.
347 * This size will be typically a power of 2.
348 * Value less or equal to %0 is forbidden.
350 * General pointer up-rounding macro. Already aligned pointer is left as is.
352 * glib NOTE: YOU MAY NOT STORE POINTERS IN INTEGERS.
354 * @Returns: Up-rounded @pointer to the integer multiple of @fragment.
355 * Resulting pointer has the same type as @pointer.
357 #define CAPTIVE_ROUND_UP(pointer,fragment) \
358 /* new retyping as 'pointer' gets passed as 'char *' to CAPTIVE_ROUND_DOWN(). */ \
359 ((typeof(pointer))(CAPTIVE_ROUND_DOWN(((guint32)(pointer))+(fragment)-1,(fragment))))
360 #define CAPTIVE_ROUND_UP64(pointer,fragment) \
361 /* new retyping as 'pointer' gets passed as 'char *' to CAPTIVE_ROUND_DOWN(). */ \
362 ((typeof(pointer))(CAPTIVE_ROUND_DOWN64(((guint64)(pointer))+(fragment)-1,(fragment))))
367 #endif /* _CAPTIVE_MACROS_H */