From 62e89974afbb6628344fb084c50712bfab4419de Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 16 Jul 2018 00:15:49 -0400 Subject: [PATCH] sort config file variables --- libretro-common/file/config_file.c | 80 ++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index 942de7da65..1bb3e1db2c 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -68,6 +68,84 @@ struct config_include_list static config_file_t *config_file_new_internal( const char *path, unsigned depth); +static int config_sort_compare_func(struct config_entry_list *a, + struct config_entry_list *b) +{ + const char *a_key = a ? a->key : NULL; + const char *b_key = b ? b->key : NULL; + + if (!a_key || !b_key) + return 0; + + return strcasecmp(a_key, b_key); +} + +/* https://stackoverflow.com/questions/7685/merge-sort-a-linked-list */ +static struct config_entry_list* merge_sort_linked_list(struct config_entry_list *list, int (*compare)(struct config_entry_list *one,struct config_entry_list *two)) +{ + struct config_entry_list + *right = list, + *temp = list, + *last = list, + *result = 0, + *next = 0, + *tail = 0; + + /* Trivial case. */ + if (!list || !list->next) + return list; + + /* Find halfway through the list (by running two pointers, one at twice the speed of the other). */ + while (temp && temp->next) + { + last = right; + right = right->next; + temp = temp->next->next; + } + + /* Break the list in two. (prev pointers are broken here, but we fix later) */ + last->next = 0; + + /* Recurse on the two smaller lists: */ + list = merge_sort_linked_list(list, compare); + right = merge_sort_linked_list(right, compare); + + /* Merge: */ + while (list || right) + { + /* Take from empty lists, or compare: */ + if (!right) + { + next = list; + list = list->next; + } + else if (!list) + { + next = right; + right = right->next; + } + else if (compare(list, right) < 0) + { + next = list; + list = list->next; + } + else + { + next = right; + right = right->next; + } + + if (!result) + result=next; + else + tail->next=next; + + tail = next; + } + + return result; +} + static char *strip_comment(char *str) { /* Remove everything after comment. @@ -913,6 +991,8 @@ void config_file_dump(config_file_t *conf, FILE *file) list = (struct config_entry_list*)conf->entries; + merge_sort_linked_list(list, config_sort_compare_func); + while (list) { if (!list->readonly && list->key)