Updated libretro-common (#609)

This commit is contained in:
Alberto Fustinoni
2024-06-29 07:41:51 +09:00
committed by GitHub
parent 819805ea75
commit 9e685cda13
9 changed files with 758 additions and 302 deletions

View File

@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <locale.h>
#include <sys/stat.h>
@@ -68,6 +69,31 @@
#endif
/* Time format strings with AM-PM designation require special
* handling due to platform dependence */
void strftime_am_pm(char *s, size_t len, const char* format,
const void *ptr)
{
char *local = NULL;
const struct tm *timeptr = (const struct tm*)ptr;
/* Ensure correct locale is set
* > Required for localised AM/PM strings */
setlocale(LC_TIME, "");
strftime(s, len, format, timeptr);
#if !(defined(__linux__) && !defined(ANDROID))
if ((local = local_to_utf8_string_alloc(s)))
{
if (!string_is_empty(local))
strlcpy(s, local, len);
free(local);
local = NULL;
}
#endif
}
/**
* Create a new linked list with one node in it
* The path on this node will be set to NULL
@@ -172,9 +198,9 @@ const char *path_get_archive_delim(const char *path)
string_to_lower(buf);
/* Check if this is a '.zip', '.apk' or '.7z' file */
if (string_is_equal(buf, ".zip") ||
string_is_equal(buf, ".apk") ||
string_is_equal(buf + 1, ".7z"))
if ( string_is_equal(buf, ".zip")
|| string_is_equal(buf, ".apk")
|| string_is_equal(buf + 1, ".7z"))
return delim;
}
else if (delim - path > 3)
@@ -208,7 +234,7 @@ const char *path_get_archive_delim(const char *path)
const char *path_get_extension(const char *path)
{
const char *ext;
if (!string_is_empty(path) && ((ext = strrchr(path_basename(path), '.'))))
if (!string_is_empty(path) && ((ext = (char*)strrchr(path_basename(path), '.'))))
return ext + 1;
return "";
}
@@ -228,7 +254,7 @@ const char *path_get_extension(const char *path)
char *path_get_extension_mutable(const char *path)
{
char *ext = NULL;
if (!string_is_empty(path) && ((ext = strrchr(path_basename(path), '.'))))
if (!string_is_empty(path) && ((ext = (char*)strrchr(path_basename(path), '.'))))
return ext;
return NULL;
}
@@ -302,14 +328,16 @@ bool path_is_compressed_file(const char* path)
size_t fill_pathname(char *out_path, const char *in_path,
const char *replace, size_t size)
{
size_t _len;
char tmp_path[PATH_MAX_LENGTH];
char *tok = NULL;
strlcpy(tmp_path, in_path, sizeof(tmp_path));
if ((tok = (char*)strrchr(path_basename(tmp_path), '.')))
*tok = '\0';
strlcpy(out_path, tmp_path, size);
return strlcat(out_path, replace, size);
_len = strlcpy(out_path, tmp_path, size);
_len += strlcpy(out_path + _len, replace, size - _len);
return _len;
}
@@ -319,21 +347,20 @@ size_t fill_pathname(char *out_path, const char *in_path,
* @size : size of path
*
* Find last slash in path. Tries to find
* a backslash on Windows too which takes precedence
* over regular slash.
* a backslash as used for Windows paths,
* otherwise checks for a regular slash.
* @return pointer to last slash/backslash found in @str.
**/
char *find_last_slash(const char *str)
{
const char *slash = strrchr(str, '/');
#ifdef _WIN32
const char *backslash = strrchr(str, '\\');
if (!slash || (backslash > slash))
return (char*)backslash;
#endif
return (char*)slash;
else
return (char*)slash;
}
/**
@@ -344,24 +371,20 @@ char *find_last_slash(const char *str)
* Assumes path is a directory. Appends a slash
* if not already there.
**/
void fill_pathname_slash(char *path, size_t size)
size_t fill_pathname_slash(char *path, size_t size)
{
size_t path_len;
const char *last_slash = find_last_slash(path);
if (!last_slash)
{
strlcat(path, PATH_DEFAULT_SLASH(), size);
return;
}
path_len = strlen(path);
return strlcat(path, PATH_DEFAULT_SLASH(), size);
path_len = strlen(path);
/* Try to preserve slash type. */
if (last_slash != (path + path_len - 1))
{
path[path_len] = last_slash[0];
path[path_len+1] = '\0';
path[ path_len] = last_slash[0];
path[++path_len] = '\0';
}
return path_len;
}
/**
@@ -384,12 +407,11 @@ void fill_pathname_slash(char *path, size_t size)
size_t fill_pathname_dir(char *in_dir, const char *in_basename,
const char *replace, size_t size)
{
const char *base = NULL;
fill_pathname_slash(in_dir, size);
base = path_basename(in_basename);
strlcat(in_dir, base, size);
return strlcat(in_dir, replace, size);
size_t _len = fill_pathname_slash(in_dir, size);
const char *base = path_basename(in_basename);
_len += strlcpy(in_dir + _len, base, size - _len);
_len += strlcpy(in_dir + _len, replace, size - _len);
return _len;
}
/**
@@ -514,14 +536,14 @@ void fill_pathname_parent_dir(char *out_dir,
size_t fill_dated_filename(char *out_filename,
const char *ext, size_t size)
{
time_t cur_time = time(NULL);
size_t _len;
struct tm tm_;
time_t cur_time = time(NULL);
rtime_localtime(&cur_time, &tm_);
strftime(out_filename, size,
_len = strftime(out_filename, size,
"RetroArch-%m%d-%H%M%S", &tm_);
return strlcat(out_filename, ext, size);
_len += strlcpy(out_filename + _len, ext, size - _len);
return _len;
}
/**
@@ -542,21 +564,24 @@ size_t fill_dated_filename(char *out_filename,
size_t fill_str_dated_filename(char *out_filename,
const char *in_str, const char *ext, size_t size)
{
char format[NAME_MAX_LENGTH];
struct tm tm_;
char format[NAME_MAX_LENGTH];
size_t _len = 0;
time_t cur_time = time(NULL);
rtime_localtime(&cur_time, &tm_);
strlcpy(out_filename, in_str, size);
_len = strlcpy(out_filename, in_str, size);
if (string_is_empty(ext))
{
strftime(format, sizeof(format), "-%y%m%d-%H%M%S", &tm_);
return strlcat(out_filename, format, size);
_len += strlcpy(out_filename + _len, format, size - _len);
}
strftime(format, sizeof(format), "-%y%m%d-%H%M%S.", &tm_);
strlcat(out_filename, format, size);
return strlcat(out_filename, ext, size);
else
{
strftime(format, sizeof(format), "-%y%m%d-%H%M%S.", &tm_);
_len += strlcpy(out_filename + _len, format, size - _len);
_len += strlcpy(out_filename + _len, ext, size - _len);
}
return _len;
}
/**
@@ -626,18 +651,12 @@ void path_parent_dir(char *path, size_t len)
**/
const char *path_basename(const char *path)
{
/* We cut at the first compression-related hash */
const char *delim = path_get_archive_delim(path);
if (delim)
return delim + 1;
{
/* We cut at the last slash */
const char *last = find_last_slash(path);
if (last)
return last + 1;
}
/* We cut either at the first compression-related hash,
* or we cut at the last slash */
const char *ptr = NULL;
if ( (ptr = path_get_archive_delim(path))
|| (ptr = find_last_slash(path)))
return ptr + 1;
return path;
}
@@ -670,24 +689,23 @@ const char *path_basename_nocompression(const char *path)
**/
bool path_is_absolute(const char *path)
{
if (string_is_empty(path))
return false;
if (path[0] == '/')
return true;
#if defined(_WIN32)
/* Many roads lead to Rome...
* Note: Drive letter can only be 1 character long */
return ( string_starts_with_size(path, "\\\\", STRLEN_CONST("\\\\"))
|| string_starts_with_size(path + 1, ":/", STRLEN_CONST(":/"))
|| string_starts_with_size(path + 1, ":\\", STRLEN_CONST(":\\")));
#elif defined(__wiiu__) || defined(VITA)
if (!string_is_empty(path))
{
const char *seperator = strchr(path, ':');
return (seperator && (seperator[1] == '/'));
}
if (path[0] == '/')
return true;
#if defined(_WIN32)
/* Many roads lead to Rome...
* Note: Drive letter can only be 1 character long */
return ( string_starts_with_size(path, "\\\\", STRLEN_CONST("\\\\"))
|| string_starts_with_size(path + 1, ":/", STRLEN_CONST(":/"))
|| string_starts_with_size(path + 1, ":\\", STRLEN_CONST(":\\")));
#elif defined(__wiiu__) || defined(VITA)
{
const char *seperator = strchr(path, ':');
return (seperator && (seperator[1] == '/'));
}
#endif
}
return false;
}
@@ -713,7 +731,7 @@ char *path_resolve_realpath(char *buf, size_t size, bool resolve_symlinks)
{
#if !defined(RARCH_CONSOLE) && defined(RARCH_INTERNAL)
#ifdef _WIN32
char *ret = NULL;
char *ret = NULL;
wchar_t *rel_path = utf8_to_utf16_string_alloc(buf);
if (rel_path)
@@ -767,13 +785,13 @@ char *path_resolve_realpath(char *buf, size_t size, bool resolve_symlinks)
{
size_t len;
/* rebase on working directory */
if (!getcwd(tmp, PATH_MAX_LENGTH-1))
if (!getcwd(tmp, PATH_MAX_LENGTH - 1))
return NULL;
len = strlen(tmp);
t += len;
t += len;
if (tmp[len-1] != '/')
if (tmp[len - 1] != '/')
tmp[t++] = '/';
if (string_is_empty(buf))
@@ -804,8 +822,8 @@ char *path_resolve_realpath(char *buf, size_t size, bool resolve_symlinks)
return NULL;
/* delete previous segment in tmp by adjusting size t
* tmp[t-1] == '/', find '/' before that */
t = t-2;
* tmp[t - 1] == '/', find '/' before that */
t -= 2;
while (tmp[t] != '/')
t--;
t++;
@@ -817,7 +835,7 @@ char *path_resolve_realpath(char *buf, size_t size, bool resolve_symlinks)
else
{
/* fail when truncating */
if (t + next-p+1 > PATH_MAX_LENGTH-1)
if (t + next - p + 1 > PATH_MAX_LENGTH - 1)
return NULL;
while (p <= next)
@@ -936,11 +954,13 @@ void fill_pathname_resolve_relative(char *out_path,
size_t fill_pathname_join(char *out_path,
const char *dir, const char *path, size_t size)
{
size_t _len = 0;
if (out_path != dir)
strlcpy(out_path, dir, size);
_len = strlcpy(out_path, dir, size);
if (*out_path)
fill_pathname_slash(out_path, size);
return strlcat(out_path, path, size);
_len = fill_pathname_slash(out_path, size);
_len += strlcpy(out_path + _len, path, size - _len);
return _len;
}
/**
@@ -974,18 +994,19 @@ size_t fill_pathname_join_special(char *out_path,
/* Try to preserve slash type. */
if (last_slash != (out_path + len - 1))
{
out_path[len] = last_slash[0];
out_path[len+1] = '\0';
out_path[ len] = last_slash[0];
out_path[++len] = '\0';
}
}
else
{
out_path[len] = PATH_DEFAULT_SLASH_C();
out_path[len+1] = '\0';
out_path[ len] = PATH_DEFAULT_SLASH_C();
out_path[++len] = '\0';
}
}
return strlcat(out_path, path, size);
len += strlcpy(out_path + len, path, size - len);
return len;
}
size_t fill_pathname_join_special_ext(char *out_path,
@@ -993,12 +1014,12 @@ size_t fill_pathname_join_special_ext(char *out_path,
const char *last, const char *ext,
size_t size)
{
fill_pathname_join(out_path, dir, path, size);
size_t _len = fill_pathname_join(out_path, dir, path, size);
if (*out_path)
fill_pathname_slash(out_path, size);
strlcat(out_path, last, size);
return strlcat(out_path, ext, size);
_len = fill_pathname_slash(out_path, size);
_len += strlcpy(out_path + _len, last, size - _len);
_len += strlcpy(out_path + _len, ext, size - _len);
return _len;
}
/**
@@ -1015,19 +1036,19 @@ size_t fill_pathname_join_special_ext(char *out_path,
size_t fill_pathname_join_delim(char *out_path, const char *dir,
const char *path, const char delim, size_t size)
{
size_t copied;
/* behavior of strlcpy is undefined if dst and src overlap */
size_t _len;
/* Behavior of strlcpy is undefined if dst and src overlap */
if (out_path == dir)
copied = strlen(dir);
_len = strlen(dir);
else
copied = strlcpy(out_path, dir, size);
_len = strlcpy(out_path, dir, size);
out_path[copied] = delim;
out_path[copied+1] = '\0';
out_path[_len] = delim;
out_path[_len+1] = '\0';
if (path)
return strlcat(out_path, path, size);
return copied;
return _len;
}
size_t fill_pathname_expand_special(char *out_path,
@@ -1135,12 +1156,12 @@ size_t fill_pathname_abbreviate_special(char *out_path,
*
* Leaf function.
*
* Changes the slashes to the correct kind for the os
* Changes the slashes to the correct kind for the OS
* So forward slash on linux and backslash on Windows
**/
void pathname_conform_slashes_to_os(char *path)
{
/* Conform slashes to os standard so we get proper matching */
/* Conform slashes to OS standard so we get proper matching */
char *p;
for (p = path; *p; p++)
if (*p == '/' || *p == '\\')
@@ -1158,7 +1179,7 @@ void pathname_conform_slashes_to_os(char *path)
**/
void pathname_make_slashes_portable(char *path)
{
/* Conform slashes to os standard so we get proper matching */
/* Conform slashes to OS standard so we get proper matching */
char *p;
for (p = path; *p; p++)
if (*p == '/' || *p == '\\')
@@ -1334,8 +1355,8 @@ void fill_pathname_application_path(char *s, size_t len)
if (realpath(s, resolved_bundle_dir_buf))
{
size_t _len = strlcpy(s, resolved_bundle_dir_buf, len - 1);
s[_len ] = '/';
s[_len+1] = '\0';
s[ _len] = '/';
s[++_len] = '\0';
}
}
#endif