return head;
}
+/****f* silcutil/silc_list_sort
+ *
+ * SYNOPSIS
+ *
+ * void silc_list_sort(SilcList *list,
+ * int (*compare)(void *entry1, void *entry2,
+ * void *context), void *context);
+ *
+ * DESCRIPTION
+ *
+ * Sort the list. The `compare' function will be called with `context'
+ * to do comparison between the entries. The `compare' must return
+ * less than, equal to, or greater than zero if the first argument is
+ * considered to be respectively less than, equal to, or greater than
+ * the second. The entries are then sorted in ascending order.
+ *
+ * NOTES
+ *
+ * The list must be initialized with silc_list_init_prev for sorting
+ * to work.
+ *
+ ***/
+#define silc_list_sort(x, comp, ctx) __silc_list_sort(&(x), comp, ctx)
+static inline
+void __silc_list_sort(SilcList *list,
+ int (*compare)(void *entry1, void *entry2,
+ void *context), void *context)
+{
+ void *c_cur, *c_prev;
+
+ SILC_ASSERT(list->prev_set);
+ if (!list->prev_set)
+ return;
+
+ if (silc_list_count(*list) < 2)
+ return;
+
+ /* Gnome sort */
+ silc_list_start(*list);
+ c_prev = silc_list_get(*list);
+ while ((c_cur = silc_list_get(*list))) {
+ if (compare(c_prev, c_cur, context) > 0) {
+ list->current = *__silc_list_prev(*list, c_prev);
+ silc_list_del(*list, c_prev);
+ silc_list_insert(*list, c_cur, c_prev);
+
+ if (list->current) {
+ c_prev = list->current;
+ list->current = c_cur;
+ continue;
+ }
+ list->current = c_cur;
+ silc_list_get(*list);
+ }
+ c_prev = c_cur;
+ }
+
+ list->current = NULL;
+}
+
#endif /* SILCLIST_H */
struct foo *prev;
};
+static int compare(void *e1, void *e2, void *context)
+{
+ struct foo *ee1 = e1, *ee2 = e2;
+ SILC_LOG_DEBUG(("entry %d, %p, next=%p, prev=%p", ee1->i, ee1, ee1->next,
+ ee1->prev));
+ SILC_LOG_DEBUG(("> entry %d, %p, next=%p, prev=%p", ee2->i, ee2, ee2->next,
+ ee2->prev));
+ return ee1->i - ee2->i;
+}
+
int main(int argc, char **argv)
{
SilcBool success = FALSE;
SilcList list;
- struct foo *f, *f1, *f2, *f3, *f4;
+ struct foo *f, *f1, *f2, *f3, *f4, *f5, *f6, *f7;
if (argc > 1 && !strcmp(argv[1], "-d")) {
silc_log_debug(TRUE);
if (!f4)
goto err;
f4->i = 4;
+ f5 = silc_calloc(1, sizeof(*f4));
+ if (!f5)
+ goto err;
+ f5->i = 5;
+ f6 = silc_calloc(1, sizeof(*f4));
+ if (!f6)
+ goto err;
+ f6->i = 6;
+ f7 = silc_calloc(1, sizeof(*f4));
+ if (!f7)
+ goto err;
+ f7->i = 7;
SILC_LOG_DEBUG(("Add one entry"));
silc_list_add(list, f1);
if (silc_list_count(list))
goto err;
+ /* Sort */
+ silc_list_init_prev(list, struct foo, next, prev);
+ silc_list_add(list, f2);
+ silc_list_add(list, f7);
+ silc_list_add(list, f4);
+ silc_list_add(list, f6);
+ silc_list_add(list, f5);
+ silc_list_add(list, f1);
+ silc_list_add(list, f3);
+
+ SILC_LOG_DEBUG(("Unsorted list"));
+ silc_list_start(list);
+ while ((f = silc_list_get(list)) != SILC_LIST_END)
+ SILC_LOG_DEBUG(("entry %d, %p, next=%p, prev=%p", f->i, f, f->next,
+ f->prev));
+
+ SILC_LOG_DEBUG(("Sorting"));
+ silc_list_sort(list, compare, NULL);
+
+ SILC_LOG_DEBUG(("Sorted list"));
+ silc_list_start(list);
+ while ((f = silc_list_get(list)) != SILC_LIST_END)
+ SILC_LOG_DEBUG(("entry %d, %p, next=%p, prev=%p", f->i, f, f->next,
+ f->prev));
+
success = TRUE;
err: