#!/afs/athena/contrib/perl/p

require "getopt.pl";

$ATTACH_PATH =	'/bin/athena/attach';
$LOCKER =	'logos';
$CONFIG_MENU =	'/mit/logos/lib/config.menu';

&Getopt('');
&init_stuff;
&process_ng_file("",$CONFIG_MENU);
&do_menu_file("olh:top_menu",1);
&check_db;

#----------------------------------------------------------------------------

sub check_db {
    print "Checking Database..\n" if ($opt_v);
    foreach $node_id (keys %db) {
	@foo = &unstruct($db{$node_id});
	&attach_locker($foo[$FILESYSTEM]);
	$lock{$foo[$FILESYSTEM]}++;
	$form{$foo[$FILE_FORMAT]}++;
	if (($foo[$FILE_LOC] ne "") && (! -e $foo[$FILE_LOC])) {
	    print "Cannot access file $foo[$FILE_LOC] for module $node_id in database file $foo[$ORIG_FILE]\n";
	}
	$ty{$foo[$TYPE]}++;
    }
    if ($opt_v) {
	print "\nLockers used:\n";
	foreach $x (sort keys %lock) {
	    printf "  %20s %5d\n",$x,$lock{$x};
	}
	
	print "\nFile formats used:\n";
	foreach $x (sort keys %form) {
	    printf "  %20s %5d\n",$x,$form{$x};
	}
	
	print "\nFile types used:\n";
	foreach $x (sort keys %ty) {
	    printf "  %20s %5d\n",$x,$ty{$x};
	}
    }
}


#----------------------------------------------------------------------------

sub init_stuff {
    $FILE_LOC =		0;
    $FILE_FORMAT =	1;
    $FILESYSTEM =	2;
    $LABEL =		3;
    $POINTER =		4;
    $TYPE =		5;
    $ORIG_FILE =        6;

    undef %db;
}

#----------------------------------------------------------------------------

sub struct {
    # Format is:
    #  - file location
    #  - file format
    #  - filesystem
    #  - label
    #  - pointer
    #  - type
    #  - file the node is found it
    join("\n",@_);
}

sub follow_pointer {
    local(@foo) = split("\n",@_[0]);
    local(@bar);
    if ($foo[$POINTER] ne "") {
	if (defined($db{$foo[$POINTER]})) {
	    @bar = &unstruct($db{$foo[$POINTER]});
	} else {
	    print STDERR "Undefined pointer $foo[$POINTER] in file $foo[$ORIG_FILE]\n";
	}
	$foo[$FILE_LOC] = $bar[$FILE_LOC] if ($foo[$FILE_LOC] eq "");
	$foo[$FILE_FORMAT] = $bar[$FILE_FORMAT] if ($foo[$FILE_FORMAT] eq "");
	$foo[$FILESYSTEM] = $bar[$FILESYSTEM] if ($foo[$FILESYSTEM] eq "");
	$foo[$LABEL] = $bar[$LABEL] if ($foo[$LABEL] eq "");
	$foo[$TYPE] = $bar[$TYPE] if ($foo[$TYPE] eq "");
	$foo[$POINTER] = $bar[$POINTER];
    }
    @foo;
}

sub unstruct {
    split("\n",@_[0]);
}

#----------------------------------------------------------------------------

sub do_menu_file {
    local($menu_node_id,$what) = @_;
    local(*FD,$filename);
    local($keyword,$value);
    local($was_blank_line,$first,$num);
    local($file_loc,$file_format,$locker,$label,$pointer,$type);
    local($node_id);

    if ($what == 1) {
	@bar = &follow_pointer($db{$menu_node_id});
	if ($bar[$TYPE] ne "MENU") {
	    print STDERR "Node $menu_node_id is not a menu!\n";
	    return;
	}
	$filename = $bar[$FILE_LOC];
    } else {
	$filename = $menu_node_id;
    }				# 
    
    if (! open(FD,$filename)) {
	print STDERR "Couldn't open $filename for menu node $menu_node_id: $!\n";
	exit 1;
    }

    print "Processing menu file $filename...\n" if ($opt_v);
    $was_blank_line = 0;
    $first = 1;
    $file_loc = $file_format = $locker = $label = $pointer = $type = "";
    $node_id = "";

    while (<FD>) {
	chop;
	if (/^\s*$/) {
	    $was_blank_line = 1;
	    next;
	}

	if ($was_blank_line) {
	    $was_blank_line = 0;
	    if ($first) {
		$first = 0;
	    } else {
		$tmp = &struct($file_loc, $file_format,
			       $locker, $label, $pointer,
			       $type,$filename);
		@bar = &follow_pointer($tmp);
		if ($bar[$FILE_FORMAT] eq "MENU") {
		    &do_menu_file($bar[$FILE_LOC],0);
		}
	    }
	    $file_loc = $file_format = $locker = $label = $pointer = $type = "";
	    $node_id = "";
	}
		    
	($keyword,$value) = /^([\w-]+)\s+(.*)/;
	next if ($keyword eq "");

	# stuffing values into the right thing by keyword
	if ($keyword =~ /^type/) {
	    if ($type ne "") {
		print "Duplicate type $type in menu node $menu_node_id in file $filename line $.\n";
	    }
	    $type = $value;
	    next;
	}
	if ($keyword =~ /^file-location/) {
	    if ($file_loc ne "") {
		print "Duplicate file-location $file_loc in node $node_id in file $filename line $.\n";
	    }
	    $file_loc = $value;
	    next;
	}

	if ($keyword =~ /^file-format/) {
	    if ($file_format ne "") {
		print "Duplicate file_format $file_format in node $node_id in file $filename line $.\n";
	    }
	    if (! ($value =~
		   /^DIRHOOK|^MENU|^ez|^latex|^plain_text|^scribe_PS/))  {
		print "Unknown file format $value in file $filename line $.\n";
	    }
	    $file_format = $value;
	    next;
	}
	if ($keyword =~ /^filesystem/) {
	    if ($locker ne "") {
		print "Duplicate filesystem $locker in node $node_id in file $filename line $. \n";
	    }
	    $locker = $value;
	    next;
	}
	if ($keyword =~ /^label/) {
	    if ($label ne "") {
		print "Duplicate label $label in node $node_id in file $filename line $.\n";
	    }
	    $label = $value;
	    next;
	}
	if ($keyword =~ /^pointer/) {
	    if ($pointer ne "") {
		print "Duplicate pointer $pointer in node $node_id in file $filename line $.\n";
	    }
	    $pointer = $value;
	    next;
	}
	next if ($keyword =~ /^do-keywords|^author|^maintainer|^primary-parent|^keywords/);
	print "Unrecognized keyword $keyword in file $filename, line $.\n";
    }
    close FD;

    if ((! $was_blank_line) && (!$first)) {
	$tmp = &struct($file_loc, $file_format,
		       $locker, $label, $pointer,
		       $type,$filename);
	@bar = &follow_pointer($tmp);
	if ($bar[$FILE_FORMAT] eq "MENU") {
	    &do_menu_file($bar[$FILE_LOC],0);
	}
    }
}

#----------------------------------------------------------------------------

sub process_ng_file {
    local($prefix,$filename) = @_;
    local(*FD);
    local($node_id);
    local($file_loc,$file_format,$locker,$label,$pointer,$type);
    local($keyword,$value);

    if (! open(FD,$filename)) {
	print STDERR "Couldn't open $filename: $!\n";
	exit 1;
    }

    print "Processing node group file $filename...\n" if ($opt_v);

    $file_loc = $file_format = $locker = $label = $pointer = $type = "";
    $node_id = "";

    while (<FD>) {
	chop;
	next if (/^\s*$/);
	    
	($keyword,$value) = /^([\w-]+)\s+(.*)/;
	next if ($keyword eq "");

	# stuffing values into the right thing by keyword
	if ($keyword =~ /^type/) {
		
	    # write out previous information
	    if ($type ne "") {
		$db{$prefix . $node_id} = &struct($file_loc, $file_format,
						  $locker, $label, $pointer,
						  $type,$filename);
		if ($type eq "NODE GROUP MENU") { # 
		    &process_ng_file(($node_id . ":"), $file_loc);
		}
		$file_loc = $file_format = $locker = $label = $pointer =
		    $type = "";
		$node_id = "";
	    }

	    if ($type ne "") {
		print "Duplicate type $type in node $node_id in file $filename, line $.\n";
	    }
	    $type = $value;
	    next;
	}
	if ($keyword =~ /^file-location/) {
	    if ($file_loc ne "") {
		print "Duplicate file-location $file_loc in node $node_id in file $filename, line $.\n";
	    }
	    $file_loc = $value;
	    next;
	}

	if ($keyword =~ /^file-format/) {
	    if ($file_format ne "") {
		print "Duplicate file_format $file_format in node $node_id in file $filename, line $.\n";
	    }
	    $file_format = $value;
	    next;
	}
	if ($keyword =~ /^filesystem/) {
	    if ($locker ne "") {
		print "Duplicate filesystem $locker in node $node_id in file $filename, line $.\n";
	    }
	    $locker = $value;
	    next;
	}
	if ($keyword =~ /^label/) {
	    if ($label ne "") {
		print "Duplicate label $label in node $node_id in file $filename, line $.\n";
	    }
	    $label = $value;
	    next;
	}
	if ($keyword =~ /^pointer/) {
	    if ($pointer ne "") {
		print "Duplicate pointer $pointer in node $node_id in file $filename, line $.\n";
	    }
	    $pointer = $value;
	    next;
	}
	if ($keyword =~ /^node-id/) {
	    if ($node_id ne "") {
		print "Duplicate node id $node_id in node $node_id in file $filename, line $.\n";
	    }
	    $node_id = $value;
	    next;
	}
	next if ($keyword =~ /^do-keywords|^author|^maintainer|^primary-parent|^keywords/);
	print "punting unknown keyword $keyword in file $filename, line $.\n";
    }
    close FD;

    if ($type ne "") {
	$db{$prefix . $node_id} = &struct($file_loc, $file_format, $locker,
					  $label, $pointer,$type,$filename);
    }
}


#----------------------------------------------------------------------------

sub attach_locker {
    local($locker) = @_;
    return if ($locker eq "");
    if (! $attached{$locker}) {
	$retval = system($ATTACH_PATH,'-q',$locker);
	$retval = int($retval/256);
	if ($retval != 0) {
	    print STDERR "Couldn't attach $locker: error $retval\n";
	    exit 1;
	}
	$attached{$locker} = 1;
    }
}

#
# Local Variables:
# mode: perl
# End:
#
