#! /usr/bin/env perl # this script is written by Stephan Kulow with # much help from Sirtaj Singh Kang if ($ARGV[0]) { $topdir = $ARGV[0]; } else { $topdir=`pwd`; } chomp $topdir; $lastdir = '.'; # this is the important part. Left from the '=>' you find the regular # expression for the g++ output and right from '=>' the header file to # include %messages = ( 'implicit declaration of function `int i18n\(\.\.\.\)\'' => "klocale", '`i18n\' undeclared \(first use this function\)' => "klocale", 'variable `class QPixmap \S*\' has initializer but incomplete type' => "qpixmap", '`kapp\' undeclared \(first use this function\)' => "kapplication", 'no matching function for call to `KLocale::' => "klocale", '`klocale\' undeclared \(first use this function\)' => "klocale", 'no matching function for call to `QPopupMenu::' => "qpopupmenu", '`QTextStream\' undeclared \(first use this function\)' => "qtextstream", '`QTextStream\' was not declared in this scope' => "qtextstream", 'incomplete type `QSocketNotifier\'' => "qsocketnotifier", 'no matching function for call to `TDEConfig' => "kconfig", 'variable `class TDEConfig \S*\' has initializer but incomplete type' => "kconfig", 'implicit declaration of function `int kdDebug' => "kdebug", 'implicit declaration of function `int kdWarning' => "kdebug", '`QFile\' undeclared \(first use this function' => "qfile", 'variable `QFile \S*\' has initializer but incomplete type' => "qfile", 'type `TDEConfigBase\' is not a base type for type `TDEConfig' => "kconfig", 'invalid use of undefined type `class QAccel' => "qaccel", 'invalid use of undefined type `class TDEAboutData' => "kaboutdata", 'incomplete type `TDEAboutData\'' => "kaboutdata", 'incomplete type `QGrid\'' => "qgrid", 'invalid use of undefined type `class QGrid\'' => "qgrid", 'aggregate `class TDEConfig \S*\' has incomplete type' => "kconfig", '`stderr\' undeclared \(first use this function' => "stdio", 'invalid use of undefined type `class TDEConfig' => "kconfig", 'implicit declaration of function `int f?printf' => "stdio", 'no method `TDEGlobal::' => "kglobal", '`TDEGlobal\' undeclared \(first use this function\)' => "kglobal", 'implicit declaration of function `int locate\(\.\.\.\)' => "kstddirs", '`locate\' undeclared \(first use this function\)' => "kstddirs", 'no matching function for call to `KStandardDirs' => "kstddirs", 'no method `KStandardDirs::' => "kstddirs", 'variable `class QFile \S*\' has initializer but incomplete type' => "qfile", 'implicit declaration of function `int ICON\(\.\.\.\)' => "kiconloader", '`QMessageBox\' undeclared \(first use this function\)' => "qmessagebox", 'no matching function for call to `QBoxLayout::QBoxLayout' => "qlayout", '`QUriDrag\' undeclared \(first use this function\)' => "qdragobject", '`kdDebug\' undeclared \(first use this function\)' => "kdebug", '`kdWarning\' undeclared \(first use this function\)' => "kdebug", 'no matching function for call to `KMenuBar::insertItem\(QString, KPopupMenu' => "kpopupmenu", 'no matching function for call to `KMenuBar::' => "kmenubar", 'invalid use of undefined type `class QPointArray' => "qpointarray", 'variable `QPainter \S*\' has initializer but incomplete type' => "qpainter", 'invalid use of undefined type `class QRegExp' => "qregexp", 'invalid use of undefined type `class QPushButton' => "qpushbutton", 'cannot convert `QPushButton \*\' to `QButton \*' => "qpushbutton", 'invalid use of undefined type `class QButton' => "qbutton", '`QButton\' undeclared \(first use this function\)' => "qbutton", 'no method `QCursor::pos' => "qcursor", '`DesktopIcon\' undeclared \(first use this function\)' => "kiconloader", '`BarIcon\' undeclared \(first use this function\)' => "kiconloader", '`SmallIcon\' undeclared \(first use this function\)' => "kiconloader", '`UserIcon\' undeclared \(first use this function\)' => "kiconloader", 'implicit declaration of function `int UserIcon\(...\)\'' => "kiconloader", '`KIcon\' undeclared \(first use this function\)' => "kiconloader", 'invalid use of undefined type `class KIconLoader' => "kiconloader", 'invalid use of undefined type `class TDEInstance' => "kinstance", 'invalid use of undefined type `class DCOPClient' => "dcopclient", '`DCOPClient\' undeclared \(first use this function\)' => "dcopclient", 'invalid use of undefined type `class KStatusBar\'' => "kstatusbar", 'invalid use of undefined type `class QLabel\'' => "qlabel", 'invalid use of undefined type `class QImage\'' => "qimage", 'invalid use of undefined type `class QImageIO\'' => "qimage", 'invalid use of undefined type `class QLineEdit\'' => "qlineedit", 'invalid use of undefined type `class QComboBox\'' => "qcombobox", 'invalid use of undefined type `class QStyle\'' => "qstyle", 'invalid use of undefined type `class KPopupMenu\'' => "kpopupmenu", 'invalid use of undefined type `class QPopupMenu\'' => "qpopupmenu", 'cannot convert `KPopupMenu \*\' to `QPopupMenu \*' => "kpopupmenu", 'aggregate `QPopupMenu \S*\' has incomplete type' => "qpopupmenu", 'invalid use of undefined type `class KURL' => "kurl", 'no method `QApplication::' => "qapplication", 'no method `QFile::' => "qfile", 'error: \'Q3CString\' is used as a type' => "q3cstring", 'error: ISO C\+\+ forbids declaration of \`Q3CString\' with' => "q3cstring", 'error: incomplete type \'QPixmap\' cannot be used' => 'qpixmap', 'error: invalid use of undefined type `struct QVector' => 'qvector', 'error: incomplete type `Q3ValueList' => 'q3valuelist', 'error: variable `Q3ValueList<' => 'q3valuelist', 'error: `Q3PointArray\' undeclared' => 'q3pointarray', 'error: invalid use of undefined type \`struct QColor' => 'qcolor', 'error: `QX11Info::' => 'qx11info_x11', 'error: incomplete type \'QX11Info' => 'qx11info_x11', 'error: \'Q3AsciiDi' => 'q3asciidict' ); # Initial values are simply to get into the while $exitcode=2; # exit-code from last 'make' command $addedone=1; # 1 when something has been fixed, means we can try again while ( $exitcode != 0 && $addedone != 0 ) { $addedone = 0; %changes = (); open(INPUT,"makeobj -j10 -k 2>&1 |") || die "Couldn't run makeobj"; while() { if (/make.*Entering directory \`(.+)\'/) { $lastdir = $1; $lastdir =~ s/^$topdir\///; print STDERR "entering $lastdir\n"; next; } if (/^([^:]*):\d*: (.*)$/) { $file = $1; $line = $2; if ($file !~ m,^\/,) { $file = "$lastdir/$file"; } #print STDERR "file=$file\n"; } else { # This could be a continuation line if ( defined $line && $line ne "" ) { $line .= $_; #print STDERR "file still $file\n"; #print STDERR "line=$line\n"; } else { # Compilation line, or other unparsable line -> ignore print STDOUT $_; next; } } #print STDERR "Already having changes for $file\n" if defined($changes{$file}); next if defined($changes{$file}); print STDOUT $_; foreach $message (keys %messages) { if ($line =~ /$message/) { $changes{$file} = $messages{$message}; $addedone = fixFile($file, $messages{$message}); } } if (defined($changes{$file})) { $file=""; $line=""; } } # end of while() close(INPUT); $exitcode=($?>>8); } # end of main while sub fixFile { my( $file, $adding ) = @_; my $lastinclude = ""; # read file open ( FILE, "$file" ) || die "Can't read $file"; my $flines; my $cpplevel = 0; while () { $flines .= $_; if ($_ =~ m/^#if/ && $_ !~ m/^#ifn/) { $cpplevel = $cpplevel + 1; } if ($_ =~ m/^#endif/) { $cpplevel = $cpplevel - 1; } if ($cpplevel == 0 && $_ =~ m/^(#include\s*[\"<]q\S*\.h[\">]\S*)/) { $lastinclude = $1; } } close FILE; if (!$lastinclude) { print STDERR "ERROR: no include found in $file! (tried to add $adding.h)\n"; return 0; } if ($flines =~ m/#include\s*[\"<]$adding\.h[\">]\s*\n/) { print STDERR "ERROR: $adding.h already included in $file!\n"; return 0; } if ($flines =~ /(\n$lastinclude)/) { $flines =~ s/$lastinclude(.*\n)/$lastinclude$1#include <$adding.h>\n/; print STDERR "ADDED <$adding.h> after \"$lastinclude\" in $file\n"; } else { print STDERR "ERROR: can't find $lastinclude in $file\n"; return 0; } # write file rename($file, "$file.old"); open( FILE, ">$file" ) || die "Can't write to $file"; print FILE $flines; close FILE; return 1; }