#!/usr/bin/perl

# This program is like "makedepend", except that it uses gcc/g++ to
# generate the dependencies. The benefit is C++ support, which
# makedepend doesn't have.
#
# Author: Dave Coppit (http://www.coppit.org/)
#

my $VERSION = 0.10;

use strict;
use Getopt::Std;

die "usage: $0 [-a] -- <complete g++ compile line with -M flag>\n"
  unless @ARGV;

my %opts = Get_Options();

# Get dependencies. Slam all the arguments together as one big command
# line to the compiler.
my $dependencies = `@ARGV`;

my $makefile_name = Get_Makefile_Name();

Back_Up_Makefile($makefile_name);

my $makefile_text = Get_Makefile_Text($makefile_name);

$makefile_text = Remove_Old_Dependencies($makefile_text)
  unless $opts{'a'};

$makefile_text = Add_Dependencies($makefile_text, $dependencies);

Write_Makefile_Text($makefile_name, $makefile_text);

exit;

sub Get_Options
{
  my %opts;

  $opts{'a'} = 0;

  getopt('',\%opts);

  return %opts;
}

sub Get_Makefile_Name
{
  my $makefile_name =
    -e 'makefile' ? 'makefile' : -e 'Makefile' ? 'Makefile' : undef;

  die "Couldn't find makefile!" unless defined $makefile_name;

  return $makefile_name
}

sub Back_Up_Makefile
{
  my $makefile_name = shift;

  unlink "$makefile_name.bak"
    or die "Couldn't remove $makefile_name.bak: $!\n";

  system("cp $makefile_name $makefile_name.bak") == 0
    or die "Couldn't copy $makefile_name to $makefile_name.bak: $!\n";
}

sub Get_Makefile_Text
{
  my $makefile_name = shift;

  open MAKEFILE, "$makefile_name"
    or die "Couldn't open $makefile_name: $!\n";
  local $/ = undef;
  my $makefile_text = <MAKEFILE>;
  close MAKEFILE;

  return $makefile_text;
}

sub Remove_Old_Dependencies
{
  my $makefile_text = shift;

  $makefile_text =~ s/\n# DO NOT DELETE\s*\n.*$/\n/s;

  return $makefile_text;
}

sub Add_Dependencies
{
  my $makefile_text = shift;
  my $dependencies = shift;

  $makefile_text .= "\n# DO NOT DELETE\n" unless $opts{'a'};
  $makefile_text .= "\n$dependencies";

  return $makefile_text;
}

sub Write_Makefile_Text
{
  my $makefile_name = shift;
  my $makefile_text = shift;

  open MAKEFILE, ">$makefile_name"
    or die "Couldn't open $makefile_name for writing: $!\n";
  print MAKEFILE $makefile_text;
  close MAKEFILE;
}

