aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorhjk <hjk@qt.io>2022-10-21 10:43:09 +0200
committerChristian Stenger <christian.stenger@qt.io>2022-11-22 07:15:54 +0000
commita333efe901c0c737c81d1a4426f040b2e2ce7413 (patch)
treeb1a6b499ec24b885704d236a64251a6915919b16 /src/libs
parent9635b1545b8f0946b0206f96c24ce52ab4e881c0 (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.cpp49
-rw-r--r--src/libs/utils/devicefileaccess.h8
-rw-r--r--src/libs/utils/filepath.cpp10
-rw-r--r--src/libs/utils/filepath.h4
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;