OSDN Git Service

3b8f7fb1b85a06a65e7d4519c19b38a8ba63ffd6
[qt-creator-jp/qt-creator-jp.git] / src / plugins / projectexplorer / linuxiccparser.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
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
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
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.
24 **
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.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include "linuxiccparser.h"
35 #include "ldparser.h"
36 #include "taskwindow.h"
37 #include "projectexplorerconstants.h"
38
39 #include <QtCore/QDir>
40
41 using namespace ProjectExplorer;
42
43 LinuxIccParser::LinuxIccParser()
44     : m_expectFirstLine(true), m_indent(0), m_temporary(Task())
45 {
46     setObjectName(QLatin1String("LinuxIccParser"));
47     // main.cpp(53): error #308: function \"AClass::privatefunc\" (declared at line 4 of \"main.h\") is inaccessible
48
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);
54
55                                             // Note pattern also matches caret lines
56     m_continuationLines.setPattern("^\\s+"  // At least one whitespace
57                                    "(.*)$");// description
58     m_continuationLines.setMinimal(true);
59
60     m_caretLine.setPattern("^\\s*"          // Whitespaces
61                            "\\^"            // a caret
62                            "\\s*$");        // and again whitespaces
63     m_caretLine.setMinimal(true);
64
65     appendOutputParser(new LdParser);
66 }
67
68 LinuxIccParser::~LinuxIccParser()
69 {
70     if (!m_temporary.isNull())
71         addTask(m_temporary);
72 }
73
74 void LinuxIccParser::stdError(const QString &line)
75 {
76     if (m_expectFirstLine  && m_firstLine.indexIn(line) != -1) {
77         // Clear out old task
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;
87
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);
96
97         QTextLayout::FormatRange fr2;
98         fr2.start = fr.start + line.indexOf('^') - m_indent;
99         fr2.length = 1;
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");
108         m_indent = 0;
109         while (m_indent < line.length() && line.at(m_indent).isSpace())
110             m_indent++;
111         m_temporary.description.append(m_continuationLines.cap(1).trimmed());
112     } else {
113         IOutputParser::stdError(line);
114     }
115 }
116
117 #ifdef WITH_TESTS
118 #   include <QTest>
119 #   include "projectexplorer.h"
120 #   include "metatypedeclarations.h"
121 #   include "outputparser_test.h"
122
123 void ProjectExplorerPlugin::testLinuxIccOutputParsers_data()
124 {
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");
131
132
133     QTest::newRow("pass-through stdout")
134             << QString::fromLatin1("Sometext") << OutputParserTester::STDOUT
135             << QString::fromLatin1("Sometext") << QString()
136             << QList<ProjectExplorer::Task>()
137             << QString();
138     QTest::newRow("pass-through stderr")
139             << QString::fromLatin1("Sometext") << OutputParserTester::STDERR
140             << QString() << QString::fromLatin1("Sometext")
141             << QList<ProjectExplorer::Task>()
142             << QString();
143
144     QTest::newRow("undeclared function")
145             << QString::fromLatin1("main.cpp(13): error: identifier \"f\" is undefined\n"
146                                    "      f(0);\n"
147                                    "      ^\n"
148                                    "\n")
149             << OutputParserTester::STDERR
150             << QString() << QString()
151             << (QList<ProjectExplorer::Task>()
152                 << Task(Task::Error,
153                         QLatin1String("identifier \"f\" is undefined\nf(0);"),
154                         QLatin1String("main.cpp"), 13,
155                         Constants::TASK_CATEGORY_COMPILE))
156             << QString();
157
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"
161                                    "        ^\n"
162                                    "\n")
163             << OutputParserTester::STDERR
164             << QString() << QString()
165             << (QList<ProjectExplorer::Task>()
166                 << Task(Task::Error,
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))
170             << QString();
171
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"
175                                    "             ^\n"
176                                    "\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))
184             << QString();
185 }
186
187 void ProjectExplorerPlugin::testLinuxIccOutputParsers()
188 {
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);
197
198     testbench.testParsing(input, inputChannel,
199                           tasks, childStdOutLines, childStdErrLines,
200                           outputLines);
201 }
202
203 #endif