forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -4,9 +4,10 @@
|
|||||||
#include "devicefileaccess.h"
|
#include "devicefileaccess.h"
|
||||||
|
|
||||||
#include "algorithm.h"
|
#include "algorithm.h"
|
||||||
#include "qtcassert.h"
|
|
||||||
#include "hostosinfo.h"
|
|
||||||
#include "commandline.h"
|
#include "commandline.h"
|
||||||
|
#include "environment.h"
|
||||||
|
#include "hostosinfo.h"
|
||||||
|
#include "qtcassert.h"
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QOperatingSystemVersion>
|
#include <QOperatingSystemVersion>
|
||||||
@@ -244,11 +245,19 @@ qint64 DeviceFileAccess::bytesAvailable(const FilePath &filePath) const
|
|||||||
|
|
||||||
QByteArray DeviceFileAccess::fileId(const FilePath &filePath) const
|
QByteArray DeviceFileAccess::fileId(const FilePath &filePath) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(filePath);
|
Q_UNUSED(filePath)
|
||||||
QTC_CHECK(false);
|
QTC_CHECK(false);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DeviceFileAccess::refersToExecutableFile(
|
||||||
|
const FilePath &filePath,
|
||||||
|
FilePath::MatchScope matchScope) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(matchScope)
|
||||||
|
return isExecutableFile(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
void DeviceFileAccess::asyncFileContents(
|
void DeviceFileAccess::asyncFileContents(
|
||||||
const FilePath &filePath,
|
const FilePath &filePath,
|
||||||
const Continuation<std::optional<QByteArray>> &cont,
|
const Continuation<std::optional<QByteArray>> &cont,
|
||||||
@@ -292,6 +301,40 @@ bool DesktopDeviceFileAccess::isExecutableFile(const FilePath &filePath) const
|
|||||||
return fi.isExecutable() && !fi.isDir();
|
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
|
bool DesktopDeviceFileAccess::isReadableFile(const FilePath &filePath) const
|
||||||
{
|
{
|
||||||
const QFileInfo fi(filePath.path());
|
const QFileInfo fi(filePath.path());
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ protected:
|
|||||||
virtual qint64 bytesAvailable(const FilePath &filePath) const;
|
virtual qint64 bytesAvailable(const FilePath &filePath) const;
|
||||||
virtual QByteArray fileId(const FilePath &filePath) const;
|
virtual QByteArray fileId(const FilePath &filePath) const;
|
||||||
|
|
||||||
|
virtual bool refersToExecutableFile(
|
||||||
|
const FilePath &filePath,
|
||||||
|
FilePath::MatchScope matchScope) const;
|
||||||
|
|
||||||
virtual void iterateDirectory(
|
virtual void iterateDirectory(
|
||||||
const FilePath &filePath,
|
const FilePath &filePath,
|
||||||
const FilePath::IterateDirCallback &callBack,
|
const FilePath::IterateDirCallback &callBack,
|
||||||
@@ -114,6 +118,10 @@ protected:
|
|||||||
qint64 bytesAvailable(const FilePath &filePath) const override;
|
qint64 bytesAvailable(const FilePath &filePath) const override;
|
||||||
QByteArray fileId(const FilePath &filePath) const override;
|
QByteArray fileId(const FilePath &filePath) const override;
|
||||||
|
|
||||||
|
bool refersToExecutableFile(
|
||||||
|
const FilePath &filePath,
|
||||||
|
FilePath::MatchScope matchScope) const override;
|
||||||
|
|
||||||
void iterateDirectory(
|
void iterateDirectory(
|
||||||
const FilePath &filePath,
|
const FilePath &filePath,
|
||||||
const FilePath::IterateDirCallback &callBack,
|
const FilePath::IterateDirCallback &callBack,
|
||||||
|
|||||||
@@ -396,6 +396,16 @@ bool FilePath::isExecutableFile() const
|
|||||||
return fileAccess()->isExecutableFile(*this);
|
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
|
bool FilePath::isReadableFile() const
|
||||||
{
|
{
|
||||||
return fileAccess()->isReadableFile(*this);
|
return fileAccess()->isReadableFile(*this);
|
||||||
|
|||||||
@@ -179,6 +179,10 @@ public:
|
|||||||
[[nodiscard]] FilePath searchInPath(const FilePaths &additionalDirs = {},
|
[[nodiscard]] FilePath searchInPath(const FilePaths &additionalDirs = {},
|
||||||
PathAmending = AppendToPath) const;
|
PathAmending = AppendToPath) const;
|
||||||
|
|
||||||
|
enum MatchScope { ExactMatchOnly, WithExeSuffix, WithBatSuffix,
|
||||||
|
WithExeOrBatSuffix, WithAnySuffix };
|
||||||
|
bool refersToExecutableFile(MatchScope considerScript) const;
|
||||||
|
|
||||||
// makes sure that capitalization of directories is canonical
|
// makes sure that capitalization of directories is canonical
|
||||||
// on Windows and macOS. This is rarely needed.
|
// on Windows and macOS. This is rarely needed.
|
||||||
[[nodiscard]] FilePath normalizedPathName() const;
|
[[nodiscard]] FilePath normalizedPathName() const;
|
||||||
|
|||||||
Reference in New Issue
Block a user