Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / libcaptive / include / captive / macros.h
1 /* $Id$
2  * Include file with general macros and typedefs used through Captive project
3  * Copyright (C) 2002 Jan Kratochvil <project-captive@jankratochvil.net>
4  * 
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
8  * 
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.
13  * 
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
17  */
18
19
20 #ifndef _CAPTIVE_MACROS_H
21 #define _CAPTIVE_MACROS_H 1
22
23
24 #include <glib/gmacros.h>
25 #include <glib/gmem.h>
26 #include <stdarg.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> */
31
32
33 G_BEGIN_DECLS
34
35 /**
36  * CAPTIVE_FAKEUSE:
37  *
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.
41  *
42  * <informalexample>
43  * <programlisting>
44  * g_some_type some_variable CAPTIVE_FAKEUSE;
45  * </programlisting>
46  * </informalexample>
47  */
48 #define CAPTIVE_FAKEUSE =0
49
50
51 /**
52  * captive_newn:
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).
56  *
57  * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp.
58  * Allocated memory may contain garbage.
59  *
60  * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp))*n.
61  * Value %NULL is returned iff @n==%0;
62  */
63 #define captive_newn(objp,n) ((objp)=g_new(typeof(*(objp)),(n)))
64
65
66 /**
67  * captive_new0n:
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).
71  *
72  * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp.
73  * Allocated memory is precleared.
74  * 
75  * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp))*n.
76  * Value %NULL is returned iff @n==%0;
77  */
78 #define captive_new0n(objp,n) ((objp)=g_new0(typeof(*(objp)),(n)))
79
80
81 /**
82  * captive_renewn:
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).
86  *
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
90  * passed as zero.
91  * 
92  * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp))*n.
93  * Value %NULL is returned iff @n==%0;
94  */
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); \
99                 })
100
101
102 /**
103  * captive_new:
104  * @objp: Variable with the pointer to the object wished to be allocated.
105  * Original value is discarded.
106  *
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.
109  *
110  * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp)).
111  * Value %NULL is never returned.
112  */
113 #define captive_new(objp) (captive_newn((objp),1))
114
115
116 /**
117  * captive_new0:
118  * @objp: Variable with the pointer to the object wished to be allocated and precleared.
119  * Original value is discarded.
120  *
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.
123  * 
124  * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp)).
125  * Value %NULL is never returned.
126  */
127 #define captive_new0(objp) (captive_new0n((objp),1))
128
129
130 /**
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).
135  *
136  * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp.
137  * Allocated memory may contain garbage.
138  * 
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.
142  *
143  * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp))*n.
144  * Value %NULL is returned iff @n==%0;
145  */
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))); \
150                 })
151
152
153 /**
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).
158  *
159  * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp.
160  * Allocated memory is precleared.
161  * 
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.
165  * 
166  * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp))*n.
167  * Value %NULL is returned iff @n==%0;
168  */
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); \
174                 })
175
176
177 /**
178  * captive_new_alloca:
179  * @objp: Variable with the pointer to the object wished to be allocated.
180  * Original value is discarded.
181  *
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.
184  * 
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.
188  *
189  * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp)).
190  * Value %NULL is never returned.
191  */
192 #define captive_new_alloca(objp) (captive_newn_alloca((objp),1))
193
194
195 /**
196  * captive_new0_alloca:
197  * @objp: Variable with the pointer to the object wished to be allocated and precleared.
198  * Original value is discarded.
199  *
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.
202  * 
203  * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp)).
204  */
205 #define captive_new0_alloca(objp) (captive_new0n_alloca((objp),1))
206
207
208 /**
209  * captive_memdup:
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.
213  *
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.
216  * 
217  * You must free the allocated memory of @destp by g_free().
218  * 
219  * @Returns: Initialized @destp value as the copied memory of size #sizeof(typeof(*srcp)).
220  */
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); \
227                 })
228
229
230 /**
231  * captive_va_arg:
232  * @objp: Variable to be filled from the next argument of @ap.
233  * @ap: Initialized #va_list type.
234  *
235  * Automatically determines the size of @objp.
236  * Equivalent to objp=va_arg(ap,typeof(objp)) call.
237  *
238  * @Returns: Initialized @objp value.
239  */
240 #define captive_va_arg(objp,ap) ((objp)=va_arg((ap),typeof(objp)))
241
242
243 /**
244  * CAPTIVE_MEMZERO:
245  * @objp: Pointer to the variable to be cleared.
246  *
247  * Clears the sizeof(*@objp) bytes of the given pointer with memset().
248  * Pass _pointer_ to the object to be cleared.
249  */
250 #define CAPTIVE_MEMZERO(objp) (memset((objp),0,sizeof(*(objp))))
251
252
253 /**
254  * captive_printf_alloca:
255  * @format: Format string. See the sprintf() documentation.
256  * @args...: Arguments for @format. See the sprintf() documentation.
257  *
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().
261  *
262  * @Returns: Formatted output string located in g_alloca() memory.
263  */
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; \
269                 })
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,...)
272 {
273 va_list ap;
274 gsize r;
275
276         va_start(ap,format);
277         r=g_printf_string_upper_bound(format,ap);
278         va_end(ap);
279         return r;
280 }
281
282
283 /**
284  * captive_strdup_alloca:
285  * @string: #const #gchar * string to duplicate.
286  *
287  * Macro to do g_strdup() equivalent in g_alloca() style.
288  * 
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.
292  *
293  * @Returns: Duplicated @string. You may modify its items if the length is not changed.
294  */
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); \
300                 })
301
302
303 /**
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.
309  *
310  * General pointer down-rounding macro. Already aligned pointer is left as is.
311  *
312  * glib NOTE: YOU MAY NOT STORE POINTERS IN INTEGERS.
313  *
314  * @Returns: Down-rounded @pointer to the integer multiple of @fragment.
315  * Resulting pointer has the same type as @pointer.
316  */
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))))
321
322
323 /**
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.
329  *
330  * Detects current non-aligned amount of data exceeding over integer multiple of @fragment.
331  * It will return value %0 for an aligned pointer.
332  *
333  * glib NOTE: YOU MAY NOT STORE POINTERS IN INTEGERS.
334  *
335  * @Returns: #gsize typed number of bytes exceeding over integer multiple of @fragment.
336  */
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)))
341
342
343 /**
344  * CAPTIVE_ROUND_UP:
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.
349  *
350  * General pointer up-rounding macro. Already aligned pointer is left as is.
351  *
352  * glib NOTE: YOU MAY NOT STORE POINTERS IN INTEGERS.
353  *
354  * @Returns: Up-rounded @pointer to the integer multiple of @fragment.
355  * Resulting pointer has the same type as @pointer.
356  */
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))))
363
364 G_END_DECLS
365
366
367 #endif /* _CAPTIVE_MACROS_H */