Home
Phabricator
Search
Log In
Files
F3921734
patch-KDevelopPath=canonical.diff
rjvbb (René J.V. Bertin)
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Author
rjvbb
Created
Sep 22 2017, 7:56 PM
Size
2 KB
Mime Type
text/x-diff
Engine
blob
Format
Raw Data
Handle
1820280
Attached To
D7930: Kdevelop CMake plugin : use canonical paths to build.dir
patch-KDevelopPath=canonical.diff
View Options
diff --git a/kdevplatform/util/path.cpp b/kdevplatform/util/path.cpp
index edcbfbe9adbcdb80b8b51759099aad0cc9e7deb1..b71b6f186f3ba514c2ebae480a06e4fa73a77b6d 100644
--- a/kdevplatform/util/path.cpp
+++ b/kdevplatform/util/path.cpp
@@ -23,6 +23,7 @@
#include "path.h"
#include <QStringList>
+#include <QFileInfo>
#include <QDebug>
#include <language/util/kdevhash.h>
@@ -397,13 +398,36 @@ static QVarLengthArray<QString, 16> splitPath(const QString &source)
return list;
}
+//
+static QString toCanonicalPath(const QString &path)
+{
+ const QFileInfo info(path);
+ if (info.exists()) {
+ if (info.isDir()) {
+ // the simple case: just resolve all symlinks in the entire path
+ return info.canonicalFilePath();
+ } else {
+ // resolve the symlinks in the path to the file, and reappend the filename
+ return QFileInfo(info.absolutePath()).canonicalFilePath() + QStringLiteral("/") + info.fileName();
+ }
+ }
+ // don't attempt anything on non-existing files, it will fail
+ return path;
+}
+
void Path::addPath(const QString& path)
{
if (path.isEmpty()) {
return;
}
- const auto& newData = splitPath(path);
+ // convert local paths to canonical if not adding it to an existing path
+ const bool convertToCanonical = m_data.isEmpty() && path.startsWith(QLatin1Char('/'));
+ // Use QFileInfo::canonicalPath() to resolve any symlinks on the path, but not the
+ // final element (filename). This returns an empty string when path doesn't exist
+ // so we need to check the result.
+ const QString canonicalPath = convertToCanonical ? toCanonicalPath(path) : QString();
+ const auto& newData = splitPath(canonicalPath.isEmpty() ? path : canonicalPath);
if (newData.isEmpty()) {
if (m_data.size() == (isRemote() ? 1 : 0)) {
// this represents the root path, we just turned an invalid path into it
@@ -421,6 +445,17 @@ void Path::addPath(const QString& path)
std::copy(it, newData.end(), std::back_inserter(m_data));
cleanPath(&m_data, isRemote());
+ // convert the concatenated result to canonical if local
+ // can surely be done in a more efficient manner
+ if (canonicalPath.isEmpty() && isLocalFile()) {
+ Path temp;
+ // using the default Path ctor is the fastest and easiest way
+ // to call ourselves with a fresh temporary m_data instance
+ temp.addPath(toCanonicalPath(generatePathOrUrl(true, true, m_data)));
+ if (!temp.m_data.isEmpty()) {
+ m_data = temp.m_data;
+ }
+ }
}
Path Path::parent() const
Log In to Comment