Utils: Add FilePath::pathComponents()

Change-Id: I8741ea395435d90b30c2d07a1c33355213300ad7
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Marcus Tillmanns
2025-02-04 12:47:55 +01:00
parent 34afbf6a6b
commit 22720fdd3e
3 changed files with 86 additions and 0 deletions

View File

@@ -531,6 +531,37 @@ QString FilePath::completeSuffix() const
return {}; return {};
} }
QList<QStringView> FilePath::pathComponents() const
{
QList<QStringView> result;
QStringView path = pathView();
int start = 0;
if (osType() == OsTypeWindows && startsWithDriveLetter()) {
start = 2;
result.append(path.mid(0, 2));
if (path.size() == 2)
return result;
else if (path.at(2) == '/') {
result.append(path.mid(2, 1));
start = 3;
}
}
while (start < path.size()) {
int end = path.indexOf('/', start);
if (end == -1)
end = path.size();
// Consider "/" as a path component
if (end == 0)
result.append(path.mid(start, 1));
else
result.append(path.mid(start, end - start));
start = end + 1;
}
return result;
}
QStringView FilePath::scheme() const QStringView FilePath::scheme() const
{ {
return QStringView{m_data}.mid(m_pathLen, m_schemeLen); return QStringView{m_data}.mid(m_pathLen, m_schemeLen);

View File

@@ -138,6 +138,8 @@ public:
QStringView suffixView() const; QStringView suffixView() const;
QString completeSuffix() const; QString completeSuffix() const;
[[nodiscard]] QList<QStringView> pathComponents() const;
[[nodiscard]] FilePath pathAppended(const QString &str) const; [[nodiscard]] FilePath pathAppended(const QString &str) const;
[[nodiscard]] FilePath stringAppended(const QString &str) const; [[nodiscard]] FilePath stringAppended(const QString &str) const;
[[nodiscard]] std::optional<FilePath> tailRemoved(const QString &str) const; [[nodiscard]] std::optional<FilePath> tailRemoved(const QString &str) const;

View File

@@ -129,6 +129,9 @@ private slots:
void isRelativePath(); void isRelativePath();
void isRelativePath_data(); void isRelativePath_data();
void pathComponents();
void pathComponents_data();
private: private:
QTemporaryDir tempDir; QTemporaryDir tempDir;
QString rootPath; QString rootPath;
@@ -1883,6 +1886,56 @@ void tst_filepath::dontBreakPathOnWierdWindowsPaths()
QCOMPARE(path4.toUrlishString(), "device://host/./foo/bar"); QCOMPARE(path4.toUrlishString(), "device://host/./foo/bar");
} }
void tst_filepath::pathComponents_data()
{
QTest::addColumn<QString>("path");
QTest::addColumn<QStringList>("expected");
QTest::newRow("empty") << "" << QStringList{};
QTest::newRow("root") << "/" << QStringList{"/"};
QTest::newRow("relative") << "foo" << QStringList{"foo"};
QTest::newRow("relative-path") << "foo/bar" << QStringList{"foo", "bar"};
QTest::newRow("absolute") << "/foo" << QStringList{"/", "foo"};
QTest::newRow("absolute-path") << "/foo/bar" << QStringList{"/", "foo", "bar"};
QTest::newRow("remote") << "device://host/foo" << QStringList{"/", "foo"};
QTest::newRow("remote-path") << "device://host/foo/bar" << QStringList{"/", "foo", "bar"};
QTest::newRow("remote-relative") << "device://host/./foo" << QStringList{"foo"};
QTest::newRow("windows-current-dir") << "c:" << QStringList{"c:"};
QTest::newRow("single-letter") << "c" << QStringList{"c"};
QTest::newRow("single-letter-path") << "c/b" << QStringList{"c", "b"};
QTest::newRow("single-letter-path-with-root") << "/c/b" << QStringList{"/", "c", "b"};
if (HostOsInfo::isWindowsHost()) {
QTest::newRow("cwd-windows-path") << "c:foo" << QStringList{"c:", "foo"};
QTest::newRow("windows-path") << "c:/" << QStringList{"c:", "/"};
QTest::newRow("windows-path-2") << "c:/test" << QStringList{"c:", "/", "test"};
QTest::newRow("single-letter-path-with-windows-root")
<< "c:/a/b/c" << QStringList{"c:", "/", "a", "b", "c"};
QTest::newRow("windows-path-with-dir") << "c:/foo" << QStringList{"c:", "/", "foo"};
} else {
QTest::newRow("cwd-windows-path") << "c:foo" << QStringList{"c:foo"};
QTest::newRow("windows-path") << "c:/" << QStringList{"c:"};
QTest::newRow("windows-path-2") << "c:/test" << QStringList{"c:", "test"};
QTest::newRow("single-letter-path-with-windows-root")
<< "c:/a/b/c" << QStringList{"c:", "a", "b", "c"};
QTest::newRow("windows-path-with-dir") << "c:/foo" << QStringList{"c:", "foo"};
}
}
void tst_filepath::pathComponents()
{
QFETCH(QString, path);
QFETCH(QStringList, expected);
const auto components
= Utils::transform<QStringList>(FilePath::fromString(path).pathComponents(), [](auto view) {
return QString(view);
});
QCOMPARE(components, expected);
}
} // Utils } // Utils
QTEST_GUILESS_MAIN(Utils::tst_filepath) QTEST_GUILESS_MAIN(Utils::tst_filepath)