#!/usr/local/bin/perl
eval "exec /usr/local/bin/perl -S $0 $*"
    if $running_under_some_shell;
			# this emulates #! processing on NIH machines.
			# (remove #! line above if indigestible)

eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_0-9]+=)(.*)/ && shift;
			# process any FOO=bar switches

$[ = 1;			# set array base to 1
$, = ' ';		# set output field separator
$\ = "\n";		# set output record separator

&Initialize();
$dir = 'DIR';

line: while (<>) {
    chop;	# strip record separator
    if (($. == 1)) {
	$SomethingThere = 1;
    }

    if (/<Entry>/) {
	$InEntry = 1;
	s/<Entry>/<Entry dir=DIR>/;
	s/><Entry/>\n<Entry/;
	&Text($_);
	next line;
    }

    if (/<\/Decl>/) {
	$InEntry = 0;
	&Text(sprintf("%s\n</Entry>", $_));
	&Initialize();
	next line;
    }

    if (/<\/Entry>/) {
	if (!$InEntry) {
	    next line;
	}
    }

    if (/<Function/) {
	if (!$InEntry) {
	    $a = sprintf("<Entry dir=\"%s\">", $dir);
	    &Text($a);
	    $InEntry = 1;
	    &Text($_);
	    next line;
	}
    }

    if (/<Class>/) {
	$Class = $_;
	$Class =~ s/^ *<Class>[ 	]*//;
	$gotClass = 1;
	if ($gotName) {
	    &StartPrinting();
	}
    }

    if (/<Name>/) {
	$Name = $_;
	$Name =~ s/^.*<Name>[ 	]*//;
	$Name =~ s/[ 	]*<\/Name>.*$//;
	$gotName = 1;
	if ($gotClass) {
	    &StartPrinting();
	}
    }

    if (/<\/Function>/) {
	$InEntry = 0;
    }

    &Text($_);
}

if ($SomethingThere) {
    if (!$printing) {
	&StartPrinting();
    }
}
else {
    print '**** empty';
}

if ($OtherClasses ne '') {
    $n = (@Names = split(/[ 	]*,[ 	]*/, $OtherClasses, 9999));
    while ($n > 0) {
	printf "** %s links to %s\n", $FileName, $Names[$n];
	$Names[$n] =~ s/ /_/g;
	system(sprintf("mkdir -p `dirname \"Categories/%s\"`", $Names[$n]));
	system(sprintf('ln -s %s %s', $FileName, $Names[$n]));
	$n--;
    }
}

sub Initialize {
    if ($SavedLineCount) {
	&StartPrinting();
    }

    if ($FileName) {
	delete $opened{$FileName} && close($FileName);
    }
    $InEntry = 0;
    $SomethingThere = 0;
    $Class = 'Other';
    $Name = 'Other';
    $FileName = 'not-set-yet';
    $SavedLineCount = 0;
    $printing = 0;
    $gotName = 0;
    $gotClass = 0;
    $OtherClasses = '';
}

sub Text {
    local($Line) = @_;
    if ($printing) {
	&Pick('>>', $FileName) &&
	    (print $fh $Line);
    }
    else {
	$Lines{++$SavedLineCount} = $Line;
    }
}

sub StartPrinting {
    local($i) = @_;
    if ($Class =~ /,/) {
	$OtherClasses = $Class;
	$OtherClasses =~ s/[^,]*, *//;
	$Class =~ s/[ 	]*,.*$//;
    }

    $FileName = sprintf('Categories/%s/Name', $Class);
    $FileName =~ s/ /_/g;
    $t = $Class;
    $t =~ s/ /_/g;
    $a = sprintf("mkdir -p 'Categories/%s", $t);
    printf '**** ';
    $S = "test -f '" . $FileName;
    $S = $S . "' || ( echo '<!DOCTYPE File SYSTEM \"doc.dtd\"><File>' > \"";
    $S = sprintf('%s%s', $S, $FileName);
    $S = $S . "\"; echo -n \"Created \" 1>&2 )";

    system($S);
    printf "%s\n", $FileName;

    for ($i = 1; $i <= $SavedLineCount; $i++) {
	&Pick('>>', $FileName) &&
	    (print $fh $Lines{$i});
    }
    $printing = 1;
    $SavedLineCount = 0;
}

sub Pick {
    local($mode,$name,$pipe) = @_;
    $fh = $name;
    open($name,$mode.$name.$pipe) unless $opened{$name}++;
}
