From a16ef95ff6ce617009c942264c64c7214c6e9eb7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 6 Dec 2022 10:41:16 +1100 Subject: [PATCH] Fix T102914: bpy.ops.wm.append no longer supports / in paths for WIN32 Support both forward and back slashes on WIN32. Forward slashes for paths in WIN32 was removed in [0] (for BLI_path_join) & [1] (for BLI_path_name_at_index), this is correct on UNIX as back slashes can be used in paths but not on WIN32 which can use both. Note that other path functions such as BLI_path_append & BLI_path_slash_ensure should be updated too, but this is out of scope for a bug-fix. Documenting and ensuring Windows path handling functions all handle forward slashes can be done separately. [0]: 8f7ab1bf46d5e8610b167180b7631ff62e718a08 [1]: 511ae2226473df57e47b439392da387cd355abef Reviewed By: harley Ref D16700 --- source/blender/blenlib/intern/path_util.c | 31 ++++++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index 25549de182a..b379cd58619 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -51,6 +51,23 @@ static bool BLI_path_is_abs(const char *name); // #define DEBUG_STRSIZE +/** + * On UNIX it only makes sense to treat `/` as a path separator. + * On WIN32 either may be used. + */ +static bool is_sep_native_compat(const char ch) +{ + if (ch == SEP) { + return true; + } +#ifdef WIN32 + if (ch == ALTSEP) { + return true; + } +#endif + return false; +} + /* implementation */ int BLI_path_sequence_decode(const char *string, char *head, char *tail, ushort *r_digits_len) @@ -1532,7 +1549,7 @@ size_t BLI_path_join_array(char *__restrict dst, bool has_trailing_slash = false; if (ofs != 0) { size_t len = ofs; - while ((len != 0) && (path[len - 1] == SEP)) { + while ((len != 0) && is_sep_native_compat(path[len - 1])) { len -= 1; } @@ -1546,18 +1563,18 @@ size_t BLI_path_join_array(char *__restrict dst, path = path_array[path_index]; has_trailing_slash = false; const char *path_init = path; - while (path[0] == SEP) { + while (is_sep_native_compat(path[0])) { path++; } size_t len = strlen(path); if (len != 0) { - while ((len != 0) && (path[len - 1] == SEP)) { + while ((len != 0) && is_sep_native_compat(path[len - 1])) { len -= 1; } if (len != 0) { /* the very first path may have a slash at the end */ - if (ofs && (dst[ofs - 1] != SEP)) { + if (ofs && !is_sep_native_compat(dst[ofs - 1])) { dst[ofs++] = SEP; if (ofs == dst_last) { break; @@ -1580,7 +1597,7 @@ size_t BLI_path_join_array(char *__restrict dst, } if (has_trailing_slash) { - if ((ofs != dst_last) && (ofs != 0) && (dst[ofs - 1] != SEP)) { + if ((ofs != dst_last) && (ofs != 0) && !is_sep_native_compat(dst[ofs - 1])) { dst[ofs++] = SEP; } } @@ -1608,7 +1625,7 @@ static bool path_name_at_index_forward(const char *__restrict path, int i = 0; while (true) { const char c = path[i]; - if (ELEM(c, SEP, '\0')) { + if ((c == '\0') || is_sep_native_compat(c)) { if (prev + 1 != i) { prev += 1; /* Skip '/./' (behave as if they don't exist). */ @@ -1643,7 +1660,7 @@ static bool path_name_at_index_backward(const char *__restrict path, int i = prev - 1; while (true) { const char c = i >= 0 ? path[i] : '\0'; - if (ELEM(c, SEP, '\0')) { + if ((c == '\0') || is_sep_native_compat(c)) { if (prev - 1 != i) { i += 1; /* Skip '/./' (behave as if they don't exist). */