diff --git a/driver.c b/driver.c index 5ca1a4184c..31e419fc7d 100644 --- a/driver.c +++ b/driver.c @@ -484,7 +484,7 @@ static void init_shader_dir(void) g_extern.shader_dir.size = dir_list_size(g_extern.shader_dir.elems); g_extern.shader_dir.ptr = 0; - dir_list_sort(g_extern.shader_dir.elems); + dir_list_sort(g_extern.shader_dir.elems, false); for (unsigned i = 0; i < g_extern.shader_dir.size; i++) RARCH_LOG("Found shader \"%s\"\n", g_extern.shader_dir.elems[i]); diff --git a/file.h b/file.h index 33e06b223f..b4f4179bb0 100644 --- a/file.h +++ b/file.h @@ -41,7 +41,7 @@ bool init_rom_file(enum rarch_game_type type); // If non-NULL, only files with extension ext are added. char **dir_list_new(const char *dir, const char *ext, bool include_dirs); size_t dir_list_size(char * const *dir_list); -void dir_list_sort(char **dir_list); +void dir_list_sort(char **dir_list, bool dir_first); void dir_list_free(char **dir_list); bool path_is_directory(const char *path); diff --git a/file_path.c b/file_path.c index ad92bbed80..860f3cf69e 100644 --- a/file_path.c +++ b/file_path.c @@ -173,43 +173,31 @@ size_t dir_list_size(char * const *dir_list) return size; } -static size_t strcountelem(const char *str, const char *valid) +static int qstrcmp_plain(const void *a, const void *b) { - size_t count = 0; - - while (*str) - { - if (strchr(valid, *str++)) - count++; - } - - return count; + return strcasecmp(*(const char * const*)a, *(const char * const*)b); } -static int qstrcmp(const void *a_, const void *b_) +static int qstrcmp_dir(const void *a_, const void *b_) { const char *a = *(const char * const*)a_; const char *b = *(const char * const*)b_; - ssize_t a_cnt = strcountelem(a, "/\\"); - ssize_t b_cnt = strcountelem(b, "/\\"); + // Sort directories before files. + int a_dir = path_is_directory(a); + int b_dir = path_is_directory(b); + if (a_dir != b_dir) + return b_dir - a_dir; - // Place directories on top. - // It is assumed that number of '/' or '\\' in path can determine - // if one path is a directory and the other is not. - - if (a_cnt != b_cnt) - return a_cnt - b_cnt; - else - return strcasecmp(a, b); + return strcasecmp(a, b); } -void dir_list_sort(char **dir_list) +void dir_list_sort(char **dir_list, bool dir_first) { if (!dir_list) return; - qsort(dir_list, dir_list_size(dir_list), sizeof(char*), qstrcmp); + qsort(dir_list, dir_list_size(dir_list), sizeof(char*), dir_first ? qstrcmp_dir : qstrcmp_plain); } #ifdef _WIN32 // Because the API is just fucked up ...