#!/usr/bin/perl
#
#NAME
#  mfl - makefile list munger
#
#SYNOPSIS
#   mfl [$len]
#
#DESCRIPTION
#  This little program reformats a "makefile list".  That's one of the
#  common sort of makefile entries that consists of an initial chunk
#  in column 1, followed by a list of file names.  For example:
#
#  FOO= foo.c bar.c foo.h qux.h
#  foo.o: foo.c bar.c foo.h qux.h blorch.c kumquat.c loquat.c loquat.o local.h
#
#  What this program does:  It reads these lists of file  names,  and
#  coughs  them  up  formatted as make likes to see them.  The result
#  will be in alphabetical order, with a tab in col 1, as  many  file
#  names  as will fit into $len bytes, and a backslash on all but the
#  last line. Blank lines are ignored. If the first non-blank line is
#  indented,  its  first "word" will be proceeded by a blank line and
#  produced on a line by itself.  This can be used from vi to rewrite
#  a file list in a neater form.
#
#  When fed the above lines (without the initial "#  " chars), the
#  result of the vi command ".,+!mfl 40" is:
#  
#  FOO= \
#      bar.c foo.c foo.h qux.h 
#  
#  foo.o: \
#      bar.c blorch.c foo.c foo.h kumquat.c \
#      local.h loquat.c loquat.o qux.h 
#
#  This program was designed to be used mostly from inside  an  editor
#  like  vi that allows using external programs as edit commands.  The
#  default line length is 70 chars, for assorted reasons.   Note  that
#  the  resulting lines will generally be somewhat longer, because the
#  algorithm is to add names to the line until $len is passed.
#
#AUTHOR
#  John Chambers <jc@trillian.mit.edu>
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

$len = $ARGV[0] || 80;

# Read in the data and collect the file names.
for $line (<STDIN>) {
	$line =~ s/\s*\\+\s*/ /g;
	@line = split(/\s+/,$line);
	if ($line[0]) {
		&par() if ($name || %name);
		$name = shift(@line);
	}
	foreach $fld (@line) {
		next if !$fld;
		next if $fld eq "\\";
		$name{$fld} ++;
	}
}
&par() if ($name || %name);
exit 0;

sub par {
	$line = '';
	# If there was an initial name, produce it on a separate line.
	if ($name) {
		print "\n$name";
		print " \\\n" if %name;
	}
	# Run thru the file names and produce all but the last line.
	if (%name) {
		for $key (sort keys %name) {
			if (length($line) + length($key) > $len) {
				print "\t$line\\\n";
				$line = '';
			}
			$line .= "$key ";
		}
	# The above guarantees at least one file name on the last line.
	print "\t$line\n";
	}
	$name = '';
	%name = ();
}
