Some kind of general purpose C library. This is discontinued and only kept as a reference just in case I need something from it.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

308 lines
15 KiB

/**
* \file scot/list_mod.h
* \author Georg Steffers <georg@steffers.org>
* \brief Templates of functions to modify typesafe lists.
*
* Here are macro definitions that create functions to modify typesafe
* lists. That is read, write, insert, delete a.s.f.
*
* Normally the macros defined here will be never called directly but only
* via MACROS that group them in a sensefull way in scot/list_impl.h.\n
* \anchor onlyfunc_mod
* \attention
* All documentation here does document the functions that are created by
* the macros, as the macros themself are pretty easy and all used the same.
* They are called with a type, that MUST be one word (use typedef if needed)
* and generates the function defined with their value.
*
* Copyright (C)2006 Georg Steffers <georg@steffers.org>
*
* 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.
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LIST_MOD_H
#define LIST_MOD_H
#include <stdlib.h>
#include <scot/list_impl.h>
#include <scot/memory.h> /* because we use functions from there */
/**
* \internal
* \param node a list_[type]_node_t* that should be checked for
* beeing an anchor.
* \param line the line where this MACRO is called.
* \pre a variable of type list_<type>_node_t* must exist.
* \return the code fragment
* \post None
*
* \brief check for anchor.
*
* This checks if the given \a node is an anchor. If not it calls
* LIST_ERROR, which either raises an exception if exceptions are user
* or otherwise prints out an error message to stderr and aborts the
* program.
*/
#define MOD_NODE_NO_ANCHOR_ERROR(node, line) \
if ((node->e) != NULL) \
LIST_ERROR ("list_mod.h", (line), NODE_NO_ANCHOR_ERR);
/**
* \attention
* Only the generated function is explained here, for the reason look
* \ref onlyfunc_mod "here".
*
* \param node A pointer to a node in the list.
* \pre The \a node must be part of a correctly
* initialized list.
* \return The element saved in the node.
* \post None
*
* \brief Retrive element from node.
*
* This function retrieves the element from a node of a list.
*/
#define GEN_LIST_RETRIVE(type) \
STATIC \
type * \
list_ ## type ## _retrive (list_ ## type ## _node_t *node) \
{ \
LIST_EXC_START \
LIST_CHECK_NULL (node, "list_mod.h", 18); \
LIST_EXC_END ("list_mod.h", 19, LIST_RETR_ERR); \
\
return (type *) node->e; \
}
/**
* \attention
* Only the generated function is explained here, for the reason look
* \ref onlyfunc_mod "here".
*
* \param node A pointer to a node in the list.
* \param e A pointer to a variable of the \a type, the
* list was created for.
* \pre The \a node must be part of a correctly
* initialized list. \a e must not be NULL.
* \return Nothing
* \post The element of \a node is \a e.
*
* \brief Set element od node.
*
* This function sets the element from a node of a list.
*/
#define GEN_LIST_SET(type) \
STATIC \
void \
list_ ## type ## _set ( \
list_ ## type ## _node_t *node, \
const type *e) \
{ \
LIST_EXC_START \
{ \
LIST_CHECK_NULL (node, "list_mod.h", 33); \
LIST_CHECK_NULL (e, "list_mod.h", 34); \
} \
LIST_EXC_END ("list_mod.h", 36, LIST_SET_ERR); \
\
node->e = e; \
}
/**
* \attention
* Only the generated function is explained here, for the reason look
* \ref onlyfunc_mod "here".
*
* \param node A pointer to a node in the list.
* \param e A pointer to a variable of the \a type, the
* list was created for.
* \pre The \a node must be part of a correctly
* initialized list.
* \a e must not be NULL.
* \return The node of the inserted element.
* \post List has one new node containing \a e.
*
* \brief Inserts a new node with element \a e into the list.
*
* This function creates a new list node and initializes it with
* \a e. Then this new node will be inserted behind \a node.
*/
#define GEN_LIST_INSERT(type) \
STATIC \
list_ ## type ## _node_t * \
list_ ## type ## _insert ( \
list_ ## type ## _node_t *node, \
const type *e) \
{ \
list_ ## type ## _node_t *ret; \
\
LIST_EXC_START \
{ \
list_ ## type ## _node_t *new_node; \
\
LIST_CHECK_NULL (node, "list_mod.h", 54); \
LIST_CHECK_NULL (e, "list_mod.h", 55); \
\
new_node = (list_ ## type ## _node_t *) \
LIST_MALLOC (sizeof (list_ ## type ## _node_t), \
"list_mod.h", 58); \
\
new_node->e = e; \
new_node->prev = node; \
new_node->next = node->next; \
node->next->prev = new_node; \
node->next = new_node; \
\
ret = new_node; \
} \
LIST_EXC_END ("list_mod.h", 69, LIST_INSERT_ERR); \
\
return ret; \
}
/**
* \attention
* Only the generated function is explained here, for the reason look
* \ref onlyfunc_mod "here".
*
* \param node A pointer to a node in the list.
* \pre The \a node must be part of a correctly
* initialized list.
* \return The next node behind the deleted one.
* \post The \a node is removed from the list and
* freed.
*
* \brief Deletes a new node with element \a e into the list.
*
* This function deletes a node from the list it is in. The node
* will be freed but by default NOT the element. Anyway, one can set
* a free function for elements of the list. This should free any
* resource the element has reserved.
* This function can be set with
* \link list_man.h::GEN_LIST_SET_ELEM_FREE
* list_[type]_set_elem_free ()\endlink
* and if set, is called by list_[type]_delete(). If such a function
* was set and one wants to reset to default behaviour (not to delete any
* element) one can pass NULL to \link list_man.h::GEN_LIST_SET_ELEM_FREE
* list_[type]_set_elem_free ()\endlink.
*/
#define GEN_LIST_DELETE(type) \
STATIC \
list_ ## type ## _node_t * \
list_ ## type ## _delete (list_ ## type ## _node_t *node) \
{ \
type *e; \
list_ ## type ## _node_t *prev, \
*next; \
\
LIST_EXC_START \
{ \
if (list_ ## type ## _isempty (node)) \
LIST_WARNING ("list_mod.h", 86, DEL_ON_EMPTY_LIST_WRN); \
\
e = (type *) node->e; \
\
prev = node->prev; \
next = node->next; \
prev->next = next; \
next->prev = prev; \
\
if (list_ ## type ## _elem_free != NULL && e != NULL) \
list_ ## type ## _elem_free (e); \
\
SCOT_MEM_FREE (node); \
} \
LIST_EXC_END ("list_mod.h", 101, LIST_DELETE_ERR); \
\
return next; \
}
/**
* \attention
* Only the generated function is explained here, for the reason look
* \ref onlyfunc_mod "here".
*
* \param anchor1 A pointer to the first list anchor.
* \param anchor2 A pointer to the second list anchor.
* \pre Both, \a anchor1 and \a anchor2 must be
* valid list_anchors.
* \return The anchor of the new concatenated list.
* \post A new list was created that contains both
* given lists. The anchor of at least one of the
* given lists is no longer valid and should no
* longer be used. In fact only the returned
* anchor is garantied to point to a valid list.
*
* \brief Concatenates two lists.
*
* This function joins the given two list to one. This will be done
* partly destructive...that is, at least one of the old anchors
* will be deleted.
*/
#define GEN_LIST_CONCAT(type) \
STATIC \
list_ ## type ## _node_t * \
list_ ## type ## _concat ( \
list_ ## type ## _node_t *anchor1, \
list_ ## type ## _node_t *anchor2) \
{ \
LIST_EXC_START \
{ \
LIST_CHECK_NULL (anchor1, "list_mod.h", 115); \
MOD_NODE_NO_ANCHOR_ERROR (anchor1, 116); \
LIST_CHECK_NULL (anchor2, "list_mod.h", 117); \
MOD_NODE_NO_ANCHOR_ERROR (anchor2, 118); \
} \
LIST_EXC_END ("list_mod.h", 120, LIST_CONCAT_ERR); \
\
if (list_ ## type ## _isempty (anchor1)) \
return anchor2; \
\
if (list_ ## type ## _isempty (anchor2)) \
return anchor1; \
\
anchor2->next->prev = anchor1->prev; \
anchor2->prev->next = anchor1; \
anchor1->prev->next = anchor2->next; \
anchor1->prev = anchor2->prev; \
}
/**
* \param type the datatype that this list code should handle.
* \pre Type must be a single word typename. If one wants
* to use e.g. lists of structs one has to use typedef
* to create a single word type name like this:
* typedef struct mystruct_t mystruct_t;
* \return Nothing
* \post The functions for the given datatype that are described
* here are generated within the calling build file.
*
* \brief create functions neccesary to modify lists of the given \a type.
*
* Normally this is not called directly, but by GEN_LIST_IMPL() because this
* defines just a subset of all functions neccesarry to handle typesafe lists.
*/
#define GEN_LIST_MODIFY(type) \
GEN_LIST_RETRIVE (type); \
GEN_LIST_SET (type); \
GEN_LIST_INSERT (type); \
GEN_LIST_DELETE (type); \
GEN_LIST_CONCAT (type);
#endif /* LIST_MOD_H */