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