Standard-Macros

Defines some generic C macros useful during preprocessing time of C files.

Summary
Standard-MacrosDefines some generic C macros useful during preprocessing time of C files.
CopyrightThis program is free software.
Files
C-kern/api/context/stdmacros.hHeader file Standard-Macros.
C-kern/konfig.hIncluded from header Konfiguration.
Macros
string
CONCATCombines two language tokens into one.
CONCAT2Used by CONCAT to ensure expansion of arguments.
STRMakes string token out of argument.
STR2Used by STR to ensure expansion of arguments.
cast
CONST_CASTRemoves the const from ptr.
structofConverts pointer to member of structure to pointer of containing structure.
VOLATILE_CASTRemoves the volatile from ptr.
function-declaration
IDNAMEIt’s a marker in a function declaration.
TYPENAMEIt’s a marker in a function declaration.
TYPEQUALIFIERIt’s a marker in a function declaration.
size-calculations
bitsofCalculates memory size of a type in number of bits.
lengthofReturns number of elements of the first dimension of a static array.
memory
MEMCOPYCopies memory from source to destination.
MEMSET0Sets memory of variable to 0.
SWAPSwaps content of two local variables.

Copyright

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.

Author

© 2012 Jörg Seebohn

Files

C-kern/api/context/stdmacros.h

Header file Standard-Macros.

C-kern/konfig.h

Included from header Konfiguration.

Macros

Summary
string
CONCATCombines two language tokens into one.
CONCAT2Used by CONCAT to ensure expansion of arguments.
STRMakes string token out of argument.
STR2Used by STR to ensure expansion of arguments.
cast
CONST_CASTRemoves the const from ptr.
structofConverts pointer to member of structure to pointer of containing structure.
VOLATILE_CASTRemoves the volatile from ptr.
function-declaration
IDNAMEIt’s a marker in a function declaration.
TYPENAMEIt’s a marker in a function declaration.
TYPEQUALIFIERIt’s a marker in a function declaration.
size-calculations
bitsofCalculates memory size of a type in number of bits.
lengthofReturns number of elements of the first dimension of a static array.
memory
MEMCOPYCopies memory from source to destination.
MEMSET0Sets memory of variable to 0.
SWAPSwaps content of two local variables.

string

CONCAT

#define CONCAT(S1,
S2) CONCAT2(S1,S2)

Combines two language tokens into one.  Calls CONCAT2 to ensure expansion of arguments.

Example

CONCAT(var,__LINE__)  // generates token var10 if current line number is 10
CONCAT2(var,__LINE__) // generates token var__LINE__

CONCAT2

#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.

STR

#define STR(S1) STR2(S1)

Makes string token out of argument.  Calls STR2 to ensure expansion of argument.

Example

STR(__LINE__)  // generates token "10" if current line number is 10
STR2(__LINE__) // generates token "__LINE__"

STR2

#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.

cast

CONST_CAST

#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 ;

structof

#define structof(
   struct_t,
   member,
   ptrmember
) ( __extension__ ({ typeof(((struct_t*)0)->member) * _ptr2 ; _ptr2 = (ptrmember) ; (struct_t*) ((uintptr_t)_ptr2 - offsetof(struct_t, member)) ; }))

Converts pointer to member of structure to pointer of containing structure.

VOLATILE_CAST

#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 ;

function-declaration

IDNAME

#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.

TYPENAME

#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.

TYPEQUALIFIER

#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.

size-calculations

bitsof

#define bitsof(type_t) (8*sizeof(type_t))

Calculates memory size of a type in number of bits.

lengthof

#define lengthof(static_array) (sizeof(static_array) / sizeof(*(static_array)))

Returns number of elements of the first dimension of a static array.

memory

MEMCOPY

#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.

Parameter

destinationPointer to destination address
sourcePointer to source address

MEMSET0

#define MEMSET0(pointer) memset((pointer), 0, sizeof(*(pointer)))

Sets memory of variable to 0.

Parameter

pointerPointer to the variable which will be cleared.

To clear a whole array use &array as parameter

int array[100] ;
MEMSET0(&array) ;

SWAP

#define SWAP(
   var1,
   var2
) { typeof(var1) _temp ; _temp = (var1), (var1) = (var2), (var2) = _temp ; }

Swaps content of two local variables.  This works only for simple types.

Defines some generic C macros useful during preprocessing time of C files.
Global generic configurations.
#define CONCAT(S1,
S2) CONCAT2(S1,S2)
Combines two language tokens into one.
#define CONCAT2(S1,
S2) S1 ## S2
Used by CONCAT to ensure expansion of arguments.
#define STR(S1) STR2(S1)
Makes string token out of argument.
#define STR2(S1) # S1
Used by STR to ensure expansion of arguments.
#define CONST_CAST(
   type_t,
   ptr
) ( __extension__ ({ const type_t * _ptr1 = (ptr) ; (type_t*) ((uintptr_t)_ptr1) ; }))
Removes the const from ptr.
#define structof(
   struct_t,
   member,
   ptrmember
) ( __extension__ ({ typeof(((struct_t*)0)->member) * _ptr2 ; _ptr2 = (ptrmember) ; (struct_t*) ((uintptr_t)_ptr2 - offsetof(struct_t, member)) ; }))
Converts pointer to member of structure to pointer of containing structure.
#define VOLATILE_CAST(
   type_t,
   ptr
) ( __extension__ ({ volatile type_t * _ptr = (ptr) ; (type_t*)((uintptr_t)_ptr) ; }))
Removes the volatile from ptr.
#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*
It’s a marker in a function declaration.
#define bitsof(type_t) (8*sizeof(type_t))
Calculates memory size of a type in number of bits.
#define lengthof(static_array) (sizeof(static_array) / sizeof(*(static_array)))
Returns number of elements of the first dimension of a static array.
#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.
#define MEMSET0(pointer) memset((pointer), 0, sizeof(*(pointer)))
Sets memory of variable to 0.
#define SWAP(
   var1,
   var2
) { typeof(var1) _temp ; _temp = (var1), (var1) = (var2), (var2) = _temp ; }
Swaps content of two local variables.
#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 dlist_t.dlist_IMPLEMENT.
#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 typeadapt_lifetime_it.genericcast_typeadaptlifetime.
#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) ; }))
Implements mmfile_t.genericcast_mmfile.
#define static_assert(C,
S) ((void)(sizeof(char[(C)?1:-1])))
Checks condition to be true during compilation.
Close