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 14use strict; 15 16sub usage { 17 print "Usage: checkincludes.pl [-r]\n"; 18 print "By default we just warn of duplicates\n"; 19 print "To remove duplicated includes in place use -r\n"; 20 exit 1; 21} 22 23my $remove = 0; 24 25if ($#ARGV < 0) { 26 usage(); 27} 28 29if ($#ARGV >= 1) { 30 if ($ARGV[0] =~ /^-/) { 31 if ($ARGV[0] eq "-r") { 32 $remove = 1; 33 shift; 34 } else { 35 usage(); 36 } 37 } 38} 39 40foreach my $file (@ARGV) { 41 open(my $f, '<', $file) 42 or die "Cannot open $file: $!.\n"; 43 44 my %includedfiles = (); 45 my @file_lines = (); 46 47 while (<$f>) { 48 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { 49 ++$includedfiles{$1}; 50 } 51 push(@file_lines, $_); 52 } 53 54 close($f); 55 56 if (!$remove) { 57 foreach my $filename (keys %includedfiles) { 58 if ($includedfiles{$filename} > 1) { 59 print "$file: $filename is included more than once.\n"; 60 } 61 } 62 next; 63 } 64 65 open($f, '>', $file) 66 or die("Cannot write to $file: $!"); 67 68 my $dups = 0; 69 foreach (@file_lines) { 70 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { 71 foreach my $filename (keys %includedfiles) { 72 if ($1 eq $filename) { 73 if ($includedfiles{$filename} > 1) { 74 $includedfiles{$filename}--; 75 $dups++; 76 } else { 77 print {$f} $_; 78 } 79 } 80 } 81 } else { 82 print {$f} $_; 83 } 84 } 85 if ($dups > 0) { 86 print "$file: removed $dups duplicate includes\n"; 87 } 88 close($f); 89} 90