/*
- silclist.h
+ silclist.h
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2002 - 2003 Pekka Riikonen
+ Copyright (C) 2002 - 2007 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
* DESCRIPTION
*
* Implementation of the SilcList interface. This interface provides
- * simple linked list.
+ * simple linked list. This 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.
*
***/
/****s* silcutil/SilcList/SilcList
*
* NAME
- *
+ *
* typedef struct { ... } SilcList;
*
* DESCRIPTION
* 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 */
/****d* silcutil/SilcList/SILC_LIST_END
*
* NAME
- *
+ *
* #define SILC_LIST_END ...
*
* DESCRIPTION
*
* 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'.
*
***/
(list).count++; \
} while(0)
+/****f* silcutil/SilcList/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/SilcList/silc_list_del
*
* SYNOPSIS
*
* 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) {
* ...