Added silc_list_pop
authorPekka Riikonen <priikone@silcnet.org>
Sat, 23 Feb 2008 13:43:28 +0000 (15:43 +0200)
committerPekka Riikonen <priikone@silcnet.org>
Sat, 23 Feb 2008 13:43:28 +0000 (15:43 +0200)
The silc_list_pop removes the current head of the list and returns the
removed head.

Changed also documentation.

lib/silcutil/silclist.h
lib/silcutil/tests/test_silclist.c

index 14fab3f54af3aa02c56e7c4dc0b68907dc41240f..52454c30d7f1dd2b2ec1ab575d6d46a7b7520a2e 100644 (file)
@@ -165,7 +165,7 @@ do {                                                                \
  *
  * SYNOPSIS
  *
- *    #define silc_list_count(list) ...
+ *    SilcUInt32 silc_list_count(SilcList list);
  *
  * DESCRIPTION
  *
@@ -178,7 +178,7 @@ do {                                                                \
  *
  * SYNOPSIS
  *
- *    #define silc_list_start(list) ...
+ *    void silc_list_start(SilcList list);
  *
  * DESCRIPTION
  *
@@ -193,7 +193,7 @@ do {                                                                \
  *
  * SYNOPSIS
  *
- *    #define silc_list_end(list) ...
+ *    void silc_list_end(SilcList list);
  *
  * DESCRIPTION
  *
@@ -219,7 +219,7 @@ do {                                                                \
  *
  * SYNOPSIS
  *
- *    #define silc_list_add(list, entry) ...
+ *    void silc_list_add(SilcList list, void *entry);
  *
  * DESCRIPTION
  *
@@ -244,7 +244,7 @@ do {                                                        \
  *
  * SYNOPSIS
  *
- *    #define silc_list_insert(list, current, entry) ...
+ *    void silc_list_insert(SilcList list, void *current, void *entry);
  *
  * DESCRIPTION
  *
@@ -286,7 +286,7 @@ do {                                                                         \
  *
  * SYNOPSIS
  *
- *    #define silc_list_del(list, entry) ...
+ *    void silc_list_del(SilcListlist, void *entry);
  *
  * DESCRIPTION
  *
@@ -300,7 +300,7 @@ do {                                                                        \
   for (p = &(list).head; *p; p = __silc_list_next(list, *p)) {         \
     if (*p == (entry)) {                                               \
       *p = *__silc_list_next(list, entry);                             \
-      if (*p && (list).prev_set)                                       \
+      if ((list).prev_set && *p)                                       \
         *__silc_list_prev(list, *p) = *__silc_list_prev(list, entry);  \
       if ((list).current == (entry))                                   \
         (list).current = *p;                                           \
@@ -317,7 +317,7 @@ do {                                                                        \
  *
  * SYNOPSIS
  *
- *    #define silc_list_get(list) ...
+ *    void *silc_list_get(SilcList list);
  *
  * DESCRIPTION
  *
@@ -355,4 +355,43 @@ void *__silc_list_get(SilcList *list)
   return pos;
 }
 
-#endif
+/****f* silcutil/silc_list_pop
+ *
+ * SYNOPSIS
+ *
+ *    void *silc_list_pop(SilcList list);
+ *
+ * DESCRIPTION
+ *
+ *    Pops the head of the list.  Removes the head of the list and returns
+ *    the removed head.  This will always remove the head of the list even
+ *    if silc_list_end was called.  Calling silc_list_start is not necessary.
+ *    Returns SILC_LIST_END if the list is empty.
+ *
+ ***/
+#define silc_list_pop(x) __silc_list_pop(&(x))
+static inline
+void *__silc_list_pop(SilcList *list)
+{
+  void *head, **p;
+
+  if (!list->head)
+    return NULL;
+
+  head = list->head;
+  p = &list->head;
+  *p = *__silc_list_next(*list, head);
+  if (list->prev_set && *p)
+    *__silc_list_prev(*list, *p) = *__silc_list_prev(*list, head);
+
+  if (list->current == head)
+    list->current = *p;
+  if (head == list->tail)
+    list->tail = NULL;
+
+  list->count--;
+
+  return head;
+}
+
+#endif /* SILCLIST_H */
index 9efff72a047f6574d1ea50e2a3014456e2e77aec..70c1cb0eb167fc98b756c51cfb65f02f2f55cf58 100644 (file)
@@ -155,6 +155,13 @@ int main(int argc, char **argv)
                   f->prev));
   }
 
+  while ((f = silc_list_pop(list)) != SILC_LIST_END) {
+    SILC_LOG_DEBUG(("POPPED entry %d, %p, next=%p, prev=%p", f->i, f, f->next,
+                  f->prev));
+  }
+  if (silc_list_count(list))
+    goto err;
+
   success = TRUE;
 
  err: