#!/usr/bin/perl -w

# A faster version than the bash thing...
# it shouldn't be to hard to do !!!

# See the makefile for how to call it

use IO::File;
use strict;
use vars qw($objdir);

my %hash = ();
my %processed = ();

my @incdir =
  qw(source source/mame source/68000 source/68020 source/z80 source/6502
     source/m68705 source/sound source/games source/video source/gui
    source/video/i386 source/sdl source/sdl/gui source/sdl/SDL_gfx 
    source/alleg source/debug source/debug/dz80);

sub myopen($) {
  my $name = shift;
  my $f = new IO::File;
  my $bak = $name;
  if ($name =~ /^$objdir/) { # passed an object
    my $objname = $name; # We want to return this when we get an object
    $objname =~ s/$objdir/\$\(OBJDIR\)/;
    $name =~ s/^$objdir\/(.+)\..+/source\/$1\.c/;
    if ($f->open($name)) {
      return ($f,$objname);
    } else {
      # This is the only case where we are not sure about extension...
      foreach (qw(s asm cpp)) {
	my $name2 = $name;
	$name2 =~ s/\.c/\.$_/;
	return ($f,$objname) if ($f->open($name2)); # Try asm .s
      }
    }
  }
#   $name =~ s/.+\/(.+)/$1/; # Without dir
  if ($f->open($name)) {
    return ($f,$name);
  } else {
    for (my $n=0; $n<=$#incdir; $n++) {
      my $name2 = $incdir[$n]."/$name";
      if ($f->open($name2)) {
        return ($f,$name2);
      }
    }
  }
  return undef;
}

sub process_file {
  my $fich0 = shift;
  my $f;
  my $fich = $fich0;
  my %newfiles = ();
  my $fich2;
  return "source/games/driver.c" if ($fich eq "driver.c");

  ($f,$fich) = myopen("$fich");
  if (!$f) {
    print STDERR "File not found : $fich0\n";
    return "";
  }

  return $fich if ($hash{$fich}); # Already done ?
  if ($processed{$fich}) { # means that we loop in recursion !
    return $fich;
  } else {
    $processed{$fich} = 1;
  }
  while (<$f>) {
    if (/^\#include[ \t]*\"(.+?)\"/) {
      my $res = $1;
      my $newincs = process_file($res);
#      $newincs = $res if (!$newincs); # as a minimum...
      $newfiles{$newincs} = 1; # No recursion, just add 1st level...
    }
  }
  $f->close();
  $hash{$fich} = join(" ",keys %newfiles);
  return $fich;
}

$objdir = shift;
$objdir =~ s/\//\\\//g; # Quote slashes

while ((my $name = shift)) {
  process_file($name);
}

my $name;

# Pre-process include files...
# We are forced to do it because clearly make does not make recursion...

print "# Included files\n\n";

foreach $name (sort { $b cmp $a } keys %hash) {
  if ($name =~ /^source/) { # This file is included -> change it !
    my ($name2) = ($name =~ /.+\/(.+)/); # Only filename
    $name2 =~ s/\./_/g;
    my $namer = $name; # Suitable form for replace
    $namer =~ s/\//\\\//g;
    foreach my $key (keys %hash) { # Replace in the hash with our new name
      while ($hash{$key} =~ s/$namer/\$\($name2\)/g) {};
    }
    print "$name2 = $name $hash{$name}\n";
    delete $hash{$name};
  }
}

print "\n# Object files\n\n";

foreach $name (sort { $b cmp $a } keys %hash) {
  if (!($hash{$name} =~ /^ *$/)) {
    print "$name: ",$hash{$name},"\n";
  }
}
