#!/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 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # $len = $ARGV[0] || 80; # Read in the data and collect the file names. for $line () { $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 = (); }