This message introduces makesort.pl which is quite handy when you
change to much the layout of Makefiles, just like my previous patch
does: it becomes nearly impossible to just diff.
--
#! /usr/bin/perl -w
# -*- perl -*-
# @configure_input@
eval 'exec @PERL@ -S $0 ${1+"$@"}'
if 0;
require 5;
# String constants.
$IGNORE_PATTERN = "^##([^#].*)?\$";
# $WHITE_PATTERN = "^[ \t]*\$";
$COMMENT_PATTERN = "^#";
$TARGET_PATTERN="[\$a-zA-Z_.][-.a-zA-Z0-9_(){}/\$]*";
# An action starts with a tab not preceded by an escaped new lines,
# and runs to the end of the paragraph.
# $ACTION_PATTERN="(?!\\)\n\t.*\$";
# A rule has three parts: a list of targets, a list of dependencies,
# and optionally actions.
$RULE_PATTERN =
"^($TARGET_PATTERN(?:(?:\n|\\s)+$TARGET_PATTERN)*) *:([^=].*|)\$";
# $SUFFIX_RULE_PATTERN = "^\\.([a-zA-Z0-9]+)\\.([a-zA-Z0-9]+)\$";
# Only recognize leading spaces, not leading tabs. If we recognize
# leading tabs here then we need to make the reader smarter, because
# otherwise it will think rules like `foo=bar; \' are errors.
$MACRO_PATTERN = "^ *([A-Za-z0-9_]+)[ \t]*([:+]?)=[ \t]*(.*)\$";
local $verbose = 0;
my $diff = 0;
my @files = ();
foreach (@ARGV)
{
if ($_ eq '--diff' || $_ eq '-d')
{
$diff = "diff";
next;
}
elsif ($_ eq '--unidiff' || $_ eq '-u')
{
$diff = "diff -u";
next;
}
# Remove `.sort', it makes it easier to use shell history:
# ./makesort Makefile.in.old.sort Makefile.in.new.sort
# diff -u Makefile.in.old.sort Makefile.in.new.sort | less
s/\.sort$//;
push (@files, "$_.sort");
process_file ($_);
}
if ($diff)
{
system ("$diff @files | less\n");
}
sub process_file
{
my ($in) = @_;
my $out = "$in.sort";
local (*OUT);
local %variables = ();
local %dependencies = ();
local %actions = ();
local @scories = ();
open (OUT, "$out") || die "open $out: $!\n";
file_contents ($in);
print OUT "## Variables ##\n";
foreach (sort keys %variables)
{
print OUT pretty ("$_ =", "\t", split (' ' , $variables{$_}));
print OUT "\n";
}
print OUT "\n\n";
print OUT "## Rules ## \n";
foreach (sort target_cmp keys %dependencies)
{
print OUT pretty ("$_:", "\t", @{$dependencies{$_}});
print OUT $actions{$_}
if defined $actions{$_};
print OUT "\n";
}
print OUT "\n\n";
print OUT "## Scories ##\n";
foreach (sort @scories)
{
print OUT "$_\n";
print OUT "\n";
}
print OUT "\n\n";
close (OUT) || die "close $out: $!\n";
}
# target_cmp ($A, $B)
#
# Subroutine for handle_factored_dependencies to let `.PHONY' be last.
sub target_cmp
{
return
if $a eq $b;
return -1
if $b eq '.PHONY';
return 1
if $a eq '.PHONY';
return $a cmp $b;
}
# Pretty-print something. HEAD is what should be printed at the
# beginning of the first line, FILL is what should be printed at the
# beginning of every subsequent line.
sub pretty
{
my ($head, $fill, @values) = @_;
my ($column) = length ($head);
my ($result) = $head;
# Fill length is number of characters. However, each Tab
# character counts for eight. So we count the number of Tabs and
# multiply by 7.
my ($fill_length) = length ($fill);
$fill_length += 7 * ($fill =~ tr/\t/\t/d);
my ($bol) = ($head eq '');
foreach (@values)
{
# "75" because we also print a space, and diff add two chars.
if ($column + length ($_) 75)
{
$result .= " \\\n" . $fill;
$column = $fill_length;
$bol = 1;
}
$result .= ' ' unless ($bol);
$result .= $_;
$column += length ($_) + 1;
$bol = 0;
}
$result .= "\n";
return $result;
}
# $FLATTENED
# flatten ($STRING)
# --
# Flatten the $STRING and return the result.
sub flatten ($)
{
($_) = @_;
s/\\\n//somg;
s/\s+/ /g;
s/^ //;
s/ $//;
return $_;
}
sub verbose (@)
{
print STDERR "@_\n"
if $verbose;
}
# $CONTENTS
# file_contents ($FILENAME)
# --
# Return contents of a file from $am_dir, automatically skipping
# macros or rules which are already known. Runs command on each line
# as it is read; this command can modify $_.
sub file_contents
{
my ($file, $command) = @_;
open (FC_FILE, $file)
|| die "automake: installation error: cannot open \`$file'\n";
# Swallow into $CONTENTS the whole content of the file, after
# having performed the $COMMAND, and removed Automake comments.
my ($contents) = '';
while (FC_FILE)
{
# Merely delete comments beginning with two hashes.
next if /$IGNORE_PATTERN/o || /$COMMENT_PATTERN/o;
$contents .= $_;
}