Defines some generic C macros useful during preprocessing time of C files.
Standard-Macros | Defines some generic C macros useful during preprocessing time of C files. |
Copyright | This program is free software. |
Files | |
C-kern/ | Header file Standard-Macros. |
C-kern/ | Included from header Konfiguration. |
Macros | |
string | |
CONCAT | Combines two language tokens into one. |
CONCAT2 | Used by CONCAT to ensure expansion of arguments. |
STR | Makes string token out of argument. |
STR2 | Used by STR to ensure expansion of arguments. |
cast | |
CONST_CAST | Removes the const from ptr. |
structof | Converts pointer to member of structure to pointer of containing structure. |
VOLATILE_CAST | Removes the volatile from ptr. |
function-declaration | |
IDNAME | It’s a marker in a function declaration. |
TYPENAME | It’s a marker in a function declaration. |
TYPEQUALIFIER | It’s a marker in a function declaration. |
size-calculations | |
bitsof | Calculates memory size of a type in number of bits. |
lengthof | Returns number of elements of the first dimension of a static array. |
memory | |
MEMCOPY | Copies memory from source to destination. |
MEMSET0 | Sets memory of variable to 0. |
SWAP | Swaps content of two local variables. |
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; either version 2 of the License, or (at your option) any later version.
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.
© 2012 Jörg Seebohn
Header file Standard-Macros.
Included from header Konfiguration.
string | |
CONCAT | Combines two language tokens into one. |
CONCAT2 | Used by CONCAT to ensure expansion of arguments. |
STR | Makes string token out of argument. |
STR2 | Used by STR to ensure expansion of arguments. |
cast | |
CONST_CAST | Removes the const from ptr. |
structof | Converts pointer to member of structure to pointer of containing structure. |
VOLATILE_CAST | Removes the volatile from ptr. |
function-declaration | |
IDNAME | It’s a marker in a function declaration. |
TYPENAME | It’s a marker in a function declaration. |
TYPEQUALIFIER | It’s a marker in a function declaration. |
size-calculations | |
bitsof | Calculates memory size of a type in number of bits. |
lengthof | Returns number of elements of the first dimension of a static array. |
memory | |
MEMCOPY | Copies memory from source to destination. |
MEMSET0 | Sets memory of variable to 0. |
SWAP | Swaps content of two local variables. |
#define CONCAT( S1, S2 ) CONCAT2(S1,S2)
Combines two language tokens into one. Calls CONCAT2 to ensure expansion of arguments.
CONCAT(var,__LINE__) // generates token var10 if current line number is 10 CONCAT2(var,__LINE__) // generates token var__LINE__
#define CONCAT2( S1, S2 ) S1 ## S2
Used by CONCAT to ensure expansion of arguments. This macro does the real work - combining two language tokens into one.
#define STR( S1 ) STR2(S1)
Makes string token out of argument. Calls STR2 to ensure expansion of argument.
STR(__LINE__) // generates token "10" if current line number is 10 STR2(__LINE__) // generates token "__LINE__"
#define STR2( S1 ) # S1
Used by STR to ensure expansion of arguments. This macro does the real work - making a string out of its argument.
#define CONST_CAST( type_t, ptr ) ( __extension__ ({ const type_t * _ptr1 = (ptr) ; (type_t*) ((uintptr_t)_ptr1) ; }))
Removes the const from ptr. Use this macro to remove a const from a pointer. This macro is safe so if you cast the pointer to a wrong type a warning is issued by the compiler. Parameter ptr must be of type
const type_t * ptr ;
The returned type is
(type_t *) ptr ;
#define VOLATILE_CAST( type_t, ptr ) ( __extension__ ({ volatile type_t * _ptr = (ptr) ; (type_t*)((uintptr_t)_ptr) ; }))
Removes the volatile from ptr. Use this macro to remove a vvolatile from a pointer. This macro is safe so if you cast the pointer to a wrong type a warning is issued by the compiler. Parameter ptr must be of type
volatile type_t * ptr ;
The returned type is
(type_t*) ptr ;
#define IDNAME void*
It’s a marker in a function declaration. It is used in function declarations which are implemented as macro. An identifier name is not supported in language C99 or later. See dlist_IMPLEMENT for an example.
#define TYPENAME void*
It’s a marker in a function declaration. It is used in function declarations which are implemented as macro. A type name is not supported in language C99 or later. See genericcast_typeadaptlifetime for an example.
#define TYPEQUALIFIER void*
It’s a marker in a function declaration. It is used in function declarations which are implemented as macro. Set it to either an empty value ,, or to ,const,. See genericcast_mmfile for an example.
#define MEMCOPY( destination, source ) do { static_assert(sizeof(*(destination)) == sizeof(*(source)),"same size") ; memcpy((destination), (source), sizeof(*(destination))) ; } while(0)
Copies memory from source to destination. The values of sizeof(*(source)) and sizeof(*(destination)) must compare equal. This is checked by static_assert.
destination | Pointer to destination address |
source | Pointer to source address |
Combines two language tokens into one.
#define CONCAT( S1, S2 ) CONCAT2(S1,S2)
Used by CONCAT to ensure expansion of arguments.
#define CONCAT2( S1, S2 ) S1 ## S2
Makes string token out of argument.
#define STR( S1 ) STR2(S1)
Used by STR to ensure expansion of arguments.
#define STR2( S1 ) # S1
Removes the const from ptr.
#define CONST_CAST( type_t, ptr ) ( __extension__ ({ const type_t * _ptr1 = (ptr) ; (type_t*) ((uintptr_t)_ptr1) ; }))
Converts pointer to member of structure to pointer of containing structure.
#define structof( struct_t, member, ptrmember ) ( __extension__ ({ typeof(((struct_t*)0)->member) * _ptr2 ; _ptr2 = (ptrmember) ; (struct_t*) ((uintptr_t)_ptr2 - offsetof(struct_t, member)) ; }))
Removes the volatile from ptr.
#define VOLATILE_CAST( type_t, ptr ) ( __extension__ ({ volatile type_t * _ptr = (ptr) ; (type_t*)((uintptr_t)_ptr) ; }))
It’s a marker in a function declaration.
#define IDNAME void*
It’s a marker in a function declaration.
#define TYPENAME void*
It’s a marker in a function declaration.
#define TYPEQUALIFIER void*
Calculates memory size of a type in number of bits.
#define bitsof( type_t ) (8*sizeof(type_t))
Returns number of elements of the first dimension of a static array.
#define lengthof( static_array ) (sizeof(static_array) / sizeof(*(static_array)))
Copies memory from source to destination.
#define MEMCOPY( destination, source ) do { static_assert(sizeof(*(destination)) == sizeof(*(source)),"same size") ; memcpy((destination), (source), sizeof(*(destination))) ; } while(0)
Sets memory of variable to 0.
#define MEMSET0( pointer ) memset((pointer), 0, sizeof(*(pointer)))
Swaps content of two local variables.
#define SWAP( var1, var2 ) { typeof(var1) _temp ; _temp = (var1), (var1) = (var2), (var2) = _temp ; }
Implements dlist_t.dlist_IMPLEMENT.
#define dlist_IMPLEMENT( _fsuffix, object_t, nodeprefix ) typedef dlist_iterator_t iteratortype##_fsuffix ; typedef object_t * iteratedtype##_fsuffix ; static inline int initfirst##_fsuffix##iterator(dlist_iterator_t * iter, dlist_t * list) __attribute__ ((always_inline)) ; static inline int initlast##_fsuffix##iterator(dlist_iterator_t * iter, dlist_t * list) __attribute__ ((always_inline)) ; static inline int free##_fsuffix##iterator(dlist_iterator_t * iter) __attribute__ ((always_inline)) ; static inline bool next##_fsuffix##iterator(dlist_iterator_t * iter, object_t ** node) __attribute__ ((always_inline)) ; static inline bool prev##_fsuffix##iterator(dlist_iterator_t * iter, object_t ** node) __attribute__ ((always_inline)) ; static inline void init##_fsuffix(dlist_t * list) __attribute__ ((always_inline)) ; static inline int free##_fsuffix(dlist_t * list, struct typeadapt_t * typeadp) __attribute__ ((always_inline)) ; static inline int isempty##_fsuffix(const dlist_t * list) __attribute__ ((always_inline)) ; static inline object_t * first##_fsuffix(const dlist_t * list) __attribute__ ((always_inline)) ; static inline object_t * last##_fsuffix(const dlist_t * list) __attribute__ ((always_inline)) ; static inline object_t * next##_fsuffix(object_t * node) __attribute__ ((always_inline)) ; static inline object_t * prev##_fsuffix(object_t * node) __attribute__ ((always_inline)) ; static inline bool isinlist##_fsuffix(object_t * node) __attribute__ ((always_inline)) ; static inline void insertfirst##_fsuffix(dlist_t * list, object_t * new_node) __attribute__ ((always_inline)) ; static inline void insertlast##_fsuffix(dlist_t * list, object_t * new_node) __attribute__ ((always_inline)) ; static inline void insertafter##_fsuffix(dlist_t * list, object_t * prev_node, object_t * new_node) __attribute__ ((always_inline)) ; static inline void insertbefore##_fsuffix(object_t* next_node, object_t * new_node) __attribute__ ((always_inline)) ; static inline int removefirst##_fsuffix(dlist_t * list, object_t ** removed_node) __attribute__ ((always_inline)) ; static inline int removelast##_fsuffix(dlist_t * list, object_t ** removed_node) __attribute__ ((always_inline)) ; static inline int remove##_fsuffix(dlist_t * list, object_t * node) __attribute__ ((always_inline)) ; static inline void replacenode##_fsuffix(dlist_t * list, object_t * newnode, object_t * oldnode) __attribute__ ((always_inline)) ; static inline int removeall##_fsuffix(dlist_t * list, struct typeadapt_t * typeadp) __attribute__ ((always_inline)) ; static inline void transfer##_fsuffix(dlist_t * tolist, dlist_t * fromlist) __attribute__ ((always_inline)) ; static inline uint16_t nodeoffset##_fsuffix(void) __attribute__ ((always_inline)) ; static inline uint16_t nodeoffset##_fsuffix(void) { static_assert(UINT16_MAX > (uintptr_t) & (((object_t*)0)->nodeprefix next), "offset fits in uint16_t") ; return (uint16_t) (uintptr_t) & (((object_t*)0)->nodeprefix next) ; } static inline dlist_node_t * asnode##_fsuffix(object_t * object) { static_assert(&(((object_t*)0)->nodeprefix next) == (dlist_node_t**)((uintptr_t)nodeoffset##_fsuffix()), "correct type") ; static_assert(&(((object_t*)0)->nodeprefix prev) == (dlist_node_t**)(nodeoffset##_fsuffix() + sizeof(dlist_node_t*)), "correct type and offset") ; return (dlist_node_t *) ((uintptr_t)object + nodeoffset##_fsuffix()) ; } static inline object_t * asobject##_fsuffix(dlist_node_t * node) { return (object_t *) ((uintptr_t)node - nodeoffset##_fsuffix()) ; } static inline object_t * asobjectnull##_fsuffix(dlist_node_t * node) { return node ? (object_t *) ((uintptr_t)node - nodeoffset##_fsuffix()) : 0 ; } static inline void init##_fsuffix(dlist_t * list) { init_dlist(list) ; } static inline int free##_fsuffix(dlist_t * list, struct typeadapt_t * typeadp) { return free_dlist(list, nodeoffset##_fsuffix(), typeadp) ; } static inline int isempty##_fsuffix(const dlist_t * list) { return isempty_dlist(list) ; } static inline object_t * first##_fsuffix(const dlist_t * list) { return asobjectnull##_fsuffix(first_dlist(list)) ; } static inline object_t * last##_fsuffix(const dlist_t * list) { return asobjectnull##_fsuffix(last_dlist(list)) ; } static inline object_t * next##_fsuffix(object_t * node) { return asobject##_fsuffix(next_dlist(asnode##_fsuffix(node))) ; } static inline object_t * prev##_fsuffix(object_t * node) { return asobject##_fsuffix(prev_dlist(asnode##_fsuffix(node))) ; } static inline bool isinlist##_fsuffix(object_t * node) { return isinlist_dlist(asnode##_fsuffix(node)) ; } static inline void insertfirst##_fsuffix(dlist_t * list, object_t * new_node) { insertfirst_dlist(list, asnode##_fsuffix(new_node)) ; } static inline void insertlast##_fsuffix(dlist_t * list, object_t * new_node) { insertlast_dlist(list, asnode##_fsuffix(new_node)) ; } static inline void insertafter##_fsuffix(dlist_t * list, object_t * prev_node, object_t * new_node) { insertafter_dlist(list, asnode##_fsuffix(prev_node), asnode##_fsuffix(new_node)) ; } static inline void insertbefore##_fsuffix(object_t * next_node, object_t * new_node) { insertbefore_dlist(asnode##_fsuffix(next_node), asnode##_fsuffix(new_node)) ; } static inline int removefirst##_fsuffix(dlist_t * list, object_t ** removed_node) { int err = removefirst_dlist(list, (dlist_node_t**)removed_node) ; if (!err) *removed_node = asobject##_fsuffix(*(dlist_node_t**)removed_node) ; return err ; } static inline int removelast##_fsuffix(dlist_t * list, object_t ** removed_node) { int err = removelast_dlist(list, (dlist_node_t**)removed_node) ; if (!err) *removed_node = asobject##_fsuffix(*(dlist_node_t**)removed_node) ; return err ; } static inline int remove##_fsuffix(dlist_t * list, object_t * node) { return remove_dlist(list, asnode##_fsuffix(node)) ; } static inline void replacenode##_fsuffix(dlist_t * list, object_t * newnode, object_t * oldnode) { replacenode_dlist(list, asnode##_fsuffix(newnode), asnode##_fsuffix(oldnode)) ; } static inline int removeall##_fsuffix(dlist_t * list, struct typeadapt_t * typeadp) { return removeall_dlist(list, nodeoffset##_fsuffix(), typeadp) ; } static inline void transfer##_fsuffix(dlist_t * tolist, dlist_t * fromlist) { transfer_dlist(tolist, fromlist) ; } static inline int initfirst##_fsuffix##iterator(dlist_iterator_t * iter, dlist_t * list) { return initfirst_dlistiterator(iter, list) ; } static inline int initlast##_fsuffix##iterator(dlist_iterator_t * iter, dlist_t * list) { return initlast_dlistiterator(iter, list) ; } static inline int free##_fsuffix##iterator(dlist_iterator_t * iter) { return free_dlistiterator(iter) ; } static inline bool next##_fsuffix##iterator(dlist_iterator_t * iter, object_t ** node) { bool isNext = next_dlistiterator(iter, (dlist_node_t**)node) ; if (isNext) *node = asobject##_fsuffix(*(dlist_node_t**)node) ; return isNext ; } static inline bool prev##_fsuffix##iterator(dlist_iterator_t * iter, object_t ** node) { bool isNext = prev_dlistiterator(iter, (dlist_node_t**)node) ; if (isNext) *node = asobject##_fsuffix(*(dlist_node_t**)node) ; return isNext ; }
Implements typeadapt_lifetime_it.genericcast_typeadaptlifetime.
#define genericcast_typeadaptlifetime( adplife, typeadapter_t, object_t ) ( __extension__ ({ static_assert( offsetof(typeadapt_lifetime_it, newcopy_object) == offsetof(typeof(*(adplife)), newcopy_object) && offsetof(typeadapt_lifetime_it, delete_object) == offsetof(typeof(*(adplife)), delete_object), "ensure same structure") ; if (0) { int _err = (adplife)->newcopy_object((typeadapter_t*)0, (object_t**)0, (const object_t*)0) ; _err += (adplife)->delete_object((typeadapter_t*)0, (object_t**)0) ; (void) _err ; } (typeadapt_lifetime_it*) (adplife) ; }))
Implements mmfile_t.genericcast_mmfile.
#define genericcast_mmfile( obj, nameprefix, qualifier ) ( __extension__ ({ typeof(obj) _obj = (obj) ; static_assert( sizeof(_obj->nameprefix##addr) == sizeof(((mmfile_t*)0)->addr) && 0 == offsetof(mmfile_t, addr), && (typeof(_obj->nameprefix##addr)*)0 == (uint8_t**)0 && sizeof(_obj->nameprefix##size) == sizeof(((mmfile_t*)0)->size) && offsetof(mmfile_t, size) == ((uintptr_t)&_obj->nameprefix##size) -((uintptr_t)&_obj->nameprefix##addr) && (typeof(_obj->nameprefix##size)*)0 == (size_t**)0 "structure is compatible") ; (qualifier mmfile_t *)(&_obj->nameprefix##addr) ; }))
Checks condition to be true during compilation.
#define static_assert( C, S ) ((void)(sizeof(char[(C)?1:-1])))