diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-11-26 07:51:38 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-11-26 07:51:38 +0200 |
commit | f5a1ff9b5a2caa67c1bee2cbf4a00dc4f7946bb4 (patch) | |
tree | d6b31c78747558dcf47fdbbbf6c45643ae2df117 | |
parent | 1e6dc073c8b89d740c7eeba747965dfb76be5f2a (diff) | |
download | mailutils-f5a1ff9b5a2caa67c1bee2cbf4a00dc4f7946bb4.tar.gz mailutils-f5a1ff9b5a2caa67c1bee2cbf4a00dc4f7946bb4.tar.bz2 |
Improve list sorting API
* libmailutils/list/sort.c (mu_list_sort_r): New function.
* include/mailutils/list.h: Provide prototype.
-rw-r--r-- | include/mailutils/list.h | 3 | ||||
-rw-r--r-- | libmailutils/list/sort.c | 31 |
2 files changed, 27 insertions, 7 deletions
diff --git a/include/mailutils/list.h b/include/mailutils/list.h index adf61b485..7da3c2973 100644 --- a/include/mailutils/list.h +++ b/include/mailutils/list.h @@ -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 } diff --git a/libmailutils/list/sort.c b/libmailutils/list/sort.c index 0950d36e8..92d918336 100644 --- a/libmailutils/list/sort.c +++ b/libmailutils/list/sort.c @@ -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); } + |