diff --git a/Makefile.common b/Makefile.common
index 2c027d738e..43af61e5be 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -91,6 +91,7 @@ OBJ += frontend/frontend.o \
retroarch.o \
file.o \
file_list.o \
+ dir_list.o \
string_list.o \
file_path.o \
hash.o \
@@ -614,6 +615,7 @@ RETROLAUNCH_OBJ += tools/retrolaunch/main.o \
compat/fnmatch_rarch.o \
tools/input_common_launch.o \
file_path.o \
+ dir_list.o \
string_list.o \
compat/compat.o \
conf/config_file.o \
diff --git a/dir_list.c b/dir_list.c
new file mode 100644
index 0000000000..1a177e7549
--- /dev/null
+++ b/dir_list.c
@@ -0,0 +1,265 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
+ * Copyright (C) 2011-2014 - Daniel De Matteis
+ *
+ * RetroArch is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with RetroArch.
+ * If not, see .
+ */
+
+#include "dir_list.h"
+#include "file_path.h"
+#include "compat/strl.h"
+#include "miscellaneous.h"
+
+#if defined(_WIN32)
+#ifdef _MSC_VER
+#define setmode _setmode
+#endif
+#include "msvc/msvc_compat.h"
+#ifdef _XBOX
+#include
+#define INVALID_FILE_ATTRIBUTES -1
+#else
+#include
+#include
+#include
+#include
+#endif
+#else
+#include
+#include
+#include
+#include
+#endif
+
+static int qstrcmp_plain(const void *a_, const void *b_)
+{
+ const struct string_list_elem *a = (const struct string_list_elem*)a_;
+ const struct string_list_elem *b = (const struct string_list_elem*)b_;
+
+ return strcasecmp(a->data, b->data);
+}
+
+static int qstrcmp_dir(const void *a_, const void *b_)
+{
+ const struct string_list_elem *a = (const struct string_list_elem*)a_;
+ const struct string_list_elem *b = (const struct string_list_elem*)b_;
+ int a_type = a->attr.i;
+ int b_type = b->attr.i;
+
+
+ /* Sort directories before files. */
+ if (a_type != b_type)
+ return b_type - a_type;
+ return strcasecmp(a->data, b->data);
+}
+
+void dir_list_sort(struct string_list *list, bool dir_first)
+{
+ if (!list)
+ return;
+
+ qsort(list->elems, list->size, sizeof(struct string_list_elem),
+ dir_first ? qstrcmp_dir : qstrcmp_plain);
+}
+
+void dir_list_free(struct string_list *list)
+{
+ string_list_free(list);
+}
+
+#ifdef _WIN32
+
+struct string_list *dir_list_new(const char *dir,
+ const char *ext, bool include_dirs)
+{
+ struct string_list *list = string_list_new();
+ if (!list)
+ return NULL;
+
+ HANDLE hFind = INVALID_HANDLE_VALUE;
+ WIN32_FIND_DATA ffd;
+
+ char path_buf[PATH_MAX];
+ snprintf(path_buf, sizeof(path_buf), "%s\\*", dir);
+
+ struct string_list *ext_list = NULL;
+ if (ext)
+ ext_list = string_split(ext, "|");
+
+ hFind = FindFirstFile(path_buf, &ffd);
+ if (hFind == INVALID_HANDLE_VALUE)
+ goto error;
+
+ do
+ {
+ union string_list_elem_attr attr;
+ char file_path[PATH_MAX];
+ const char *name = ffd.cFileName;
+ const char *file_ext = path_get_extension(name);
+ bool is_dir = ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+ bool is_compressed_file = false;
+ bool supported_by_core = false;
+ attr.i = RARCH_FILETYPE_UNSET;
+
+ fill_pathname_join(file_path, dir, name, sizeof(file_path));
+
+ if (!is_dir)
+ {
+ is_compressed_file = path_is_compressed_file(file_path);
+ if (string_list_find_elem_prefix(ext_list, ".", file_ext))
+ supported_by_core = true;
+ }
+
+ if (!include_dirs && is_dir)
+ continue;
+
+ if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
+ continue;
+
+ if (!is_compressed_file && !is_dir && ext_list && !supported_by_core)
+ continue;
+
+ if (is_dir)
+ attr.i = RARCH_DIRECTORY;
+ if (is_compressed_file)
+ attr.i = RARCH_COMPRESSED_ARCHIVE;
+ /* The order of these ifs is important.
+ * If the file format is explicitly supported by the libretro-core, we
+ * need to immediately load it and not designate it as a compressed file.
+ *
+ * Example: .zip could be supported as a image by the core and as a
+ * compressed_file. In that case, we have to interpret it as a image.
+ *
+ * */
+ if (supported_by_core)
+ attr.i = RARCH_PLAIN_FILE;
+
+ if (!string_list_append(list, file_path, attr))
+ goto error;
+ }
+ while (FindNextFile(hFind, &ffd) != 0);
+
+ FindClose(hFind);
+ string_list_free(ext_list);
+ return list;
+
+error:
+ RARCH_ERR("Failed to open directory: \"%s\"\n", dir);
+ if (hFind != INVALID_HANDLE_VALUE)
+ FindClose(hFind);
+
+ string_list_free(list);
+ string_list_free(ext_list);
+ return NULL;
+}
+#else
+static bool dirent_is_directory(const char *path,
+ const struct dirent *entry)
+{
+#if defined(PSP)
+ return (entry->d_stat.st_attr & FIO_SO_IFDIR) == FIO_SO_IFDIR;
+#elif defined(DT_DIR)
+ if (entry->d_type == DT_DIR)
+ return true;
+ else if (entry->d_type == DT_UNKNOWN /* This can happen on certain file systems. */
+ || entry->d_type == DT_LNK)
+ return path_is_directory(path);
+ return false;
+#else /* dirent struct doesn't have d_type, do it the slow way ... */
+ return path_is_directory(path);
+#endif
+}
+
+struct string_list *dir_list_new(const char *dir,
+ const char *ext, bool include_dirs)
+{
+ DIR *directory = NULL;
+ const struct dirent *entry = NULL;
+ struct string_list *ext_list = NULL;
+ struct string_list *list = (struct string_list*)string_list_new();
+
+ if (!list)
+ return NULL;
+
+ if (ext)
+ ext_list = string_split(ext, "|");
+
+ directory = opendir(dir);
+ if (!directory)
+ goto error;
+
+ while ((entry = readdir(directory)))
+ {
+ bool is_dir;
+ char file_path[PATH_MAX];
+ union string_list_elem_attr attr;
+ const char *name = entry->d_name;
+ const char *file_ext = path_get_extension(name);
+ bool is_compressed_file = false;
+ bool supported_by_core = false;
+ attr.i = RARCH_FILETYPE_UNSET;
+
+ fill_pathname_join(file_path, dir, name, sizeof(file_path));
+
+ is_dir = dirent_is_directory(file_path, entry);
+
+ if (!is_dir)
+ {
+ is_compressed_file = path_is_compressed_file(file_path);
+ if (string_list_find_elem_prefix(ext_list, ".", file_ext))
+ supported_by_core = true;
+ }
+
+ if (!include_dirs && is_dir)
+ continue;
+
+ if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
+ continue;
+
+ if (!is_dir && ext_list && !is_compressed_file && !supported_by_core)
+ continue;
+
+ if (is_dir)
+ attr.i = RARCH_DIRECTORY;
+ if (is_compressed_file)
+ attr.i = RARCH_COMPRESSED_ARCHIVE;
+ /* The order of these ifs is important.
+ * If the file format is explicitly supported by the libretro-core, we
+ * need to immediately load it and not designate it as a compressed file.
+ *
+ * Example: .zip could be supported as a image by the core and as a
+ * compressed_file. In that case, we have to interpret it as a image.
+ *
+ * */
+ if (supported_by_core)
+ attr.i = RARCH_PLAIN_FILE;
+
+ if (!string_list_append(list, file_path, attr))
+ goto error;
+ }
+
+ closedir(directory);
+
+ string_list_free(ext_list);
+ return list;
+
+error:
+ RARCH_ERR("Failed to open directory: \"%s\"\n", dir);
+
+ if (directory)
+ closedir(directory);
+
+ string_list_free(list);
+ string_list_free(ext_list);
+ return NULL;
+}
+#endif
diff --git a/dir_list.h b/dir_list.h
new file mode 100644
index 0000000000..433685e465
--- /dev/null
+++ b/dir_list.h
@@ -0,0 +1,37 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
+ * Copyright (C) 2011-2014 - Daniel De Matteis
+ *
+ * RetroArch is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with RetroArch.
+ * If not, see .
+ */
+
+#ifndef _DIR_LIST_H
+#define _DIR_LIST_H
+
+#include "string_list.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct string_list *dir_list_new(const char *dir, const char *ext,
+ bool include_dirs);
+
+void dir_list_sort(struct string_list *list, bool dir_first);
+
+void dir_list_free(struct string_list *list);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/file_path.c b/file_path.c
index f5d668f3bc..c25dcb7ed4 100644
--- a/file_path.c
+++ b/file_path.c
@@ -262,37 +262,6 @@ char *path_remove_extension(char *path)
return last;
}
-static int qstrcmp_plain(const void *a_, const void *b_)
-{
- const struct string_list_elem *a = (const struct string_list_elem*)a_;
- const struct string_list_elem *b = (const struct string_list_elem*)b_;
-
- return strcasecmp(a->data, b->data);
-}
-
-static int qstrcmp_dir(const void *a_, const void *b_)
-{
- const struct string_list_elem *a = (const struct string_list_elem*)a_;
- const struct string_list_elem *b = (const struct string_list_elem*)b_;
- int a_type = a->attr.i;
- int b_type = b->attr.i;
-
-
- /* Sort directories before files. */
- if (a_type != b_type)
- return b_type - a_type;
- return strcasecmp(a->data, b->data);
-}
-
-void dir_list_sort(struct string_list *list, bool dir_first)
-{
- if (!list)
- return;
-
- qsort(list->elems, list->size, sizeof(struct string_list_elem),
- dir_first ? qstrcmp_dir : qstrcmp_plain);
-}
-
struct string_list *compressed_file_list_new(const char *path,
const char* ext)
{
@@ -311,199 +280,6 @@ struct string_list *compressed_file_list_new(const char *path,
return NULL;
}
-#ifdef _WIN32
-
-struct string_list *dir_list_new(const char *dir,
- const char *ext, bool include_dirs)
-{
- struct string_list *list = string_list_new();
- if (!list)
- return NULL;
-
- HANDLE hFind = INVALID_HANDLE_VALUE;
- WIN32_FIND_DATA ffd;
-
- char path_buf[PATH_MAX];
- snprintf(path_buf, sizeof(path_buf), "%s\\*", dir);
-
- struct string_list *ext_list = NULL;
- if (ext)
- ext_list = string_split(ext, "|");
-
- hFind = FindFirstFile(path_buf, &ffd);
- if (hFind == INVALID_HANDLE_VALUE)
- goto error;
-
- do
- {
- union string_list_elem_attr attr;
- char file_path[PATH_MAX];
- const char *name = ffd.cFileName;
- const char *file_ext = path_get_extension(name);
- bool is_dir = ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
- bool is_compressed_file = false;
- bool supported_by_core = false;
- attr.i = RARCH_FILETYPE_UNSET;
-
- fill_pathname_join(file_path, dir, name, sizeof(file_path));
-
- if (!is_dir)
- {
- is_compressed_file = path_is_compressed_file(file_path);
- if (string_list_find_elem_prefix(ext_list, ".", file_ext))
- supported_by_core = true;
- }
-
- if (!include_dirs && is_dir)
- continue;
-
- if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
- continue;
-
- if (!is_compressed_file && !is_dir && ext_list && !supported_by_core)
- continue;
-
- if (is_dir)
- attr.i = RARCH_DIRECTORY;
- if (is_compressed_file)
- attr.i = RARCH_COMPRESSED_ARCHIVE;
- /* The order of these ifs is important.
- * If the file format is explicitly supported by the libretro-core, we
- * need to immediately load it and not designate it as a compressed file.
- *
- * Example: .zip could be supported as a image by the core and as a
- * compressed_file. In that case, we have to interpret it as a image.
- *
- * */
- if (supported_by_core)
- attr.i = RARCH_PLAIN_FILE;
-
- if (!string_list_append(list, file_path, attr))
- goto error;
- }
- while (FindNextFile(hFind, &ffd) != 0);
-
- FindClose(hFind);
- string_list_free(ext_list);
- return list;
-
-error:
- RARCH_ERR("Failed to open directory: \"%s\"\n", dir);
- if (hFind != INVALID_HANDLE_VALUE)
- FindClose(hFind);
-
- string_list_free(list);
- string_list_free(ext_list);
- return NULL;
-}
-#else
-static bool dirent_is_directory(const char *path,
- const struct dirent *entry)
-{
-#if defined(PSP)
- return (entry->d_stat.st_attr & FIO_SO_IFDIR) == FIO_SO_IFDIR;
-#elif defined(DT_DIR)
- if (entry->d_type == DT_DIR)
- return true;
- else if (entry->d_type == DT_UNKNOWN /* This can happen on certain file systems. */
- || entry->d_type == DT_LNK)
- return path_is_directory(path);
- return false;
-#else /* dirent struct doesn't have d_type, do it the slow way ... */
- return path_is_directory(path);
-#endif
-}
-
-struct string_list *dir_list_new(const char *dir,
- const char *ext, bool include_dirs)
-{
- DIR *directory = NULL;
- const struct dirent *entry = NULL;
- struct string_list *ext_list = NULL;
- struct string_list *list = (struct string_list*)string_list_new();
-
- if (!list)
- return NULL;
-
- if (ext)
- ext_list = string_split(ext, "|");
-
- directory = opendir(dir);
- if (!directory)
- goto error;
-
- while ((entry = readdir(directory)))
- {
- bool is_dir;
- char file_path[PATH_MAX];
- union string_list_elem_attr attr;
- const char *name = entry->d_name;
- const char *file_ext = path_get_extension(name);
- bool is_compressed_file = false;
- bool supported_by_core = false;
- attr.i = RARCH_FILETYPE_UNSET;
-
- fill_pathname_join(file_path, dir, name, sizeof(file_path));
-
- is_dir = dirent_is_directory(file_path, entry);
-
- if (!is_dir)
- {
- is_compressed_file = path_is_compressed_file(file_path);
- if (string_list_find_elem_prefix(ext_list, ".", file_ext))
- supported_by_core = true;
- }
-
- if (!include_dirs && is_dir)
- continue;
-
- if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
- continue;
-
- if (!is_dir && ext_list && !is_compressed_file && !supported_by_core)
- continue;
-
- if (is_dir)
- attr.i = RARCH_DIRECTORY;
- if (is_compressed_file)
- attr.i = RARCH_COMPRESSED_ARCHIVE;
- /* The order of these ifs is important.
- * If the file format is explicitly supported by the libretro-core, we
- * need to immediately load it and not designate it as a compressed file.
- *
- * Example: .zip could be supported as a image by the core and as a
- * compressed_file. In that case, we have to interpret it as a image.
- *
- * */
- if (supported_by_core)
- attr.i = RARCH_PLAIN_FILE;
-
- if (!string_list_append(list, file_path, attr))
- goto error;
- }
-
- closedir(directory);
-
- string_list_free(ext_list);
- return list;
-
-error:
- RARCH_ERR("Failed to open directory: \"%s\"\n", dir);
-
- if (directory)
- closedir(directory);
-
- string_list_free(list);
- string_list_free(ext_list);
- return NULL;
-}
-#endif
-
-void dir_list_free(struct string_list *list)
-{
- string_list_free(list);
-}
-
static bool path_char_is_slash(char c)
{
#ifdef _WIN32
diff --git a/file_path.h b/file_path.h
index b053ff72a0..a8e4d14f6f 100644
--- a/file_path.h
+++ b/file_path.h
@@ -23,6 +23,7 @@
#include
#include
#include "string_list.h"
+#include "dir_list.h"
#ifdef __cplusplus
extern "C" {
@@ -52,10 +53,6 @@ bool write_empty_file(const char *path);
struct string_list *compressed_file_list_new(const char *filename,
const char* ext);
-struct string_list *dir_list_new(const char *dir, const char *ext,
- bool include_dirs);
-void dir_list_sort(struct string_list *list, bool dir_first);
-void dir_list_free(struct string_list *list);
/* path_is_compressed_file also means: The compressed file is supported */
bool path_is_compressed_file(const char *path);
diff --git a/griffin/griffin.c b/griffin/griffin.c
index 4062a4f032..4369465a92 100644
--- a/griffin/griffin.c
+++ b/griffin/griffin.c
@@ -524,6 +524,7 @@ DYNAMIC
FILE
============================================================ */
#include "../file.c"
+#include "../dir_list.c"
#include "../string_list.c"
#include "../file_path.c"
#include "../file_list.c"
diff --git a/string_list.h b/string_list.h
index e124b360cb..9a3cbc9664 100644
--- a/string_list.h
+++ b/string_list.h
@@ -18,6 +18,8 @@
#define __RARCH_STRING_LIST_H
#include "boolean.h"
+#include
+#include
#ifdef __cplusplus
extern "C" {