6D/
6D/area/
6D/boards/
6D/city/
6D/color/
6D/corpses/
6D/councils/
6D/htowns/
6D/news/
6D/specials/
6D/src/specials/
6D/src/trades/
#!/usr/bin/perl
use strict;

##
# mktables script version 01.00
# Copyright (C) 2002 by Cronel (cronel@millicom.com.ar)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version. See LICENSE for more details.
##
my $version = "01.00";

die "Syntax: mktables <out file> <template file> -h <header> [DEFINE] [-r <func> <DEFINE>]\n"
  unless(scalar(@ARGV) != 0);

# get the arguments
my $out_file = shift @ARGV;
my $template = shift @ARGV;
my @headers = ();
my (%restrict_h, %restrict_over);
ARGLOOP: for(;;) {
  my $arg = shift @ARGV;
  defined($arg) or last ARGLOOP;
  if($arg eq "-h") {
  my $header = shift @ARGV;
  die "Error: Bad arguments for -h.\n" unless defined($header);
  unshift @headers, $header;
  $arg = shift @ARGV;
  defined($arg) or last ARGLOOP;
  if(!($arg =~ /\-.*/)) {
   $restrict_h{$header} = $arg;
  }
  else { unshift @ARGV, $arg; }
  }
  elsif($arg eq "-r") {
  my $func = shift @ARGV;
  my $restrict = shift @ARGV;
  die "Error: Bad arguments for -r\n"
   unless (defined($func) && defined($restrict));
  $restrict_over{$func} = $restrict;
  }
}

die "Error: no out file\n" unless defined($out_file);
die "Error: no template file\n" unless defined($template);
die "Error: no header files\n" unless (scalar(@headers) != 0);

# collect cmd and spell funcs
my (@funcs, @spells, %restrict_func);
foreach my $header (@headers) {
  open FILE, "<$header";
  while(<FILE>) {
#  if(/^\s*DECLARE_DO_FUN\ \(\s*(.*?)\s*\);/) {
  if(/^\s*DECLARE_DO_FUN\(\s*(.*?)\s*\);/) {
   unshift @funcs, $1;
   $restrict_func{$1} = $restrict_h{$header};
   if($restrict_over{$1}) {
     $restrict_func{$1} = $restrict_over{$1};
   }
  }
#  if(/^\s*DECLARE_SPELL_FUN\ \(\s*(.*?)\s*\);/) {
  if(/^\s*DECLARE_SPELL_FUN\(\s*(.*?)\s*\);/) {
   unshift @spells, $1;
   $restrict_func{$1} = $restrict_h{$header};
   if($restrict_over{$1}) {
     $restrict_func{$1} = $restrict_over{$1};
   }
  }
  }
  close FILE;
}

# sort the funcs
my %sorted_funcs;
foreach my $func (@funcs) {
  my $ch;
  ($ch) = $func =~ /...(.).*/ or die "Error: Can't get the 4th letter of function name (function '$func')!\n";
  if(!defined($sorted_funcs{$ch})) {
  $sorted_funcs{$ch} = [$func];
  }
  else {
  unshift @{$sorted_funcs{$ch}}, $func;
  }
}

my ($skill_func, $spell_func, $skill_name, $spell_name);

# make skill_func
$skill_func = "    switch(VAR[3])\n";
$skill_func = $skill_func . "    {\n";
my $prev_restrict = 0;
LOOP: foreach my $ch (('a'..'z')) {
  (defined($sorted_funcs{$ch}) && scalar(@{$sorted_funcs{$ch}}) != 0) or next LOOP;
  handle_restrict(\$skill_func, \$prev_restrict, 0);
  $skill_func = $skill_func . "    case '$ch':\n";
  foreach my $ch_func (@{$sorted_funcs{$ch}}) {
  handle_restrict(\$skill_func, \$prev_restrict, $restrict_func{$ch_func});
  $skill_func = $skill_func . "        if(!str_cmp(VAR, \"$ch_func\")) return $ch_func;\n";
  }
  $skill_func = $skill_func . "        break;\n";
}
handle_restrict(\$skill_func, \$prev_restrict, 0);
$skill_func = $skill_func . "    }\n";

# make skill_name
$skill_name = "";
$prev_restrict = 0;
foreach my $func (@funcs) {
  handle_restrict(\$skill_name, \$prev_restrict, $restrict_func{$func});
  $skill_name = $skill_name . "    if(VAR == $func) return \"$func\";\n";
}
handle_restrict(\$skill_name, \$prev_restrict, 0);

# make spell_func
$spell_func = "";
$prev_restrict = 0;
foreach my $spell (@spells) {
  handle_restrict(\$spell_func, \$prev_restrict, $restrict_func{$spell});
  $spell_func = $spell_func . "    if(!str_cmp(VAR, \"$spell\")) return $spell;\n";
}
handle_restrict(\$spell_func, \$prev_restrict, 0);

# make spell_name
$spell_name = "";
$prev_restrict = 0;
foreach my $spell (@spells) {
  handle_restrict(\$spell_name, \$prev_restrict, $restrict_func{$spell});
  $spell_name = $spell_name . "    if(VAR == $spell) return \"$spell\";\n";
}
handle_restrict(\$spell_name, \$prev_restrict, 0);

open FILE, "<$template";
open OUT, ">$out_file";
print OUT "/**\n";
print OUT " * Warning, This file was automatically generated by mktables from the files:\n";
print OUT " * Template: $template\n";
print OUT " * Headers: ";
foreach my $header (@headers) {
  print OUT "$header ";
  if($restrict_h{$header}) {
  print OUT "($restrict_h{$header}) ";
  }
}
print OUT "\n";
my $timestr = localtime(time());
print OUT " * At: ", $timestr, "\n";
print OUT " * Any changes to this file will be overwritten! You should modify the\n";
print OUT " * template instead.\n";
print OUT " *\n";
print OUT " * Mktables $version by Cronel\n";
print OUT " */\n\n";

my ($which_func, $var_name, $out);
while(<FILE>) {
  if(/^\s*\/\*\*\s*INSERT\s+headers\s*\*\/\s*$/) {
  foreach my $header (reverse @headers) {
   print OUT "#include \"$header\"\n";
  }
  }
  elsif(($which_func, $var_name) = /^\s*\/\*\*\s*INSERT\s+(\S+?)\s+(\S+?)\s+\*\*\//) {
  if($which_func eq "skill_function") {
   $out = $skill_func;
  }
  elsif($which_func eq "skill_name") {
   $out = $skill_name;
  }
  elsif($which_func eq "spell_function") {
   $out = $spell_func;
  }
  elsif($which_func eq "spell_name") {
   $out = $spell_name;
  }
  $out =~ s/VAR/$var_name/g;
  print OUT $out;
  }
  else { print OUT; }
}
close FILE;
close OUT;

sub handle_restrict
{
  my ($strref, $prev_rest_ref, $cur_rest) = @_;

  if($cur_rest) {
  if(!($$prev_rest_ref eq $cur_rest)) {
   if($$prev_rest_ref) {
     $$strref = $$strref . "#endif\n";
   }
   $$strref = $$strref . "#ifdef $cur_rest\n";
  }
  $$prev_rest_ref = $cur_rest;
  }
  elsif($$prev_rest_ref) {
  $$strref = $$strref . "#endif\n";
  $$prev_rest_ref = 0;
  }
}