[Scummvm-git-logs] scummvm master -> c53b42311d29a338c93ca6e10a29ab0d18e9358d
mduggan
noreply at scummvm.org
Sat Dec 31 08:57:58 UTC 2022
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
c53b42311d COMMON: Fix path split+join combinations, add tests for same
Commit: c53b42311d29a338c93ca6e10a29ab0d18e9358d
https://github.com/scummvm/scummvm/commit/c53b42311d29a338c93ca6e10a29ab0d18e9358d
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2022-12-31T17:57:07+09:00
Commit Message:
COMMON: Fix path split+join combinations, add tests for same
This resolves multiple scenarios where a path ends up with a trailing
separator.
Changed paths:
A test/common/path.h
common/path.cpp
common/path.h
diff --git a/common/path.cpp b/common/path.cpp
index c824b723d3c..7319896a6aa 100644
--- a/common/path.cpp
+++ b/common/path.cpp
@@ -61,13 +61,17 @@ String Path::toString(char separator) const {
return res;
}
-size_t Path::findLastSeparator() const {
+size_t Path::findLastSeparator(size_t last) const {
+ if (_str.size() < 2)
+ return String::npos;
+
size_t res = String::npos;
- for (uint i = 0; i + 2 < _str.size(); i++) {
- if (_str[i] == ESCAPER) {
- i++;
- if (_str[i] == ESCAPE_SEPARATOR)
- res = i - 1;
+ if (last == String::npos || last > _str.size())
+ last = _str.size();
+
+ for (uint i = 0; i < last - 1; i++) {
+ if (_str[i] == ESCAPER && _str[i + 1] == ESCAPE_SEPARATOR) {
+ res = i;
}
}
@@ -77,7 +81,8 @@ size_t Path::findLastSeparator() const {
Path Path::getParent() const {
if (_str.size() < 2)
return Path();
- size_t separatorPos = findLastSeparator();
+ // ignore potential trailing separator
+ size_t separatorPos = findLastSeparator(_str.size() - 1);
if (separatorPos == String::npos)
return Path();
Path ret;
@@ -88,7 +93,8 @@ Path Path::getParent() const {
Path Path::getLastComponent() const {
if (_str.size() < 2)
return *this;
- size_t separatorPos = findLastSeparator();
+ // ignore potential trailing separator
+ size_t separatorPos = findLastSeparator(_str.size() - 1);
if (separatorPos == String::npos)
return *this;
Path ret;
@@ -197,7 +203,7 @@ Path &Path::joinInPlace(const Path &x) {
return *this;
size_t lastSep = findLastSeparator();
- if (!_str.empty() && (lastSep == String::npos || lastSep != _str.size() - 2) && x._str.hasPrefix(DIR_SEPARATOR))
+ if (!_str.empty() && (lastSep == String::npos || lastSep != _str.size() - 2) && !x._str.hasPrefix(DIR_SEPARATOR))
_str += DIR_SEPARATOR;
_str += x._str;
diff --git a/common/path.h b/common/path.h
index 3d3a5f087e3..7cf5530f2ee 100644
--- a/common/path.h
+++ b/common/path.h
@@ -49,7 +49,7 @@ private:
String _str;
String getIdentifierString() const;
- size_t findLastSeparator() const;
+ size_t findLastSeparator(size_t last = String::npos) const;
public:
/**
diff --git a/test/common/path.h b/test/common/path.h
new file mode 100644
index 00000000000..d7c48f3b869
--- /dev/null
+++ b/test/common/path.h
@@ -0,0 +1,69 @@
+#include <cxxtest/TestSuite.h>
+
+#include "common/path.h"
+
+static const char *TEST_PATH = "parent/dir/file.txt";
+
+class PathTestSuite : public CxxTest::TestSuite
+{
+ public:
+ void test_Path() {
+ Common::Path p;
+ TS_ASSERT_EQUALS(p.toString(), Common::String());
+
+ Common::Path p2(TEST_PATH);
+ TS_ASSERT_EQUALS(p2.toString(), Common::String(TEST_PATH));
+ }
+
+ void test_getLastComponent() {
+ Common::Path p(TEST_PATH);
+ TS_ASSERT_EQUALS(p.getLastComponent().toString(), "file.txt");
+ }
+
+ void test_getParent() {
+ Common::Path p(TEST_PATH);
+ TS_ASSERT_EQUALS(p.getParent().toString(), "parent/dir/");
+ // TODO: should this work?
+ TS_ASSERT_EQUALS(p.getParent().getLastComponent().toString(), "dir/");
+ }
+
+ void test_join() {
+ Common::Path p("dir");
+ Common::Path p2 = p.join("file.txt");
+ TS_ASSERT_EQUALS(p2.toString(), "dir/file.txt");
+
+ Common::Path p3(TEST_PATH);
+ Common::Path p4 = p3.getParent().join("other.txt");
+ TS_ASSERT_EQUALS(p4.toString(), "parent/dir/other.txt");
+ }
+
+ // Ensure we can joinInPlace correctly with leading or trailing separators
+ void test_joinInPlace() {
+ Common::Path p("abc/def");
+ p.joinInPlace("file.txt");
+ TS_ASSERT_EQUALS(p.toString(), "abc/def/file.txt");
+
+ Common::Path p2("xyz/def");
+ p2.joinInPlace(Common::Path("file.txt"));
+ TS_ASSERT_EQUALS(p2.toString(), "xyz/def/file.txt");
+
+ Common::Path p3("ghi/def/");
+ p3.joinInPlace(Common::Path("file.txt"));
+ TS_ASSERT_EQUALS(p3.toString(), "ghi/def/file.txt");
+
+ Common::Path p4("123/def");
+ p4.joinInPlace(Common::Path("/file4.txt"));
+ TS_ASSERT_EQUALS(p4.toString(), "123/def/file4.txt");
+ }
+
+ void test_separator() {
+ Common::Path p(TEST_PATH, '\\');
+ TS_ASSERT_EQUALS(p.getLastComponent().toString(), TEST_PATH);
+ TS_ASSERT_EQUALS(p.getParent().toString(), "");
+
+ Common::Path p2(TEST_PATH, 'e');
+ TS_ASSERT_EQUALS(p2.getLastComponent().toString(), ".txt");
+ TS_ASSERT_EQUALS(p2.getParent().toString('#'), "par#nt/dir/fil#");
+ TS_ASSERT_EQUALS(p2.getParent().getParent().toString('#'), "par#");
+ }
+};
More information about the Scummvm-git-logs
mailing list