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