Macros For Typesafe List Handling

The macros of this group facilitates typesafe use of lists.

Let's assume you have a structure type called MYSTRUCT and you want to manage lists of them. Let's further assume that you want the functions dealing with that struct have prefixes like MyStruct (as in MyStruct_new)

The header file would look like this:

/ * mystruct.h * /
#ifndef MYSTRUCT_H
#define MYSTRUCT_H
typedef struct MYSTRUCT MYSTRUCT;
GWEN_LIST_FUNCTION_DEFS(MYSTRUCT, MyStruct);
struct MYSTRUCT {
GWEN_LIST_ELEMENT(MYSTRUCT);
int myData;
}
MYSTRUCT *MyStruct_new(int myData);
void MyStruct_free(MYSTRUCT *myStruct);
#endif
GWEN_LIST_FUNCTION_DEFS
#define GWEN_LIST_FUNCTION_DEFS(t, pr)
Definition list1.h:358
GWEN_LIST_ELEMENT
#define GWEN_LIST_ELEMENT(t)
Definition list1.h:255

This defines all necessary data and function prototypes needed for list management.

The code file would look quite similar to the following:

/ * mystruct.c * /
GWEN_LIST_FUNCTIONS(MYSTRUCT, MyStruct)
MYSTRUCT *MyStruct_new(int myData) {
MYSTRUCT *pMyStruct;
pMyStruct=(MYSTRUCT*)malloc(sizeof(MYSTRUCT));
memset(pMyStruct, 0, sizeof(MYSTRUCT));
GWEN_LIST_INIT(MYSTRUCT, pMyStruct)
pMyStruct->myData=myData;
return pMyStruct;
}
void MyStruct_free(MYSTRUCT *pMyStruct) {
if (pMyStruct) {
pMyStruct->myData=0;
GWEN_LIST_FINI(MYSTRUCT, pMyStruct)
free(pMyStruct);
}
}
GWEN_LIST_FINI
#define GWEN_LIST_FINI(t, element)
Definition list1.h:475
GWEN_LIST_FUNCTIONS
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition list1.h:367
GWEN_LIST_INIT
#define GWEN_LIST_INIT(t, element)
Definition list1.h:466

Please note the three macros used in the code file:

- GWEN_LIST_FUNCTIONS creates the functions for the list management
- GWEN_LIST_INIT initializes the list data inside your struct to defined values
- GWEN_LIST_FINI frees all ressources occupied by the list management code. Please note that this macro should be the last statement inside the destructor function before free()

Note: When writing these macro code lines, the original ISO C89 standard for the C language does not allow terminating the macro statement with a semicolon ';'. Any recent compiler will probably silently ignore such an extra ';', but you should be aware that this can cause problems once one of your users tries to compile this with a different compiler. Therefore these code lines should end directly with the closing parentheses.

The list management code assumes that there is a function called (in this example) MyStruct_free() (or generally: TYPEPREFIX_free). This is used when destroying a list of MYSTRUCT elements. In this case all elements still enlisted are destroyed upon destruction of the list.