X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilclist.h;h=14fab3f54af3aa02c56e7c4dc0b68907dc41240f;hb=4d96aec5a0942c3b9bf66dcbec47c593f267c5ec;hp=60e1bcc4f31e3ef32b44564ad5ebca45a77a62b8;hpb=413da0f8686910f5e627393157566ae729ca99c4;p=runtime.git diff --git a/lib/silcutil/silclist.h b/lib/silcutil/silclist.h index 60e1bcc4..14fab3f5 100644 --- a/lib/silcutil/silclist.h +++ b/lib/silcutil/silclist.h @@ -1,10 +1,10 @@ /* - silclist.h + silclist.h Author: Pekka Riikonen - Copyright (C) 2002 - 2003 Pekka Riikonen + Copyright (C) 2002 - 2008 Pekka Riikonen 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 @@ -17,22 +17,38 @@ */ -/****h* silcutil/SILC List Interface +/****h* silcutil/List Interface * * DESCRIPTION * - * Implementation of the SilcList interface. This interface provides - * simple linked list. + * Generic list interface that can turn any structure with list pointers + * into a SilcList. The interface can provide both singly and doubly linked + * lists. The interface does not allocate any memory. + * + * SILC List is not thread-safe. If the same list context must be used + * in multithreaded environment concurrency control must be employed. + * + * EXAMPLE + * + * struct EntryStruct { + * char *dummy; + * struct EntryStruct *next; // The list member pointer + * }; + * + * SilcList list; + * + * // Initialize list + * silc_list_init(list, struct EntryStruct, next); * ***/ #ifndef SILCLIST_H #define SILCLIST_H -/****s* silcutil/SilcList/SilcList +/****s* silcutil/SilcList * * NAME - * + * * typedef struct { ... } SilcList; * * DESCRIPTION @@ -41,22 +57,22 @@ * function silc_list_init. * ***/ -typedef struct { +typedef struct SilcListStruct { void *head; /* Start of the list */ void *tail; /* End of the list */ void *current; /* Current pointer in list */ - unsigned int next_offset : 16; /* Offset to 'next' pointer */ - unsigned int prev_offset : 16; /* Offset to 'prev' pointer */ + SilcUInt16 next_offset; /* Offset to 'next' pointer */ + SilcUInt16 prev_offset; /* Offset to 'prev' pointer */ unsigned int prev_set : 1; /* Set if 'prev' exists */ unsigned int end_set : 1; /* Set if silc_list_end was called */ unsigned int count : 30; /* Number of entries in the list */ } SilcList; -/****d* silcutil/SilcList/SILC_LIST_END +/****d* silcutil/SILC_LIST_END * * NAME - * - * #define SILC_LIST_END ... + * + * #define SILC_LIST_END NULL * * DESCRIPTION * @@ -68,7 +84,7 @@ typedef struct { #define SILC_LIST_END NULL /***/ -/****f* silcutil/SilcList/silc_list_init +/****f* silcutil/silc_list_init * * SYNOPSIS * @@ -101,10 +117,11 @@ do { \ (list).next_offset = silc_offsetof(type, nextfield); \ (list).prev_set = 0; \ (list).prev_offset = 0; \ + (list).end_set = 0; \ (list).head = (list).tail = (list).current = NULL; \ } while(0) -/****f* silcutil/SilcList/silc_list_init_prev +/****f* silcutil/silc_list_init_prev * * SYNOPSIS * @@ -131,7 +148,7 @@ do { \ * }; * * SilcList list; - * silc_list_init(list, struct SilcInternalEntryStruct, next, prev); + * silc_list_init_prev(list, struct SilcInternalEntryStruct, next, prev); * ***/ #define silc_list_init_prev(list, type, nextfield, prevfield) \ @@ -140,10 +157,11 @@ do { \ (list).next_offset = silc_offsetof(type, nextfield); \ (list).prev_offset = silc_offsetof(type, prevfield); \ (list).prev_set = 1; \ + (list).end_set = 0; \ (list).head = (list).tail = (list).current = NULL; \ } while(0) -/****f* silcutil/SilcList/silc_list_count +/****f* silcutil/silc_list_count * * SYNOPSIS * @@ -156,7 +174,7 @@ do { \ ***/ #define silc_list_count(list) (list).count -/****f* silcutil/SilcList/silc_list_start +/****f* silcutil/silc_list_start * * SYNOPSIS * @@ -171,7 +189,7 @@ do { \ #define silc_list_start(list) \ ((list).current = (list).head, (list).end_set = 0) -/****f* silcutil/SilcList/silc_list_end +/****f* silcutil/silc_list_end * * SYNOPSIS * @@ -197,7 +215,7 @@ do { \ #define __silc_list_prev(list, pos) \ ((void **)((unsigned char *)(pos) + (list).prev_offset)) -/****f* silcutil/SilcList/silc_list_add +/****f* silcutil/silc_list_add * * SYNOPSIS * @@ -205,7 +223,7 @@ do { \ * * DESCRIPTION * - * Adds new entry indicated by `entry' to the end of the list indicated + * Adds new entry indicated by `entry' to the end of the list indicated * by `list'. * ***/ @@ -222,7 +240,49 @@ do { \ (list).count++; \ } while(0) -/****f* silcutil/SilcList/silc_list_del +/****f* silcutil/silc_list_insert + * + * SYNOPSIS + * + * #define silc_list_insert(list, current, entry) ... + * + * DESCRIPTION + * + * Insert new entry indicated by `entry' after the entry `current' + * to the list indicated by `list'. If `current' is NULL, then the + * `entry' is added at the head of the list. Use the silc_list_add + * to add at the end of the list. + * + ***/ +#define silc_list_insert(list, current, entry) \ +do { \ + if (!(current)) { \ + if ((list).head) \ + *__silc_list_next(list, entry) = (list).head; \ + else \ + *__silc_list_next(list, entry) = NULL; \ + if ((list).prev_set && (list).head) \ + *__silc_list_prev(list, (list).head) = entry; \ + if (!(list).tail) \ + (list).tail = (entry); \ + (list).head = (entry); \ + if ((list).prev_set) \ + *__silc_list_prev(list, entry) = NULL; \ + } else { \ + *__silc_list_next(list, entry) = *__silc_list_next(list, current); \ + *__silc_list_next(list, current) = entry; \ + if ((list).prev_set) { \ + *__silc_list_prev(list, entry) = current; \ + if (*__silc_list_next(list, entry)) \ + *__silc_list_prev(list, *__silc_list_next(list, entry)) = entry; \ + } \ + if ((list).tail == (current)) \ + (list).tail = (entry); \ + } \ + (list).count++; \ +} while(0) + +/****f* silcutil/silc_list_del * * SYNOPSIS * @@ -253,7 +313,7 @@ do { \ (list).tail = prev; \ } while(0) -/****f* silcutil/SilcList/silc_list_get +/****f* silcutil/silc_list_get * * SYNOPSIS * @@ -271,7 +331,7 @@ do { \ * * EXAMPLE * - * // Traverse the list from the beginning to the end + * // Traverse the list from the beginning to the end * silc_list_start(list); * while ((entry = silc_list_get(list)) != SILC_LIST_END) { * ...