# $Id: faqfile.pl,v 1.5 1992/03/26 19:38:54 jik Exp $
# 
# Copyright (c) 1992 Jonathan I. Kamens.  See the GNU Public License
# (any version) for terms of distribution.

package faqfile;

$default_interval = 0;
$default_sigfile = "none";
$default_force = 0;

sub parse_faq {
    # The format of an individual FAQ specification line in the config
    # file is as follows:
    # 
    # idname file timestamp interval sigfile force parent
    # 
    # The fields are separated by blank space, which means, of course,
    # that the contents of the fields cannot contain spaces or tabs.
    # To specify an empty field (for fields that are allowed to be
    # empty -- timestamp, interval, sigfile, force, parent), use a
    # single period.  The meaning of each field is as follows:
    # 
    # idname -- The string to use as the unique name of the FAQ in the
    #   Message ID of the posted article.
    # file -- The file containing the text of the FAQ.  This should be
    # 	readable from the current directory.
    # timestamp -- The timestamp of when the article was last posted.
    # 	If unspecified, the article is assumed not to have been
    #   posted.  This field is filled in automatically by the program
    #   when it rewrites the config file after doing a set of
    #   postings.
    # interval -- The number of days to wait after the last posting
    #   before posting the FAQ again.  Defaults to the interval
    #   hard-coded into the program, or to the interval specified with
    #   the "-interval" command-line option.
    # sigfile -- The signature file to append to the bottom of the
    #   message, with "-- \n" prepended to it.  If unspecified,
    #   defaults to the hard-coded path or to the file specified with
    #   "-sigfile".  If "none", don't include a signature file.  So,
    #   you can't have a signature file named "none" in the current
    #   working directory; use "./none". So sue me.
    # force -- If specified, then treat the contents as a number.  If
    # 	it is 0, then never force the posting of this article.  If it
    # 	is a 1, then force the posting of this article just once, and
    # 	replace the 1 with an empty field ('.') when done doing so.
    # 	If it is anything else, then always force the posting of this
    # 	article.  If not specified, then use the hard-coded force
    # 	parameter or the presence or absence of "-force" on the
    # 	command line to decide whether or not to force.
    # parent -- The ID name of the parent article of this one, if any.
    # 	The parent's FAQ specification must appear earlier in the
    #   config file than the child's.  If a parent is specified, then
    #   the child article will not be posted unless the parent was
    #   posted successfully.  Note that *if* the parent posts
    #   successfully, the child won't post unless its interval has
    #   expired, so if you want the child to post whenever the parent
    #   did, make sure to use "force" (see above).
    # 
    # Blank lines, lines with only whitespace, and lines starting with
    # '#' in the config file are ignored.

    return if (($_[0] =~ /^[ \t]*$/) || ($_[0] =~ /^\#/));

    local(@fields) = split(' ', $_[0]);
    if (@fields != 7) {
	warn "Wrong number of fields in FAQ specification \"$_[0]\".  Ignoring FAQ.\n";
	return undef;
    }

    local($idname) = shift @fields;

    if ($idname eq "") {
	warn "No ID name specified in FAQ specification \"$_[0]\".  Ignoring FAQ.\n";
	return undef;
    }

    if ($faqs{"$idname\034file"}) {
	warn "Duplicate ID name $idname.  Ignoring FAQ.\n";
	return undef;
    }
    local($file) = shift @fields;

    if ($file eq "") {
	warn "No file specified in FAQ specification in \"$_[0]\".  Ignoring FAQ.\n";
	return undef;
    }

    local($timestamp) = shift @fields;
    if ($timestamp eq ".") {
	$timestamp = undef;
    }
    elsif ($timestamp !~ /^[0-9]+$/) {
	warn "Timestamp in FAQ specification \"$_[0]\" is invalid.  Ignoring FAQ.\n";
	return undef;
    }

    local($interval) = shift @fields;
    if ($interval eq ".") {
	$interval = undef;
    }
    elsif ($interval !~ /^[0-9.]+$/) {
	warn "Interval in FAQ specification \"$_[0]\" is invalid.  Ignoring FAQ.\n";
	return undef;
    }

    local($sigfile) = shift @fields;
    ($sigfile = undef) if ($sigfile eq ".");

    local($force) = shift @fields;
    if ($force eq ".") {
	$force = undef;
    }
    else {
	$force += 0;		# force it to be a number
    }

    local($parent) = shift @fields;
    if ($parent eq ".") {
	$parent = undef;
    }
    elsif (! $faqs{"$parent\034file"}) {
	warn "FAQ specification \"$_[0]\" has unknown parent.  Ignoring FAQ.\n";
	return undef;
    }

    push(@faqlist, $idname);
    $faqs{"$idname\034file"} = $file;
    $faqs{"$idname\034timestamp"} = $timestamp;
    $faqs{"$idname\034interval"} = $interval;
    $faqs{"$idname\034sigfile"} = $sigfile;
    $faqs{"$idname\034force"} = $force;
    $faqs{"$idname\034parent"} = $parent;
    $faqs{"$idname\034configline"} = $_[0];

    return($idname, eval "\"$file\"", $timestamp, 
	   $interval ? $interval : $default_interval,
	   $sigfile ? $sigfile : $default_sigfile,
	   $force ? $force : $default_force, $parent);
}

sub set_posted {
    $faqs{"$_[0]\034posted"}++;
}

sub set_timestamp {
    local($idname, $timestamp) = @_;
    ($timestamp = ".") if (! $timestamp);
    $faqs{"$idname\034timestamp"} = $timestamp;
    $faqs{"$idname\034configline"} =~ 
	s/^([^ \t]+[ \t]+[^ \t]+[ \t]+)[^ \t]+/$1$timestamp/;
}

sub set_force {
    local($idname, $force) = @_;
    ($force = ".") if (! $force);
    $faqs{"$idname\034force"} = $force;
    $faqs{"$idname\034configline"} =~ 
	s/^([^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+)[^ \t]+/$1$force/;
}

sub set_interval {
    local($idname, $interval) = @_;
    ($interval = ".") if (! $interval);
    $faqs{"$idname\034interval"} = $interval;
    $faqs{"$idname\034configline"} =~ 
	s/^([^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+)[^ \t]+/$1$interval/;
}

sub set_parent {
    local($idname, $parent) = @_;
    ($parent = ".") if (! $parent);
    $faqs{"$idname\034parent"} = $parent;
    $faqs{"$idname\034configline"} =~ 
	s/^([^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+)[^ \t]+/$1$parent/;
}

sub configline {
#    local($id) = $_[0];
#    local($t, $i, $s, $f, $p) = ($faqs{"$id\034timestamp"},
#				 $faqs{"$id\034interval"},
#				 $faqs{"$id\034sigfile"},
#				 $faqs{"$id\034force"},
#				 $faqs{"$id\034parent"});
#
#    sprintf("%s\t%s\t%s\t%s\t%s\t%s\t%s", $id, $faqs{"$id\034file"},
#	    $t ? $t : ".", $i ? $i : ".", $s ? $s : ".", $f ? $f : ".", 
#	    $p ? $p : ".");
    $faqs{"$_[0]\034configline"};
}
    
sub was_posted {
    $faqs{"$_[0]\034posted"};
}

sub timestamp {
    $faqs{"$_[0]\034timestamp"};
}

sub new_configline {
    local($idname, $file, $timestamp, $interval, $sigfile, $force, $parent) =
	@_;

    sprintf("%s\t%s\t%s\t%s\t%s\t%s\t%s", $idname, $file,
	    $timestamp ? $timestamp : ".", $interval ? $interval : ".",
	    $sigfile ? $sigfile : ".", $force ? $force : ".",
	    $parent ? $parent : ".");
}

1;
