/* $Id$ * Include file with general macros and typedefs used through Captive project * Copyright (C) 2002 Jan Kratochvil * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; exactly version 2 of June 1991 is required * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CAPTIVE_MACROS_H #define _CAPTIVE_MACROS_H 1 #include #include #include #include /* for memset() */ #include #include G_BEGIN_DECLS /** * CAPTIVE_FAKEUSE: * * Prevent 'might be used uninitialized' warning. * Macro will fakes the use of the variable as sometimes GCC can't code flow * analyse #C correctly. * * * * g_some_type some_variable CAPTIVE_FAKEUSE; * * */ #define CAPTIVE_FAKEUSE =0 /** * captive_newn: * @objp: Variable with the pointer to the objects wished to be allocated. * Original value is discarded. * @n: Numbers of objects to be allocated. Value %0 is permitted (%NULL assignment effect). * * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp. * Allocated memory may contain garbage. * * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp))*n. * Value %NULL is returned iff @n==%0; */ #define captive_newn(objp,n) ((objp)=g_new(typeof(*(objp)),(n))) /** * captive_new0n: * @objp: Variable with the pointer to the objects wished to be allocated and precleared. * Original value is discarded. * @n: Numbers of objects to be allocated. Value %0 is permitted (%NULL assignment effect). * * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp. * Allocated memory is precleared. * * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp))*n. * Value %NULL is returned iff @n==%0; */ #define captive_new0n(objp,n) ((objp)=g_new0(typeof(*(objp)),(n))) /** * captive_renewn: * @objp: Variable with the pointer to the objects wished to be reallocated. * Value %NULL is permitted (g_malloc() effect). * @n: Numbers of objects to be allocated. Value %0 is permitted (g_free() effect). * * Macro to reallocate the original memory stored in @objp * to the size @n objects of type *@objp and to assign the resulting pointer to @objp. * New allocated space may contain garbage. Both @objp and @n can be nonexclusively * passed as zero. * * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp))*n. * Value %NULL is returned iff @n==%0; */ #define captive_renewn(objp,n) ({ \ typeof(&(objp)) _captive_renewn_objpp=&(objp); \ *_captive_renewn_objpp=g_renew(typeof(*(objp)),*_captive_renewn_objpp,(n)); \ (*_captive_renewn_objpp); \ }) /** * captive_new: * @objp: Variable with the pointer to the object wished to be allocated. * Original value is discarded. * * Macro to allocate one object of type *@objp and to assign the resulting pointer to @objp. * Allocated memory may contain garbage. Equivalent to captive_newn(objp,1) call. * * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp)). * Value %NULL is never returned. */ #define captive_new(objp) (captive_newn((objp),1)) /** * captive_new0: * @objp: Variable with the pointer to the object wished to be allocated and precleared. * Original value is discarded. * * Macro to allocate one object of type *@objp and to assign the resulting pointer to @objp. * Allocated memory is precleared. Equivalent to captive_new0n(objp,1) call. * * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp)). * Value %NULL is never returned. */ #define captive_new0(objp) (captive_new0n((objp),1)) /** * captive_newn_alloca: * @objp: Variable with the pointer to the objects wished to be allocated. * Original value is discarded. * @n: Numbers of objects to be allocated. Value %0 is permitted (%NULL assignment effect). * * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp. * Allocated memory may contain garbage. * * Memory is allocated on the stack frame by g_alloca() and it will be automatically deallocated * during exit of current function (or current block if variable sized variables present there). * You cannot deallocate or reallocate such memory in any other way. * * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp))*n. * Value %NULL is returned iff @n==%0; */ #define captive_newn_alloca(objp,n) ({ \ gsize _captive_newn_alloca_n=(n); \ /* Fix 'g_alloca(0)!=NULL': */ \ ((objp)=(!_captive_newn_alloca_n ? NULL : g_alloca(sizeof(*(objp))*_captive_newn_alloca_n))); \ }) /** * captive_new0n_alloca: * @objp: Variable with the pointer to the objects wished to be allocated and precleared. * Original value is discarded. * @n: Numbers of objects to be allocated. Value %0 is permitted (%NULL assignment effect). * * Macro to allocate @n objects of type *@objp and to assign the resulting pointer to @objp. * Allocated memory is precleared. * * Memory is allocated on the stack frame by g_alloca() and it will be automatically deallocated * during exit of current function (or current block if variable sized variables present there). * You cannot deallocate or reallocate such memory in any other way. * * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp))*n. * Value %NULL is returned iff @n==%0; */ #define captive_new0n_alloca(objp,n) ({ \ typeof(&(objp)) _captive_new0n_alloca_objpp=&(objp); \ captive_newn_alloca(*_captive_new0n_alloca_objpp,(n)); \ CAPTIVE_MEMZERO(*_captive_new0n_alloca_objpp); \ (*_captive_new0n_alloca_objpp); \ }) /** * captive_new_alloca: * @objp: Variable with the pointer to the object wished to be allocated. * Original value is discarded. * * Macro to allocate one object of type *@objp and to assign the resulting pointer to @objp. * Allocated memory may contain garbage. Equivalent to captive_newn_alloca(objp,1) call. * * Memory is allocated on the stack frame by g_alloca() and it will be automatically deallocated * during exit of current function (or current block if variable sized variables present there). * You cannot deallocate or reallocate such memory in any other way. * * @Returns: Initialized @objp value as the memory of size #sizeof(typeof(*objp)). * Value %NULL is never returned. */ #define captive_new_alloca(objp) (captive_newn_alloca((objp),1)) /** * captive_new0_alloca: * @objp: Variable with the pointer to the object wished to be allocated and precleared. * Original value is discarded. * * Macro to allocate one object of type *@objp and to assign the resulting pointer to @objp. * Allocated memory is precleared. Equivalent to captive_new0n_alloca(objp,1) call. * * @Returns: Initialized @objp value as the cleared memory of size #sizeof(typeof(*objp)). */ #define captive_new0_alloca(objp) (captive_new0n_alloca((objp),1)) /** * captive_va_arg: * @objp: Variable to be filled from the next argument of @ap. * @ap: Initialized #va_list type. * * Automatically determines the size of @objp. * Equivalent to objp=va_arg(ap,typeof(objp)) call. * * @Returns: Initialized @objp value. */ #define captive_va_arg(objp,ap) ((objp)=va_arg((ap),typeof(objp))) /** * CAPTIVE_MEMZERO: * @objp: Pointer to the variable to be cleared. * * Clears the sizeof(*@objp) bytes of the given pointer with memset(). * Pass _pointer_ to the object to be cleared. */ #define CAPTIVE_MEMZERO(objp) (memset((objp),0,sizeof(*(objp)))) /** * captive_printf_alloca: * @format: Format string. See the sprintf() documentation. * @args: Arguments for @format. See the sprintf() documentation. * * Format the given format string @format as in sprintf(). * Output buffer is allocated automatically and it does not need to be deallocated * manually as it is managed by g_alloca(). * * @Returns: Formatted output string located in g_alloca() memory. */ #define captive_printf_alloca(format,args...) ({ \ gsize _captive_printf_alloca_size=captive_nv_printf_string_upper_bound((format) , ## args); \ gchar *_captive_printf_alloca_r=g_alloca(_captive_printf_alloca_size); \ g_snprintf(_captive_printf_alloca_r,_captive_printf_alloca_size,(format) , ## args); \ (const gchar *)_captive_printf_alloca_r; \ }) static inline gsize captive_nv_printf_string_upper_bound(const gchar *format,...) G_GNUC_PRINTF(1,0); static inline gsize captive_nv_printf_string_upper_bound(const gchar *format,...) { va_list ap; gsize r; va_start(ap,format); r=g_printf_string_upper_bound(format,ap); va_end(ap); return r; } G_END_DECLS #endif /* _CAPTIVE_MACROS_H */