Allow loading files from archive subdirectory (#13443)
* Allow loading files from archive subdirectory Common example is "games.7z#game1/version1.ext" current code assumes that everything that is before last slash is part of filesystem directory which is false in this case. * Fix listing of archive subdirectories Currently file_archive_get_file_list_cb returns 0 on skipped entries. It's wrong as calling convention for it is "0 means to stop iterating". So on first extensionless file or an explicitly listed directory further listing has stopped
This commit is contained in:
parent
4dda10b86d
commit
2f130a23e4
|
@ -62,7 +62,7 @@ static int file_archive_get_file_list_cb(
|
||||||
|
|
||||||
/* Skip if directory. */
|
/* Skip if directory. */
|
||||||
if (last_char == '/' || last_char == '\\' )
|
if (last_char == '/' || last_char == '\\' )
|
||||||
return 0;
|
return 1;
|
||||||
|
|
||||||
string_list_initialize(&ext_list);
|
string_list_initialize(&ext_list);
|
||||||
if (string_split_noalloc(&ext_list, valid_exts, "|"))
|
if (string_split_noalloc(&ext_list, valid_exts, "|"))
|
||||||
|
@ -72,7 +72,7 @@ static int file_archive_get_file_list_cb(
|
||||||
if (!file_ext)
|
if (!file_ext)
|
||||||
{
|
{
|
||||||
string_list_deinitialize(&ext_list);
|
string_list_deinitialize(&ext_list);
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string_list_find_elem_prefix(&ext_list, ".", file_ext))
|
if (!string_list_find_elem_prefix(&ext_list, ".", file_ext))
|
||||||
|
|
|
@ -82,33 +82,23 @@
|
||||||
*/
|
*/
|
||||||
const char *path_get_archive_delim(const char *path)
|
const char *path_get_archive_delim(const char *path)
|
||||||
{
|
{
|
||||||
const char *last_slash = find_last_slash(path);
|
|
||||||
const char *delim = NULL;
|
const char *delim = NULL;
|
||||||
char buf[5];
|
char buf[5];
|
||||||
|
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
|
|
||||||
/* We search for delimiters after the last slash
|
|
||||||
* in the file path to avoid capturing delimiter
|
|
||||||
* characters in any parent directory names.
|
|
||||||
* If there are no slashes in the file name, then
|
|
||||||
* the path is just the file basename - in this
|
|
||||||
* case we search the path in its entirety */
|
|
||||||
if (!last_slash)
|
|
||||||
last_slash = path;
|
|
||||||
|
|
||||||
/* Find delimiter position
|
/* Find delimiter position
|
||||||
* > Since filenames may contain '#' characters,
|
* > Since filenames may contain '#' characters,
|
||||||
* must loop until we find the first '#' that
|
* must loop until we find the first '#' that
|
||||||
* is directly *after* a compression extension */
|
* is directly *after* a compression extension */
|
||||||
delim = strchr(last_slash, '#');
|
delim = strchr(path, '#');
|
||||||
|
|
||||||
while (delim)
|
while (delim)
|
||||||
{
|
{
|
||||||
/* Check whether this is a known archive type
|
/* Check whether this is a known archive type
|
||||||
* > Note: The code duplication here is
|
* > Note: The code duplication here is
|
||||||
* deliberate, to maximise performance */
|
* deliberate, to maximise performance */
|
||||||
if (delim - last_slash > 4)
|
if (delim - path > 4)
|
||||||
{
|
{
|
||||||
strlcpy(buf, delim - 4, sizeof(buf));
|
strlcpy(buf, delim - 4, sizeof(buf));
|
||||||
buf[4] = '\0';
|
buf[4] = '\0';
|
||||||
|
@ -121,7 +111,7 @@ const char *path_get_archive_delim(const char *path)
|
||||||
string_is_equal(buf + 1, ".7z"))
|
string_is_equal(buf + 1, ".7z"))
|
||||||
return delim;
|
return delim;
|
||||||
}
|
}
|
||||||
else if (delim - last_slash > 3)
|
else if (delim - path > 3)
|
||||||
{
|
{
|
||||||
strlcpy(buf, delim - 3, sizeof(buf));
|
strlcpy(buf, delim - 3, sizeof(buf));
|
||||||
buf[3] = '\0';
|
buf[3] = '\0';
|
||||||
|
|
Loading…
Reference in New Issue