#!/usr/bin/perl
# -*- perl -*-

#   Copyright (C) 2001-2022 Free Software Foundation, Inc.
#
# This file is part of the libiberty library.
# Libiberty is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# Libiberty is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with libiberty; see the file COPYING.LIB.  If not,
# write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# Originally written by DJ Delorie <dj@redhat.com>


# This is a trivial script which checks the lists of C and O files in
# the Makefile for consistency.

$mode = shift;
$srcdir = ".";

if ($mode eq "-s") {
    $srcdir = shift;
    $mode = shift;
}

&missing() if $mode eq "missing";
&undoc() if $mode eq "undoc";
&deps() if $mode eq "deps";

exit 0;

format STDOUT =
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~
$out
        ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
$out
.

######################################################################

sub missing {

    opendir(S, $srcdir);
    while ($f = readdir S) {
	$have{$f} = 1;
    }
    closedir(S);
    opendir(S, ".");
    while ($f = readdir S) {
	$have{$f} = 1;
    }
    closedir(S);

    for $a (@ARGV) {
	$listed{$a} = 1;
	$have{$a} = 0;
    }

    for $f (sort keys %have) {
	next unless $have{$f};
	if ($f =~ /\.c$/) {
	    print "S $f\n";
	}
    }
    for $f (sort keys %listed) {
	if ($f =~ /(.*)\.c$/) {
	    $base = $1;
	    if (! $listed{"./$base.o"}) {
		print "O $f\n";
	    }
	}
    }
}

######################################################################

sub undoc {

    opendir(S, $srcdir);
    while ($file = readdir S) {
	if ($file =~ /\.texi$/) {
	    open(T, "$srcdir/$file");
	    while (<T>) {
		if (/^\@deftype[^\(]* ([^\s\(]+) *\(/) {
		    $documented{$1} = 1;
		}
	    }
	    close(T);
	}
	if ($file =~ /\.c$/) {
	    open(C, "$srcdir/$file");
	    while (<C>) {
		if (/\@undocumented (\S+)/) {
		    $documented{$1} = 1;
		}
		if (/^static /) {
		    if (! /[\(;]/) {
			s/[\r\n]+$/ /;
			$_ .= <C>;
		    }
		    while ($_ =~ /\([^\)]*$/) {
			s/[\r\n]+$/ /;
			$_ .= <C>;
		    }
		}
		s/ VPARAMS([ \(])/$1/;
		s/PREFIX\(([^\)]*)\)/byte_$1/;
		if (/^static [^\(]* ([^\s\(]+) *\(.*\)$/) {
		    $documented{$1} = 1;
		}
	    }
	}
    }
    closedir(D);

    # $out = join(' ', sort keys %documented);
    # write;
    # print "\n";

    system "etags $srcdir/*.c $srcdir/../include/*.h";
    open(TAGS, "TAGS");
    while (<TAGS>) {
	s/[\r\n]+$//;
	if (/^\014$/) {
	    $filename = <TAGS>;
	    $filename =~ s/[\r\n]+$//;
	    $filename =~ s/,\d+$//;
	    $filename =~ s@.*[/\\]@@;
	    next;
	}
	if ($filename =~ /\.c$/ ) {
	    next unless /^[_a-zA-Z]/;
	} else {
	    next unless /^\# *define/;
	    s/\# *define *//;
	}

	s/ VPARAMS//;
	s/ *\177.*//;
	s/,$//;
	s/DEFUN\(//;
	s/\(//;

	next if /^static /;
	next if /\s/;
	next if /^_/;
	next if $documented{$_};
	next if /_H_?$/;

	if ($seen_in{$_} ne $filename) {
	    $saw{$_} ++;
	}
	$seen_in{$_} = $filename;
    }

    for $k (keys %saw) {
	delete $saw{$k} if $saw{$k} > 1;
    }

    for $k (sort keys %saw) {
	$fromfile{$seen_in{$k}} .= " " if $fromfile{$seen_in{$k}};
	$fromfile{$seen_in{$k}} .= $k;
    }

    for $f (sort keys %fromfile) {
	$out = "$f: $fromfile{$f}";
	write;
    }
}

######################################################################

sub deps_for {
    my($f) = @_;
    my(%d);
    open(F, $f);
    %d = ();
    while (<F>) {
	if (/^#\s*include\s+["<](.*)[">]/) {
	    $d{$1} = 1;
	}
    }
    close(F);
    return keys %d;
}

sub canonicalize {
    my ($p) = @_;
    0 while $p =~ s@/\./@/@g;
    0 while $p =~ s@^\./@@g;
    0 while $p =~ s@/[^/]+/\.\./@/@g;
    return $p;
}

sub locals_first {
    my ($a,$b) = @_;
    return -1 if $a eq "config.h";
    return  1 if $b eq "config.h";
    return $a cmp $b;
}

sub deps {

    $crule  = "\tif [ x\"\$(PICFLAG)\" != x ]; then \\\n";
    $crule .= "\t  \$(COMPILE.c) \$(PICFLAG) \$< -o pic/\$@; \\\n";
    $crule .= "\telse true; fi\n";
    $crule .= "\tif [ x\"\$(NOASANFLAG)\" != x ]; then \\\n";
    $crule .= "\t  \$(COMPILE.c) \$(PICFLAG) \$(NOASANFLAG) \$< -o noasan/\$@; \\\n";
    $crule .= "\telse true; fi\n";
    $crule .= "\t\$(COMPILE.c) \$< \$(OUTPUT_OPTION)\n";
    $crule .= "\n";

    $incdir = shift @ARGV;

    opendir(INC, $incdir);
    while ($f = readdir INC) {
	next unless $f =~ /\.h$/ || $f =~ /\.def$/;
	$mine{$f} = "\$(INCDIR)/$f";
	$deps{$f} = join(' ', &deps_for("$incdir/$f"));
    }
    $mine{'config.h'} = "config.h";

    opendir(INC, $srcdir);
    while ($f = readdir INC) {
	next unless $f =~ /\.h$/;
	$mine{$f} = "\$(srcdir)/$f";
	$deps{$f} = join(' ', &deps_for("$srcdir/$f"));
    }
    $mine{'config.h'} = "config.h";

    open(IN, "$srcdir/Makefile.in");
    open(OUT, ">$srcdir/Makefile.tmp");
    while (<IN>) {
	last if /remainder of this file/;
	print OUT;
    }
    print OUT "# The dependencies in the remainder of this file are automatically\n";
    print OUT "# generated by \"make maint-deps\".  Manual edits will be lost.\n\n";

    opendir(S, $srcdir);
    for $f (sort readdir S) {
	if ($f =~ /\.c$/) {

	    %scanned = ();
	    @pending = &deps_for("$srcdir/$f");
	    while (@pending) {
		@tmp = @pending;
		@pending = ();
		for $p (@tmp) {
		    next unless $mine{$p};
		    if (!$scanned{$p}) {
			push(@pending, split(' ', $deps{$p}));
			$scanned{$p} = 1;
		    }
		}
	    }
	    @deps = sort { &locals_first($a,$b) } keys %scanned;
	    $obj = $f;
	    $obj =~ s/\.c$/.\$(objext)/;
	    $obj = "./$obj:";
	    if ($#deps >= 0) {
		print OUT "$obj \$(srcdir)/$f";
		$len = length("$obj $f");
		for $dt (@deps) {
		    $d = $mine{$dt};
		    if ($len + length($d) > 70) {
			printf OUT " \\\n\t$d";
			$len = 8 + length($d);
		    } else {
			print OUT " $d";
			$len += length($d) + 1;
		    }
		}
		print OUT "\n";
	    } else {
		print OUT "$obj \$(srcdir)/$f\n";
	    }
	    $c = $crule;
	    $c =~ s@\$\<@\$\(srcdir\)\/$f@g;
	    print OUT $c;
	}
    }
    closedir(S);
    close(IN);
    close(OUT);

    rename("$srcdir/Makefile.tmp", "$srcdir/Makefile.in");
}
