summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2016-11-26 07:51:38 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2016-11-26 07:51:38 +0200
commitf5a1ff9b5a2caa67c1bee2cbf4a00dc4f7946bb4 (patch)
treed6b31c78747558dcf47fdbbbf6c45643ae2df117
parent1e6dc073c8b89d740c7eeba747965dfb76be5f2a (diff)
downloadmailutils-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.h3
-rw-r--r--libmailutils/list/sort.c31
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);
}
+

Return to:

Send suggestions and report system problems to the System administrator.