#! /usr/bin/perl -w

# This script looks all installed man page, and report some stats about them
#  (usefull only to guide reflexions to po-man implementation)

use strict;

use File::Find ();

# for the convenience of &wanted calls, including -eval statements:
#use vars qw/*name *dir *prune/;
#*name   = *File::Find::name;
#*dir    = *File::Find::dir;
#*prune  = *File::Find::prune;

my %page;
$page{'pod'}{'desc'} = "generated by Pod::Man";
$page{'help2man'}{'desc'} = "generated by help2man";
$page{'docbook-to-man'}{'desc'} = "generated by docbook-to-man";
$page{'docbook2man'}{'desc'} = "generated by docbook2man";
$page{'latex2man'}{'desc'} = "generated by latex2man";
$page{'db2man.xsl'}{'desc'} = "generated by db2man.xsl";
$page{'mtex2man'}{'desc'} = "generated by mtex2man(1)";
$page{'auto'}{'desc'} = "contains 'THIS FILE HAS BEEN AUTOMATICALLY GENERATED.  DO NOT EDIT.'";
$page{'notedit'}{'desc'} = "contains 'DO NOT EDIT' or 'generated', but I dunno by who.";
$page{'man'}{'desc'} = "seem to be a source file";

my %used=();    # used macros
my %defined=(); # self defined macros

foreach my $type (keys %page) {
    $page{$type}{'defcount'} = 0;
}

sub wanted {
    my ($dev,$ino,$mode,$nlink,$uid,$gid);

    if ((($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) && -f $_) {
	my $file = $File::Find::dir."/".$_;
	return unless $file =~ m|/usr/share/man/man|; # pass translations
	if ($file =~ /\.gz$/) {
	    open FILE,"zcat $file|" || die "Can't open $file\n";
	} else {
	    open FILE,"<$file" || die "Can't open $file\n";
	}

	my $header="";
	while ($_=<FILE>) {
	    last unless /^.."/;#"
#	    chomp;
	    $header .= "    $_";
	}
	$header = "\n$header" if (length $header);
	my $define="";
	while (<FILE>) {
	    if (m/^\.de (.*)$/) {
		my $macro=$1;
		$define .= $macro.",";
		$defined{$macro} =(defined($defined{$macro}) ? $defined{$macro}+1 : 1);
		next;
	    } elsif (m/^\.de/) {
		print "DEF: $_";
	    } elsif (m/^\.([^ ]*)/) {
		my $macro=$1;
		chomp($macro);
		$macro =~ s/\s*$//g;
		$macro =~ s/^\s*//g;
		$macro =~ s/.".*$/|"/;
		next unless (length($macro));
#		unless ($define =~ m/$macro/) { # ignore self defined macro
		    $used{$macro} = (defined($used{$macro}) ? $used{$macro}+1 : 1);
#		}
	    }
	}
	close FILE;
	my $type="man";
	     if ($header =~ /Pod::Man/)                 { $type="pod";
	} elsif ($header =~ /generated by help2man/)    { $type="help2man";
	} elsif ($header =~ /with docbook-to-man/)      { $type="docbook-to-man";
	} elsif ($header =~ /generated by docbook2man/) { $type="docbook2man";
	} elsif ($header =~ /created with latex2man/)   { $type="latex2man";
	} elsif ($header =~ /Generated by db2man.xsl/)  { $type="db2man.xsl";
	} elsif ($header =~ /generated automatically by mtex2man/)  { $type="mtex2man";
	} elsif ($header =~ /THIS FILE HAS BEEN AUTOMATICALLY GENERATED.  DO NOT EDIT./) {
	    $type="auto";
	} elsif ($header =~ /DO NOT EDIT/i || $header =~ /generated/i) {
	    $type="notedit";
	}
	if (length($define)) {
	    $page{$type}{'define'}{$file} = $define;
	    $page{$type}{'defcount'}++;
	}
	push @{$page{$type}{'files'}},$file;
	push @{$page{$type}{'headers'}},"$file\n$header";
    }
}
# Traverse desired filesystems
File::Find::find({wanted => \&wanted}, '/usr/share/man');

my $total=0;
foreach my $type (sort keys %page) {
    $page{$type}{'num'} = scalar @{$page{$type}{'files'}};
    $total += $page{$type}{'num'};
}
print "Seen $total pages.\n";
foreach my $type (sort {$page{$a}{'num'} <=> $page{$b}{'num'}} keys %page) {
    print "  ".$page{$type}{'num'}." ".$page{$type}{'desc'}.". ".
	$page{$type}{'defcount'}." seem to define new macro.\n";
}

print "\nHere is a list of the (regular and self defined) macros used:\n";
foreach my $macro (sort {$used{$a} <=> $used{$b}} keys %used) {
    print " $macro (used ".$used{$macro}." times)\n";
}

#print "\nHere is the list of pages seeming to be source page, and defining new macros:\n";
#foreach my $page(sort { $page{'man'}{'define'}{$a} cmp $page{'man'}{'define'}{$b}
#		      } keys %{$page{'man'}{'define'}}) {
#    print $page{'man'}{'define'}{$page}.". in $page\n";
#}
