X-Git-Url: http://pileus.org/git/?p=wmpus;a=blobdiff_plain;f=util.c;h=30df76c28a39d2e25320226545be0bfc8253904b;hp=cfe69a9b863e1d1a1b80825c506209b7dffc3f6c;hb=HEAD;hpb=88e2a1773e458b1f79e2e743e3d5bdc659caf822 diff --git a/util.c b/util.c index cfe69a9..30df76c 100644 --- a/util.c +++ b/util.c @@ -90,6 +90,41 @@ list_t *list_find(list_t *list, void *data) return NULL; } +list_t *list_sort(list_t *list, int rev, int (*func)(void *a, void*b)) +{ + if (list == NULL || list->next == NULL) + return list; + + /* Split list */ + list_t *sides[2] = {NULL, NULL}; + for (int i = 0; list; i=(i+1)%2) { + list_t *head = list; + list = list->next; + head->next = sides[i]; + sides[i] = head; + } + + /* Sort sides */ + sides[0] = list_sort(sides[0], !rev, func); + sides[1] = list_sort(sides[1], !rev, func); + + /* Merge sides */ + while (sides[0] || sides[1]) { + int i = sides[0] == NULL ? 1 : + sides[1] == NULL ? 0 : + func(sides[0]->data, + sides[1]->data) > 0 ? !!rev : !rev; + list_t *head = sides[i]; + sides[i] = sides[i]->next; + head->next = list; + head->prev = NULL; + if (list) + list->prev = head; + list = head; + } + return list; +} + /* Misc */ int str2num(char *str, int def) {