2009-02-25 09:15:00 +01:00
/**************************************************************************
2008-12-02 12:01:29 +01:00
* *
* * This file is part of Qt Creator
* *
2010-03-05 11:25:49 +01:00
* * Copyright ( c ) 2010 Nokia Corporation and / or its subsidiary ( - ies ) .
2008-12-02 12:01:29 +01:00
* *
2009-06-17 00:01:27 +10:00
* * Contact : Nokia Corporation ( qt - info @ nokia . com )
2008-12-02 12:01:29 +01:00
* *
2009-02-25 09:15:00 +01:00
* * Commercial Usage
2008-12-02 14:17:16 +01:00
* *
2009-02-25 09:15:00 +01:00
* * Licensees holding valid Qt Commercial licenses may use this file in
* * accordance with the Qt Commercial License Agreement provided with the
* * Software or , alternatively , in accordance with the terms contained in
* * a written agreement between you and Nokia .
2008-12-02 14:17:16 +01:00
* *
2009-02-25 09:15:00 +01:00
* * GNU Lesser General Public License Usage
2008-12-02 14:17:16 +01:00
* *
2009-02-25 09:15:00 +01:00
* * Alternatively , this file may be used under the terms of the GNU Lesser
* * General Public License version 2.1 as published by the Free Software
* * Foundation and appearing in the file LICENSE . LGPL included in the
* * packaging of this file . Please review the following information to
* * ensure the GNU Lesser General Public License version 2.1 requirements
* * will be met : http : //www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
2008-12-02 14:17:16 +01:00
* *
2009-02-25 09:15:00 +01:00
* * If you are unsure which license is appropriate for your use , please
2009-08-14 09:30:56 +02:00
* * contact the sales department at http : //qt.nokia.com/contact.
2008-12-02 12:01:29 +01:00
* *
2009-02-25 09:15:00 +01:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-12-02 12:01:29 +01:00
# include "msvcparser.h"
2009-02-16 13:12:12 +01:00
# include "projectexplorerconstants.h"
2008-12-02 12:01:29 +01:00
2010-08-13 13:27:02 +02:00
namespace {
const char * const FILE_POS_PATTERN = " ([^ \\ (]+) \\ (( \\ d+) \\ ) \\ s: " ;
}
2009-02-16 13:12:12 +01:00
using namespace ProjectExplorer ;
2008-12-02 12:01:29 +01:00
MsvcParser : : MsvcParser ( )
{
2010-08-13 13:27:02 +02:00
m_compileRegExp . setPattern ( QString : : fromLatin1 ( " ^ " ) + QLatin1String ( FILE_POS_PATTERN ) + QLatin1String ( " ([^: \\ d]+) \\ s([A-Z]+( \\ d+):.*)$ " ) ) ;
2008-12-02 12:01:29 +01:00
m_compileRegExp . setMinimal ( true ) ;
2010-08-13 13:27:02 +02:00
m_additionalInfoRegExp . setPattern ( QString : : fromLatin1 ( " ^ " ) + QLatin1String ( FILE_POS_PATTERN ) + QLatin1String ( " \\ s(.*)$ " ) ) ;
m_additionalInfoRegExp . setMinimal ( true ) ;
m_linkRegExp . setPattern ( QString : : fromLatin1 ( " ^ " ) + QLatin1String ( FILE_POS_PATTERN ) + QLatin1String ( " [^: \\ d]+( \\ d+):(.*)$ " ) ) ;
2008-12-02 12:01:29 +01:00
m_linkRegExp . setMinimal ( true ) ;
}
2009-12-09 13:54:46 +01:00
void MsvcParser : : stdOutput ( const QString & line )
2008-12-02 12:01:29 +01:00
{
QString lne = line . trimmed ( ) ;
2010-08-12 16:29:58 +02:00
if ( m_compileRegExp . indexIn ( lne ) > - 1 & & m_compileRegExp . numCaptures ( ) = = 5 ) {
Task task ( Task : : Unknown ,
m_compileRegExp . cap ( 4 ) /* description */ ,
m_compileRegExp . cap ( 1 ) /* filename */ ,
m_compileRegExp . cap ( 2 ) . toInt ( ) /* linenumber */ ,
Constants : : TASK_CATEGORY_COMPILE ) ;
if ( m_compileRegExp . cap ( 3 ) = = QLatin1String ( " warning " ) )
task . type = Task : : Warning ;
else if ( m_compileRegExp . cap ( 3 ) = = QLatin1String ( " error " ) )
task . type = Task : : Error ;
else
task . type = toType ( m_compileRegExp . cap ( 5 ) . toInt ( ) ) ;
addTask ( task ) ;
2009-11-12 15:54:45 +01:00
return ;
}
2010-08-13 13:27:02 +02:00
if ( m_additionalInfoRegExp . indexIn ( line ) > - 1 & & m_additionalInfoRegExp . numCaptures ( ) = = 3 ) {
addTask ( Task ( Task : : Unknown ,
m_additionalInfoRegExp . cap ( 3 ) ,
m_additionalInfoRegExp . cap ( 1 ) ,
m_additionalInfoRegExp . cap ( 2 ) . toInt ( ) ,
Constants : : TASK_CATEGORY_COMPILE ) ) ;
return ;
}
2009-11-12 15:54:45 +01:00
if ( m_linkRegExp . indexIn ( lne ) > - 1 & & m_linkRegExp . numCaptures ( ) = = 3 ) {
2008-12-02 12:01:29 +01:00
QString fileName = m_linkRegExp . cap ( 1 ) ;
if ( fileName . contains ( QLatin1String ( " LINK " ) , Qt : : CaseSensitive ) )
fileName . clear ( ) ;
2010-03-12 13:53:00 +01:00
emit addTask ( Task ( toType ( m_linkRegExp . cap ( 2 ) . toInt ( ) ) /* task type */ ,
m_linkRegExp . cap ( 3 ) /* description */ ,
fileName /* filename */ ,
- 1 /* line number */ ,
Constants : : TASK_CATEGORY_COMPILE ) ) ;
2009-11-12 15:54:45 +01:00
return ;
2008-12-02 12:01:29 +01:00
}
2010-07-27 14:22:23 +02:00
IOutputParser : : stdOutput ( line ) ;
2008-12-02 12:01:29 +01:00
}
2010-03-12 13:53:00 +01:00
Task : : TaskType MsvcParser : : toType ( int number )
2008-12-02 12:01:29 +01:00
{
2010-08-12 16:29:58 +02:00
// This is unfortunately not true for all possible kinds of errors, but better
// than not having a fallback at all!
2008-12-02 12:01:29 +01:00
if ( number = = 0 )
2010-03-12 13:53:00 +01:00
return Task : : Unknown ;
2008-12-02 12:01:29 +01:00
else if ( number > 4000 & & number < 5000 )
2010-03-12 13:53:00 +01:00
return Task : : Warning ;
2008-12-02 12:01:29 +01:00
else
2010-03-12 13:53:00 +01:00
return Task : : Error ;
2008-12-02 12:01:29 +01:00
}
2010-08-12 16:29:58 +02:00
// Unit tests:
# ifdef WITH_TESTS
# include <QTest>
# include "projectexplorer.h"
# include "projectexplorer / outputparser_test.h"
using namespace ProjectExplorer : : Internal ;
void ProjectExplorerPlugin : : testMsvcOutputParsers_data ( )
{
QTest : : addColumn < QString > ( " input " ) ;
QTest : : addColumn < OutputParserTester : : Channel > ( " inputChannel " ) ;
QTest : : addColumn < QString > ( " childStdOutLines " ) ;
QTest : : addColumn < QString > ( " childStdErrLines " ) ;
QTest : : addColumn < QList < ProjectExplorer : : Task > > ( " tasks " ) ;
QTest : : addColumn < QString > ( " outputLines " ) ;
QTest : : newRow ( " pass-through stdout " )
< < QString : : fromLatin1 ( " Sometext " ) < < OutputParserTester : : STDOUT
< < QString : : fromLatin1 ( " Sometext " ) < < QString ( )
< < QList < ProjectExplorer : : Task > ( )
< < QString ( ) ;
QTest : : newRow ( " pass-through stderr " )
< < QString : : fromLatin1 ( " Sometext " ) < < OutputParserTester : : STDERR
< < QString ( ) < < QString : : fromLatin1 ( " Sometext " )
< < QList < ProjectExplorer : : Task > ( )
< < QString ( ) ;
QTest : : newRow ( " labeled error " )
< < QString : : fromLatin1 ( " qmlstandalone \\ main.cpp(54) : error C4716: 'findUnresolvedModule' : must return a value " ) < < OutputParserTester : : STDOUT
< < QString ( ) < < QString ( )
< < ( QList < ProjectExplorer : : Task > ( ) < < Task ( Task : : Error ,
QLatin1String ( " C4716: 'findUnresolvedModule' : must return a value " ) ,
QLatin1String ( " qmlstandalone \\ main.cpp " ) , 54 ,
QLatin1String ( ProjectExplorer : : Constants : : TASK_CATEGORY_COMPILE ) ) )
< < QString ( ) ;
QTest : : newRow ( " labeled warning " )
< < QString : : fromLatin1 ( " x: \\ src \\ plugins \\ projectexplorer \\ msvcparser.cpp(69) : warning C4100: 'something' : unreferenced formal parameter " ) < < OutputParserTester : : STDOUT
< < QString ( ) < < QString ( )
< < ( QList < ProjectExplorer : : Task > ( ) < < Task ( Task : : Warning ,
QLatin1String ( " C4100: 'something' : unreferenced formal parameter " ) ,
QLatin1String ( " x: \\ src \\ plugins \\ projectexplorer \\ msvcparser.cpp " ) , 69 ,
QLatin1String ( ProjectExplorer : : Constants : : TASK_CATEGORY_COMPILE ) ) )
< < QString ( ) ;
2010-08-13 13:27:02 +02:00
QTest : : newRow ( " additional information " )
< < QString : : fromLatin1 ( " x: \\ src \\ plugins \\ texteditor \\ icompletioncollector.h(50) : warning C4099: 'TextEditor::CompletionItem' : type name first seen using 'struct' now seen using 'class' \n "
" x: \\ src \\ plugins \\ texteditor \\ completionsupport.h(39) : see declaration of 'TextEditor::CompletionItem' " )
< < OutputParserTester : : STDOUT
< < QString ( ) < < QString ( )
< < ( QList < ProjectExplorer : : Task > ( )
< < Task ( Task : : Warning ,
QLatin1String ( " C4099: 'TextEditor::CompletionItem' : type name first seen using 'struct' now seen using 'class' " ) ,
QLatin1String ( " x: \\ src \\ plugins \\ texteditor \\ icompletioncollector.h " ) , 50 ,
QLatin1String ( ProjectExplorer : : Constants : : TASK_CATEGORY_COMPILE ) )
< < Task ( Task : : Unknown ,
QLatin1String ( " see declaration of 'TextEditor::CompletionItem' " ) ,
QLatin1String ( " x: \\ src \\ plugins \\ texteditor \\ completionsupport.h " ) , 39 ,
QLatin1String ( ProjectExplorer : : Constants : : TASK_CATEGORY_COMPILE ) ) )
< < QString ( ) ;
2010-08-12 16:29:58 +02:00
}
void ProjectExplorerPlugin : : testMsvcOutputParsers ( )
{
OutputParserTester testbench ;
testbench . appendOutputParser ( new MsvcParser ) ;
QFETCH ( QString , input ) ;
QFETCH ( OutputParserTester : : Channel , inputChannel ) ;
QFETCH ( QList < Task > , tasks ) ;
QFETCH ( QString , childStdOutLines ) ;
QFETCH ( QString , childStdErrLines ) ;
QFETCH ( QString , outputLines ) ;
testbench . testParsing ( input , inputChannel ,
tasks , childStdOutLines , childStdErrLines ,
outputLines ) ;
}
# endif