#!/usr/bin/perl
# checkstd - Checks standards entries in configuration files
#
$VERSION = '1.02';
($Prog = $0) =~ s:.*/::;
#
#         Required files:  guestnik.cfg   (Documentation in file)
#
# Mike Heins 
# Copyright 1995 Mike Heins and Internet Robotics - ALL RIGHTS RESERVED
#

$USAGE = "usage: $Prog [-s] [file]";

$BASEDIR     = $ENV{'GUESTNIK'} || '';
$BASEDIR 	.= '/' if $BASEDIR;

$Verbose = 1;
if($ARGV[0] =~ /^-s/) {
	undef $Verbose;
	shift(@ARGV);
}
if($ARGV[0]) {
	$CFGFILE = shift @ARGV;
}
if(scalar(@ARGV)) {
	die "Too many params.\n\n$USAGE\n";
}

sub prompt {
    local($pr) = shift || '? ';
    local($def) = shift;
    local($ans);

    print $pr;
    print "[$def] " if $def;
    chop($ans = <STDIN>);
    $ans ? $ans : $def;
}

$| = 1;

$CFGFILE = &prompt("Which configuration file to check? ", 'guestnik.cfg')
	unless $CFGFILE;

# Read our configuration file
&read_config($CFGFILE);

if(! scalar(@Required)) {
	die <<EOF ;

There are no required fields in your configuration file.
Can't check standards.
EOF
}

if(! scalar(keys %Standards)) {
	die <<EOF ;

There are no standards entries in your configuration file.
Can't check standards.
EOF
}

for(;;) {
		printf("\n%2s %-16s %-13s %s\n",
					'', 'FIELD', 'VALID?', 'FORMAT ERROR MESSAGE');
		$count = 1;
	foreach $field (@Required) {
		if($Standards{$field}) {
			$valid{$field} = &check_valid($field,'',$Standards{$field});
		}
		else { $valid{$field} = 'no standard'; }
		$error = $FormatError{$field} || '';
		printf("%2d %-16s %-12s %s\n",
			$count, $field, $valid{$field}, $error);
		 $count++;
	}
	$which = &prompt("Enter number to check, q to quit: ", '');
	exit if $which =~ /^\s*q/i;
	next unless $which--;
	if($Required[$which]) {
		unless($valid{$Required[$which]} =~ /yes/i) {
			print "\cG\nError! No valid standard defined.";
			sleep 2;
			print "\n";
			next;
		}
	}
	else {
		print $which, $/;
		print "\cG\nError! That is not a number corresponding to a field.";
		sleep 2;
		print "\n";
		next;
	}
	$field = $Required[$which];
	$standard = $Standards{$field};
	TESTCASE:
		for(;;) {
			$msg = <<EOF ;

Enter the string you want to check against the standard,
(press 'q' to exit)....
                      .
EOF
			$msg = $Verbose ? $msg . "          String" : '';
			$testcase = &prompt("$msg? ", '');
			last TESTCASE if $testcase =~ /^\s*q/i;
			if(&check_field($field,$testcase,$standard)) {
				print "\n"
					if $Verbose;
				print "VALID\n";
				print "\n($testcase against $standard)\n\n"
					if $Verbose;
			}
			else {
				print "\n\cG" if $Verbose;
				print "FAILED";
				print " CHECK\n\n($testcase against $standard)\n"
					if $Verbose;
				print "\n";
			}
		}
}

sub dontwarn { %FormatError + 1 + &dontwarn + $VERSION;}
sub read_config {

	local($file) = shift(@_);
	open(CONFIG, $file) 
		|| die "Couldn't read configuration file $file: $!\n";

	local($ref,$name,$found_one);
	local(*ary);

	%Config = ();
	%BlankError = ();
	%Destination = ();
	%FormatError = ();
	%GetInfo = ();
	@Required = ();
	%Standards = ();
	%Thanks = ();
	%ValidForm = ();
	%WhatInfo = ();
	local(%recognized) = (
					'blankerror',	'BlankError',	
					'destination',	'Destination',	
					'deleteblank',	'DeleteBlank',	
					'datestyle',	'DateStyle',
					'formaterror',	'FormatError',	
					'getinfo',		'GetInfo',		
					'ignoreoutput', 'IgnoreOutput',
					'required',		'Required',		
					'standards',	'Standards',	
					'thanks',		'Thanks',		
					'validform',	'ValidForm',	
					'whatinfo',		'WhatInfo',		
					'debug',		'DEBUG',		
					);
	local(%arraytype) = (
					'BlankError',	'hash',
					'DateStyle',	'scalar',
					'DeleteBlank',	'scalar',
					'Destination',	'hash',
					'FormatError',	'hash',
					'GetInfo',		'HASH',
					'IgnoreOutput',	'hash',
					'Required',		'array',
					'Standards',	'hash',
					'Thanks',		'hash',
					'ValidForm',	'hash',
					'WhatInfo',		'HASH',
					'DEBUG',		'scalar',
					);


	$lookahead = <CONFIG>;
	while(<CONFIG>) {
		unless (s/^\s+//) {
			$prev = $lookahead;
			$lookahead = $_;
			$_ = $prev;
		}
		else {
			$lookahead .= $_;
			next;
		}
		next unless /\S/ || eof(CONFIG);
		chop;
		s/^\s*(\w+)\s+(\w+)\s*//;
		$name = $1;
		$ref = $2;
		next unless $name;
		$val = &regularize($_);
		unless($type = $recognized{"\L$name"}) {
			warn "Unknown define in config file $file: $name";
		}
		elsif ($arraytype{$type} eq 'hash') {
			*ary = $type;
			$ary{"\L$ref"} = $val;
		}
		elsif ($arraytype{$type} eq 'HASH') {
			*ary = $type;
			$ary{$ref} = $val;
		}
		elsif ($arraytype{$type} eq 'array') {
			*ary = $type;
			$ref = "\L$ref";
			$ref = "$ref $val";
			$ref =~ s/^\s+//;
			$ref =~ s/\s+$//;
			push(@ary, split(/\s+/,$ref) );
		}
		elsif ($arraytype{$type} eq 'scalar') {
			undef *ary;
			$ref .= " $val" if $val;
			$Config{"\L$type"} = "$ref";
		}
		elsif ($arraytype{$type} eq 'SCALAR') {
			undef *ary;
			$ref .= " $val" if $val;
			$Config{$type} = "$ref";
		}
		else {
			die "Unrecognized type! This shouldn't happen.";
		}
	}
	close CONFIG;
	unless (&is_yes($Config{'DEBUG'}) ) {
		*ary = '';
		return 1;
	}
	for(values %recognized) {
			if ($arraytype{$_} eq 'hash') {
				*ary = $_;
				print "%$_:\n";
				for(keys %ary) {
					print "\t$_: $ary{$_}\n";
				}
			}
			elsif ($arraytype{$_} eq 'array') {
				*ary = $_;
				next unless defined @ary;
			}
			elsif ($arraytype{$_} eq 'scalar') {
				next unless defined $Config{$_};
			}
			else {
				die "Unrecognized type $_! This shouldn't happen.";
			}
	}
	*ary = '';
}

sub regularize {
	for (@_) {
			s/[\\]\n//g;
			s/\n\s+/ /g;
			s/\s+$//g;
	}
	wantarray ? @_ : $_[0];
}

sub check_field {
	local($field, $value, $standard) = @_;
	
	eval '/$standard/';
	if ($@) {
		return -1;
	}
	else {
		return 1 if $value =~ /$standard/;
	}
	return 0;
}

sub check_valid {

	local($standard) = $_[0];
	
	return "No standard" unless $standard;
	eval '/$standard/';
	if ($@) {
		return "NOT VALID";
	}
	return "Yes";
}

sub is_yes {
	return( defined($_[$[]) && ($_[$[] =~ /^[yYtT1]/));
}

sub is_no {
	return( !defined($_[$[]) || ($_[$[] =~ /^[nNfF0]/));
}

__END__
