diff --git a/Makefile b/Makefile index c2bd8d27cd..8872056274 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ include config.mk TARGET = ssnes tools/ssnes-joyconfig -OBJ = ssnes.o file.o hash.o driver.o settings.o dynamic.o message.o rewind.o gfx/gfx_common.o patch.o compat/compat.o screenshot.o audio/utils.o +OBJ = ssnes.o file.o file_path.o hash.o driver.o settings.o dynamic.o message.o rewind.o gfx/gfx_common.o patch.o compat/compat.o screenshot.o audio/utils.o JOYCONFIG_OBJ = tools/ssnes-joyconfig.o conf/config_file.o compat/compat.o HEADERS = $(wildcard */*.h) $(wildcard *.h) diff --git a/Makefile.win b/Makefile.win index 435077d739..e847d38f3c 100644 --- a/Makefile.win +++ b/Makefile.win @@ -1,6 +1,6 @@ TARGET = ssnes.exe JTARGET = ssnes-joyconfig.exe -OBJ = ssnes.o file.o driver.o conf/config_file.o settings.o hash.o dynamic.o message.o rewind.o movie.o gfx/gfx_common.o patch.o compat/compat.o screenshot.o audio/utils.o +OBJ = ssnes.o file.o file_path.o driver.o conf/config_file.o settings.o hash.o dynamic.o message.o rewind.o movie.o gfx/gfx_common.o patch.o compat/compat.o screenshot.o audio/utils.o JOBJ = conf/config_file.o tools/ssnes-joyconfig.o compat/compat.o CC = gcc diff --git a/file.c b/file.c index 55892f358a..5f0c0c2684 100644 --- a/file.c +++ b/file.c @@ -26,27 +26,6 @@ #include "compat/strl.h" #include "hash.h" -#ifdef __CELLOS_LV2__ -#include -#endif - -#if defined(_WIN32) && !defined(_XBOX) -#include -#include -#include -#ifdef _MSC_VER -#define setmode _setmode -#endif -#elif defined(_XBOX) -#include -#define setmode _setmode -#define INVALID_FILE_ATTRIBUTES -1 -#else -#include -#include -#include -#endif - // Generic file loader. ssize_t read_file(const char *path, void **buf) { @@ -691,210 +670,3 @@ bool init_rom_file(enum ssnes_game_type type) return true; } -// Yep, this is C alright ;) -char **dir_list_new(const char *dir, const char *ext) -{ - size_t cur_ptr = 0; - size_t cur_size = 32; - char **dir_list = NULL; - -#ifdef _WIN32 - WIN32_FIND_DATA ffd; - HANDLE hFind = INVALID_HANDLE_VALUE; - - char path_buf[PATH_MAX]; - - if (strlcpy(path_buf, dir, sizeof(path_buf)) >= sizeof(path_buf)) - goto error; -#ifdef _XBOX - if (strlcat(path_buf, "*", sizeof(path_buf)) >= sizeof(path_buf)) -#else - if (strlcat(path_buf, "/*", sizeof(path_buf)) >= sizeof(path_buf)) -#endif - goto error; - - if (ext) - { - if (strlcat(path_buf, ext, sizeof(path_buf)) >= sizeof(path_buf)) - goto error; - } - - hFind = FindFirstFile(path_buf, &ffd); - if (hFind == INVALID_HANDLE_VALUE) - goto error; -#else - DIR *directory = NULL; - const struct dirent *entry = NULL; - - directory = opendir(dir); - if (!directory) - goto error; -#endif - - dir_list = (char**)calloc(cur_size, sizeof(char*)); - if (!dir_list) - goto error; - -#ifdef _WIN32 // Hard to read? Blame non-POSIX heathens! - do -#else - while ((entry = readdir(directory))) -#endif - { - // Not a perfect search of course, but hopefully good enough in practice. -#ifdef _WIN32 - if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - continue; - if (ext && !strstr(ffd.cFileName, ext)) - continue; -#else - if (ext && !strstr(entry->d_name, ext)) - continue; -#endif - - dir_list[cur_ptr] = (char*)malloc(PATH_MAX); - if (!dir_list[cur_ptr]) - goto error; - - strlcpy(dir_list[cur_ptr], dir, PATH_MAX); -#ifndef _XBOX - strlcat(dir_list[cur_ptr], "/", PATH_MAX); -#endif -#ifdef _WIN32 - strlcat(dir_list[cur_ptr], ffd.cFileName, PATH_MAX); -#else - strlcat(dir_list[cur_ptr], entry->d_name, PATH_MAX); -#endif - - cur_ptr++; - if (cur_ptr + 1 == cur_size) // Need to reserve for NULL. - { - cur_size *= 2; - dir_list = (char**)realloc(dir_list, cur_size * sizeof(char*)); - if (!dir_list) - goto error; - - // Make sure it's all NULL'd out since we cannot rely on realloc to do this. - memset(dir_list + cur_ptr, 0, (cur_size - cur_ptr) * sizeof(char*)); - } - } -#if defined(_WIN32) - while (FindNextFile(hFind, &ffd) != 0); -#endif - -#ifdef _WIN32 - FindClose(hFind); -#else - closedir(directory); -#endif - return dir_list; - -error: - SSNES_ERR("Failed to open directory: \"%s\"\n", dir); -#ifdef _WIN32 - if (hFind != INVALID_HANDLE_VALUE) - FindClose(hFind); -#else - if (directory) - closedir(directory); -#endif - dir_list_free(dir_list); - return NULL; -} - -void dir_list_free(char **dir_list) -{ - if (!dir_list) - return; - - char **orig = dir_list; - while (*dir_list) - free(*dir_list++); - free(orig); -} - -bool path_is_directory(const char *path) -{ -#ifdef _WIN32 - DWORD ret = GetFileAttributes(path); - return (ret & FILE_ATTRIBUTE_DIRECTORY) && (ret != INVALID_FILE_ATTRIBUTES); -#elif defined(__CELLOS_LV2__) - CellFsStat buf; - if (cellFsStat(path, &buf) < 0) - return false; - - return buf.st_mode & CELL_FS_S_IFDIR; -#elif defined(XENON) - // Dummy - (void)path; - return false; -#else - struct stat buf; - if (stat(path, &buf) < 0) - return false; - - return S_ISDIR(buf.st_mode); -#endif -} - -bool path_file_exists(const char *path) -{ - FILE *dummy = fopen(path, "rb"); - if (dummy) - { - fclose(dummy); - return true; - } - return false; -} - -void fill_pathname(char *out_path, const char *in_path, const char *replace, size_t size) -{ - char tmp_path[PATH_MAX]; - - ssnes_assert(strlcpy(tmp_path, in_path, sizeof(tmp_path)) < sizeof(tmp_path)); - char *tok = strrchr(tmp_path, '.'); - if (tok) - *tok = '\0'; - - ssnes_assert(strlcpy(out_path, tmp_path, size) < size); - ssnes_assert(strlcat(out_path, replace, size) < size); -} - -void fill_pathname_noext(char *out_path, const char *in_path, const char *replace, size_t size) -{ - ssnes_assert(strlcpy(out_path, in_path, size) < size); - ssnes_assert(strlcat(out_path, replace, size) < size); -} - -void fill_pathname_dir(char *in_dir, const char *in_basename, const char *replace, size_t size) -{ - ssnes_assert(strlcat(in_dir, "/", size) < size); - - const char *base = strrchr(in_basename, '/'); - if (!base) - base = strrchr(in_basename, '\\'); - - if (base) - base++; - else - base = in_basename; - - ssnes_assert(strlcat(in_dir, base, size) < size); - ssnes_assert(strlcat(in_dir, replace, size) < size); -} - -void fill_pathname_base(char *out_dir, const char *in_path, size_t size) -{ - const char *ptr = strrchr(in_path, '/'); - if (!ptr) - ptr = strrchr(in_path, '\\'); - - if (ptr) - ptr++; - else - ptr = in_path; - - ssnes_assert(strlcpy(out_dir, ptr, size) < size); -} - diff --git a/file_path.c b/file_path.c new file mode 100644 index 0000000000..49834c439f --- /dev/null +++ b/file_path.c @@ -0,0 +1,251 @@ +/* SSNES - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * + * SSNES 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. + * + * SSNES 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 SSNES. + * If not, see . + */ + +#include "file.h" +#include "general.h" +#include +#include "boolean.h" +#include +#include +#include "compat/strl.h" + +#ifdef __CELLOS_LV2__ +#include +#endif + +#if defined(_WIN32) && !defined(_XBOX) +#include +#include +#include +#ifdef _MSC_VER +#define setmode _setmode +#endif +#elif defined(_XBOX) +#include +#define setmode _setmode +#define INVALID_FILE_ATTRIBUTES -1 +#else +#include +#include +#include +#endif + +// Yep, this is C alright ;) +char **dir_list_new(const char *dir, const char *ext) +{ + size_t cur_ptr = 0; + size_t cur_size = 32; + char **dir_list = NULL; + +#ifdef _WIN32 + WIN32_FIND_DATA ffd; + HANDLE hFind = INVALID_HANDLE_VALUE; + + char path_buf[PATH_MAX]; + + if (strlcpy(path_buf, dir, sizeof(path_buf)) >= sizeof(path_buf)) + goto error; +#ifdef _XBOX + if (strlcat(path_buf, "*", sizeof(path_buf)) >= sizeof(path_buf)) +#else + if (strlcat(path_buf, "/*", sizeof(path_buf)) >= sizeof(path_buf)) +#endif + goto error; + + if (ext) + { + if (strlcat(path_buf, ext, sizeof(path_buf)) >= sizeof(path_buf)) + goto error; + } + + hFind = FindFirstFile(path_buf, &ffd); + if (hFind == INVALID_HANDLE_VALUE) + goto error; +#else + DIR *directory = NULL; + const struct dirent *entry = NULL; + + directory = opendir(dir); + if (!directory) + goto error; +#endif + + dir_list = (char**)calloc(cur_size, sizeof(char*)); + if (!dir_list) + goto error; + +#ifdef _WIN32 // Hard to read? Blame non-POSIX heathens! + do +#else + while ((entry = readdir(directory))) +#endif + { + // Not a perfect search of course, but hopefully good enough in practice. +#ifdef _WIN32 + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + continue; + if (ext && !strstr(ffd.cFileName, ext)) + continue; +#else + if (ext && !strstr(entry->d_name, ext)) + continue; +#endif + + dir_list[cur_ptr] = (char*)malloc(PATH_MAX); + if (!dir_list[cur_ptr]) + goto error; + + strlcpy(dir_list[cur_ptr], dir, PATH_MAX); +#ifndef _XBOX + strlcat(dir_list[cur_ptr], "/", PATH_MAX); +#endif +#ifdef _WIN32 + strlcat(dir_list[cur_ptr], ffd.cFileName, PATH_MAX); +#else + strlcat(dir_list[cur_ptr], entry->d_name, PATH_MAX); +#endif + + cur_ptr++; + if (cur_ptr + 1 == cur_size) // Need to reserve for NULL. + { + cur_size *= 2; + dir_list = (char**)realloc(dir_list, cur_size * sizeof(char*)); + if (!dir_list) + goto error; + + // Make sure it's all NULL'd out since we cannot rely on realloc to do this. + memset(dir_list + cur_ptr, 0, (cur_size - cur_ptr) * sizeof(char*)); + } + } +#if defined(_WIN32) + while (FindNextFile(hFind, &ffd) != 0); +#endif + +#ifdef _WIN32 + FindClose(hFind); +#else + closedir(directory); +#endif + return dir_list; + +error: + SSNES_ERR("Failed to open directory: \"%s\"\n", dir); +#ifdef _WIN32 + if (hFind != INVALID_HANDLE_VALUE) + FindClose(hFind); +#else + if (directory) + closedir(directory); +#endif + dir_list_free(dir_list); + return NULL; +} + +void dir_list_free(char **dir_list) +{ + if (!dir_list) + return; + + char **orig = dir_list; + while (*dir_list) + free(*dir_list++); + free(orig); +} + +bool path_is_directory(const char *path) +{ +#ifdef _WIN32 + DWORD ret = GetFileAttributes(path); + return (ret & FILE_ATTRIBUTE_DIRECTORY) && (ret != INVALID_FILE_ATTRIBUTES); +#elif defined(__CELLOS_LV2__) + CellFsStat buf; + if (cellFsStat(path, &buf) < 0) + return false; + + return buf.st_mode & CELL_FS_S_IFDIR; +#elif defined(XENON) + // Dummy + (void)path; + return false; +#else + struct stat buf; + if (stat(path, &buf) < 0) + return false; + + return S_ISDIR(buf.st_mode); +#endif +} + +bool path_file_exists(const char *path) +{ + FILE *dummy = fopen(path, "rb"); + if (dummy) + { + fclose(dummy); + return true; + } + return false; +} + +void fill_pathname(char *out_path, const char *in_path, const char *replace, size_t size) +{ + char tmp_path[PATH_MAX]; + + ssnes_assert(strlcpy(tmp_path, in_path, sizeof(tmp_path)) < sizeof(tmp_path)); + char *tok = strrchr(tmp_path, '.'); + if (tok) + *tok = '\0'; + + ssnes_assert(strlcpy(out_path, tmp_path, size) < size); + ssnes_assert(strlcat(out_path, replace, size) < size); +} + +void fill_pathname_noext(char *out_path, const char *in_path, const char *replace, size_t size) +{ + ssnes_assert(strlcpy(out_path, in_path, size) < size); + ssnes_assert(strlcat(out_path, replace, size) < size); +} + +void fill_pathname_dir(char *in_dir, const char *in_basename, const char *replace, size_t size) +{ + ssnes_assert(strlcat(in_dir, "/", size) < size); + + const char *base = strrchr(in_basename, '/'); + if (!base) + base = strrchr(in_basename, '\\'); + + if (base) + base++; + else + base = in_basename; + + ssnes_assert(strlcat(in_dir, base, size) < size); + ssnes_assert(strlcat(in_dir, replace, size) < size); +} + +void fill_pathname_base(char *out_dir, const char *in_path, size_t size) +{ + const char *ptr = strrchr(in_path, '/'); + if (!ptr) + ptr = strrchr(in_path, '\\'); + + if (ptr) + ptr++; + else + ptr = in_path; + + ssnes_assert(strlcpy(out_dir, ptr, size) < size); +} +