home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl
-
- # Usage: inctree [options] [files]
-
- # Configuration parameters.
-
- $CPP = 'cc -E';
- # $CPP = "cc -P";
- # $CPP = "/lib/cpp";
-
- $shiftwidth = 4;
-
- # Process switches.
-
- while ($ARGV[0] =~ /^-/) {
- $_ = shift;
- if (/^-D(.*)/) {
- $defines .= " -D" . ($1 ? $1 : shift);
- }
- elsif (/^-I(.*)/) {
- $includes .= " -I" . ($1 ? $1 : shift);
- }
- elsif (/^-m(.*)/) {
- push(@pats, $1 ? $1 : shift);
- }
- elsif (/^-l/) {
- $lines++;
- }
- else {
- die "Unrecognized switch: $_\n";
- }
- }
-
- # Build a subroutine to scan for any specified patterns.
-
- if (@pats) {
- $sub = "sub pats {\n";
- foreach $pat (@pats) {
- $sub .= " print '>>>>>>> ',\$_ if m$pat;\n";
- }
- $sub .= "}\n";
- eval $sub;
- ++$pats;
- }
-
- # Now process each file on the command line.
-
- foreach $file (@ARGV) {
- open(CPP,"$CPP $defines $includes $file|")
- || die "Can't run cpp: $!\n";
- $line = 2;
-
- while (<CPP>) {
- ++$line;
- &pats if $pats; # Avoid expensive call if we can.
- next unless /^#/;
- next unless /^# \d/;
- ($junk,$newline,$filename) = split;
- $filename =~ s/"//g;
-
- # Now figure out if it's a push, a pop, or neither.
-
- if ($stack[$#stack] eq $filename) { # Same file.
- $line = $newline-1;
- next;
- }
-
- if ($stack[$#stack-1] eq $filename) { # Leaving file.
- $indent -= $shiftwidth;
- $line = pop(@lines)-1;
- pop(@stack);
- }
- else { # New file.
- printf "%6d ", $line-2 if $lines;
- push(@lines,$line);
- $line = $newline;
- print "\t" x ($indent / 8), ' ' x ($indent % 8),
- $filename;
- print " DUPLICATE" if $seen{$filename}++;
- print "\n";
- $indent += $shiftwidth;
- push(@stack,$filename);
- }
- }
- close CPP;
- $indent = 0;
- %seen = ();
- print "\n\n";
- $line = 0;
- }
-