Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Libretro
tyrquake
Commits
2ca27640
Commit
2ca27640
authored
Feb 22, 2018
by
Libretro-Admin
Browse files
Update libretro-common files
parent
ec1e090e
Changes
7
Show whitespace changes
Inline
Side-by-side
.gitignore
0 → 100644
View file @
2ca27640
*.o
Makefile.common
View file @
2ca27640
...
...
@@ -101,8 +101,9 @@ ifneq ($(STATIC_LINKING),1)
$(CORE_DIR)
/libretro-common/file/retro_dirent.c
\
$(CORE_DIR)
/libretro-common/encodings/encoding_utf.c
\
$(CORE_DIR)
/libretro-common/string/stdstring.c
\
$(CORE_DIR)
/libretro-common/file/
retro_st
at.c
\
$(CORE_DIR)
/libretro-common/file/
file_p
at
h
.c
\
$(CORE_DIR)
/libretro-common/compat/compat_strl.c
\
$(CORE_DIR)
/libretro-common/compat/compat_strcasestr.c
\
$(CORE_DIR)
/libretro-common/compat/compat_snprintf.c
endif
...
...
common/libretro.c
View file @
2ca27640
...
...
@@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "libretro.h"
#include <retro_miscellaneous.h>
#include <
retro_st
at.h>
#include <
file/file_p
at
h
.h>
#if defined(_WIN32) && !defined(_XBOX)
#include <windows.h>
...
...
@@ -275,7 +275,7 @@ int Sys_FileTime(const char *path)
void
Sys_mkdir
(
const
char
*
path
)
{
mkdir
_norecurse
(
path
);
path_
mkdir
(
path
);
}
void
Sys_DebugLog
(
const
char
*
file
,
const
char
*
fmt
,
...)
...
...
libretro-common/
include/retro_stat.h
→
libretro-common/
compat/compat_strcasestr.c
View file @
2ca27640
/* Copyright (C) 2010-201
6
The RetroArch team
/* Copyright (C) 2010-201
7
The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (
retro_stat.h
).
* The following license statement only applies to this file (
compat_strcasestr.c
).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
...
...
@@ -20,44 +20,39 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __RETRO_STAT_H
#define __RETRO_STAT_H
#include <ctype.h>
#include <stdint.h>
#include <stddef.h>
#include <compat/strcasestr.h>
#include <retro_common_api.h>
/* Pretty much strncasecmp. */
static
int
casencmp
(
const
char
*
a
,
const
char
*
b
,
size_t
n
)
{
size_t
i
;
#include <boolean.h>
for
(
i
=
0
;
i
<
n
;
i
++
)
{
int
a_lower
=
tolower
(
a
[
i
]);
int
b_lower
=
tolower
(
b
[
i
]);
if
(
a_lower
!=
b_lower
)
return
a_lower
-
b_lower
;
}
RETRO_BEGIN_DECLS
return
0
;
}
/**
* path_is_directory:
* @path : path
*
* Checks if path is a directory.
*
* Returns: true (1) if path is a directory, otherwise false (0).
*/
bool
path_is_directory
(
const
char
*
path
);
bool
path_is_character_special
(
const
char
*
path
);
char
*
strcasestr_retro__
(
const
char
*
haystack
,
const
char
*
needle
)
{
size_t
i
,
search_off
;
size_t
hay_len
=
strlen
(
haystack
);
size_t
needle_len
=
strlen
(
needle
);
bool
path_is_valid
(
const
char
*
path
);
int32_t
path_get_size
(
const
char
*
path
);
/**
* path_mkdir_norecurse:
* @dir : directory
*
* Create directory on filesystem.
*
* Returns: true (1) if directory could be created, otherwise false (0).
**/
bool
mkdir_norecurse
(
const
char
*
dir
);
if
(
needle_len
>
hay_len
)
return
NULL
;
RETRO_END_DECLS
search_off
=
hay_len
-
needle_len
;
for
(
i
=
0
;
i
<=
search_off
;
i
++
)
if
(
!
casencmp
(
haystack
+
i
,
needle
,
needle_len
))
return
(
char
*
)
haystack
+
i
;
#endif
return
NULL
;
}
libretro-common/file/file_path.c
0 → 100644
View file @
2ca27640
/* Copyright (C) 2010-2017 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (file_path.c).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <sys/stat.h>
#include <boolean.h>
#include <file/file_path.h>
#include <retro_assert.h>
#include <string/stdstring.h>
#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#endif
#ifdef __HAIKU__
#include <kernel/image.h>
#endif
#ifndef __MACH__
#include <compat/strl.h>
#include <compat/posix_string.h>
#endif
#include <compat/strcasestr.h>
#include <retro_miscellaneous.h>
#include <encodings/utf.h>
#if defined(_WIN32)
#ifdef _MSC_VER
#define setmode _setmode
#endif
#include <sys/stat.h>
#ifdef _XBOX
#include <xtl.h>
#define INVALID_FILE_ATTRIBUTES -1
#else
#include <io.h>
#include <fcntl.h>
#include <direct.h>
#include <windows.h>
#if defined(_MSC_VER) && _MSC_VER <= 1200
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
#endif
#elif defined(VITA)
#define SCE_ERROR_ERRNO_EEXIST 0x80010011
#include <psp2/io/fcntl.h>
#include <psp2/io/dirent.h>
#include <psp2/io/stat.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif
#if defined(PSP)
#include <pspkernel.h>
#endif
#if defined(__CELLOS_LV2__)
#include <cell/cell_fs.h>
#endif
#if defined(VITA)
#define FIO_S_ISDIR SCE_S_ISDIR
#endif
#if (defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)) || defined(__QNX__) || defined(PSP)
#include <unistd.h>
/* stat() is defined here */
#endif
/* Assume W-functions do not work below Win2K and Xbox platforms */
#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 || defined(_XBOX)
#ifndef LEGACY_WIN32
#define LEGACY_WIN32
#endif
#endif
enum
stat_mode
{
IS_DIRECTORY
=
0
,
IS_CHARACTER_SPECIAL
,
IS_VALID
};
static
bool
path_stat
(
const
char
*
path
,
enum
stat_mode
mode
,
int32_t
*
size
)
{
#if defined(VITA) || defined(PSP)
SceIoStat
buf
;
char
*
tmp
=
strdup
(
path
);
size_t
len
=
strlen
(
tmp
);
if
(
tmp
[
len
-
1
]
==
'/'
)
tmp
[
len
-
1
]
=
'\0'
;
if
(
sceIoGetstat
(
tmp
,
&
buf
)
<
0
)
{
free
(
tmp
);
return
false
;
}
free
(
tmp
);
#elif defined(__CELLOS_LV2__)
CellFsStat
buf
;
if
(
cellFsStat
(
path
,
&
buf
)
<
0
)
return
false
;
#elif defined(_WIN32)
struct
_stat
buf
;
char
*
path_local
;
wchar_t
*
path_wide
;
DWORD
file_info
;
if
(
!
path
||
!*
path
)
return
false
;
(
void
)
path_wide
;
(
void
)
path_local
;
(
void
)
file_info
;
#if defined(LEGACY_WIN32)
path_local
=
utf8_to_local_string_alloc
(
path
);
file_info
=
GetFileAttributes
(
path_local
);
_stat
(
path_local
,
&
buf
);
if
(
path_local
)
free
(
path_local
);
#else
path_wide
=
utf8_to_utf16_string_alloc
(
path
);
file_info
=
GetFileAttributesW
(
path_wide
);
_wstat
(
path_wide
,
&
buf
);
if
(
path_wide
)
free
(
path_wide
);
#endif
if
(
file_info
==
INVALID_FILE_ATTRIBUTES
)
return
false
;
#else
struct
stat
buf
;
if
(
stat
(
path
,
&
buf
)
<
0
)
return
false
;
#endif
if
(
size
)
*
size
=
(
int32_t
)
buf
.
st_size
;
switch
(
mode
)
{
case
IS_DIRECTORY
:
#if defined(VITA) || defined(PSP)
return
FIO_S_ISDIR
(
buf
.
st_mode
);
#elif defined(__CELLOS_LV2__)
return
((
buf
.
st_mode
&
S_IFMT
)
==
S_IFDIR
);
#elif defined(_WIN32)
return
(
file_info
&
FILE_ATTRIBUTE_DIRECTORY
);
#else
return
S_ISDIR
(
buf
.
st_mode
);
#endif
case
IS_CHARACTER_SPECIAL
:
#if defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__) || defined(_WIN32)
return
false
;
#else
return
S_ISCHR
(
buf
.
st_mode
);
#endif
case
IS_VALID
:
return
true
;
}
return
false
;
}
/**
* path_is_directory:
* @path : path
*
* Checks if path is a directory.
*
* Returns: true (1) if path is a directory, otherwise false (0).
*/
bool
path_is_directory
(
const
char
*
path
)
{
return
path_stat
(
path
,
IS_DIRECTORY
,
NULL
);
}
bool
path_is_character_special
(
const
char
*
path
)
{
return
path_stat
(
path
,
IS_CHARACTER_SPECIAL
,
NULL
);
}
bool
path_is_valid
(
const
char
*
path
)
{
return
path_stat
(
path
,
IS_VALID
,
NULL
);
}
int32_t
path_get_size
(
const
char
*
path
)
{
int32_t
filesize
=
0
;
if
(
path_stat
(
path
,
IS_VALID
,
&
filesize
))
return
filesize
;
return
-
1
;
}
static
bool
path_mkdir_error
(
int
ret
)
{
#if defined(VITA)
return
(
ret
==
SCE_ERROR_ERRNO_EEXIST
);
#elif defined(PSP) || defined(_3DS) || defined(WIIU)
return
(
ret
==
-
1
);
#else
return
(
ret
<
0
&&
errno
==
EEXIST
);
#endif
}
/**
* path_mkdir:
* @dir : directory
*
* Create directory on filesystem.
*
* Returns: true (1) if directory could be created, otherwise false (0).
**/
bool
path_mkdir
(
const
char
*
dir
)
{
/* Use heap. Real chance of stack overflow if we recurse too hard. */
const
char
*
target
=
NULL
;
bool
sret
=
false
;
bool
norecurse
=
false
;
char
*
basedir
=
NULL
;
if
(
dir
&&
*
dir
)
basedir
=
strdup
(
dir
);
if
(
!
basedir
)
return
false
;
path_parent_dir
(
basedir
);
if
(
!*
basedir
||
!
strcmp
(
basedir
,
dir
))
goto
end
;
if
(
path_is_directory
(
basedir
))
{
target
=
dir
;
norecurse
=
true
;
}
else
{
target
=
basedir
;
sret
=
path_mkdir
(
basedir
);
if
(
sret
)
{
target
=
dir
;
norecurse
=
true
;
}
}
if
(
norecurse
)
{
#if defined(_WIN32)
#ifdef LEGACY_WIN32
int
ret
=
_mkdir
(
dir
);
#else
wchar_t
*
dirW
=
utf8_to_utf16_string_alloc
(
dir
);
int
ret
=
-
1
;
if
(
dirW
)
{
ret
=
_wmkdir
(
dirW
);
free
(
dirW
);
}
#endif
#elif defined(IOS)
int
ret
=
mkdir
(
dir
,
0755
);
#elif defined(VITA) || defined(PSP)
int
ret
=
sceIoMkdir
(
dir
,
0777
);
#elif defined(__QNX__)
int
ret
=
mkdir
(
dir
,
0777
);
#else
int
ret
=
mkdir
(
dir
,
0750
);
#endif
/* Don't treat this as an error. */
if
(
path_mkdir_error
(
ret
)
&&
path_is_directory
(
dir
))
ret
=
0
;
if
(
ret
<
0
)
printf
(
"mkdir(%s) error: %s.
\n
"
,
dir
,
strerror
(
errno
));
sret
=
(
ret
==
0
);
}
end:
if
(
target
&&
!
sret
)
printf
(
"Failed to create directory:
\"
%s
\"
.
\n
"
,
target
);
free
(
basedir
);
return
sret
;
}
/**
* path_get_archive_delim:
* @path : path
*
* Find delimiter of an archive file. Only the first '#'
* after a compression extension is considered.
*
* Returns: pointer to the delimiter in the path if it contains
* a path inside a compressed file, otherwise NULL.
*/
const
char
*
path_get_archive_delim
(
const
char
*
path
)
{
const
char
*
last
=
find_last_slash
(
path
);
const
char
*
delim
=
NULL
;
if
(
last
)
{
delim
=
strcasestr
(
last
,
".zip#"
);
if
(
!
delim
)
delim
=
strcasestr
(
last
,
".apk#"
);
}
if
(
delim
)
return
delim
+
4
;
if
(
last
)
delim
=
strcasestr
(
last
,
".7z#"
);
if
(
delim
)
return
delim
+
3
;
return
NULL
;
}
/**
* path_get_extension:
* @path : path
*
* Gets extension of file. Only '.'s
* after the last slash are considered.
*
* Returns: extension part from the path.
*/
const
char
*
path_get_extension
(
const
char
*
path
)
{
const
char
*
ext
=
!
string_is_empty
(
path
)
?
strrchr
(
path_basename
(
path
),
'.'
)
:
NULL
;
if
(
!
ext
)
return
""
;
return
ext
+
1
;
}
/**
* path_remove_extension:
* @path : path
*
* Removes the extension from the path and returns the result.
* Removes all text after and including the last '.'.
* Only '.'s after the last slash are considered.
*
* Returns: path with the extension part removed.
*/
char
*
path_remove_extension
(
char
*
path
)
{
char
*
last
=
!
string_is_empty
(
path
)
?
(
char
*
)
strrchr
(
path_basename
(
path
),
'.'
)
:
NULL
;
if
(
!
last
)
return
NULL
;
if
(
*
last
)
*
last
=
'\0'
;
return
last
;
}
/**
* path_is_compressed_file:
* @path : path
*
* Checks if path is a compressed file.
*
* Returns: true (1) if path is a compressed file, otherwise false (0).
**/
bool
path_is_compressed_file
(
const
char
*
path
)
{
const
char
*
ext
=
path_get_extension
(
path
);
if
(
strcasestr
(
ext
,
"zip"
)
||
strcasestr
(
ext
,
"apk"
)
||
strcasestr
(
ext
,
"7z"
))
return
true
;
return
false
;
}
/**
* fill_pathname:
* @out_path : output path
* @in_path : input path
* @replace : what to replace
* @size : buffer size of output path
*
* FIXME: Verify
*
* Replaces filename extension with 'replace' and outputs result to out_path.
* The extension here is considered to be the string from the last '.'
* to the end.
*
* Only '.'s after the last slash are considered as extensions.
* If no '.' is present, in_path and replace will simply be concatenated.
* 'size' is buffer size of 'out_path'.
* 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
)
{
char
tmp_path
[
PATH_MAX_LENGTH
];
char
*
tok
=
NULL
;
tmp_path
[
0
]
=
'\0'
;
strlcpy
(
tmp_path
,
in_path
,
sizeof
(
tmp_path
));
if
((
tok
=
(
char
*
)
strrchr
(
path_basename
(
tmp_path
),
'.'
)))
*
tok
=
'\0'
;
fill_pathname_noext
(
out_path
,
tmp_path
,
replace
,
size
);
}
/**
* fill_pathname_noext:
* @out_path : output path
* @in_path : input path
* @replace : what to replace
* @size : buffer size of output path
*
* Appends a filename extension 'replace' to 'in_path', and outputs
* result in 'out_path'.
*
* Assumes in_path has no extension. If an extension is still
* present in 'in_path', it will be ignored.
*
*/
void
fill_pathname_noext
(
char
*
out_path
,
const
char
*
in_path
,
const
char
*
replace
,
size_t
size
)
{
strlcpy
(
out_path
,
in_path
,
size
);
strlcat
(
out_path
,
replace
,
size
);
}
char
*
find_last_slash
(
const
char
*
str
)
{
const
char
*
slash
=
strrchr
(
str
,
'/'
);
#ifdef _WIN32
const
char
*
backslash
=
strrchr
(
str
,
'\\'
);
if
(
backslash
&&
((
slash
&&
backslash
>
slash
)
||
!
slash
))
slash
=
backslash
;
#endif
return
(
char
*
)
slash
;
}
/**
* fill_pathname_slash:
* @path : path
* @size : size of path
*
* Assumes path is a directory. Appends a slash
* if not already there.
**/
void
fill_pathname_slash
(
char
*
path
,
size_t
size
)
{
size_t
path_len
=
strlen
(
path
);
const
char
*
last_slash
=
find_last_slash
(
path
);
/* Try to preserve slash type. */
if
(
last_slash
&&
(
last_slash
!=
(
path
+
path_len
-
1
)))
{
char
join_str
[
2
];
join_str
[
0
]
=
'\0'
;
strlcpy
(
join_str
,
last_slash
,
sizeof
(
join_str
));
strlcat
(
path
,
join_str
,
size
);
}
else
if
(
!
last_slash
)
strlcat
(
path
,
path_default_slash
(),
size
);
}
/**