From 57a8bbac231ce81851da261a82d9d1f7825f5b5f Mon Sep 17 00:00:00 2001 From: vector-of-bool Date: Sun, 8 Oct 2017 13:28:38 -0600 Subject: [PATCH] Respect POSIX path separators on Windows (#6356) --- src/openrct2-ui/windows/LoadSave.cpp | 5 ++++- src/openrct2/core/Path.cpp | 18 +++++++----------- src/openrct2/core/String.cpp | 6 +++--- src/openrct2/core/String.hpp | 2 +- src/openrct2/drawing/string.c | 4 ++-- src/openrct2/util/util.c | 10 ++++++++-- 6 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/openrct2-ui/windows/LoadSave.cpp b/src/openrct2-ui/windows/LoadSave.cpp index ce383a228d..fb9e6a21ae 100644 --- a/src/openrct2-ui/windows/LoadSave.cpp +++ b/src/openrct2-ui/windows/LoadSave.cpp @@ -629,11 +629,14 @@ static void window_loadsave_populate_list(rct_window *w, sint32 includeNewItem, // Remove the separator at the end of the path, if present safe_strcpy(_parentDirectory, directory, sizeof(_parentDirectory)); - if (_parentDirectory[strlen(_parentDirectory) - 1] == *PATH_SEPARATOR) + if (_parentDirectory[strlen(_parentDirectory) - 1] == *PATH_SEPARATOR + || _parentDirectory[strlen(_parentDirectory) - 1] == '/') _parentDirectory[strlen(_parentDirectory) - 1] = '\0'; // Remove everything past the now last separator char *ch = strrchr(_parentDirectory, *PATH_SEPARATOR); + char *posix_ch = strrchr(_parentDirectory, '/'); + ch = ch < posix_ch ? posix_ch : ch; if (ch != nullptr) { *(ch + 1) = '\0'; } else if (drives) { diff --git a/src/openrct2/core/Path.cpp b/src/openrct2/core/Path.cpp index 1ab842861a..3285b210fa 100644 --- a/src/openrct2/core/Path.cpp +++ b/src/openrct2/core/Path.cpp @@ -64,13 +64,16 @@ namespace Path utf8 * GetDirectory(utf8 * buffer, size_t bufferSize, const utf8 * path) { - size_t lastPathSepIndex = String::LastIndexOf(path, *PATH_SEPARATOR); - if (lastPathSepIndex == SIZE_MAX) + auto lastPathSepIndex = Math::Max( + String::LastIndexOf(path, *PATH_SEPARATOR), + String::LastIndexOf(path, '/') + ); + if (lastPathSepIndex < 0) { return String::Set(buffer, bufferSize, String::Empty); } - size_t copyLength = Math::Min(lastPathSepIndex, bufferSize - 1); + size_t copyLength = Math::Min(lastPathSepIndex, static_cast(bufferSize - 1)); Memory::Copy(buffer, path, copyLength); buffer[copyLength] = '\0'; return buffer; @@ -86,17 +89,10 @@ namespace Path const utf8 * lastPathSeperator = nullptr; for (const utf8 * ch = path; *ch != '\0'; ch++) { - if (*ch == *PATH_SEPARATOR) + if (*ch == *PATH_SEPARATOR || *ch == '/') { lastPathSeperator = ch; } -#ifdef _WIN32 - // Windows also allows forward slashes in paths - else if (*ch == '/') - { - lastPathSeperator = ch; - } -#endif } return lastPathSeperator == nullptr ? diff --git a/src/openrct2/core/String.cpp b/src/openrct2/core/String.cpp index bdc11056ee..36378f96cb 100644 --- a/src/openrct2/core/String.cpp +++ b/src/openrct2/core/String.cpp @@ -157,7 +157,7 @@ namespace String return SIZE_MAX; } - size_t LastIndexOf(const utf8 * str, utf8 match) + ptrdiff_t LastIndexOf(const utf8 * str, utf8 match) { const utf8 * lastOccurance = nullptr; const utf8 * ch = str; @@ -171,11 +171,11 @@ namespace String if (lastOccurance == nullptr) { - return SIZE_MAX; + return -1; } else { - return (size_t)(lastOccurance - str); + return lastOccurance - str; } } diff --git a/src/openrct2/core/String.hpp b/src/openrct2/core/String.hpp index 74613b02a9..895e419ce6 100644 --- a/src/openrct2/core/String.hpp +++ b/src/openrct2/core/String.hpp @@ -38,7 +38,7 @@ namespace String bool StartsWith(const utf8 * str, const utf8 * match, bool ignoreCase = false); bool StartsWith(const std::string &str, const std::string &match, bool ignoreCase = false); size_t IndexOf(const utf8 * str, utf8 match, size_t startIndex = 0); - size_t LastIndexOf(const utf8 * str, utf8 match); + ptrdiff_t LastIndexOf(const utf8 * str, utf8 match); /** * Gets the length of the given string in codepoints. diff --git a/src/openrct2/drawing/string.c b/src/openrct2/drawing/string.c index 64b91bdaf0..9328036338 100644 --- a/src/openrct2/drawing/string.c +++ b/src/openrct2/drawing/string.c @@ -1129,7 +1129,7 @@ void shorten_path(utf8 *buffer, size_t bufferSize, const utf8 *path, sint32 avai // Count path separators sint32 path_separators = 0; for (size_t x = 0; x < length; x++) { - if (path[x] == *PATH_SEPARATOR) { + if (path[x] == *PATH_SEPARATOR || path[x] == '/') { path_separators++; } } @@ -1142,7 +1142,7 @@ void shorten_path(utf8 *buffer, size_t bufferSize, const utf8 *path, sint32 avai for (sint32 x = 0; x < path_separators; x++){ do { begin++; - } while (path[begin] != *PATH_SEPARATOR); + } while (path[begin] != *PATH_SEPARATOR && path[begin] != '/'); safe_strcpy(buffer + 3, path + begin, bufferSize - 3); if (gfx_get_string_width(buffer) <= availableWidth) { diff --git a/src/openrct2/util/util.c b/src/openrct2/util/util.c index 6b9400b1db..dadc9f3bed 100644 --- a/src/openrct2/util/util.c +++ b/src/openrct2/util/util.c @@ -66,10 +66,13 @@ utf8 *path_get_directory(const utf8 *path) { // Find the last slash or backslash in the path char *filename = strrchr(path, *PATH_SEPARATOR); + char *filename_posix = strrchr(path, '/'); + filename = filename < filename_posix ? filename_posix : filename; // If the path is invalid (e.g. just a file name), return NULL - if (filename == NULL) + if (filename == NULL) { return NULL; + } char *directory = _strdup(path); safe_strtrunc(directory, strlen(path) - strlen(filename) + 2); @@ -81,6 +84,8 @@ const char *path_get_filename(const utf8 *path) { // Find last slash or backslash in the path char *filename = strrchr(path, *PATH_SEPARATOR); + char *filename_posix = strchr(path, '/'); + filename = filename < filename_posix ? filename_posix : filename; // Checks if the path is valid (e.g. not just a file name) if (filename == NULL) @@ -145,8 +150,9 @@ void path_end_with_separator(utf8 *path, size_t size) { size_t length = strnlen(path, size); if (length >= size - 1) return; - if ((length == 0) || (path[length - 1] != *PATH_SEPARATOR)) + if ((length == 0) || ((path[length - 1] != *PATH_SEPARATOR) && path[length - 1] != '/')) { safe_strcat(path, PATH_SEPARATOR, size); + } } sint32 bitscanforward(sint32 source)