summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libs/utils/filepath.cpp10
-rw-r--r--src/libs/utils/filepath.h3
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp4
-rw-r--r--src/plugins/debugger/stackframe.cpp3
-rw-r--r--src/plugins/docker/dockerdevice.cpp27
-rw-r--r--src/plugins/docker/dockerdevice.h1
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicemanager.cpp8
-rw-r--r--src/plugins/projectexplorer/devicesupport/idevice.cpp10
-rw-r--r--src/plugins/projectexplorer/devicesupport/idevice.h2
9 files changed, 64 insertions, 4 deletions
diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp
index 7f4e38d73a..944fe2a5ce 100644
--- a/src/libs/utils/filepath.cpp
+++ b/src/libs/utils/filepath.cpp
@@ -1588,6 +1588,16 @@ FilePath FilePath::resolvePath(const QString &tail) const
return resolvePath(FilePath::fromString(tail));
}
+expected_str<FilePath> FilePath::localSource() const
+{
+ if (!needsDevice())
+ return *this;
+
+ QTC_ASSERT(s_deviceHooks.localSource,
+ return make_unexpected(Tr::tr("No 'localSource' device hook set.")));
+ return s_deviceHooks.localSource(*this);
+}
+
// Cleans path part similar to QDir::cleanPath()
// - directory separators normalized (that is, platform-native
// separators converted to "/") and redundant ones removed, and "."s and ".."s
diff --git a/src/libs/utils/filepath.h b/src/libs/utils/filepath.h
index 5f5a5bad7f..2897b278ec 100644
--- a/src/libs/utils/filepath.h
+++ b/src/libs/utils/filepath.h
@@ -238,6 +238,8 @@ public:
[[nodiscard]] static int schemeAndHostLength(const QStringView path);
static QString calcRelativePath(const QString &absolutePath, const QString &absoluteAnchorPath);
+ //! Returns a filepath the represents the same file on a local drive
+ expected_str<FilePath> localSource() const;
private:
friend class ::tst_fileutils;
@@ -268,6 +270,7 @@ public:
std::function<bool(const FilePath &, const FilePath &)> ensureReachable;
std::function<Environment(const FilePath &)> environment;
std::function<bool(const FilePath &left, const FilePath &right)> isSameDevice;
+ std::function<expected_str<FilePath>(const FilePath &)> localSource;
};
} // namespace Utils
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 67e0dd72e5..b3327cac37 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -1165,7 +1165,9 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
showMessage("INVALID STOPPED REASON", LogWarning);
}
- const FilePath fileName = FilePath::fromString(fullName);
+ const FilePath onDevicePath = FilePath::fromString(fullName).onDevice(
+ runParameters().debugger.command.executable());
+ const FilePath fileName = onDevicePath.localSource().value_or(onDevicePath);
if (!nr.isEmpty() && frame.isValid()) {
// Use opportunity to update the breakpoint marker position.
diff --git a/src/plugins/debugger/stackframe.cpp b/src/plugins/debugger/stackframe.cpp
index 1a68e4ae3a..740868889e 100644
--- a/src/plugins/debugger/stackframe.cpp
+++ b/src/plugins/debugger/stackframe.cpp
@@ -74,7 +74,8 @@ StackFrame StackFrame::parseFrame(const GdbMi &frameMi, const DebuggerRunParamet
frame.function = frameMi["function"].data();
frame.module = frameMi["module"].data();
const FilePath debugger = rp.debugger.command.executable();
- frame.file = FilePath::fromString(frameMi["file"].data()).onDevice(debugger);
+ const FilePath onDevicePath = FilePath::fromString(frameMi["file"].data()).onDevice(debugger);
+ frame.file = onDevicePath.localSource().value_or(onDevicePath);
frame.line = frameMi["line"].toInt();
frame.address = frameMi["address"].toAddress();
frame.context = frameMi["context"].data();
diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp
index c37e2d106e..a71ccfef50 100644
--- a/src/plugins/docker/dockerdevice.cpp
+++ b/src/plugins/docker/dockerdevice.cpp
@@ -144,6 +144,7 @@ public:
void changeMounts(QStringList newMounts);
bool ensureReachable(const FilePath &other);
void shutdown();
+ expected_str<FilePath> localSource(const FilePath &other) const;
QString containerId() { return m_container; }
DockerDeviceData data() { return m_data; }
@@ -828,6 +829,11 @@ bool DockerDevice::ensureReachable(const FilePath &other) const
return d->ensureReachable(other.parentDir());
}
+expected_str<FilePath> DockerDevice::localSource(const Utils::FilePath &other) const
+{
+ return d->localSource(other);
+}
+
Environment DockerDevice::systemEnvironment() const
{
return d->environment();
@@ -1125,6 +1131,27 @@ void DockerDevicePrivate::changeMounts(QStringList newMounts)
}
}
+expected_str<FilePath> DockerDevicePrivate::localSource(const FilePath &other) const
+{
+ const auto devicePath = FilePath::fromString(other.path());
+ for (const TemporaryMountInfo &info : m_temporaryMounts) {
+ if (devicePath.isChildOf(info.containerPath)) {
+ const FilePath relativePath = devicePath.relativeChildPath(info.containerPath);
+ return info.path.pathAppended(relativePath.path());
+ }
+ }
+
+ for (const QString &mount : m_data.mounts) {
+ const FilePath mountPoint = FilePath::fromString(mount);
+ if (devicePath.isChildOf(mountPoint)) {
+ const FilePath relativePath = devicePath.relativeChildPath(mountPoint);
+ return mountPoint.pathAppended(relativePath.path());
+ }
+ }
+
+ return make_unexpected(Tr::tr("localSource: No mount point found for %1").arg(other.toString()));
+}
+
bool DockerDevicePrivate::ensureReachable(const FilePath &other)
{
for (const QString &mount : m_data.mounts) {
diff --git a/src/plugins/docker/dockerdevice.h b/src/plugins/docker/dockerdevice.h
index 4c5cd20e92..03bfc3f2a6 100644
--- a/src/plugins/docker/dockerdevice.h
+++ b/src/plugins/docker/dockerdevice.h
@@ -86,6 +86,7 @@ public:
bool handlesFile(const Utils::FilePath &filePath) const override;
bool ensureReachable(const Utils::FilePath &other) const override;
+ Utils::expected_str<Utils::FilePath> localSource(const Utils::FilePath &other) const override;
Utils::Environment systemEnvironment() const override;
diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
index f65839bacc..f23bf70113 100644
--- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
+++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
@@ -4,6 +4,7 @@
#include "devicemanager.h"
#include "idevicefactory.h"
+#include "projectexplorertr.h"
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
@@ -414,6 +415,13 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique<DeviceManager
return leftDevice == rightDevice;
};
+ deviceHooks.localSource = [](const FilePath &file) -> expected_str<FilePath> {
+ auto device = DeviceManager::deviceForPath(file);
+ if (!device)
+ return make_unexpected(Tr::tr("No device for path \"%1\"").arg(file.toUserOutput()));
+ return device->localSource(file);
+ };
+
deviceHooks.fileAccess = [](const FilePath &filePath) -> DeviceFileAccess * {
if (!filePath.needsDevice())
return DesktopDeviceFileAccess::instance();
diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp
index 83cfa72fd3..e1cc72bc71 100644
--- a/src/plugins/projectexplorer/devicesupport/idevice.cpp
+++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp
@@ -10,11 +10,11 @@
#include "../kit.h"
#include "../kitinformation.h"
+#include "../projectexplorertr.h"
+#include "../target.h"
#include <coreplugin/icore.h>
-#include <projectexplorer/target.h>
-
#include <utils/devicefileaccess.h>
#include <utils/displayname.h>
#include <utils/icon.h>
@@ -630,6 +630,12 @@ bool IDevice::ensureReachable(const FilePath &other) const
return handlesFile(other); // Some first approximation.
}
+expected_str<FilePath> IDevice::localSource(const Utils::FilePath &other) const
+{
+ Q_UNUSED(other);
+ return make_unexpected(Tr::tr("localSource() not implemented for this device type."));
+}
+
bool IDevice::prepareForBuild(const Target *target)
{
Q_UNUSED(target)
diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h
index b61e9c9471..e2dfe57ffd 100644
--- a/src/plugins/projectexplorer/devicesupport/idevice.h
+++ b/src/plugins/projectexplorer/devicesupport/idevice.h
@@ -7,6 +7,7 @@
#include "idevicefwd.h"
#include <utils/id.h>
+#include <utils/expected.h>
#include <utils/filepath.h>
#include <utils/hostosinfo.h>
#include <utils/tasktree.h>
@@ -215,6 +216,7 @@ public:
virtual void aboutToBeRemoved() const {}
virtual bool ensureReachable(const Utils::FilePath &other) const;
+ virtual Utils::expected_str<Utils::FilePath> localSource(const Utils::FilePath &other) const;
virtual bool prepareForBuild(const Target *target);
virtual std::optional<Utils::FilePath> clangdExecutable() const;