#!/usr/bin/env perl
 #############################################################################
# Copyright (c) 2003 Pelle Johansson.                                         #
# All rights reserved.                                                        #
#                                                                             #
# This file is part of the moftpd package. Use and distribution of            #
# this software is governed by the terms in the file LICENCE, which           #
# should have come with this package.                                         #
 #############################################################################

# $moftpd: make_table.pl 1251 2005-03-06 22:24:29Z morth $

$forwardName = shift(@ARGV);
$reverseName = shift(@ARGV);

$maxseq = 0;
while (<>)
{
    chomp;
    s/[ \t]*\#.*//;
    
    if (/([^ ]+) +(.*)/)
    {
	$ucode = $1;
	@seq = split / +/, $2;
	$maxseq = scalar (@seq) if (scalar (@seq) > $maxseq);
	if ($maxseq > 4)
	{
	    print STDERR "Can't have longer sequences than 4. Edit table.[ch] and " .
		"this file to change this.\n";
	    exit 1;
	}
	
	$fortable{$ucode} = [@seq];
	$revtable{$seq[0]} = [@{$revtable{$seq[0]}}, [@seq[1 .. $#seq], $ucode]];
    }
}

sub hexcmp
{
    my $lendiff = length ($a) - length ($b);
    
    return $lendiff if $lendiff;
    $a cmp $b;
}

if ($forwardName ne "none")
{
    print "const int num$forwardName" . "s = " . keys (%fortable) . ";\n";
    print "const int $forwardName" . "[][6] = \n";
    print "{\n";
    foreach $key (sort hexcmp (keys (%fortable)))
    {
	print "  { 0x$key, 0x" . join (', 0x', @{$fortable{$key}}) . ", 0 }, \n";
    }
    print "};\n\n";
}

if ($reverseName ne "none")
{
    @tables = ( "_" , \%revtable );
    $output = "const int num$reverseName" . "s = " . keys (%revtable) . ";\n";
    $output .= "const int max$reverseName" . "Depth = $maxseq;\n\n";
    $output .= "const sized_table_t $reverseName = { " . keys (%revtable) . ", $reverseName" . "_ };\n\n";
    while (($tag, $table, @tables) = @tables)
    {
	next if ($tags{$tag});
	$tags{$tag} = 1;
	$text = "const table_t $reverseName$tag" . "[] = \n{\n";
	foreach $key (sort hexcmp (keys (%$table)))
	{
	    $val = $$table{$key};
	    if (scalar (@$val) > 1 || scalar (@{$$val[0]}) > 1)
	    {
		my %newtable = ();
		foreach $arr (@$val)
		{
		    if (scalar (@$arr) > 1)
		    {
			$newtable{$$arr[0]} = [@{$newtable{$$arr[0]}}, [@$arr[1 .. $#$arr]]];
		    }
		    elsif (scalar (@$arr))
		    {
			$newtable{"0   "} = [[$$arr[0]]];
		    }
		}
		$text .= "  { 0x$key, { " . keys(%newtable) . ", $reverseName$tag$key } },\n";
		@tables = (@tables, "$tag$key", \%newtable);
	    }
	    else
	    {
		$text .= "  { 0x$key, { 0x" . $$val[0]->[0] . ", NULL } },\n";
	    }
	}
	$text .= "};\n\n";
	$output = $text . $output;
    }
    print $output;
}


syntax highlighted by Code2HTML, v. 0.9.1