Skip to content

Commit c4309a0

Browse files
committed
Improve msvc output parser
1 parent f85b2ca commit c4309a0

File tree

3 files changed

+66
-51
lines changed

3 files changed

+66
-51
lines changed

src/plugins/projectexplorer/ioutputparser.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,6 @@ const QList<OutputTaskParser::TaskInfo> OutputTaskParser::taskInfo() const
7474
return d->scheduledTasks;
7575
}
7676

77-
bool OutputTaskParser::hasCurrentTask() const
78-
{
79-
return !d->currentTask.isNull();
80-
}
81-
82-
void OutputTaskParser::amendTaskDetails(const QString &originalLine)
83-
{
84-
d->currentTask.details.append(originalLine);
85-
++d->lineCount;
86-
}
87-
8877
void OutputTaskParser::scheduleTask(const Task &task, int outputLines, int skippedLines)
8978
{
9079
TaskInfo ts(task, outputLines, skippedLines);

src/plugins/projectexplorer/ioutputparser.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ class PROJECTEXPLORER_EXPORT OutputTaskParser : public Utils::OutputLineParser
2828
const QList<TaskInfo> taskInfo() const;
2929

3030
protected:
31-
bool hasCurrentTask() const;
32-
void amendTaskDetails(const QString &originalLine);
33-
3431
void flush() override;
3532

3633
void setOrigin(const QString &source);

src/plugins/projectexplorer/msvcparser.cpp

Lines changed: 66 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,62 @@
1515
using namespace Utils;
1616

1717
namespace ProjectExplorer {
18+
namespace {
1819

19-
// As of MSVC 2015: "foo.cpp(42) :" -> "foo.cpp(42):"
20-
static const char FILE_POS_PATTERN[] = "^(?:\\d+>)?(cl|LINK|.+?[^ ]) ?: ";
20+
auto constexpr filePosRegexString() -> std::string_view {
21+
// As of MSVC 2015: "foo.cpp(42) :" -> "foo.cpp(42):"
22+
return R"(^(?:\d+>)?(cl|LINK|.+?[^ ]) ?: )";
23+
}
24+
25+
struct FileData {
26+
FilePath fileName{};
27+
int lineNo{-1};
28+
int columnNo{-1};
29+
};
2130

22-
static QPair<FilePath, int> parseFileName(const QString &input)
31+
auto parseFileName(QStringView input) -> FileData
2332
{
24-
QString fileName = input;
25-
if (fileName.startsWith("LINK") || fileName.startsWith("cl"))
26-
return {{}, -1};
33+
auto result = FileData{};
34+
35+
if (input.startsWith(QStringView{u"LINK "}) || input.startsWith(QStringView{u"cl "})){
36+
return result;
37+
}
38+
auto& [fileName, lineNo, columnNo] = result;
2739

2840
// Extract linenumber (if it is there):
29-
int linenumber = -1;
30-
if (fileName.endsWith(')')) {
31-
int pos = fileName.lastIndexOf('(');
32-
if (pos >= 0) {
33-
// clang-cl gives column, too: "foo.cpp(34,1)" as opposed to MSVC "foo.cpp(34)".
34-
int endPos = fileName.indexOf(',', pos + 1);
35-
if (endPos < 0)
36-
endPos = fileName.size() - 1;
37-
bool ok = false;
38-
const int n = fileName.mid(pos + 1, endPos - pos - 1).toInt(&ok);
39-
if (ok) {
40-
fileName = fileName.left(pos);
41-
linenumber = n;
41+
if (input.size() > 2 && input.endsWith(')')) {
42+
auto rit = input.rbegin() + 1;
43+
auto rend = input.rend();
44+
auto f = 0;
45+
auto n = -1;
46+
while (rit != rend) {
47+
auto ch = *rit++;
48+
if (ch.isDigit()) {
49+
if (n < 0) {
50+
n = ch.digitValue();
51+
f = 10;
52+
}
53+
else {
54+
n += ch.digitValue() * f;
55+
f *= 10;
56+
}
57+
continue;
4258
}
59+
if (ch == u',') {
60+
if (n >= 0) columnNo = n;
61+
n = -1;
62+
continue;
63+
}
64+
if (ch == u'(') {
65+
if (n >= 0) lineNo = n;
66+
input = input.sliced(0, rend - rit);
67+
break;
68+
}
69+
break;
4370
}
4471
}
45-
return {FilePath::fromUserInput(fileName), linenumber};
72+
fileName = FilePath::fromUserInput(input.toString());
73+
return result;
4674
}
4775

4876
// nmake/jom messages.
@@ -79,15 +107,17 @@ static Task::TaskType taskType(const QString &category)
79107
return type;
80108
}
81109

110+
} // namespace
111+
82112
MsvcParser::MsvcParser()
83113
{
84114
setObjectName("MsvcParser");
85115
setOrigin("MSVC compiler");
86116

87-
m_compileRegExp.setPattern(QString(FILE_POS_PATTERN)
88-
+ ".*(?:(warning|error) ([A-Z]+\\d{4} ?: )|note: )(.*)$");
117+
m_compileRegExp.setPattern(QLatin1String(filePosRegexString())
118+
+ R"(.*(?:(warning|error) ([A-Z]+\d{4} ?: )|note: )(.*)$)");
89119
QTC_CHECK(m_compileRegExp.isValid());
90-
m_additionalInfoRegExp.setPattern("^ (?:(could be |or )\\s*')?(.*)\\((\\d+)\\) : (.*)$");
120+
m_additionalInfoRegExp.setPattern(R"(^ (?:(could be |or )\s*')?(.*)\((\d+)\) : (.*)$)");
91121
QTC_CHECK(m_additionalInfoRegExp.isValid());
92122
}
93123

@@ -122,19 +152,19 @@ MsvcParser::Result MsvcParser::processCompileLine(const QString &line)
122152
m_isCaretDiagnostics = line.contains("/diagnostics:caret");
123153
}
124154
if (QRegularExpressionMatch match = m_compileRegExp.match(line); match.hasMatch()) {
125-
QPair<FilePath, int> position = parseFileName(match.captured(1));
126-
const FilePath filePath = absoluteFilePath(position.first);
155+
auto [rawFileName, lineNo, columnNo] = parseFileName(match.captured(1));
156+
const FilePath filePath = absoluteFilePath(rawFileName);
127157
LinkSpecs linkSpecs;
128-
addLinkSpecForAbsoluteFilePath(linkSpecs, filePath, position.second, -1, match, 1);
129-
const QString &description = match.captured(3) + match.captured(4).trimmed();
158+
addLinkSpecForAbsoluteFilePath(linkSpecs, filePath, lineNo, columnNo, match, 1);
159+
const auto description = match.captured(3) + match.captured(4).trimmed();
130160
createOrAmendTask(
131161
taskType(match.captured(2)),
132162
description,
133163
line,
134164
false,
135165
filePath,
136-
position.second,
137-
0,
166+
lineNo,
167+
columnNo > 0 ? columnNo : 0,
138168
linkSpecs);
139169
m_expectCode = m_isCaretDiagnostics;
140170
return {Status::InProgress, linkSpecs};
@@ -151,7 +181,7 @@ MsvcParser::Result MsvcParser::processCompileLine(const QString &line)
151181
m_expectCode = m_isCaretDiagnostics;
152182
return {Status::InProgress, linkSpecs};
153183
}
154-
if (hasCurrentTask()) {
184+
if (!currentTask().isNull()) {
155185
bool amend = false;
156186
if (line.endsWith("^")) {
157187
m_expectCode = false; // code was before
@@ -165,7 +195,7 @@ MsvcParser::Result MsvcParser::processCompileLine(const QString &line)
165195
amend = true;
166196
}
167197
if (amend) {
168-
amendTaskDetails(line);
198+
createOrAmendTask(Task::Unknown, {}, line, true);
169199
return Status::InProgress;
170200
}
171201
}
@@ -183,7 +213,7 @@ MsvcParser::Result MsvcParser::processCompileLine(const QString &line)
183213
// ".\qwindowsgdinativeinterface.cpp(48,3) : error: unknown type name 'errr'"
184214
static inline QString clangClCompilePattern()
185215
{
186-
return QLatin1String(FILE_POS_PATTERN) + " ?(warning|error): (.*)$";
216+
return QLatin1String(filePosRegexString()) + " ?(warning|error): (.*)$";
187217
}
188218

189219
ClangClParser::ClangClParser()
@@ -234,13 +264,12 @@ OutputLineParser::Result ClangClParser::handleLine(const QString &line, OutputFo
234264
QRegularExpressionMatch match = m_compileRegExp.match(lne);
235265
if (match.hasMatch()) {
236266
flush();
237-
const QPair<FilePath, int> position = parseFileName(match.captured(1));
238-
const FilePath file = absoluteFilePath(position.first);
239-
const int lineNo = position.second;
267+
const auto [rawFileName, lineNo, columnNo] = parseFileName(match.captured(1));
268+
const FilePath file = absoluteFilePath(rawFileName);
240269
LinkSpecs linkSpecs;
241-
addLinkSpecForAbsoluteFilePath(linkSpecs, file, lineNo, -1, match, 1);
270+
addLinkSpecForAbsoluteFilePath(linkSpecs, file, lineNo, columnNo, match, 1);
242271
createOrAmendTask(
243-
taskType(match.captured(2)), match.captured(3).trimmed(), line, false, file, lineNo);
272+
taskType(match.captured(2)), match.captured(3).trimmed(), line, false, file, lineNo, columnNo, linkSpecs);
244273
return {Status::InProgress, linkSpecs};
245274
}
246275

0 commit comments

Comments
 (0)