diff --git a/src/plugins/projectexplorer/clangparser.cpp b/src/plugins/projectexplorer/clangparser.cpp index 971697f222fb4c4e22f361589d3bb614bb151f6f..0832d283d9fa3517b7ede36100509fec2c35c062 100644 --- a/src/plugins/projectexplorer/clangparser.cpp +++ b/src/plugins/projectexplorer/clangparser.cpp @@ -48,11 +48,6 @@ ClangParser::ClangParser() : appendOutputParser(new LdParser); } -ClangParser::~ClangParser() -{ - emitTask(); -} - void ClangParser::stdError(const QString &line) { const QString lne = rightTrimmed(line); @@ -64,15 +59,16 @@ void ClangParser::stdError(const QString &line) if (m_commandRegExp.indexIn(lne) > -1) { m_expectSnippet = true; - newTask(Task::Error, - m_commandRegExp.cap(4), - Utils::FileName(), /* filename */ - -1, /* line */ - Core::Id(Constants::TASK_CATEGORY_COMPILE)); + Task task(Task::Error, + m_commandRegExp.cap(4), + Utils::FileName(), /* filename */ + -1, /* line */ + Core::Id(Constants::TASK_CATEGORY_COMPILE)); if (m_commandRegExp.cap(3) == QLatin1String("warning")) - m_currentTask.type = Task::Warning; + task.type = Task::Warning; else if (m_commandRegExp.cap(3) == QLatin1String("note")) - m_currentTask.type = Task::Unknown; + task.type = Task::Unknown; + newTask(task); return; } @@ -92,47 +88,27 @@ void ClangParser::stdError(const QString &line) int lineNo = m_messageRegExp.cap(4).toInt(&ok); if (!ok) lineNo = m_messageRegExp.cap(5).toInt(&ok); - newTask(Task::Error, - m_messageRegExp.cap(8), - Utils::FileName::fromUserInput(m_messageRegExp.cap(1)), /* filename */ - lineNo, - Core::Id(Constants::TASK_CATEGORY_COMPILE)); + Task task(Task::Error, + m_messageRegExp.cap(8), + Utils::FileName::fromUserInput(m_messageRegExp.cap(1)), /* filename */ + lineNo, + Core::Id(Constants::TASK_CATEGORY_COMPILE)); if (m_messageRegExp.cap(7) == QLatin1String("warning")) - m_currentTask.type = Task::Warning; + task.type = Task::Warning; else if (m_messageRegExp.cap(7) == QLatin1String("note")) - m_currentTask.type = Task::Unknown; + task.type = Task::Unknown; + newTask(task); return; } - if (m_expectSnippet && !m_currentTask.isNull()) { - QTextLayout::FormatRange fr; - fr.start = m_currentTask.description.count() + 1; - fr.length = lne.count() + 1; - fr.format.setFontFamily(QLatin1String("Monospaced")); - fr.format.setFontStyleHint(QFont::TypeWriter); - m_currentTask.description.append(QLatin1Char('\n')); - m_currentTask.description.append(lne); - m_currentTask.formats.append(fr); + if (m_expectSnippet) { + amendDescription(lne, true); return; } IOutputParser::stdError(line); } -void ClangParser::newTask(Task::TaskType type_, const QString &description_, - const Utils::FileName &file_, int line_, const Core::Id &category_) -{ - emitTask(); - m_currentTask = Task(type_, description_, file_, line_, category_); -} - -void ClangParser::emitTask() -{ - if (!m_currentTask.isNull()) - emit addTask(m_currentTask); - m_currentTask = Task(); -} - // Unit tests: #ifdef WITH_TESTS diff --git a/src/plugins/projectexplorer/clangparser.h b/src/plugins/projectexplorer/clangparser.h index 487beeff17a7ac09c952b06174001f6e831e831a..5cda6e0764dd44f44288aa2bde96d6efe743932d 100644 --- a/src/plugins/projectexplorer/clangparser.h +++ b/src/plugins/projectexplorer/clangparser.h @@ -30,35 +30,27 @@ #ifndef CLANGPARSER_H #define CLANGPARSER_H -#include "ioutputparser.h" +#include "gccparser.h" #include "task.h" #include <QRegExp> namespace ProjectExplorer { -class ClangParser : public ProjectExplorer::IOutputParser +class ClangParser : public ProjectExplorer::GccParser { Q_OBJECT public: ClangParser(); - ~ClangParser(); void stdError(const QString &line); private: - void newTask(Task::TaskType type_, const QString &description_, - const Utils::FileName &file_, int line_, const Core::Id &category_); - - void emitTask(); - QRegExp m_commandRegExp; QRegExp m_inLineRegExp; QRegExp m_messageRegExp; QRegExp m_summaryRegExp; bool m_expectSnippet; - - Task m_currentTask; }; } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/gccparser.cpp b/src/plugins/projectexplorer/gccparser.cpp index cf0350ccedfabe6f7bb59690a3b27a802b119939..d1238f6a34a210fb6f6850e1f1e484267d9a2c0e 100644 --- a/src/plugins/projectexplorer/gccparser.cpp +++ b/src/plugins/projectexplorer/gccparser.cpp @@ -60,6 +60,11 @@ GccParser::GccParser() appendOutputParser(new LdParser); } +GccParser::~GccParser() +{ + emitTask(); +} + void GccParser::stdError(const QString &line) { QString lne = rightTrimmed(line); @@ -74,11 +79,11 @@ void GccParser::stdError(const QString &line) // Handle misc issues: if (lne.startsWith(QLatin1String("ERROR:")) || lne == QLatin1String("* cpp failed")) { - emit addTask(Task(Task::Error, - lne /* description */, - Utils::FileName() /* filename */, - -1 /* linenumber */, - Core::Id(Constants::TASK_CATEGORY_COMPILE))); + newTask(Task::Error, + lne /* description */, + Utils::FileName() /* filename */, + -1 /* linenumber */, + Core::Id(Constants::TASK_CATEGORY_COMPILE)); return; } else if (m_regExpGccNames.indexIn(lne) > -1) { QString description = lne.mid(m_regExpGccNames.matchedLength()); @@ -93,7 +98,7 @@ void GccParser::stdError(const QString &line) } else if (description.startsWith(QLatin1String("fatal: "))) { task.description = description.mid(7); } - emit addTask(task); + newTask(task); return; } else if (m_regExp.indexIn(lne) > -1) { Utils::FileName filename = Utils::FileName::fromUserInput(m_regExp.cap(1)); @@ -113,19 +118,67 @@ void GccParser::stdError(const QString &line) if (m_regExp.cap(5).startsWith(QLatin1Char('#'))) task.description = m_regExp.cap(5) + task.description; - emit addTask(task); + newTask(task); return; } else if (m_regExpIncluded.indexIn(lne) > -1) { - emit addTask(Task(Task::Unknown, - lne.trimmed() /* description */, - Utils::FileName::fromUserInput(m_regExpIncluded.cap(1)) /* filename */, - m_regExpIncluded.cap(3).toInt() /* linenumber */, - Core::Id(Constants::TASK_CATEGORY_COMPILE))); + newTask(Task::Unknown, + lne.trimmed() /* description */, + Utils::FileName::fromUserInput(m_regExpIncluded.cap(1)) /* filename */, + m_regExpIncluded.cap(3).toInt() /* linenumber */, + Core::Id(Constants::TASK_CATEGORY_COMPILE)); + return; + } else if (lne.startsWith(QLatin1Char(' '))) { + amendDescription(lne, true); return; } + + emitTask(); IOutputParser::stdError(line); } +void GccParser::stdOutput(const QString &line) +{ + emitTask(); + IOutputParser::stdOutput(line); +} + +void GccParser::newTask(const Task &task) +{ + emitTask(); + m_currentTask = task; +} + +void GccParser::newTask(Task::TaskType type_, const QString &description_, + const Utils::FileName &file_, int line_, const Core::Id &category_) +{ + newTask(Task(type_, description_, file_, line_, category_)); +} + +void GccParser::emitTask() +{ + if (!m_currentTask.isNull()) + emit addTask(m_currentTask); + m_currentTask = Task(); +} + +void GccParser::amendDescription(const QString &desc, bool monospaced) +{ + if (m_currentTask.isNull()) + return; + int start = m_currentTask.description.count() + 1; + m_currentTask.description.append(QLatin1Char('\n')); + m_currentTask.description.append(desc); + if (monospaced) { + QTextLayout::FormatRange fr; + fr.start = start; + fr.length = desc.count() + 1; + fr.format.setFontFamily(QLatin1String("Monospaced")); + fr.format.setFontStyleHint(QFont::TypeWriter); + m_currentTask.formats.append(fr); + } + return; +} + // Unit tests: #ifdef WITH_TESTS @@ -710,6 +763,27 @@ void ProjectExplorerPlugin::testGccOutputParsers_data() Utils::FileName::fromUserInput(QLatin1String("libimf.so")), -1, Constants::TASK_CATEGORY_COMPILE)) << QString(); + + QTest::newRow("gcc 4.8") + << QString::fromLatin1("In file included from /home/code/src/creator/src/libs/extensionsystem/pluginerrorview.cpp:31:0:\n" + ".uic/ui_pluginerrorview.h:14:25: fatal error: QtGui/QAction: No such file or directory\n" + " #include <QtGui/QAction>\n" + " ^") + << OutputParserTester::STDERR + << QString() << QString() + << ( QList<ProjectExplorer::Task>() + << Task(Task::Unknown, + QLatin1String("In file included from /home/code/src/creator/src/libs/extensionsystem/pluginerrorview.cpp:31:0:"), + Utils::FileName::fromUserInput(QLatin1String("/home/code/src/creator/src/libs/extensionsystem/pluginerrorview.cpp")), 31, + categoryCompile) + << Task(Task::Error, + QLatin1String("QtGui/QAction: No such file or directory\n" + " #include <QtGui/QAction>\n" + " ^"), + Utils::FileName::fromUserInput(QLatin1String(".uic/ui_pluginerrorview.h")), 14, + categoryCompile)) + << QString(); + } void ProjectExplorerPlugin::testGccOutputParsers() diff --git a/src/plugins/projectexplorer/gccparser.h b/src/plugins/projectexplorer/gccparser.h index 3ede1493dab7bd109d3a8b99f2b5e606cef4a308..fcb2108fe9f2dbe9553e67cac96a9cd0c936f97b 100644 --- a/src/plugins/projectexplorer/gccparser.h +++ b/src/plugins/projectexplorer/gccparser.h @@ -32,6 +32,8 @@ #include "ioutputparser.h" +#include <projectexplorer/task.h> + #include <QRegExp> namespace ProjectExplorer { @@ -42,12 +44,24 @@ class GccParser : public ProjectExplorer::IOutputParser public: GccParser(); + ~GccParser(); void stdError(const QString &line); + void stdOutput(const QString &line); + +protected: + void newTask(const Task &task); + void newTask(Task::TaskType type_, const QString &description_, + const Utils::FileName &file_, int line_, const Core::Id &category_); + void emitTask(); + + void amendDescription(const QString &desc, bool monospaced); private: QRegExp m_regExp; QRegExp m_regExpIncluded; QRegExp m_regExpGccNames; + + Task m_currentTask; }; } // namespace ProjectExplorer