cleanup/
#!/usr/bin/perl

# cleanup.pl by Silver - silver@ewtoo.org
# version 1.3
#
# this cleans up a clist.h file, you need to wrap the rest of the
# contents of clist.h around this
#
# Caveats:
# 1. Untested
# 2. Doesn't generate a complete clist.h file
#
# usage:   cleanup.pl > outfile
#

use strict;

my %structs;
my @commands;
my ($key, $value);
my $define;
my %ifdef;

open(CLIST, "clist.h") || die "Can't open clist.h: $!";
while (<CLIST>)
{
  if (/#ifdef (.+)/)
  {
    $define = $1;
  }

  if (/#endif/)
  {
    $define = "";
  }

  if (/( *){"(.+?)", *(.+?), *(.+?)},/)
  {
    push @commands, "$1\{\"$2\", $3, $4},^^$define";

    # check syntax, if bad then report but continue anyway
    print STDERR "Warning: '$2' cmd ('$3' fn) appears badly formed.\n" unless ($4 =~ /^.+?,.+?,.+?,.+?$/);

    unless ($structs{$3})
    {
      $structs{$3} = $2;
    }
    else
    {
      $structs{$3} .= " $2";
    }
    $ifdef{$3} = $define if ($define);
  }
}
close CLIST;

@commands = sort @commands;

my $lastchar = "";
$define = "";

foreach (sort keys %structs)
{
  if (substr($_, 0, 1) ne $lastchar)
  {
    if ($define ne "")
    {
      print "#endif /* $define */\n";
      $define = "";
    }
    print "\n/* " . substr($_, 0, 1) . " */\n";
    $lastchar = substr($_, 0, 1);
  }

  # I don't know how to do this any other way

  my @in = split(/ /, $structs{$_});
  my %saw;
  undef %saw;
  my @out = grep(!$saw{$_}++, @in);
  my $done = join(" ", @out);

  if ($ifdef{$_})
  {
    if ($define ne $ifdef{$_})
    {
      print "#endif /* $define */\n" if ($define);
      $define = $ifdef{$_};
      print "#ifdef $define\n";
    }
  }
  else
  {
    if ($define)
    {
      print "#endif /* $define */\n";
      $define = "";
    }
  }

  print "  " if ($define);
  print "extern command_func $_;  /* $done */\n";
}

print "\n\n";

$lastchar = "";
$define = "";
foreach (@commands)
{
  unless (substr($_, 0, 1) eq " ")
  { 
    my $bit = substr($_, 2, 1);

    if ($bit ne $lastchar && (isalpha($bit) || isalpha($lastchar)))
    {
      if ($define)
      {
        print "#endif /* $define */\n";
        $define = "";
      }
      print "{0, 0, 0, 0, 0, 0, 0},\n\n";
      print "/* $bit */\n";
      $lastchar = $bit;
    }
    my @bits = split(/\^\^/, $_);
    if ($bits[1])
    {
      if ($bits[1] ne $define)
      {
        if ($define)
        {
          print "#endif /* $define */\n";
        }
        $define = $bits[1];
        print "#ifdef $bits[1]\n";
      }
      print "  $bits[0]\n";
    }
    else
    {
      if ($define)
      {
        print "#endif /* $define */\n";
        $define = "";
      }
      print "$bits[0]\n";
    }
  }
}

print "{0, 0, 0, 0, 0, 0, 0},\n";

exit(0);

sub isalpha
{
  my $str = shift;
  $str =~ /^[^\W\d_]+$/;
}