: # *-*-perl-*-*
    eval 'exec perl -S $0 "$@"'
    if $running_under_some_shell;  

# -----------------------------------------------------------------
# hsrlibrary.pl
# 
# Author: Mic Bowman
#
# Collection of functions used by most HSR programs.
# 
# -----------------------------------------------------------------
require 'configure.pl';

# -----------------------------------------------------------------
# Globals
# -----------------------------------------------------------------
$HSR_Configuration = "hsr.conf";
@HSR_Month = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", 
	      "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");

# -----------------------------------------------------------------
# HSR_Initialize
#
# The hsr configuration file is found by searching the following
# locations:
#	- The first argument of the command line
#       - The HSR_CONFIGURATION variable
#       - The HSR_HOME environment variable (plus hsr.conf)
#       - The current directory (plus hsr.conf)
# -----------------------------------------------------------------
sub HSR_Initialize {
    local($tag);

    undef %Config;

    # Process the configuration file
    if (defined $ENV{"HSR_CONFIGURATION"}) {
	&ReadConfiguration($ENV{"HSR_CONFIGURATION"},*Config);
    } elsif (defined $ENV{"HSR_HOME"}) {
	&ReadConfiguration($ENV{"HSR_HOME"} . "/$HSR_Configuration",*Config);
    } else {
	&ReadConfiguration($HSR_Configuration,*Config);
    }

}

# -----------------------------------------------------------------
# HSR_FileName -- create a file name from the configuration variables
# -----------------------------------------------------------------
sub HSR_FileName
{
    local($cffamily,$cfclass) = @_;
    local($dir,$file);

    if (defined $Config{"$cffamily.$cfclass"}) {
	$file = $Config{"$cffamily.$cfclass"};
	return $file if ($file =~ m@^/.+$@);
    }

    if (defined $Config{"$cffamily.Home"}) {
	$dir = $Config{"$cffamily.Home"};
	$file = "$dir/$file";
    }

    return $file;
}

# -----------------------------------------------------------------
# HSR_ParseSOIF() -- parse a SOIF object from IFILE.
# -----------------------------------------------------------------
sub HSR_ParseSOIF {
    local($ifile);
    $ifile = @_[0];

    return () if (eof($ifile));

    local($template_type) = "UNKNOWN";
    local($url) = "UNKNOWN";
    local(%SOIF);
    undef %SOIF;
    local ($attr, $vsize, $value, $end_value);

    while (<$ifile>) {
	last if (/^\@\S+\s*{\s*\S+\s*$/o);
    }
    if (/^\@(\S+)\s*{\s*(\S+)\s*$/o) {
	$template_type = $1, $url = $2;
	$SOIF{"Type"} = $template_type;
	$SOIF{"Description"} = $url;
    } else {
	return ($template_type, $url, %SOIF);	# done
    }

    while (<$ifile>) {
	if (/^\s*([^{]+){(\d+)}:\t(.*\n)/o) {
	    $attr = $1;
	    $vsize = $2;
	    $value = $3;
	    if (length($value) < $vsize) {
		$nleft = $vsize - length($value);
		$end_value = "";
		$x = read($ifile, $end_value, $nleft);
		die "Cannot read $nleft bytes: $!" 
		    if ($x != $nleft);
		$value .= $end_value;
		undef $end_value;
	    }
	    chop ($value) if ($value =~ /\n$/);
	    $SOIF{$attr} = $value;
	    undef $value;
	    undef $end_value;
	    next;
	} 
	last if (/^}/o);
    }

    return ($template_type, $url, %SOIF);
}

# -----------------------------------------------------------------
# HSR_ParseDescription
# -----------------------------------------------------------------
sub HSR_ParseDescription {
    local($file) = @_;
    local($url,$type);
    local(%obj);

    open(DFILE,"<$file") ||
	die "Unable to open description file ($file): $!\n";

    # Skip to URL
    while (<DFILE>) {
	last if (/^<!-- Query/);
    }

    ($url) = /^<!-- Query (\S+) -->/; $_ = <DFILE>;
    ($type) = /^<!-- Type (\S+) -->/; $_ = <DFILE>;

    while (<DFILE>) {
	last if (m@</P>@);
	$desc .= $_;
    }

    while (<DFILE>) {
	last if (/<DL>/);
    }

    $tag = "";
    $val = "";
    $acc = "";
    while (<DFILE>) {
	if (m@</DL>@) {
	    $val = $acc;
	    chop($val);
	    $acc = "";
	    $obj{$tag} = $val if ($tag !~ /^\s*$/);
	    $val = $tag = "";
	} elsif (/<DT>/) {
	    $val = $acc;
	    chop($val);
	    $acc = "";
	    $obj{$tag} = $val if ($tag !~ /^\s*$/);
	    $val = $tag = "";
	} elsif (/<DD>/) {
	    $tag = $acc;
	    chop($tag);
	    $acc = "";
	} else {
	    $acc .= $_;
	}
    }

    close(DFILE);

    return ($type,$url,%obj);
}

# -----------------------------------------------------------------
# HSR_WriteDescription
# -----------------------------------------------------------------
sub HSR_WriteDescription {
    local($output);
    local($file,$type,$url,%obj) = @_;
    local($k);

    # Create the description file
    $output = "";
    foreach $k (sort keys %obj) {
	next if (! defined $obj{$k});
	$output .= "<DT>\n$k\n<DD>\n" . $obj{$k} . "\n";
    }
	
    open(DFILE,">$file") ||
	die "Unable to open description file $file: $!\n";	

    print DFILE <<EOM;
<HTML>
<HEAD>
<TITLE>$type description file</TITLE>
</HEAD>
<BODY>
<!-- Query $url -->
<!-- Type $type -->
<P>
This is the description file for the
<a href="$url">$type</a> which has the
following specifications:
</P>
<DL>
$output</DL>
</BODY>
</HTML>
EOM
    close(DFILE);
}

# -----------------------------------------------------------------
# HSR_DisplayDescription
# -----------------------------------------------------------------
sub HSR_DisplayDescription {
    local($file) = @_;

    open(DFILE,"<$file") ||
	&CGIError("Unable to open description file $sfile");

    while (<DFILE>) {
	print $_;
    }

    close(DFILE);
}

# -----------------------------------------------------------------
# MakeAttribute() -- make a single attribute
# -----------------------------------------------------------------
sub HSR_MakeAttribute {
    local($k, $v, $a) = @_;
    return "" if (($v =~ /^\s*$/) || ($k =~ /^\s*$/));

    $k = substr($k,9) if ($k =~ /^Gatherer-/) ;
    $k = substr($k,7) if ($k =~ /^Broker-/) ;

    $a = "$k{" . length($v) . "}:\t$v\n";
    return $a;
}

# -----------------------------------------------------------------
# HSR_DumpSOIFObjects() -- Dump the contents of the information array
# to the output file.
# -----------------------------------------------------------------
sub HSR_DumpSOIFObjects {
    local($ofile,*info) = @_;
    local($k,$t,$u);

    foreach $k (sort keys %info) {
	($t, $u) = split('&',$k,2);
	next if (! defined $info{$k});
	print $ofile "\@$t { $u\n";
	print $ofile $info{$k};
	print $ofile "}\n";
    }
}
    
# -----------------------------------------------------------------
# HSR_AddSOIFObject() -- Add an object to the information array.
# -----------------------------------------------------------------
sub HSR_AddSOIFObject {
    local($type,$url,%obj,*info) = @_;
    local($output);

    $output = "";
    foreach $k (sort keys %obj) {
	$output .= &HSR_MakeAttribute($k,$obj{$k});
    }
    $info{join('&',$type,$url)} = $output;
}

# -----------------------------------------------------------------
# HSR_ReadSOIFObjects() -- Read SOIF objects from a file and add them to
# the information structure.
# -----------------------------------------------------------------
sub HSR_ReadSOIFObjects {
    local($ifile,*info) = @_;
    local($output);
    local($stype, $surl, %sobj);

    ($stype, $surl, %sobj) = &HSR_ParseSOIF("$ifile");
    while (defined $stype) {
	&HSR_AddSOIFObject($stype,$surl,%sobj,*info);
    } continue {
	($stype, $surl, %sobj) = &HSR_ParseSOIF("$ifile");
    }    
}

# -----------------------------------------------------------------
1
