summaryrefslogtreecommitdiff
path: root/scripts/fixincludes
Side-by-side diff
Diffstat (limited to 'scripts/fixincludes') (more/less context) (ignore whitespace changes)
-rwxr-xr-xscripts/fixincludes61
1 files changed, 3 insertions, 58 deletions
diff --git a/scripts/fixincludes b/scripts/fixincludes
index da8613c..f07965e 100755
--- a/scripts/fixincludes
+++ b/scripts/fixincludes
@@ -1,368 +1,313 @@
#!/usr/bin/perl -w
# tries to reduce the number of includes in KDE source files
# (c) 2001 Dirk Mueller <mueller@kde.org>
use File::Basename;
use Cwd;
# declaration of useful subroutines
sub find_fixable_sources ($);
sub find_fixable_headers($);
sub find_removable_includes ($);
sub warn_before_modifying ($);
sub remove_include ($$$);
sub replace_include ($$$);
sub fix_duplicates($);
sub fix_compat_includes($);
sub fix_unnecessary($);
sub copy_file($$);
sub process_source_file($);
# some global variables
-$verbose = 0; # turns on debugging
-$modify = 0; # if 1 it should try to fix the files as well
-$experimental = 0; # try&error if an include is obsolete (slow!!)
+$verbose = 1; # turns on debugging
+$modify = 1; # if 1 it should try to fix the files as well
+$experimental = 1; # try&error if an include is obsolete (slow!!)
@explicitfiles = (); # filled in if passing files on the command line
# statistic variables
$exp_success = 0;
$exp_failure = 0;
while (defined ($ARGV[0]))
{
$_ = shift;
if (/^--help$|^-h$/) {
print "Usage: fixincludes [--verbose | -v] [--experimental | -e ] [--modify | -m ]\n";
exit 0;
}
elsif (/^--verbose$|^-v$/) {
$verbose = 1; # Oh is there a problem...?
}
elsif (/^--modify$|^-m$/) {
$modify = 1;
}
elsif (/^--experimental$|^-e$/) {
$modify = 1;
$experimental = 1;
}
elsif (!/^-/) {
push @explicitfiles, $_;
}
}
$cppExt = "(cpp|cc|cxx|C|c\\+\\+)";
$hExt = "(h|H|hh|hxx|hpp|h\\+\\+)";
# list of compat headers. scroll down ... much of boring stuff here..
%compatmap = (
- 'qapp.h' => "qapplication.h",
- #'qarray.h' => "qmemarray.h",
- #'qbitarry.h' => "qbitarray.h",
- 'qbttngrp.h' => "qbuttongroup.h",
- #'qchkbox.h' => "qcheckbox.h",
- 'qclipbrd.h' => "qclipboard.h",
- #'qcollect.h' => "qptrcollection.h",
- #'qcollection.h' => "qptrcollection.h",
- 'qcombo.h' => "qcombobox.h",
- 'qconnect.h' => "qconnection.h",
- 'qdatetm.h' => "qdatetime.h",
- 'qdrawutl.h' => "qdrawutil.h",
- 'qdstream.h' => "qdatastream.h",
- #'qfiledef.h' => "private/qfiledefs_p.h",
- 'qfiledlg.h' => "qfiledialog.h",
- 'qfileinf.h' => "qfileinfo.h",
- 'qfontdta.h' => "qfontdata.h",
- 'qfontinf.h' => "qfontinfo.h",
- 'qfontmet.h' => "qfontmetrics.h",
- 'qgrpbox.h' => "qgroupbox.h",
- 'qintcach.h' => "qintcache.h",
- 'qiodev.h' => "qiodevice.h",
- 'qlcdnum.h' => "qlcdnumber.h",
- 'qlined.h' => "qlineedit.h",
- #'qlist.h' => "qptrlist.h",
- 'qmenudta.h' => "qmenudata.h",
- 'qmetaobj.h' => "qmetaobject.h",
- 'qmlined.h' => "qtmultilineedit.h",
- 'qmsgbox.h' => "qmessagebox.h",
- 'qmultilinedit.h' => "qmultilineedit.h",
- 'qobjcoll.h' => "qobjectlist.h>\n\#include <qobjectdict.h",
- 'qobjdefs.h' => "qobjectdefs.h",
- 'qpaintd.h' => "qpaintdevice.h",
- 'qpaintdc.h' => "qpaintdevicedefs.h",
- 'qpdevmet.h' => "qpaintdevicemetrics.h",
- 'qpmcache.h' => "qpixmapcache.h",
- 'qpntarry.h' => "qpointarray.h",
- 'qpopmenu.h' => "qpopupmenu.h",
- 'qprndlg.h' => "qprintdialog.h",
- 'qprogbar.h' => "qprogressbar.h",
- 'qprogdlg.h' => "qprogressdialog.h",
- 'qpsprn.h' => "<private/qpsprinter_p.h>",
- 'qpushbt.h' => "qpushbutton.h",
- 'qqueue.h' => "qptrqueue.h",
- 'qradiobt.h' => "qradiobutton.h",
- 'qrangect.h' => "qrangecontrol.h",
- 'qscrbar.h' => "qscrollbar.h",
- 'qsocknot.h' => "qsocketnotifier.h",
-# 'qstack.h' => "qptrstack.h",
- 'qtabdlg.h' => "qtabdialog.h",
- 'qtstream.h' => "qtextstream.h",
-# 'qvector.h' => "qptrvector.h",
- 'qwidcoll.h' => "qwidgetlist.h\n\#include <qwidgetintdict.h",
- 'qwindefs.h' => "qwindowdefs.h",
-
# and now the KDE specific compat includes
# 'kapp.h' => "kapplication.h",
# 'kstddirs.h' => "kstandarddirs.h",
# 'kuniqueapp.h' => "kuniqueapplication.h",
# 'ktmainwindow.h'=> "kmainwindow.h",
# 'kcolorbtn.h' => "kcolorbutton.h",
# 'kcolordlg.h' => "kcolordialog.h",
# 'kxmlgui.h' => "kxmlguifactory.h",
);
# now it starts to get interesting again
# Look for source files in the given directory ($dir, first parameter)
sub find_fixable_sources ($)
{
# for now I grep the directory (requires srcdir==builddir)
# actually it should read the Makefile and
# find the _SOURCES / _OBJECTS tags that are put there by
# automake and am_edit, but thats an excercise to the reader ;-)
my ( $dir ) = @_;
opendir (DIR, "$dir") || die "Couldn't read '$dir'\n";
my @sources = grep { /^.*\.$cppExt$/o } readdir(DIR);
closedir(DIR);
print "found sources: [ " . join(' ', @sources) . " ] in $dir\n" if ($verbose);
# prefix them with $dir
my @retsources = ();
foreach $source(@sources) {
push @retsources, "$dir/$source";
}
return @retsources;
}
# Look for header files in the given directory ($dir, first parameter)
sub find_fixable_headers ($)
{
# for now I grep the directory (requires srcdir==builddir)
# actually it should read the Makefile and
# find the _HEADERS tags that are put there by
# automake and am_edit, but thats an excercise to the reader ;-)
my ( $dir ) = @_;
opendir (DIR, "$dir") || die "Couldn't read '$dir'\n";
my @headers = grep { /^.*\.$hExt$/o } readdir(DIR);
closedir(DIR);
print "found headers: [ " . join(' ', @headers) . " ] in $dir\n" if ($verbose);
# prefix them with $dir
my @retheaders = ();
foreach $source(@headers) {
push @retheaders, "$dir/$source";
}
return @retheaders;
}
sub find_removable_includes ($)
{
my $srcfile = shift @_;
open(SRC, "< $srcfile") || die "find_removable_includes: couldn't open '$srcfile'\n";
my @includes = ();
# we skip all includes that are somehow ifdefed
my $cpplevel = 0;
$cpplevel = -1 if ($srcfile=~m/^.*\.$hExt$/); # plan for header-protection #ifndef/#define/#endif
while (<SRC>) {
if ($_ =~ m/^\#if/) {
$cpplevel = $cpplevel + 1;
next;
}
if ($_ =~ m/^\#endif/) {
$cpplevel = $cpplevel - 1;
next;
}
#if ($cpplevel == 0 && $_ =~ m/^\#include\s*[\"<]([qk]\S*\.h)[\">]\S*/) {
if ($cpplevel == 0 && (($_ =~ m/^\#include\s*\"(\S+\.h)\"\S*/) || ($_ =~ m/^\#include\s*\<([qk]\S+.h)\>\S*/))) {
push @includes, $1;
next;
}
}
close SRC;
print "No fixable includes found in $srcfile\n" if ($verbose and not @includes);
print "found includes: [ " . join(' ', @includes) . " ]\n" if ($verbose and @includes);
return @includes;
}
# first parameter: srcfile
# second parameter: include to remove
# third parameter is the duplicate level: this include is removed $level times
sub remove_include ($$$)
{
my $srcfile = shift @_;
my $include = quotemeta(shift @_);
my $level = shift @_;
die "$srcfile is not read/writeable!\n" if( ! -r $srcfile || ! -w $srcfile);
open(I, "< $srcfile") or die "remove_include: couldn't open '$srcfile'\n";
my @contents = <I>;
close(I);
# ok, CPU time doesn't count so we do it the lazy way
# we should remove the last occurence of the include in the
# file because in case its a duplicate removing the first
# one could make a difference.
my @revcontents = reverse @contents;
@contents = ();
# we skip all inludes that are somehow ifdefed
# note the logic is reversed because it operates
# on reversed lines :)
my $cpplevel = 0;
$cpplevel = -1 if ($srcfile=~m/^.*\.$hExt$/); # plan for header-protection #ifndef/#define/#endif
foreach $line (@revcontents) {
if ($line =~ m/^\#if/) {
$cpplevel = $cpplevel - 1;
push @contents, $line;
next;
}
if ($line =~ m/^\#endif/) {
$cpplevel = $cpplevel + 1;
push @contents, $line;
next;
}
#if ($cpplevel == 0 && $level > 0 && $line =~ m/^\#include\s*[\"<]$include[\">]\S*$/) {
if ($cpplevel == 0 && (($line =~ m/^\#include\s*\"$include\"\S*/) || ($line =~ m/^\#include\s*\<$include\>\S*/))) {
$level = $level - 1;
# skipping the line..
next;
}
push @contents, $line;
}
# now we have the fixed contents in @contents, although in wrong order
open(O, "> $srcfile") || die "remove_include: couldn't open '$srcfile' for writing\n";
print O reverse @contents;
close (O);
}
# first parameter: srcfile
# second parameter: include to replace
# third parameter the include file to replace it with
sub replace_include ($$$)
{
my $srcfile = shift @_;
my $include = quotemeta(shift @_);
my $destinclude = shift @_;
die "$srcfile is not read/writeable!\n" if( ! -r $srcfile || ! -w $srcfile);
open(I, "< $srcfile") or die "replace_include: couldn't open '$srcfile'\n";
my @contents = <I>;
close(I);
# ok, CPU time doesn't count so we do it the lazy way
my @revcontents = reverse @contents;
@contents = ();
# we skip all inludes that are somehow ifdefed
# note the logic is reversed because it operates
# on reversed lines :)
my $cpplevel = 0;
$cpplevel = -1 if ($srcfile=~m/^.*\.$hExt$/); # plan for header-protection #ifndef/#define/#endif
foreach $line (@revcontents) {
if ($line =~ m/^\#if/) {
$cpplevel = $cpplevel - 1;
push @contents, $line;
next;
}
if ($line =~ m/^\#endif/) {
$cpplevel = $cpplevel + 1;
push @contents, $line;
next;
}
#if ($cpplevel == 0 && $line =~ m/^\#include\s*[\"<]$include[\">]\S*/) {
if ($cpplevel == 0 && (($line =~ m/^\#include\s*\"$include\"\S*/) || ($line =~ m/^\#include\s*\<$include\>\S*/))) {
print "HAH! found $include to replace in $srcfile!\n" if($verbose);
$line =~ s/(\#include\s*[\"<])$include([\">]\S*)/$1$destinclude$2/;
}
push @contents, $line;
}
# now we have the fixed contents in @contents
open(O, "> $srcfile") || die "replace_include: couldn't open '$srcfile' for writing\n";
print O reverse @contents;
close (O);
}
sub fix_duplicates($)
{
my $srcfile = shift @_;
my @includes = &find_removable_includes($srcfile);
my %inclMap = ();
# initialize
foreach $include (@includes) {
$inclMap{$include} = 0;
}
# count number of occurences
foreach $include (@includes) {
$inclMap{$include} = $inclMap{$include} + 1;
}
# check for duplicates
foreach $include (keys %inclMap) {
next if $inclMap{$include} <= 1;
print "$srcfile: duplicate level ". $inclMap{$include} .": ". $include ."\n";
&remove_include($srcfile, $include, $inclMap{$include} - 1) if($modify);
}
}
sub fix_compat_includes($)
{
my $srcfile = shift @_;
my @includes = &find_removable_includes($srcfile);
my %inclMap = ();
# initialize
foreach $include (@includes) {
$inclMap{$include} = 0;
}
# count number of occurences
foreach $include (@includes) {
$inclMap{$include} = $inclMap{$include} + 1;
}
# check for compat headers
foreach $include (keys %inclMap) {
if( defined $compatmap{$include}) {
print "$srcfile: compat header: $include, to be replaced by ". $compatmap{$include} ."\n";
&replace_include($srcfile, $include, $compatmap{$include}) if($modify);
}
}