KDevelop API Documentation

makeactionfilter.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 1999-2001 by Bernd Gehrmann and the KDevelop Team       *
00003  *   bernd@kdevelop.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  ***************************************************************************/
00011 
00012 #include <qdatetime.h>
00013 #include <kdebug.h>
00014 
00015 #include "makeactionfilter.h"
00016 #include "makeactionfilter.moc"
00017 #include "makeitem.h"
00018 
00019 #include <klocale.h>
00020 #include <kdebug.h>
00021 
00022 //#define DEBUG
00023 
00024 MakeActionFilter::ActionFormat::ActionFormat( const QString& _action, const QString& _tool, const char * regExp, int file )
00025     : action( _action )
00026     , tool( _tool )
00027     , expression( regExp )
00028     , fileGroup( file )
00029 {
00030 }
00031 
00032 MakeActionFilter::MakeActionFilter( OutputFilter& next )
00033     : OutputFilter( next )
00034 {
00035 
00036 #ifdef DEBUG
00037     test();
00038 #endif
00039 }
00040 
00041 //NOTE: whenever you discover a case that is not correctly recognized by the filter, please add it as a test
00042 //item and be sure that your modifications don't break the already existing test cases.
00043 
00044 // returns an array of ActionFormat
00045 MakeActionFilter::ActionFormat* MakeActionFilter::actionFormats()
00046 {
00047     static ActionFormat formats[] = {
00048         ActionFormat( i18n("compiling"), "g++", "g\\+\\+\\S* (?:\\S* )*-c (?:\\S* )*`[^`]*`(?:[^/\\s;]*/)*([^/\\s;]+)", 1 ),
00049         ActionFormat( i18n("compiling"), "g++", "g\\+\\+\\S* (?:\\S* )*-c (?:\\S* )*-o (?:\\S* )(?:[^/;]*/)*([^/\\s;]+)", 1 ),
00050         ActionFormat( i18n("compiling"), "gcc", "g\\c\\c\\S* (?:\\S* )*-c (?:\\S* )*`[^`]*`(?:[^/\\s;]*/)*([^/\\s;]+)", 1 ),
00051         ActionFormat( i18n("compiling"), "gcc", "g\\c\\c\\S* (?:\\S* )*-c (?:\\S* )*(?:[^/]*/)*([^/\\s;]*)", 1 ),
00052         ActionFormat( i18n("compiling"), "distcc", "distcc (?:\\S* )*-c (?:\\S* )*`[^`]*`(?:[^/\\s;]*/)*([^/\\s;]+)", 1 ),
00053         ActionFormat( i18n("compiling"), "distcc", "distcc (?:\\S* )*-c (?:\\S* )*(?:[^/]*/)*([^/\\s;]*)", 1 ),
00054         ActionFormat( i18n("compiling"), "unknown", "^compiling (.*)", 1 ),
00055         ActionFormat( i18n("generating"), "moc", "/moc\\b.*\\s-o\\s([^\\s;]+)", 1 ),
00056         ActionFormat( i18n("generating"), "uic", "/uic\\b.*\\s-o\\s([^\\s;]+)", 1 ),
00057         ActionFormat( i18n("linking"), "libtool", "/bin/sh\\s.*libtool.*--mode=link\\s.*\\s-o\\s([^\\s;]+)", 1 ),
00058         ActionFormat( i18n("linking"), "g++", "g\\+\\+\\S* (?:\\S* )*-o ([^\\s;]+)", 1 ),
00059         ActionFormat( i18n("linking"), "gcc", "g\\c\\c\\S* (?:\\S* )*-o ([^\\s;]+)", 1 ),
00060         ActionFormat( i18n("creating"), "", "/(?:bin/sh\\s.*mkinstalldirs).*\\s([^\\s;]+)", 1 ),
00061         ActionFormat( i18n("installing"), "", "/(?:usr/bin/install|bin/sh\\s.*mkinstalldirs|bin/sh\\s.*libtool.*--mode=install).*\\s([^\\s;]+)", 1 ),
00062         ActionFormat( i18n("generating"), "dcopidl", "dcopidl .* > ([^\\s;]+)", 1 ),
00063         ActionFormat( i18n("compiling"), "dcopidl2cpp", "dcopidl2cpp (?:\\S* )*([^\\s;]+)", 1 ),
00064 
00065         ActionFormat( QString::null, QString::null, 0, 0 )
00066     };
00067 
00068     return formats;
00069 }
00070 
00071 void MakeActionFilter::processLine( const QString& line )
00072 {
00073     ActionItem* actionItem = matchLine( line );
00074     if ( actionItem != NULL )
00075     {
00076         emit item( actionItem );
00077     }
00078     else
00079     {
00080         OutputFilter::processLine( line );
00081     }
00082 }
00083 
00084 ActionItem* MakeActionFilter::matchLine( const QString& line )
00085 {
00086 #ifdef DEBUG
00087     QTime t;
00088     t.start();
00089 #endif
00090 
00091     //900-1000ms to execute on an Athlon XP 2000+, while the UI is completely blocked.
00092     int i = 0;
00093     ActionFormat* aFormats = actionFormats();
00094     ActionFormat* format = &aFormats[i];
00095 
00096     while ( !format->action.isNull() )
00097     {
00098 //      kdDebug(9004) << "Testing filter: " << format->action << ": " << format->tool << endl;
00099         QRegExp& regExp = format->expression;
00100         if ( regExp.search( line ) != -1 )
00101         {
00102                    ActionItem *actionItem = new ActionItem( format->action, regExp.cap( format->fileGroup ), format->tool, line );
00103                kdDebug( 9004 ) << "Found: " << actionItem->m_action << " " << actionItem->m_file << "(" << actionItem->m_tool << ")" << endl;
00104            return actionItem;
00105         }
00106 #ifdef DEBUG
00107         if ( t.elapsed() > 100 )
00108             kdDebug(9004) << "MakeActionFilter::processLine: SLOW regexp matching: " << t.elapsed() << " ms \n";
00109 #endif
00110         format = &aFormats[++i];
00111     }
00112     return 0;
00113 }
00114 
00115 struct TestItem
00116 {
00117     TestItem() {}
00118     TestItem( const QString& _line, const QString& _action, const QString& _tool, const QString& _file )
00119         : line( _line )
00120         , action( _action )
00121         , tool( _tool )
00122         , file( _file )
00123     {}
00124     QString line;
00125     QString action;
00126     QString tool;
00127     QString file;
00128 };
00129 
00130 #ifdef DEBUG
00131 
00132 void MakeActionFilter::test()
00133 {
00134     static QValueList<TestItem> testItems = QValueList<TestItem>()
00135 
00136     << TestItem( // simple qmake compile
00137         "g++ -c -pipe -Wall -W -O2 -DQT_NO_DEBUG -I/home/john/src/kde/qt-copy/mkspecs/default -I. "
00138         "-I/home/john/src/kde/qt-copy/include -o test.o test.cpp",
00139         "compiling", "g++", "test.cpp" )
00140     << TestItem( // simple qmake link
00141         "g++ -o ../bin/test test.o -Wl,-rpath,/home/john/src/kde/qt-copy/lib -L/home/john/src/kde/qt-copy/lib "
00142         "-L/usr/X11R6/lib -lqt-mt -lXext -lX11 -lm",
00143         "linking", "g++", "../bin/test" )
00144     << TestItem( // automake 1.7, srcdir != builddir
00145         "if /bin/sh ../../libtool --silent --mode=compile --tag=CXX g++ -DHAVE_CONFIG_H -I. "
00146         "-I/home/john/src/kde/kdevelop/lib/interfaces -I../.. -I/usr/local/kde/include -I/home/john/src/kde/qt-copy/include "
00147         "-I/usr/X11R6/include -DQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor -Wno-long-long -Wundef -Wall -pedantic -W "
00148         "-Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion "
00149         "-Wchar-subscripts -fno-builtin -g3 -Wformat-security -Wmissing-format-attribute -fno-exceptions -fno-check-new "
00150         "-fno-common -MT kdevcore.lo -MD -MP -MF \".deps/kdevcore.Tpo\" -c -o kdevcore.lo `test -f "
00151         "'/home/john/src/kde/kdevelop/lib/interfaces/kdevcore.cpp' || echo "
00152         "'/home/john/src/kde/kdevelop/lib/interfaces/'`/home/john/src/kde/kdevelop/lib/interfaces/kdevcore.cpp; then mv "
00153         "\".deps/kdevcore.Tpo\" \".deps/kdevcore.Plo\"; else rm -f \".deps/kdevcore.Tpo\"; exit 1; fi",
00154         "compiling", "g++", "kdevcore.cpp" )
00155     << TestItem( // automake 1.7, srcdir != builddir
00156         "if g++ -DHAVE_CONFIG_H -I. -I/home/john/src/kde/kdevelop/src -I.. -I/home/john/src/kde/kdevelop/lib/interfaces "
00157         "-I/home/john/src/kde/kdevelop/lib/sourceinfo -I/home/john/src/kde/kdevelop/lib/util -I/home/john/src/kde/kdevelop/lib "
00158         "-I/home/john/src/kde/kdevelop/lib/qextmdi/include -I/home/john/src/kde/kdevelop/lib/structure -I/usr/local/kde/include "
00159         "-I/home/john/src/kde/qt-copy/include -I/usr/X11R6/include -DQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor "
00160         "-Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi "
00161         "-D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -Wchar-subscripts -fno-builtin -g3 -Wformat-security "
00162         "-Wmissing-format-attribute -fno-exceptions -fno-check-new -fno-common -MT mainwindowideal.o -MD -MP -MF "
00163         "\".deps/mainwindowideal.Tpo\" -c -o mainwindowideal.o `test -f '/home/john/src/kde/kdevelop/src/mainwindowideal.cpp' "
00164         "|| echo '/home/john/src/kde/kdevelop/src/'`/home/john/src/kde/kdevelop/src/mainwindowideal.cpp; then mv "
00165         "\".deps/mainwindowideal.Tpo\" \".deps/mainwindowideal.Po\"; else rm -f \".deps/mainwindowideal.Tpo\"; exit 1; fi",
00166         "compiling", "g++", "mainwindowideal.cpp" )
00167     << TestItem(
00168         "source='makewidget.cpp' object='makewidget.lo' libtool=yes depfile='.deps/makewidget.Plo' "
00169         "tmpdepfile='.deps/makewidget.TPlo' depmode=gcc3 /bin/sh ../../admin/depcomp /bin/sh ../../libtool --mode=compile "
00170         "--tag=CXX g++ -DHAVE_CONFIG_H -I. -I. -I../.. -I../../lib/interfaces -I../../lib/util -I/opt/kde3/include "
00171         "-I/usr/lib/qt3/include -I/usr/X11R6/include -DQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor -Wno-long-long -Wundef "
00172         "-Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE "
00173         "-Wcast-align -Wconversion -fno-builtin -g -O2 -g3 -O0 -fno-exceptions -fno-check-new -c -o makewidget.lo `test -f "
00174         "'makewidget.cpp' || echo './'`makewidget.cpp",
00175         "compiling", "g++", "makewidget.cpp" )
00176     << TestItem( // automake 1.7, srcdir != builddir
00177         "/bin/sh ../../libtool --silent --mode=link --tag=CXX g++ -Wnon-virtual-dtor -Wno-long-long -Wundef -Wall -pedantic "
00178         "-W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align "
00179         "-Wconversion -Wchar-subscripts -fno-builtin -g3 -Wformat-security -Wmissing-format-attribute -fno-exceptions "
00180         "-fno-check-new -fno-common -o libkdevoutputviews.la.closure libkdevoutputviews_la_closure.lo -L/usr/X11R6/lib "
00181         "-L/home/john/src/kde/qt-copy/lib -L/usr/local/kde/lib -avoid-version -module -no-undefined -R /usr/local/kde/lib "
00182         "-R /home/john/src/kde/qt-copy/lib -R /usr/X11R6/lib outputviewsfactory.lo makeviewpart.lo makewidget.lo "
00183         "appoutputviewpart.lo appoutputwidget.lo directorystatusmessagefilter.lo outputfilter.lo compileerrorfilter.lo "
00184         "commandcontinuationfilter.lo makeitem.lo makeactionfilter.lo otherfilter.lo ../../lib/libkdevelop.la",
00185         "linking", "libtool", "libkdevoutputviews.la.closure" )
00186     << TestItem( //libtool, linking 2
00187         "/bin/sh ../libtool --silent --mode=link --tag=CXX g++  -Wnon-virtual-dtor -Wno-long-long -Wundef -Wall -pedantic "
00188         "-W -Wpointer-arith -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -Wchar-subscripts "
00189         "-fno-builtin -g3 -fno-exceptions -fno-check-new -fno-common    -o libkfilereplacepart.la.closure libkfilereplacepart_la_closure.lo "
00190         "-module -no-undefined  -L/usr/X11R6/lib -L/usr/lib/qt3/lib -L/opt/kde3/lib  -version-info 1:0:0 kfilereplacepart.lo kfilereplacedoc.lo "
00191         "kfilereplaceview.lo kaboutkfilereplace.lo kaddstringdlg.lo kconfirmdlg.lo kernel.lo kexpression.lo kfilereplacepref.lo "
00192         "klistviewstring.lo knewprojectdlg.lo koptionsdlg.lo kresultview.lo filelib.lo knewprojectdlgs.lo -lkio -lkparts -lkhtml",
00193         "linking", "libtool", "libkfilereplacepart.la.closure")
00194     << TestItem( //libtool, linking 3
00195         "/bin/sh ../libtool --silent --mode=link --tag=CXX g++  -Wnon-virtual-dtor -Wno-long-long -Wundef -Wall -pedantic "
00196         "-W -Wpointer-arith -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -Wchar-subscripts "
00197         "-fno-builtin -g3 -fno-exceptions -fno-check-new -fno-common    -o libkfilereplacepart.la -rpath /opt/kde3/lib/kde3 "
00198         "-module -no-undefined  -L/usr/X11R6/lib -L/usr/lib/qt3/lib -L/opt/kde3/lib  -version-info 1:0:0 kfilereplacepart.lo "
00199         "kfilereplacedoc.lo kfilereplaceview.lo kaboutkfilereplace.lo kaddstringdlg.lo kconfirmdlg.lo kernel.lo kexpression.lo "
00200         "kfilereplacepref.lo klistviewstring.lo knewprojectdlg.lo koptionsdlg.lo kresultview.lo filelib.lo knewprojectdlgs.lo -lkio -lkparts -lkhtml",
00201         "linking", "libtool", "libkfilereplacepart.la")
00202     << TestItem( //automake, builddir!=srcdir, libtool=no, compiling
00203         " g++ -DHAVE_CONFIG_H -I. -I/home/andris/cvs-developement/head/quanta/quanta/project "
00204         "-I../.. -I/home/andris/cvs-developement/head/quanta/quanta/dialogs -I/opt/kde3/include -I/usr/lib/qt3/include -I/usr/X11R6/include  "
00205         "-I../../quanta/dialogs  -DQT_THREAD_SUPPORT  -D_REENTRANT -DKOMMANDER -DDESIGNER -DQT_NO_SQL -DHAVE_KDE  -Wnon-virtual-dtor "
00206         "-Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE "
00207         "-Wcast-align -Wconversion -Wchar-subscripts -fno-builtin -g3 -DKDE_NO_COMPAT -fno-exceptions -fno-check-new -fno-common  -c -o project.o "
00208         "`test -f '/home/andris/cvs-developement/head/quanta/quanta/project/project.cpp' || "
00209         "echo '/home/andris/cvs-developement/head/quanta/quanta/project/'`/home/andris/cvs-developement/head/quanta/quanta/project/project.cpp  ",
00210         "compiling", "g++", "project.cpp")
00211     << TestItem(
00212         "/usr/local/kde/bin/dcopidl /home/john/src/kde/kdevelop/lib/interfaces/KDevAppFrontendIface.h > KDevAppFrontendIface.kidl "
00213         "|| ( rm -f KDevAppFrontendIface.kidl ; /bin/false )",
00214         "generating", "dcopidl", "KDevAppFrontendIface.kidl" )
00215     << TestItem(
00216         "/usr/local/kde/bin/dcopidl2cpp --c++-suffix cpp --no-signals --no-stub KDevAppFrontendIface.kidl",
00217         "compiling", "dcopidl2cpp", "KDevAppFrontendIface.kidl" )
00218     << TestItem( //install
00219         "/usr/bin/install -c -p -m 644 /home/andris/development/quanta/quanta/kommander/editor/kmdr-editor.desktop "
00220         "/opt/kde3/share/applnk/Editors/kmdr-editor.desktop", "installing", "", "/opt/kde3/share/applnk/Editors/kmdr-editor.desktop")
00221     << TestItem( //libtool install
00222         "/bin/sh ../../libtool --silent --mode=install /usr/bin/install -c -p libkommanderwidgets.la "
00223         "/opt/kde3/lib/libkommanderwidgets.la", "installing", "", "/opt/kde3/lib/libkommanderwidgets.la")
00224     << TestItem( //libtool, automake 1.8
00225     "if g++ -DHAVE_CONFIG_H -I. -I/home/andris/  "
00226     "-DBUILD_KAFKAPART  -MT quanta_init.o -MD -MP -MF \".deps/quanta_init.Tpo\" -c -o quanta_init.o "
00227     "quanta_init.cpp; "
00228     "then mv -f \".deps/quanta_init.Tpo\" \".deps/quanta_init.Po\"; else rm -f \".deps/quanta_init.Tpo\"; "
00229     "exit 1; fi",
00230     "compiling", "g++", "quanta_init.cpp")
00231     << TestItem( //libtool, automake 1.8, file with full path
00232     "if g++ -DHAVE_CONFIG_H -I. -I/home/andris/  "
00233     "-DBUILD_KAFKAPART  -MT quanta_init.o -MD -MP -MF \".deps/quanta_init.Tpo\" -c -o quanta_init.o "
00234     "/home/andris/quanta_init.cpp; "
00235     "then mv -f \".deps/quanta_init.Tpo\" \".deps/quanta_init.Po\"; else rm -f \".deps/quanta_init.Tpo\"; "
00236     "exit 1; fi",
00237     "compiling", "g++", "quanta_init.cpp")
00238     ;
00239 
00240     QValueList<TestItem>::const_iterator it = testItems.begin();
00241     for( ; it != testItems.end(); ++it )
00242     {
00243         ActionItem* actionItem = matchLine( (*it).line );
00244         if ( actionItem == NULL )
00245         {
00246             kdError( 9004 ) << "MakeActionFilter::test(): match failed (no match):" << endl;
00247             kdError( 9004 ) << (*it).line << endl;
00248         }
00249         else if ( actionItem->m_action != (*it).action )
00250         {
00251             kdError( 9004 ) << "MakeActionFilter::test(): match failed (expected action "
00252                             << (*it).action << ", got " << actionItem->m_action << endl;
00253             kdError( 9004 ) << (*it).line << endl;
00254         }
00255         else if ( actionItem->m_tool != (*it).tool )
00256         {
00257             kdError( 9004 ) << "MakeActionFilter::test(): match failed (expected tool "
00258                             << (*it).tool << ", got " << actionItem->m_tool << endl;
00259             kdError( 9004 ) << (*it).line << endl;
00260         }
00261         else if ( actionItem->m_file != (*it).file )
00262         {
00263             kdError( 9004 ) << "MakeActionFilter::test(): match failed (expected file "
00264                             << (*it).file << ", got " << actionItem->m_file << endl;
00265             kdError( 9004 ) << (*it).line << endl;
00266         } else
00267         kdDebug( 9004 ) << "Test passed, " << actionItem->m_action << " " << actionItem->m_file << " (" << actionItem->m_tool << ") found." << endl;
00268         if ( actionItem != NULL )
00269             delete actionItem;
00270     }
00271 
00272 }
00273 
00274 #endif
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 23 00:03:57 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003