mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-23 16:09:47 +00:00
Refactor out buggy 'in-line' path handling.
This commit is contained in:
parent
6e6dbe2ab4
commit
86e21686f7
1
Makefile
1
Makefile
@ -28,6 +28,7 @@ OBJ = retroarch.o \
|
||||
|
||||
JOYCONFIG_OBJ = tools/retroarch-joyconfig.o \
|
||||
conf/config_file.o \
|
||||
file_path.o \
|
||||
compat/compat.o \
|
||||
input/input_common.o
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "../compat/strl.h"
|
||||
#include "../compat/posix_string.h"
|
||||
#include "../msvc/msvc_compat.h"
|
||||
#include "../file.h"
|
||||
|
||||
#if !defined(_WIN32) && !defined(__CELLOS_LV2__) && !defined(_XBOX)
|
||||
#include <sys/param.h> // PATH_MAX
|
||||
@ -196,55 +197,21 @@ static void add_sub_conf(config_file_t *conf, char *line)
|
||||
return;
|
||||
|
||||
add_include_list(conf, path);
|
||||
|
||||
char real_path[PATH_MAX];
|
||||
|
||||
#ifdef _WIN32
|
||||
// Accomodate POSIX systems on Win32.
|
||||
bool is_full_path = *path == '/';
|
||||
|
||||
if (is_full_path)
|
||||
strlcpy(real_path, path, sizeof(real_path));
|
||||
else
|
||||
{
|
||||
// Workaround GetFullPathName not existing on XDK.
|
||||
// : is not a valid element in a path name. (NTFS streams?)
|
||||
if (strchr(path, ':') == NULL)
|
||||
{
|
||||
strlcpy(real_path, conf->path, sizeof(real_path));
|
||||
char *split = strrchr(real_path, '/');
|
||||
if (!split)
|
||||
split = strrchr(real_path, '\\');
|
||||
|
||||
split[1] = '\0';
|
||||
strlcat(real_path, path, sizeof(real_path));
|
||||
}
|
||||
else
|
||||
strlcpy(real_path, path, sizeof(real_path));
|
||||
}
|
||||
fill_pathname_resolve_relative(real_path, conf->path, path, sizeof(real_path));
|
||||
#else
|
||||
if (*path == '/')
|
||||
strlcpy(real_path, path, sizeof(real_path));
|
||||
#ifndef __CELLOS_LV2__
|
||||
else if (*path == '~')
|
||||
if (*path == '~')
|
||||
{
|
||||
const char *home = getenv("HOME");
|
||||
strlcpy(real_path, home ? home : "/", sizeof(real_path));
|
||||
strlcpy(real_path, home ? home : "", sizeof(real_path));
|
||||
strlcat(real_path, path + 1, sizeof(real_path));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
strlcpy(real_path, conf->path, sizeof(real_path));
|
||||
char *split = strrchr(real_path, '/');
|
||||
if (split)
|
||||
{
|
||||
split[1] = '\0';
|
||||
strlcat(real_path, path, sizeof(real_path));
|
||||
}
|
||||
else
|
||||
strlcpy(real_path, path, sizeof(real_path));
|
||||
}
|
||||
#endif
|
||||
fill_pathname_resolve_relative(real_path, conf->path, path, sizeof(real_path));
|
||||
#endif
|
||||
|
||||
config_file_t *sub_conf = config_file_new_internal(real_path, conf->include_depth + 1);
|
||||
|
21
file.h
21
file.h
@ -69,6 +69,14 @@ bool path_is_directory(const char *path);
|
||||
bool path_file_exists(const char *path);
|
||||
const char *path_get_extension(const char *path);
|
||||
|
||||
// Returns basename from path.
|
||||
const char *path_basename(const char *path);
|
||||
|
||||
// Extracts base directory by mutating path. Keeps trailing '/'.
|
||||
void path_basedir(char *path);
|
||||
|
||||
bool path_is_absolute(const char *path);
|
||||
|
||||
// Path-name operations.
|
||||
// If any of these operation are detected to overflow, the application will be terminated.
|
||||
|
||||
@ -76,8 +84,8 @@ const char *path_get_extension(const char *path);
|
||||
// The extension here is considered to be the string from the last '.' to the end.
|
||||
// If no '.' is present, in_path and replace will simply be concatenated.
|
||||
// 'size' is buffer size of 'out_path'.
|
||||
// I.e.: in_path = "/foo/bar/baz/boo.c", replace = ".asm" => out_path = "/foo/bar/baz/boo.asm"
|
||||
// I.e.: in_path = "/foo/bar/baz/boo.c", replace = "" => out_path = "/foo/bar/baz/boo"
|
||||
// E.g.: in_path = "/foo/bar/baz/boo.c", replace = ".asm" => out_path = "/foo/bar/baz/boo.asm"
|
||||
// E.g.: in_path = "/foo/bar/baz/boo.c", replace = "" => out_path = "/foo/bar/baz/boo"
|
||||
void fill_pathname(char *out_path, const char *in_path, const char *replace, size_t size);
|
||||
|
||||
// Appends a filename extension 'replace' to 'in_path', and outputs result in 'out_path'.
|
||||
@ -89,7 +97,7 @@ void fill_pathname_noext(char *out_path, const char *in_path, const char *replac
|
||||
// Basename of in_basename is the string after the last '/' or '\\', i.e the filename without directories.
|
||||
// If in_basename has no '/' or '\\', the whole 'in_basename' will be used.
|
||||
// 'size' is buffer size of 'in_dir'.
|
||||
// I.e.: in_dir = "/tmp/some_dir", in_basename = "/some_roms/foo.c", replace = ".asm" =>
|
||||
// E.g..: in_dir = "/tmp/some_dir", in_basename = "/some_roms/foo.c", replace = ".asm" =>
|
||||
// in_dir = "/tmp/some_dir/foo.c.asm"
|
||||
void fill_pathname_dir(char *in_dir, const char *in_basename, const char *replace, size_t size);
|
||||
|
||||
@ -97,9 +105,14 @@ void fill_pathname_dir(char *in_dir, const char *in_basename, const char *replac
|
||||
void fill_pathname_base(char *out_path, const char *in_path, size_t size);
|
||||
|
||||
// Copies base directory of in_path into out_path.
|
||||
// If in_path is a path without any slashes (relative current directory), out_path will get path ".".
|
||||
// If in_path is a path without any slashes (relative current directory), out_path will get path "./".
|
||||
void fill_pathname_basedir(char *out_path, const char *in_path, size_t size);
|
||||
|
||||
// Joins basedir of in_refpath together with in_path.
|
||||
// If in_path is an absolute path, out_path = in_path.
|
||||
// E.g.: in_refpath = "/foo/bar/baz.a", in_path = "foobar.cg", out_path = "/foo/bar/foobar.cg".
|
||||
void fill_pathname_resolve_relative(char *out_path, const char *in_refpath, const char *in_path, size_t size);
|
||||
|
||||
size_t convert_char_to_wchar(wchar_t *out_wchar, const char *in_char, size_t size);
|
||||
size_t convert_wchar_to_char(char *out_char, const wchar_t *in_wchar, size_t size);
|
||||
|
||||
|
61
file_path.c
61
file_path.c
@ -410,17 +410,62 @@ void fill_pathname_base(char *out, const char *in_path, size_t size)
|
||||
void fill_pathname_basedir(char *out_dir, const char *in_path, size_t size)
|
||||
{
|
||||
rarch_assert(strlcpy(out_dir, in_path, size) < size);
|
||||
path_basedir(out_dir);
|
||||
}
|
||||
|
||||
char *base = strrchr(out_dir, '/');
|
||||
if (!base)
|
||||
base = strrchr(out_dir, '\\');
|
||||
void path_basedir(char *path)
|
||||
{
|
||||
if (strlen(path) < 2)
|
||||
return;
|
||||
|
||||
if (base)
|
||||
*base = '\0';
|
||||
else if (size >= 2)
|
||||
char *last = strrchr(path, '/');
|
||||
#ifdef _WIN32
|
||||
if (!last)
|
||||
last = strrchr(path, '\\');
|
||||
#endif
|
||||
|
||||
if (last)
|
||||
last[1] = '\0';
|
||||
else
|
||||
{
|
||||
out_dir[0] = '.';
|
||||
out_dir[1] = '\0';
|
||||
path[0] = '.';
|
||||
path[1] = '/';
|
||||
path[2] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
const char *path_basename(const char *path)
|
||||
{
|
||||
const char *last = strrchr(path, '/');
|
||||
#ifdef _WIN32
|
||||
if (!last)
|
||||
last = strrchr(path, '\\');
|
||||
#endif
|
||||
|
||||
if (last)
|
||||
return last + 1;
|
||||
else
|
||||
return path;
|
||||
}
|
||||
|
||||
bool path_is_absolute(const char *path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return path[0] == '/' || strstr(path, ":/") || strstr(path, ":\\");
|
||||
#else
|
||||
return path[0] == '/';
|
||||
#endif
|
||||
}
|
||||
|
||||
void fill_pathname_resolve_relative(char *out_path, const char *in_refpath, const char *in_path, size_t size)
|
||||
{
|
||||
if (path_is_absolute(in_path))
|
||||
rarch_assert(strlcpy(out_path, in_path, size) < size);
|
||||
else
|
||||
{
|
||||
rarch_assert(strlcpy(out_path, in_refpath, size) < size);
|
||||
path_basedir(out_path);
|
||||
rarch_assert(strlcat(out_path, in_path, size) < size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -708,8 +708,9 @@ static inline void rarch_sleep(unsigned msec)
|
||||
#endif
|
||||
}
|
||||
|
||||
#define rarch_assert(cond) \
|
||||
if (!(cond)) { RARCH_ERR("Assertion failed at %s:%d.\n", __FILE__, __LINE__); exit(2); }
|
||||
#define rarch_assert(cond) do { \
|
||||
if (!(cond)) { RARCH_ERR("Assertion failed at %s:%d.\n", __FILE__, __LINE__); exit(2); } \
|
||||
} while(0)
|
||||
|
||||
static inline void rarch_fail(int error_code, const char *error)
|
||||
{
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "image.h"
|
||||
#include "../dynamic.h"
|
||||
#include "../compat/posix_string.h"
|
||||
#include "../file.h"
|
||||
|
||||
#ifdef HAVE_CONFIGFILE
|
||||
#include "state_tracker.h"
|
||||
@ -533,7 +534,7 @@ static void load_texture_data(GLuint *obj, const struct texture_image *img, bool
|
||||
free(img->pixels);
|
||||
}
|
||||
|
||||
static bool load_textures(const char *dir_path, config_file_t *conf)
|
||||
static bool load_textures(const char *cgp_path, config_file_t *conf)
|
||||
{
|
||||
bool ret = true;
|
||||
char *textures = NULL;
|
||||
@ -566,11 +567,8 @@ static bool load_textures(const char *dir_path, config_file_t *conf)
|
||||
if (!config_get_bool(conf, id_absolute, &absolute))
|
||||
absolute = false;
|
||||
|
||||
char image_path[512];
|
||||
if (absolute)
|
||||
print_buf(image_path, "%s", path);
|
||||
else
|
||||
print_buf(image_path, "%s%s", dir_path, path);
|
||||
char image_path[PATH_MAX];
|
||||
fill_pathname_resolve_relative(image_path, cgp_path, path, sizeof(image_path));
|
||||
|
||||
RARCH_LOG("Loading image from: \"%s\".\n", image_path);
|
||||
struct texture_image img;
|
||||
@ -596,7 +594,7 @@ end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool load_imports(const char *dir_path, config_file_t *conf)
|
||||
static bool load_imports(const char *cgp_path, config_file_t *conf)
|
||||
{
|
||||
bool ret = true;
|
||||
char *imports = NULL;
|
||||
@ -744,9 +742,7 @@ static bool load_imports(const char *dir_path, config_file_t *conf)
|
||||
#ifdef HAVE_PYTHON
|
||||
if (config_get_string(conf, "import_script", &script))
|
||||
{
|
||||
strlcpy(script_path, dir_path, sizeof(script_path));
|
||||
strlcat(script_path, script, sizeof(script_path));
|
||||
|
||||
fill_pathname_resolve_relative(script_path, cgp_path, script, sizeof(script_path));
|
||||
tracker_info.script = script_path;
|
||||
}
|
||||
if (config_get_string(conf, "import_script_class", &script_class))
|
||||
@ -772,7 +768,7 @@ end:
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool load_shader(const char *dir_path, unsigned i, config_file_t *conf)
|
||||
static bool load_shader(const char *cgp_path, unsigned i, config_file_t *conf)
|
||||
{
|
||||
char *shader_path = NULL;
|
||||
char attr_buf[64];
|
||||
@ -781,8 +777,7 @@ static bool load_shader(const char *dir_path, unsigned i, config_file_t *conf)
|
||||
print_buf(attr_buf, "shader%u", i);
|
||||
if (config_get_string(conf, attr_buf, &shader_path))
|
||||
{
|
||||
strlcpy(path_buf, dir_path, sizeof(path_buf));
|
||||
strlcat(path_buf, shader_path, sizeof(path_buf));
|
||||
fill_pathname_resolve_relative(path_buf, cgp_path, shader_path, sizeof(path_buf));
|
||||
free(shader_path);
|
||||
}
|
||||
else
|
||||
@ -945,9 +940,6 @@ static bool load_preset(const char *path)
|
||||
return false;
|
||||
|
||||
int shaders = 0;
|
||||
// Basedir.
|
||||
char dir_path[PATH_MAX];
|
||||
char *ptr = NULL;
|
||||
|
||||
RARCH_LOG("Loading Cg meta-shader: %s\n", path);
|
||||
config_file_t *conf = config_file_new(path);
|
||||
@ -994,14 +986,6 @@ static bool load_preset(const char *path)
|
||||
fbo_smooth[i + 1] = smooth ? FILTER_LINEAR : FILTER_NEAREST;
|
||||
}
|
||||
|
||||
strlcpy(dir_path, path, sizeof(dir_path));
|
||||
ptr = strrchr(dir_path, '/');
|
||||
if (!ptr) ptr = strrchr(dir_path, '\\');
|
||||
if (ptr)
|
||||
ptr[1] = '\0';
|
||||
else // No directory.
|
||||
dir_path[0] = '\0';
|
||||
|
||||
for (int i = 0; i < shaders; i++)
|
||||
{
|
||||
if (!load_shader_params(i, conf))
|
||||
@ -1011,7 +995,7 @@ static bool load_preset(const char *path)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!load_shader(dir_path, i, conf))
|
||||
if (!load_shader(path, i, conf))
|
||||
{
|
||||
RARCH_ERR("Failed to load shaders ...\n");
|
||||
ret = false;
|
||||
@ -1019,14 +1003,14 @@ static bool load_preset(const char *path)
|
||||
}
|
||||
}
|
||||
|
||||
if (!load_textures(dir_path, conf))
|
||||
if (!load_textures(path, conf))
|
||||
{
|
||||
RARCH_ERR("Failed to load lookup textures ...\n");
|
||||
ret = false;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!load_imports(dir_path, conf))
|
||||
if (!load_imports(path, conf))
|
||||
{
|
||||
RARCH_ERR("Failed to load imports ...\n");
|
||||
ret = false;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "../compat/posix_string.h"
|
||||
#include "state_tracker.h"
|
||||
#include "../dynamic.h"
|
||||
#include "../file.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
@ -422,9 +423,8 @@ static bool get_texture_image(const char *shader_path, xmlNodePtr ptr)
|
||||
|
||||
bool linear = true;
|
||||
xmlChar *filename = xmlGetProp(ptr, (const xmlChar*)"file");
|
||||
xmlChar *filter = xmlGetProp(ptr, (const xmlChar*)"filter");
|
||||
xmlChar *id = xmlGetProp(ptr, (const xmlChar*)"id");
|
||||
char *last = NULL;
|
||||
xmlChar *filter = xmlGetProp(ptr, (const xmlChar*)"filter");
|
||||
xmlChar *id = xmlGetProp(ptr, (const xmlChar*)"id");
|
||||
struct texture_image img;
|
||||
|
||||
if (!id)
|
||||
@ -443,13 +443,7 @@ static bool get_texture_image(const char *shader_path, xmlNodePtr ptr)
|
||||
linear = false;
|
||||
|
||||
char tex_path[PATH_MAX];
|
||||
strlcpy(tex_path, shader_path, sizeof(tex_path));
|
||||
|
||||
last = strrchr(tex_path, '/');
|
||||
if (!last) last = strrchr(tex_path, '\\');
|
||||
if (last) last[1] = '\0';
|
||||
|
||||
strlcat(tex_path, (const char*)filename, sizeof(tex_path));
|
||||
fill_pathname_resolve_relative(tex_path, shader_path, (const char*)filename, sizeof(tex_path));
|
||||
|
||||
RARCH_LOG("Loading texture image from: \"%s\" ...\n", tex_path);
|
||||
if (!texture_image_load(tex_path, &img))
|
||||
@ -529,12 +523,7 @@ static bool get_script(const char *path, xmlNodePtr ptr)
|
||||
xmlChar *src = xmlGetProp(ptr, (const xmlChar*)"src");
|
||||
if (src)
|
||||
{
|
||||
strlcpy(gl_tracker_script, path, sizeof(gl_tracker_script));
|
||||
char *dir_ptr = strrchr(gl_tracker_script, '/');
|
||||
if (!dir_ptr) dir_ptr = strrchr(gl_tracker_script, '\\');
|
||||
if (dir_ptr) dir_ptr[1] = '\0';
|
||||
strlcat(gl_tracker_script, (const char*)src, sizeof(gl_tracker_script));
|
||||
|
||||
fill_pathname_resolve_relative(gl_tracker_script, path, (const char*)src, sizeof(gl_tracker_script));
|
||||
xmlFree(src);
|
||||
}
|
||||
else
|
||||
|
11
retroarch.c
11
retroarch.c
@ -1810,15 +1810,8 @@ static void fill_pathnames(void)
|
||||
fill_pathname_noext(g_extern.xml_name, g_extern.basename, ".xml", sizeof(g_extern.xml_name));
|
||||
|
||||
#ifdef HAVE_SCREENSHOTS
|
||||
if (!(*g_settings.screenshot_directory))
|
||||
{
|
||||
strlcpy(g_settings.screenshot_directory, g_extern.basename, sizeof(g_settings.screenshot_directory));
|
||||
char *dir = strrchr(g_settings.screenshot_directory, '/');
|
||||
if (!dir)
|
||||
dir = strrchr(g_settings.screenshot_directory, '\\');
|
||||
if (dir)
|
||||
*dir = '\0';
|
||||
}
|
||||
if (!*g_settings.screenshot_directory)
|
||||
fill_pathname_basedir(g_settings.screenshot_directory, g_extern.basename, sizeof(g_settings.screenshot_directory));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user