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

# This script checks the param.ent and param.xweb files for consistency

use strict;
use Getopt::Std;
use vars qw($opt_m);

my $usage = "$0 [-m makefrag ] param.xweb\n";

die $usage if ! getopts('m:');

my $file = shift @ARGV || die $usage;
my $dir = ".";
$dir = $1 if $file =~ /^(.*)\/[^\/]+$/;

if ($ENV{repo_dir}) {
  $dir = "$ENV{repo_dir}/xsl/params";
}

my $entfile = $file;
$entfile =~ s/\.xweb$/.ent/;

my $ok = 1;
my %params = ();
my %builtin = ("lt"=>1,"gt"=>1,"amp"=>1,"quot"=>1,"apos"=>1);
my @paramfiles = ();

open (F, $file) || die $usage;
while (<F>) {
    chop;
    if (/&(.*?);/) {
	my $param = $1;

	if (!$builtin{$param}) {
	    if (defined $params{$param}) {
		warn "Duplicate parameter: $param\n";
		$ok = 0;
	    }
	    if (! -f "$dir/../params/$param.xml") {
		warn "No parameter definition: $dir/../params/$param.xml\n";
		$ok = 0;
	    }
	    $params{$param} = 0;
	}
    }

    if (/<src:fragref\s+linkend=[\"\']([^\"\']+)\.frag[\"\']/) {
	my $param = $1;

	if ($params{$param} != 0) {
	    warn "Duplicate fragref: $param\n";
	    $ok = 0;
	}

	if (!defined $params{$param}) {
	    warn "Fragref for unused param: $param\n";
	    $ok = 0;
	} else {
	    $params{$param} = 1;
	}
    }
}
close (F);

foreach my $param (keys %params) {
    # nb: chunker.output.* and saxon.character.representation are special!
    if ($param eq 'saxon.character.representation'
	|| $param =~ /^chunker\.output\./) {
	next;
    }

    if ($params{$param} == 0) {
	warn "No fragref for param: $param\n";
	$ok = 0;
    }
}

if (open (F, $entfile)) {
    while (<F>) {
	next if ! /<!ENTITY\s+(\S+)\s+SYSTEM\s+[\"\']([^\"\']+)/;
	my $param = $1;
	my $pfile = $2;
	if (!defined $params{$param}) {
	    warn "Extra entity declaration: $param\n";
	    $ok = 0;
	}
	if ($pfile !~ /^.*$param\.xml$/) {
	    warn "Incorrect system identifier for $param: $pfile\n";
	    $ok = 0;
	}

	if ($params{$param} == 2) {
	    warn "Duplicate entity declaration: $param\n";
	    $ok = 0;
	} else {
	    push (@paramfiles, $pfile);
	}

	$params{$param} = 2;
    }
    close (F);

    foreach my $param (keys %params) {
	if ($params{$param} != 2) {
	    warn "No entity declaration for param: $param\n";
	    $ok = 0;
	}
    }
} else {
    warn "Failed to open entity file: $entfile\n";
    $ok = 0;
}

if ($ok && $opt_m) {
    my $param = shift @paramfiles;
    open (F, ">$opt_m");
    print F "PARAMS=$param";
    while (@paramfiles) {
	$param = shift @paramfiles;
	print F " \\\n       $param";
    }
    print F "\n";
    close (F);
}

exit 0 if $ok;
exit 1;

