Advertisement
Guest User

Untitled

a guest
Feb 28th, 2013
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 2.37 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use warnings;
  4. use strict;
  5.  
  6. use File::Find;
  7. use File::Spec;
  8. use Cwd;
  9.  
  10.  
  11. sub handle     ($);
  12. sub addInclude ($$);
  13. sub canonPath  ($);
  14. sub buildDeps  ($);
  15. sub addError   (@);
  16.  
  17.  
  18.  
  19. File::Find::find {
  20.     'follow_fast' => 1,
  21.     'dangling_symlinks' => 0,
  22.     'no_chdir' => 1,
  23.     'wanted' => sub {
  24.         return if -d;
  25.         return unless /\.[ch]pp$/;
  26.         handle $_;
  27.     }
  28. }, 'src';
  29.  
  30.  
  31. my %includes;
  32. my %errors;
  33. my $exitCode = 0;
  34.  
  35. for (sort keys %includes) {
  36.     if (m~^src/(.*)\.cpp$~) {
  37.         my @deps = buildDeps $_;
  38.         my %saw;
  39.         print "\$(OBJS_DIR)/$1.o: $_ ", join(' ', grep(!$saw{$_}++, @deps)), "\n";
  40.     }
  41. }
  42.  
  43. if (%errors) {
  44.     print STDERR "Cyclic inclusion(s) detected:\n", sort keys %errors;
  45.     $exitCode |= 2;
  46. }
  47. exit $exitCode;
  48.  
  49.  
  50.  
  51. sub handle ($) {
  52.     my $file = canonPath $_[0];
  53.     my $line;
  54.     open my $fh, '<', $file or die "$file: $!\n";
  55.     while (defined ($line = <$fh>)) {
  56.         if ($line =~ /^#\s*include\s*"([^"]*)"/) {
  57.             addInclude $file, $1;
  58.         }
  59.     }
  60.     close $fh;
  61. }
  62.  
  63. sub addInclude ($$) {
  64.     my ($file, $_include, $include) = @_;
  65.     my ($volume, $dir) = File::Spec->splitpath($file);
  66.     $dir     = File::Spec->catpath  ($volume, $dir, '');
  67.     $include = File::Spec->catfile  ($dir, $_include);
  68.     $include = canonPath $include;
  69.     $includes{$file}    = [ ] unless exists $includes{$file   };
  70.     $includes{$include} = [ ] unless exists $includes{$include};
  71.     push @{ $includes{$file} }, $include;
  72.  
  73.     if (! -f $include) {
  74.         print STDERR "$file:$.: includes nonexisting file '$_include'\n";
  75.         $exitCode |= 1;
  76.     }
  77. }
  78.  
  79. {
  80.     my $cwd = Cwd::getcwd;
  81.  
  82.     sub canonPath ($) {
  83.         File::Spec->abs2rel(Cwd::realpath($_[0]), $cwd);
  84.     }
  85. }
  86.  
  87. {
  88.     my %path;
  89.     my $path_depth = 0;
  90.  
  91.     sub buildDeps  ($) {
  92.         my $file = $_[0];
  93.  
  94.         if (exists $path{$file}) {
  95.             my %p = reverse %path;
  96.             addError @p{$path{$file} .. $path_depth};
  97.             return ( );
  98.         }
  99.  
  100.         $path{$file} = ++$path_depth;
  101.         my @ret  = ( );
  102.         for my $inc (@{ $includes{$file} }) {
  103.             push @ret, $inc, buildDeps $inc;
  104.         }
  105.         delete $path{$file};
  106.         --$path_depth;
  107.         @ret;
  108.     }
  109. }
  110.  
  111. sub addError (@) {
  112.     my $count = @_;
  113.     my $min   = $_[0];
  114.     my $pos   = 0;
  115.     my $error = '';
  116.  
  117.     for (my $i = 1; $i < $count; ++$i) {
  118.         if ($_[$i] lt $min) {
  119.             $min = $_[$i];
  120.             $pos = $i;
  121.         }
  122.     }
  123.  
  124.     for (my $i = 0; $i <= $count; ++$i) {
  125.         $error .= ' -> ' . $_[$pos];
  126.         $pos = ($pos + 1) % $count;
  127.     }
  128.  
  129.     $errors{substr($error, 4) . "\n"} = 1;
  130. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement