1#!/usr/bin/perl 2# 3# checkincludes: find/remove files included more than once 4# 5# Copyright abandoned, 2000, Niels Kristian Bech Jensen <nkbj@image.dk>. 6# Copyright 2009 Luis R. Rodriguez <mcgrof@gmail.com> 7# 8# This script checks for duplicate includes. It also has support 9# to remove them in place. Note that this will not take into 10# consideration macros so you should run this only if you know 11# you do have real dups and do not have them under #ifdef's. You 12# could also just review the results. 13 14sub usage { 15 print "Usage: checkincludes.pl [-r]\n"; 16 print "By default we just warn of duplicates\n"; 17 print "To remove duplicated includes in place use -r\n"; 18 exit 1; 19} 20 21my $remove = 0; 22 23if ($#ARGV < 0) { 24 usage(); 25} 26 27if ($#ARGV >= 1) { 28 if ($ARGV[0] =~ /^-/) { 29 if ($ARGV[0] eq "-r") { 30 $remove = 1; 31 shift; 32 } else { 33 usage(); 34 } 35 } 36} 37 38foreach $file (@ARGV) { 39 open(FILE, $file) or die "Cannot open $file: $!.\n"; 40 41 my %includedfiles = (); 42 my @file_lines = (); 43 44 while (<FILE>) { 45 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { 46 ++$includedfiles{$1}; 47 } 48 push(@file_lines, $_); 49 } 50 51 close(FILE); 52 53 if (!$remove) { 54 foreach $filename (keys %includedfiles) { 55 if ($includedfiles{$filename} > 1) { 56 print "$file: $filename is included more than once.\n"; 57 } 58 } 59 next; 60 } 61 62 open(FILE,">$file") || die("Cannot write to $file: $!"); 63 64 my $dups = 0; 65 foreach (@file_lines) { 66 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { 67 foreach $filename (keys %includedfiles) { 68 if ($1 eq $filename) { 69 if ($includedfiles{$filename} > 1) { 70 $includedfiles{$filename}--; 71 $dups++; 72 } else { 73 print FILE $_; 74 } 75 } 76 } 77 } else { 78 print FILE $_; 79 } 80 } 81 if ($dups > 0) { 82 print "$file: removed $dups duplicate includes\n"; 83 } 84 close(FILE); 85} 86