diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt index 554d2fba576..e78809ff850 100644 --- a/src/libs/utils/CMakeLists.txt +++ b/src/libs/utils/CMakeLists.txt @@ -77,7 +77,7 @@ add_qtc_library(Utils json.cpp json.h jsontreeitem.cpp jsontreeitem.h layoutbuilder.cpp layoutbuilder.h - linecolumn.h + linecolumn.cpp linecolumn.h link.cpp link.h listmodel.h listutils.h diff --git a/src/libs/utils/linecolumn.cpp b/src/libs/utils/linecolumn.cpp new file mode 100644 index 00000000000..de094d9d8f6 --- /dev/null +++ b/src/libs/utils/linecolumn.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "linecolumn.h" + +#include + +namespace Utils { + +/*! + Returns the line and column of a \a fileName and sets the \a postfixPos if + it can find a positional postfix. + + The following patterns are supported: \c {filepath.txt:19}, + \c{filepath.txt:19:12}, \c {filepath.txt+19}, + \c {filepath.txt+19+12}, and \c {filepath.txt(19)}. +*/ + +LineColumn LineColumn::extractFromFileName(const QString &fileName, int &postfixPos) +{ + static const auto regexp = QRegularExpression("[:+](\\d+)?([:+](\\d+)?)?$"); + // (10) MSVC-style + static const auto vsRegexp = QRegularExpression("[(]((\\d+)[)]?)?$"); + const QRegularExpressionMatch match = regexp.match(fileName); + QString filePath = fileName; + LineColumn lineColumn; + if (match.hasMatch()) { + postfixPos = match.capturedStart(0); + filePath = fileName.left(match.capturedStart(0)); + lineColumn.line = 0; // for the case that there's only a : at the end + if (match.lastCapturedIndex() > 0) { + lineColumn.line = match.captured(1).toInt(); + if (match.lastCapturedIndex() > 2) // index 2 includes the + or : for the column number + lineColumn.column = match.captured(3).toInt() - 1; //column is 0 based, despite line being 1 based + } + } else { + const QRegularExpressionMatch vsMatch = vsRegexp.match(fileName); + postfixPos = match.capturedStart(0); + filePath = fileName.left(vsMatch.capturedStart(0)); + if (vsMatch.lastCapturedIndex() > 1) // index 1 includes closing ) + lineColumn.line = vsMatch.captured(2).toInt(); + } + return lineColumn; +} + +} // namespace Utils diff --git a/src/libs/utils/linecolumn.h b/src/libs/utils/linecolumn.h index 1be72c281de..f592a6d89a4 100644 --- a/src/libs/utils/linecolumn.h +++ b/src/libs/utils/linecolumn.h @@ -25,22 +25,25 @@ #pragma once +#include "utils_global.h" + #include "optional.h" #include namespace Utils { -class LineColumn +class QTCREATOR_UTILS_EXPORT LineColumn { public: constexpr LineColumn() = default; constexpr LineColumn(int line, int column) : line(line), - column(column) + column(column) {} + bool isValid() const { return line >= 0 && column >= 0; @@ -56,6 +59,8 @@ public: return !(first == second); } + static LineColumn extractFromFileName(const QString &fileName, int &postfixPos); + public: int line = -1; int column = -1; diff --git a/src/libs/utils/link.cpp b/src/libs/utils/link.cpp index 34dcc07ef85..92526909b4b 100644 --- a/src/libs/utils/link.cpp +++ b/src/libs/utils/link.cpp @@ -25,14 +25,14 @@ #include "link.h" -#include +#include "linecolumn.h" namespace Utils { /*! Returns the Link to \a fileName. If \a canContainLineNumber is true the line number, and column number components - are extracted from \a fileName and the found \a postFix is set. + are extracted from \a fileName and the found \a postfix is set. The following patterns are supported: \c {filepath.txt:19}, \c{filepath.txt:19:12}, \c {filepath.txt+19}, @@ -42,33 +42,13 @@ Link Link::fromString(const QString &fileName, bool canContainLineNumber, QStrin { if (!canContainLineNumber) return {Utils::FilePath::fromString(fileName)}; - // :10:2 GCC/Clang-style - static const auto regexp = QRegularExpression("[:+](\\d+)?([:+](\\d+)?)?$"); - // (10) MSVC-style - static const auto vsRegexp = QRegularExpression("[(]((\\d+)[)]?)?$"); - const QRegularExpressionMatch match = regexp.match(fileName); - QString filePath = fileName; - int line = -1; - int column = -1; - if (match.hasMatch()) { - if (postfix) - *postfix = match.captured(0); - filePath = fileName.left(match.capturedStart(0)); - line = 0; // for the case that there's only a : at the end - if (match.lastCapturedIndex() > 0) { - line = match.captured(1).toInt(); - if (match.lastCapturedIndex() > 2) // index 2 includes the + or : for the column number - column = match.captured(3).toInt() - 1; //column is 0 based, despite line being 1 based - } - } else { - const QRegularExpressionMatch vsMatch = vsRegexp.match(fileName); - if (postfix) - *postfix = vsMatch.captured(0); - filePath = fileName.left(vsMatch.capturedStart(0)); - if (vsMatch.lastCapturedIndex() > 1) // index 1 includes closing ) - line = vsMatch.captured(2).toInt(); - } - return {Utils::FilePath::fromString(filePath), line, column}; + int postfixPos = -1; + const LineColumn lineColumn = LineColumn::extractFromFileName(fileName, postfixPos); + if (postfix && postfixPos >= 0) + *postfix = fileName.mid(postfixPos); + return {Utils::FilePath::fromString(fileName.left(postfixPos - 1)), + lineColumn.line, + lineColumn.column}; } } // namespace Utils diff --git a/src/libs/utils/utils-lib.pri b/src/libs/utils/utils-lib.pri index 33e09dd4f4c..872675f306d 100644 --- a/src/libs/utils/utils-lib.pri +++ b/src/libs/utils/utils-lib.pri @@ -144,6 +144,7 @@ SOURCES += \ $$PWD/futuresynchronizer.cpp \ $$PWD/qtcsettings.cpp \ $$PWD/link.cpp \ + $$PWD/linecolumn.cpp \ HEADERS += \ $$PWD/environmentfwd.h \ diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs index 4f91284094a..d9211602086 100644 --- a/src/libs/utils/utils.qbs +++ b/src/libs/utils/utils.qbs @@ -161,6 +161,7 @@ Project { "jsontreeitem.h", "layoutbuilder.cpp", "layoutbuilder.h", + "linecolumn.cpp", "linecolumn.h", "link.cpp", "link.h",