diff options
author | hjk <hjk@qt.io> | 2022-10-21 10:43:09 +0200 |
---|---|---|
committer | Christian Stenger <christian.stenger@qt.io> | 2022-11-22 07:15:54 +0000 |
commit | a333efe901c0c737c81d1a4426f040b2e2ce7413 (patch) | |
tree | b1a6b499ec24b885704d236a64251a6915919b16 /src/libs | |
parent | 9635b1545b8f0946b0206f96c24ce52ab4e881c0 (diff) |
Utils: Introduce a FilePath::refersToExecutableFile
... to avoid the need in user code to care for .exe and .bat suffixes.
Change-Id: Ic249f14273f72c663912482555f98be1af923823
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Diffstat (limited to 'src/libs')
-rw-r--r-- | src/libs/utils/devicefileaccess.cpp | 49 | ||||
-rw-r--r-- | src/libs/utils/devicefileaccess.h | 8 | ||||
-rw-r--r-- | src/libs/utils/filepath.cpp | 10 | ||||
-rw-r--r-- | src/libs/utils/filepath.h | 4 |
4 files changed, 68 insertions, 3 deletions
diff --git a/src/libs/utils/devicefileaccess.cpp b/src/libs/utils/devicefileaccess.cpp index 5443d6b46e..43ed665524 100644 --- a/src/libs/utils/devicefileaccess.cpp +++ b/src/libs/utils/devicefileaccess.cpp @@ -4,9 +4,10 @@ #include "devicefileaccess.h" #include "algorithm.h" -#include "qtcassert.h" -#include "hostosinfo.h" #include "commandline.h" +#include "environment.h" +#include "hostosinfo.h" +#include "qtcassert.h" #include <QCoreApplication> #include <QOperatingSystemVersion> @@ -244,11 +245,19 @@ qint64 DeviceFileAccess::bytesAvailable(const FilePath &filePath) const QByteArray DeviceFileAccess::fileId(const FilePath &filePath) const { - Q_UNUSED(filePath); + Q_UNUSED(filePath) QTC_CHECK(false); return {}; } +bool DeviceFileAccess::refersToExecutableFile( + const FilePath &filePath, + FilePath::MatchScope matchScope) const +{ + Q_UNUSED(matchScope) + return isExecutableFile(filePath); +} + void DeviceFileAccess::asyncFileContents( const FilePath &filePath, const Continuation<std::optional<QByteArray>> &cont, @@ -292,6 +301,40 @@ bool DesktopDeviceFileAccess::isExecutableFile(const FilePath &filePath) const return fi.isExecutable() && !fi.isDir(); } +static bool isWindowsExecutableHelper(const FilePath &filePath, const QStringView suffix) +{ + const QFileInfo fi(filePath.path().append(suffix)); + return fi.isExecutable() && !fi.isDir(); +} + +bool DesktopDeviceFileAccess::refersToExecutableFile( + const FilePath &filePath, + FilePath::MatchScope matchScope) const +{ + if (isExecutableFile(filePath)) + return true; + + if (HostOsInfo::isWindowsHost()) { + if (matchScope == FilePath::WithExeSuffix || matchScope == FilePath::WithExeOrBatSuffix) { + if (isWindowsExecutableHelper(filePath, u".exe")) + return true; + } + if (matchScope == FilePath::WithBatSuffix || matchScope == FilePath::WithExeOrBatSuffix) { + if (isWindowsExecutableHelper(filePath, u".bat")) + return true; + } + if (matchScope == FilePath::WithAnySuffix) { + // That's usually .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH, + static const QStringList exts = qtcEnvironmentVariable("PATHEXT").split(';'); + for (const QString &ext : exts) { + if (isWindowsExecutableHelper(filePath, ext)) + return true; + } + } + } + return false; +} + bool DesktopDeviceFileAccess::isReadableFile(const FilePath &filePath) const { const QFileInfo fi(filePath.path()); diff --git a/src/libs/utils/devicefileaccess.h b/src/libs/utils/devicefileaccess.h index 1fdfcd5d87..8e5633aa34 100644 --- a/src/libs/utils/devicefileaccess.h +++ b/src/libs/utils/devicefileaccess.h @@ -47,6 +47,10 @@ protected: virtual qint64 bytesAvailable(const FilePath &filePath) const; virtual QByteArray fileId(const FilePath &filePath) const; + virtual bool refersToExecutableFile( + const FilePath &filePath, + FilePath::MatchScope matchScope) const; + virtual void iterateDirectory( const FilePath &filePath, const FilePath::IterateDirCallback &callBack, @@ -114,6 +118,10 @@ protected: qint64 bytesAvailable(const FilePath &filePath) const override; QByteArray fileId(const FilePath &filePath) const override; + bool refersToExecutableFile( + const FilePath &filePath, + FilePath::MatchScope matchScope) const override; + void iterateDirectory( const FilePath &filePath, const FilePath::IterateDirCallback &callBack, diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index 4016676ef7..dcbcd09fb9 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -396,6 +396,16 @@ bool FilePath::isExecutableFile() const return fileAccess()->isExecutableFile(*this); } +/// \returns a bool indicating on whether a process with this FilePath's +/// .nativePath() is likely to start. +/// +/// This is equivalent to \c isExecutableFile() in general. +/// On Windows, it will check appending various suffixes, too. +bool FilePath::refersToExecutableFile(MatchScope matchScope) const +{ + return fileAccess()->refersToExecutableFile(*this, matchScope); +} + bool FilePath::isReadableFile() const { return fileAccess()->isReadableFile(*this); diff --git a/src/libs/utils/filepath.h b/src/libs/utils/filepath.h index ebbe25421e..aa809b9a71 100644 --- a/src/libs/utils/filepath.h +++ b/src/libs/utils/filepath.h @@ -179,6 +179,10 @@ public: [[nodiscard]] FilePath searchInPath(const FilePaths &additionalDirs = {}, PathAmending = AppendToPath) const; + enum MatchScope { ExactMatchOnly, WithExeSuffix, WithBatSuffix, + WithExeOrBatSuffix, WithAnySuffix }; + bool refersToExecutableFile(MatchScope considerScript) const; + // makes sure that capitalization of directories is canonical // on Windows and macOS. This is rarely needed. [[nodiscard]] FilePath normalizedPathName() const; |