1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "linuxiccparser.h"
36 #include "taskwindow.h"
37 #include "projectexplorerconstants.h"
39 #include <QtCore/QDir>
41 using namespace ProjectExplorer;
43 LinuxIccParser::LinuxIccParser()
44 : m_expectFirstLine(true), m_indent(0), m_temporary(Task())
46 setObjectName(QLatin1String("LinuxIccParser"));
47 // main.cpp(53): error #308: function \"AClass::privatefunc\" (declared at line 4 of \"main.h\") is inaccessible
49 m_firstLine.setPattern("^([^\\(\\)]+)" // filename (cap 1)
50 "\\((\\d+)\\):" // line number including : (cap 2)
51 " ((error|warning)( #\\d+)?: )?" // optional type (cap 4) and optional error number // TODO really optional ?
52 "(.*)$"); // description (cap 6)
53 //m_firstLine.setMinimal(true);
55 // Note pattern also matches caret lines
56 m_continuationLines.setPattern("^\\s+" // At least one whitespace
57 "(.*)$");// description
58 m_continuationLines.setMinimal(true);
60 m_caretLine.setPattern("^\\s*" // Whitespaces
62 "\\s*$"); // and again whitespaces
63 m_caretLine.setMinimal(true);
65 appendOutputParser(new LdParser);
68 LinuxIccParser::~LinuxIccParser()
70 if (!m_temporary.isNull())
74 void LinuxIccParser::stdError(const QString &line)
76 if (m_expectFirstLine && m_firstLine.indexIn(line) != -1) {
78 m_temporary = ProjectExplorer::Task(Task::Unknown, m_firstLine.cap(6).trimmed(),
79 QDir::fromNativeSeparators(m_firstLine.cap(1)),
80 m_firstLine.cap(2).toInt(),
81 QLatin1String(Constants::TASK_CATEGORY_COMPILE));
82 QString category = m_firstLine.cap(4);
83 if (category == QLatin1String("error"))
84 m_temporary.type = Task::Error;
85 else if (category == QLatin1String("warning"))
86 m_temporary.type = Task::Warning;
88 m_expectFirstLine = false;
89 } else if (!m_expectFirstLine && m_caretLine.indexIn(line) != -1) {
90 // Format the last line as code
91 QTextLayout::FormatRange fr;
92 fr.start = m_temporary.description.lastIndexOf('\n') + 1;
93 fr.length = m_temporary.description.length() - fr.start;
94 fr.format.setFontItalic(true);
95 m_temporary.formats.append(fr);
97 QTextLayout::FormatRange fr2;
98 fr2.start = fr.start + line.indexOf('^') - m_indent;
100 fr2.format.setFontWeight(QFont::Bold);
101 m_temporary.formats.append(fr2);
102 } else if (!m_expectFirstLine && line.trimmed().isEmpty()) { // last Line
103 m_expectFirstLine = true;
104 emit addTask(m_temporary);
105 m_temporary = Task();
106 } else if (!m_expectFirstLine && m_continuationLines.indexIn(line) != -1) {
107 m_temporary.description.append("\n");
109 while (m_indent < line.length() && line.at(m_indent).isSpace())
111 m_temporary.description.append(m_continuationLines.cap(1).trimmed());
113 IOutputParser::stdError(line);
119 # include "projectexplorer.h"
120 # include "metatypedeclarations.h"
121 # include "outputparser_test.h"
123 void ProjectExplorerPlugin::testLinuxIccOutputParsers_data()
125 QTest::addColumn<QString>("input");
126 QTest::addColumn<OutputParserTester::Channel>("inputChannel");
127 QTest::addColumn<QString>("childStdOutLines");
128 QTest::addColumn<QString>("childStdErrLines");
129 QTest::addColumn<QList<ProjectExplorer::Task> >("tasks");
130 QTest::addColumn<QString>("outputLines");
133 QTest::newRow("pass-through stdout")
134 << QString::fromLatin1("Sometext") << OutputParserTester::STDOUT
135 << QString::fromLatin1("Sometext") << QString()
136 << QList<ProjectExplorer::Task>()
138 QTest::newRow("pass-through stderr")
139 << QString::fromLatin1("Sometext") << OutputParserTester::STDERR
140 << QString() << QString::fromLatin1("Sometext")
141 << QList<ProjectExplorer::Task>()
144 QTest::newRow("undeclared function")
145 << QString::fromLatin1("main.cpp(13): error: identifier \"f\" is undefined\n"
149 << OutputParserTester::STDERR
150 << QString() << QString()
151 << (QList<ProjectExplorer::Task>()
153 QLatin1String("identifier \"f\" is undefined\nf(0);"),
154 QLatin1String("main.cpp"), 13,
155 Constants::TASK_CATEGORY_COMPILE))
158 QTest::newRow("private function")
159 << QString::fromLatin1("main.cpp(53): error #308: function \"AClass::privatefunc\" (declared at line 4 of \"main.h\") is inaccessible\n"
160 " b.privatefunc();\n"
163 << OutputParserTester::STDERR
164 << QString() << QString()
165 << (QList<ProjectExplorer::Task>()
167 QLatin1String("function \"AClass::privatefunc\" (declared at line 4 of \"main.h\") is inaccessible\nb.privatefunc();"),
168 QLatin1String("main.cpp"), 53,
169 Constants::TASK_CATEGORY_COMPILE))
172 QTest::newRow("simple warning")
173 << QString::fromLatin1("main.cpp(41): warning #187: use of \"=\" where \"==\" may have been intended\n"
174 " while (a = true)\n"
177 << OutputParserTester::STDERR
178 << QString() << QString()
179 << (QList<ProjectExplorer::Task>()
180 << Task(Task::Warning,
181 QLatin1String("use of \"=\" where \"==\" may have been intended\nwhile (a = true)"),
182 QLatin1String("main.cpp"), 41,
183 Constants::TASK_CATEGORY_COMPILE))
187 void ProjectExplorerPlugin::testLinuxIccOutputParsers()
189 OutputParserTester testbench;
190 testbench.appendOutputParser(new LinuxIccParser);
191 QFETCH(QString, input);
192 QFETCH(OutputParserTester::Channel, inputChannel);
193 QFETCH(QList<Task>, tasks);
194 QFETCH(QString, childStdOutLines);
195 QFETCH(QString, childStdErrLines);
196 QFETCH(QString, outputLines);
198 testbench.testParsing(input, inputChannel,
199 tasks, childStdOutLines, childStdErrLines,