[alt.sources] makedepend in Perl

chip@tct.uucp (Chip Salzenberg) (03/19/91)

Here's our makedepend.  It understands C and C++ as well as Informix
ESQL/C source files.  It also allows you to omit header files from
/usr/include to speed subsequent compilations.

Tricks to be gleaned:
   * The one-liner that sets $ME from $0.
   * The BYPATH sorting subroutine.
   * Delay of output (&DEP and &DEPDONE), in case of interruption.

Shar and enjoy.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  makedeps
# Wrapped by chip@count on Tue Mar 19 08:18:11 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'makedeps' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makedeps'\"
else
echo shar: Extracting \"'makedeps'\" \(3205 characters\)
sed "s/^X//" >'makedeps' <<'END_OF_FILE'
Xeval 'exec /bin/perl -wS $0 ${1+"$@"}'
X	if 0;
X
X# $Id: makedeps,v 1.6 1991/03/08 22:27:10 chip Exp $
X#
X# Make a list of dependencies for the given file(s).
X#
X# $Log: makedeps,v $
X# Revision 1.6  1991/03/08  22:27:10  chip
X# Add "-o" and "-u" options.
X#
X# Revision 1.5  1990/11/29  13:39:37  chip
X# Fix typo.
X#
X# Revision 1.4  90/09/28  11:01:51  chip
X# Handle C++.
X# 
X# Revision 1.3  90/05/03  16:49:30  chip
X# checked in with -k by chip at 90.08.17.15.17.16.
X# 
X# Revision 1.3  90/05/03  16:49:30  chip
X# Remove temp files each time around the loop.
X# Never mention temp files in output.
X# 
X# Revision 1.2  90/05/02  16:43:07  chip
X# Oops.  Write deps for the object file.
X# 
X# Revision 1.1  90/05/02  16:24:39  chip
X# Initial revision
X# 
X
X($ME = $0) =~ s#^.*/##;
X
X################################################################
X## Configuration.
X################################################################
X
X$INF = "/usr/informix" unless $INF = $ENV{'INFORMIXDIR'};
Xchop($HOME = `pwd`) unless $HOME = $ENV{'HOME'};
X
X@COPY = ("cp");
X@CPP = ("cc", "-E");
X@CPLUSPP = ("g++", "-E");
X@ESQLC = ("$INF/lib/esqlc", "-e");
X
X$T = "dep_$$";
X
X################################################################
X## Options.
X################################################################
X
Xundef $OPT_OUTPUT;
X$OPT_USER = 0;
X@CPPOPTS = ();
Xwhile (@ARGV) {
X	$_ = $ARGV[0];
X	last unless /^-/;
X	if (/^-o(.*)$/) {
X		shift;
X		die "$ME: -o needs argument"
X		    unless defined($OPT_OUTPUT = length($1) ? $1 : shift);
X	}
X	elsif (/^-u$/) {
X		shift;
X		$OPT_USER = 1;
X	}
X	else {
X		push(@CPPOPTS, shift);
X	}
X}
X
X# Avoid warnings
X@CPP, @CPLUSPP;
X
X&DEP("## These dependences were generated by the \"$ME\" program.\n");
X&DEP("## Any changes made by hand will be lost!\n");
X
Xforeach $file (@ARGV) {
X	unless (-f $file) {
X		print STDERR "$ME: $file: no such file\n";
X		next;
X	}
X
X	if (($basename) = ($file =~ /^(\S+)\.c$/)) {
X		open(CPP, "@CPP @CPPOPTS $file |");
X	}
X	elsif (($basename) = ($file =~ /^(\S+)\.(C|cc|cxx|cpp)$/)) {
X		open(CPP, "@CPLUSPP @CPPOPTS $file |");
X	}
X	elsif (($basename) = ($file =~ /^(\S+)\.ec$/)) {
X		if (system(@COPY, $file, "$T.ec")
X		 || system(@ESQLC, "$T.ec")) {
X			print STDERR "$ME: can't compile $file\n";
X			next;
X		}
X		open(CPP, "@CPP @CPPOPTS $T.c |");
X	}
X	else {
X		print STDERR "$ME: $file: not C, C++ or ESQL/C\n";
X		next;
X	}
X
X	undef %D;
X	while (<CPP>) {
X		next unless @F = /^#\s*(line\s*)?(\d+)\s+"(.+)"/;
X		$i = @F[2];
X
X		# Perform transformations on include filename here.
X		$i =~ s#//*#/#g;
X		$i =~ s#^\./##;
X
X		$D{$i} = 1 unless grep($i eq $_, $file, "$T.c", "$T.ec");
X	}
X	close(CPP);
X
X	&DEP("\n");
X	&DEP("# $file\n");
X	foreach (sort BYPATH keys(%D)) {
X		next if $OPT_USER && m#^/usr/include/#;
X		&DEP("$basename.o: $_\n");
X	}
X
X	unlink("$T.ec", "$T.c");
X}
X
X&DEPDONE;
Xexit(0);
X
Xsub BYPATH {
X	$_ = 0;
X	--$_ if $a =~ m#^/#;
X	++$_ if $b =~ m#^/#;
X	return $_ if $_;
X	return -1 if $a lt $b;
X	return 1 if $a gt $b;
X	return 0;
X}
X
Xsub DEP {
X	$DEP = "" unless defined($DEP);
X	for $x (@_) { $DEP .= $x; }
X}
X
Xsub DEPDONE {
X	if (defined($OPT_OUTPUT)) {
X		die "$ME: can't create $OUT: $!\n"
X		    unless open(OUT, "> $OPT_OUTPUT");
X		print OUT $DEP;
X		close(OUT);
X	}
X	else {
X		print $DEP;
X	}
X	$DEP = "";
X}
END_OF_FILE
if test 3205 -ne `wc -c <'makedeps'`; then
    echo shar: \"'makedeps'\" unpacked with wrong size!
fi
chmod +x 'makedeps'
# end of 'makedeps'
fi
echo shar: End of shell archive.
exit 0
-- 
Chip Salzenberg at Teltronics/TCT     <chip@tct.uucp>, <uunet!pdn!tct!chip>
 "Most of my code is written by myself.  That is why so little gets done."
                 -- Herman "HLLs will never fly" Rubin