From f7a585fad9bcb8e1ce305c18cbbe1508b5f9f844 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 21 Jan 2022 13:11:39 +0100 Subject: [PATCH] FileUtils: Add some helper to handle ls-style output Unix-ish device implementations would otherwise repeat that code. Change-Id: I1265fe1a69e55409ab2875d0b6f6113ec92edd79 Reviewed-by: Eike Ziller --- src/libs/utils/fileutils.cpp | 38 +++++++++++++++++++++++ src/libs/utils/fileutils.h | 6 ++++ src/plugins/docker/dockerdevice.cpp | 40 ++----------------------- src/plugins/remotelinux/linuxdevice.cpp | 39 ++---------------------- 4 files changed, 48 insertions(+), 75 deletions(-) diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp index 60a2d6e62fa..e0e207a9b22 100644 --- a/src/libs/utils/fileutils.cpp +++ b/src/libs/utils/fileutils.cpp @@ -42,6 +42,7 @@ #ifdef QT_GUI_LIB #include +#include #endif #ifdef Q_OS_WIN @@ -493,6 +494,43 @@ FilePaths FileUtils::getOpenFilePaths(QWidget *parent, options); return transform(result, &FilePath::fromString); } + +// Used on 'ls' output on unix-like systems. +void FileUtils::iterateLsOutput(const FilePath &base, + const QStringList &entries, + const FileFilter &filter, + const std::function &callBack) +{ + QTC_CHECK(filter.iteratorFlags != QDirIterator::NoIteratorFlags); // FIXME: Not supported yet below. + + const QList nameRegexps = + transform(filter.nameFilters, [](const QString &filter) { + QRegularExpression re; + re.setPattern(QRegularExpression::wildcardToRegularExpression(filter)); + QTC_CHECK(re.isValid()); + return re; + }); + + const auto nameMatches = [&nameRegexps](const QString &fileName) { + for (const QRegularExpression &re : nameRegexps) { + const QRegularExpressionMatch match = re.match(fileName); + if (match.hasMatch()) + return true; + } + return nameRegexps.isEmpty(); + }; + + // FIXME: Handle filters. For now bark on unsupported options. + QTC_CHECK(filter.fileFilters == QDir::NoFilter); + + for (const QString &entry : entries) { + if (!nameMatches(entry)) + continue; + if (!callBack(base.pathAppended(entry))) + break; + } +} + #endif // QT_WIDGETS_LIB } // namespace Utils diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h index 163e762e511..f76b621c484 100644 --- a/src/libs/utils/fileutils.h +++ b/src/libs/utils/fileutils.h @@ -144,6 +144,11 @@ public: static void setDeviceFileHooks(const DeviceFileHooks &hooks); + static void iterateLsOutput(const FilePath &base, + const QStringList &entries, + const FileFilter &filter, + const std::function &callBack); + #ifdef QT_WIDGETS_LIB static void setDialogParentGetter(const std::function &getter); @@ -173,6 +178,7 @@ public: QString *selectedFilter = nullptr, QFileDialog::Options options = {}); #endif + }; template diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index 921c901346a..9de4f5830a7 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -1525,41 +1525,6 @@ void DockerDevice::iterateWithFind(const FilePath &filePath, } } -static void filterEntriesHelper(const FilePath &base, - const std::function &callBack, - const QStringList &entries, - const FileFilter &filter) -{ - QTC_CHECK(filter.iteratorFlags != QDirIterator::NoIteratorFlags); // FIXME: Not supported yet below. - - const QList nameRegexps = - transform(filter.nameFilters, [](const QString &filter) { - QRegularExpression re; - re.setPattern(QRegularExpression::wildcardToRegularExpression(filter)); - QTC_CHECK(re.isValid()); - return re; - }); - - const auto nameMatches = [&nameRegexps](const QString &fileName) { - for (const QRegularExpression &re : nameRegexps) { - const QRegularExpressionMatch match = re.match(fileName); - if (match.hasMatch()) - return true; - } - return nameRegexps.isEmpty(); - }; - - // FIXME: Handle filters. For now bark on unsupported options. - QTC_CHECK(filter.fileFilters == QDir::NoFilter); - - for (const QString &entry : entries) { - if (!nameMatches(entry)) - continue; - if (!callBack(base.pathAppended(entry))) - break; - } -} - void DockerDevice::iterateDirectory(const FilePath &filePath, const std::function &callBack, const FileFilter &filter) const @@ -1585,9 +1550,8 @@ void DockerDevice::iterateDirectory(const FilePath &filePath, // if we do not have find - use ls as fallback const QByteArray output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}}); - const QString out = QString::fromUtf8(output.data(), output.size()); - const QStringList entries = out.split('\n', Qt::SkipEmptyParts); - filterEntriesHelper(filePath, callBack, entries, filter); + const QStringList entries = QString::fromUtf8(output).split('\n', Qt::SkipEmptyParts); + FileUtils::iterateLsOutput(filePath, entries, filter, callBack); } QByteArray DockerDevice::fileContents(const FilePath &filePath, qint64 limit, qint64 offset) const diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index 34bedebc13e..d5387ef85fe 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -718,40 +718,6 @@ bool LinuxDevice::setPermissions(const Utils::FilePath &filePath, QFileDevice::P return d->runInShell({"chmod", {QString::number(flags, 16), filePath.path()}}); } -static void filterEntriesHelper(const FilePath &base, - const std::function &callBack, - const QStringList &entries, - const FileFilter &filter) -{ - const QList nameRegexps = - transform(filter.nameFilters, [](const QString &filter) { - QRegularExpression re; - re.setPattern(QRegularExpression::wildcardToRegularExpression(filter)); - QTC_CHECK(re.isValid()); - return re; - }); - - const auto nameMatches = [&nameRegexps](const QString &fileName) { - for (const QRegularExpression &re : nameRegexps) { - const QRegularExpressionMatch match = re.match(fileName); - if (match.hasMatch()) - return true; - } - return nameRegexps.isEmpty(); - }; - - // FIXME: Handle filters. For now bark on unsupported options. - QTC_CHECK(filter.fileFilters == QDir::NoFilter); - QTC_CHECK(filter.iteratorFlags == QDirIterator::NoIteratorFlags); - - for (const QString &entry : entries) { - if (!nameMatches(entry)) - continue; - if (!callBack(base.pathAppended(entry))) - break; - } -} - void LinuxDevice::iterateDirectory(const FilePath &filePath, const std::function &callBack, const FileFilter &filter) const @@ -759,9 +725,8 @@ void LinuxDevice::iterateDirectory(const FilePath &filePath, QTC_ASSERT(handlesFile(filePath), return); // if we do not have find - use ls as fallback const QByteArray output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}}); - const QString out = QString::fromUtf8(output.data(), output.size()); - const QStringList entries = out.split('\n', Qt::SkipEmptyParts); - filterEntriesHelper(filePath, callBack, entries, filter); + const QStringList entries = QString::fromUtf8(output).split('\n', Qt::SkipEmptyParts); + FileUtils::iterateLsOutput(filePath, entries, filter, callBack); } QByteArray LinuxDevice::fileContents(const FilePath &filePath, qint64 limit, qint64 offset) const