#!/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; } }