#!/home/ben/software/install/bin/perl use warnings; use strict; use Carp; use C::Tokenize '0.18', '$include'; use File::Temp 'tempfile'; use IPC::Run3; use Cwd; use File::Slurper qw!read_text write_text!; sub minimize_headers { my ($file, %options) = @_; my $verbose = $options{verbose}; if ($file !~ /\.c$/) { croak "'$file' doesn't look like a C file"; } my $ofile = $file; $ofile =~ s/\.c$/\.o/; my $dir = getcwd (); if ($ofile =~ m!^(.*)/([^/]+)$!) { $dir = $1; $ofile = $2; } my $make = $options{make}; if (! $make) { $make = 'make'; } if (-f $ofile) { unlink $ofile or die "unlink $ofile failed: $!"; } my $command = "$make -C $dir $ofile"; my $status = run3 ($command, undef, \my $output, \my $errors); if (-f $ofile) { unlink $ofile or die "unlink $ofile failed: $!"; } if ($errors) { warn "$command failed, fix that and run again"; return; } my (undef, $tempfile) = tempfile ("$file.XXXXX"); if (! rename $file, $tempfile) { croak "Could not rename $file to $tempfile: $!"; } my $ctext = read_text ($tempfile); my @includes; while ($ctext =~ /$include/g) { my $include = $1; chomp ($include); push @includes, $include; } if (-f $file) { unlink ($file) or die "Could not remove $file: $!"; } my %uniques; for my $include (@includes) { if ($include !~ /#include\s*[<"](.*)[>"]/) { warn "Strange include '$include'"; } else { my $ifile = $1; if ($uniques{$ifile}) { warn "File '$ifile' seems to be included more than once.\n"; } else { $uniques{$ifile} = 1; } } } for my $include (@includes) { my $newtext = $ctext; $newtext =~ s!\Q$include!// C:MinimizeHeaders removed this: $include!g; write_text ($file, $newtext); run3 ("$make -C $dir $ofile", undef, \my $output, \my $errors); if (! $errors) { print "$file: '$include' may be unnecessary since it compiles without this.\n"; } else { if ($verbose) { print "$file: '$include' seems to be necessary.\n"; print "The make errors were as follows:\n$errors"; } } if (! unlink ($file)) { croak "Could not remove $file: $!"; } if (-f $ofile) { unlink $ofile or die "unlink $ofile failed: $!"; } } if (! rename $tempfile, $file) { croak "Could not rename $tempfile to $file: $!"; } return; } for my $file (@ARGV) { eval { minimize_headers ($file); }; if ($@) { print "Minimize failed for '$file': $@"; } } exit; # Local variables: # mode: perl # End: