The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
# $Id: Automake.pm,v 1.7 2013/03/04 21:31:49 pfeiffer Exp $

=head1 NAME

Mpp::Fixer::Automake - Fix Automake crap

=head1 DESCRIPTION

This module cleans out all the crap that automake puts into makefiles.
This is activated automatically whenever we detect a makefile that
was generated by automake.

=cut

package Mpp::Fixer::Automake;

#
# This subroutine removes all the automake junk, as best as we can, from a makefile.
# Arguments: the variable containing the makefile contents and the makefile object.
#
sub fix {
  Mpp::log LOAD_AUTOMAKE => $_[1]
    if $Mpp::log_level;
  for( $_[0] ) {
    my $lineno = 0;
    s/\n/++$lineno; "\05$lineno\n"/eg; # Append the line number to each line, so
				# we can preserve the line numbers when we
				# remake the final file.
    s/\\\05\d+\n//g;		# Get rid of all the trailing backslashes,
				# so we can grok things easier.

#
# Extract a list of the targets that are handled by recursive make, and
# fix them so they use Makepp's method instead.	 This converts a line like
# this:
#
#    RECURSIVE_TARGETS = info-recursive dvi-recursive ...
#
# into something like this:
#
#    info-recursive: $(SUBDIRS)/info info-am
#
#    dvi-recursive: $(SUBDIRS)/dvi dvi-am
#
#    ...
#
    if (/\nRECURSIVE_TARGETS\s*=(.*)\05/) {
      $_ .= join "\n\n", map {	  # Add the makepp version at the bottom.
	my $target = $_;
	$target =~ s/-recursive$//;
	"$_ : \$( \$(SUBDIRS))/$target $target-am";
      } split ' ', $1;

      s/\n\$\(RECURSIVE_TARGETS\):[\s\S]+?\n\05\d+\n/\n/;
				# Get rid of the action rule that we're
				# replacing.  Delete everything from the rule
				# start to the blank line afterwards.
    }

#
# Replace a simple recursive make invocation like this:
#   xyz : dependencies
#	 cd subdir && $(MAKE) targets
# with this:
#   xyz: dependencies subdir/targets
#
    s{\n([-\w]+)\s*: *([^\n]*)\05\d+\n\t(?:cd (.*?)\s*\&\&\s*)?\$\(MAKE\) (?:-C (\S+)\s+)?(?:\$\(AM_MAKEFLAGS\)\s+)?([-\s\w]+)$}{
      my $target = $1;
      my $deps = $2;
      my $subdir = $3 || $4;
      my $subdir_targets = $5;
      $subdir and		# Is there a subdirectory at all?
	$subdir_targets = join(" ", map { "$subdir/$_" } split(" ", $subdir_targets));
      "\n$target : $deps $subdir_targets\n";
    }e;

#
# Remove the dependency tracking junk since we have no use for it with makepp.
#
    s/\ndepcomp\s*=.*//;
    s/\n\tsource=.*?(\$\((?:LT)?CXXCOMPILE\))/\n\t$1/g;
				# Strip out the depcomp script invocation.
    s/\`test -f \'\$\<\' \|\| echo \'\$\(srcdir\)\/\'\`\$\</\$\</g;
				# Fix something that makepp won't be able to grok.
    s/\ninclude .*\.Po\05\d+\n/\n/g; # Don't include the dependency files.

#
# Make it so autoconf doesn't get invoked too often:
#
    s{\n
      ( (?:\$\(\w+\)/ )?
	(?: Makefile(?:\.in)? |	# These are the targets that are in the
	  config\.h(?:\.in)? |	# makefile to rerun automake and configure.
	  stamp-h1 |
	  config\.status |
	  configure(?:\.in)? |
	  \$\(ACLOCAL_M4\) ) ) \s* : ([^\n\05]*) }
     {\n$1 : $2 : build_check target_newer}xg;

#
# Now strip out the line numbers we put in, inserting enough newlines so
# the new line numbers are the same as the old line numbers.
#
    $lineno = 0;
    s{(?:\05(\d+))?\n}{
      $ret_str = "\n";
      ++$lineno;		# Update our line count.
      if (defined($1)) {	# Do we have a target line number?
	$ret_str .= "#\n" x ($1 - $lineno); # Add extra newlines so the line
				# numbers match.  Add comment lines instead
				# of blank lines so we don't prematurely
				# terminate a rule.
	$lineno = $1;
      }
      $ret_str;
    }eg;
  }
}

1;