Commit f5a1ff9b f5a1ff9b5a2caa67c1bee2cbf4a00dc4f7946bb4 by Sergey Poznyakoff

Improve list sorting API

* libmailutils/list/sort.c (mu_list_sort_r): New function.
* include/mailutils/list.h: Provide prototype.
1 parent 1e6dc073
......@@ -345,6 +345,9 @@ int mu_list_rfold (mu_list_t _list, mu_list_folder_t _fold, void *_data,
first of them is less than the second, and +1 otherwise.
*/
void mu_list_sort (mu_list_t _list, mu_list_comparator_t _comp);
void mu_list_sort_r (mu_list_t _list,
int (*_comp) (const void *, const void *, void *),
void *_data);
#ifdef __cplusplus
}
......
......@@ -37,7 +37,8 @@ _list_append_entry (struct _mu_list *list, struct list_data *ent)
}
static void
_list_qsort (mu_list_t list, mu_list_comparator_t cmp)
_list_qsort (mu_list_t list, int cmp (const void *, const void *, void *),
void *data)
{
struct list_data *cur, *middle;
struct _mu_list high_list, low_list;
......@@ -47,7 +48,7 @@ _list_qsort (mu_list_t list, mu_list_comparator_t cmp)
return;
if (list->count == 2)
{
if (cmp (list->head.prev->item, list->head.next->item) < 0)
if (cmp (list->head.prev->item, list->head.next->item, data) < 0)
{
cur = list->head.prev;
list->head.prev = list->head.next;
......@@ -67,7 +68,7 @@ _list_qsort (mu_list_t list, mu_list_comparator_t cmp)
cur = cur->next;
if (cur == &list->head)
return;
} while ((rc = cmp (list->head.next->item, cur->item)) == 0);
} while ((rc = cmp (list->head.next->item, cur->item, data)) == 0);
/* Select the lower of the two as the middle value */
middle = (rc > 0) ? cur : list->head.next;
......@@ -81,7 +82,7 @@ _list_qsort (mu_list_t list, mu_list_comparator_t cmp)
struct list_data *next = cur->next;
cur->next = NULL;
if (cmp (middle->item, cur->item) < 0)
if (cmp (middle->item, cur->item, data) < 0)
_list_append_entry (&high_list, cur);
else
_list_append_entry (&low_list, cur);
......@@ -89,8 +90,8 @@ _list_qsort (mu_list_t list, mu_list_comparator_t cmp)
}
/* Sort both sublists recursively */
_list_qsort (&low_list, cmp);
_list_qsort (&high_list, cmp);
_list_qsort (&low_list, cmp, data);
_list_qsort (&high_list, cmp, data);
/* Join both lists in order */
if (low_list.head.prev)
......@@ -114,8 +115,24 @@ _list_qsort (mu_list_t list, mu_list_comparator_t cmp)
}
void
mu_list_sort_r (mu_list_t list,
int (*comp) (const void *, const void *, void *), void *data)
{
if (list)
_list_qsort (list, comp, data);
}
static int
callcomp (const void *a, const void *b, void *data)
{
mu_list_comparator_t comp = data;
return comp (a, b);
}
void
mu_list_sort (mu_list_t list, mu_list_comparator_t comp)
{
if (list)
_list_qsort (list, comp ? comp : list->comp);
_list_qsort (list, callcomp, comp ? comp : list->comp);
}
......