#!/usr/bin/perl
#
# mkdp [-opt]... foo.c ...
#
# This little program is a replacement for "makedepend", which has  given  me
# so  much  grief that I decided to roll my own.  The makedepend command uses
# heuristics that often fail.  It also evaluates all  "#if"  lines  to  true,
# resulting  in  many spurious expansions.  And as a final straw, it wants to
# open all its files simultaneously, thus failing with  a  "Too  many  files"
# message. This program gives results that are correct for the current system
# (assuming that cc has the "-M" option).
#
# The command line should contain a list of .c files.  We use the  fact  that
# "cc -M foo.c" in most systems will generate a list of the things that foo.o
# depends on.  It does so  by  actually  running  the  C  preprocessor  (with
# whatever  options are given in the -opt arg, or using $CFLAGS if -opt isn't
# given).  The output is the actual list of #includes.
#
# This program chews up the list, and discards any library files (whose names
# start  with '/').  Also, as a special kludge for using jc's debug stuff, we
# drop any references to dbg.h or any of its aliases.

$len = 80;		# Approx line length.
%ignore = (		# Header files to ignore.
	'abbr.h',1,
	'audit.h',1,
	'dbg.h',1,
	'extern.h',1,
	'return.h',1,
	'test.h',1,
	'verbose.h',1
);
if ($ARGV[0] =~ /^[-+](.*)/) {
	$opt = shift(ARGV);
} else {
	$opt = $ENV{"CFLAGS"};
}
for $f (@ARGV) {
	if (open(CC,"cc -M $f |")) {
		for $l (<CC>) {
			if ($l =~ /(.*): (.*)/) {
				$t = $1;
				$d = $2;
				if ($d =~ /^\//) {
#					print "Ignore	$t: $d\n";
				} else {
					$d =~ s/^\.\///;
					next if $ignore{$d};
					$d{$t} .= " $d";
				}
			}
			$d
		}
	} else {
		print STDERR "Can't exec \"cc -M $f |\" [$!]";
	}
}
for $t (sort keys %d) {
	@l = split(/\s+/,$d{$t});	# List of dependencies for t.
	%n = ();	# List of names for this target.
	for $x (@l) {		# Run thru the dependency list.
		next if !$x;	# Ignore the null one.
		$n{$x} ++;		# Build table of dependencies.
	}
	$l = '';			# One line of dependencies.
	print "\n$t: \\\n";	# Put the target on a separate line.
	for $k (sort keys %n) {
		if (length($l) + length($k) > $len) {
			print "\t$l\\\n";
			$l = '';	# Produce line, not including k.
		}
		$l .= "$k ";	# Append one dependency.
	}
	print "\t$l\n";
}
