summaryrefslogtreecommitdiff
path: root/tools/HPMHookGen/HPMHookGen.pl
diff options
context:
space:
mode:
Diffstat (limited to 'tools/HPMHookGen/HPMHookGen.pl')
-rwxr-xr-xtools/HPMHookGen/HPMHookGen.pl253
1 files changed, 103 insertions, 150 deletions
diff --git a/tools/HPMHookGen/HPMHookGen.pl b/tools/HPMHookGen/HPMHookGen.pl
index 6f7f9e0a4..577536313 100755
--- a/tools/HPMHookGen/HPMHookGen.pl
+++ b/tools/HPMHookGen/HPMHookGen.pl
@@ -3,7 +3,7 @@
# This file is part of Hercules.
# http://herc.ws - http://github.com/HerculesWS/Hercules
#
-# Copyright (C) 2013-2015 Hercules Dev Team
+# Copyright (C) 2013-2016 Hercules Dev Team
#
# Hercules is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -40,7 +40,7 @@ sub parse($$) {
$p =~ s/^.*?\)\((.*)\).*$/$1/; # Clean up extra parentheses )(around the arglist)
# Retrieve return type
- unless ($d =~ /^(.+)\(\*\s*[a-zA-Z0-9_]+_interface::([^\)]+)\s*\)\s*\(.*\)$/) {
+ unless ($d =~ /^(.+)\(\*\s*[a-zA-Z0-9_]+_interface(?:_private)?::([^\)]+)\s*\)\s*\(.*\)$/) {
print "Error: unable to parse '$d'\n";
return {};
}
@@ -148,7 +148,7 @@ sub parse($$) {
$type1 .= "$1 ";
next;
}
- if ($current =~ /^(struct|enum)\s+(.*)$/) { # enum and struct names
+ if ($current =~ /^(struct|enum|union)\s+(.*)$/) { # union, enum and struct names
$current = $2 // '';
$type1 .= "$1 ";
}
@@ -187,28 +187,29 @@ sub parse($$) {
$post_code = "va_end(${callvar});";
$var = '';
$variadic = 1;
- } elsif (!$indirectionlvl) { # Increase indirection level when necessary
+ } else { # Increase indirection level when necessary
$dereference = '*';
$addressof = '&';
}
$indirectionlvl++ if ($array); # Arrays are pointer, no matter how cute you write them
push(@args, {
- var => $var,
- callvar => $callvar,
- type => $type1.$array.$type2,
- orig => $type1 eq '...' ? '...' : trim("$type1 $indir$var$array $type2"),
- indir => $indirectionlvl,
- hookf => $type1 eq '...' ? "va_list ${var}" : trim("$type1 $dereference$indir$var$array $type2"),
- hookc => trim("$addressof$callvar"),
- origc => trim($callvar),
- pre => $pre_code,
- post => $post_code,
+ var => $var,
+ callvar => $callvar,
+ type => $type1.$array.$type2,
+ orig => $type1 eq '...' ? '...' : trim("$type1 $indir$var$array $type2"),
+ indir => $indirectionlvl,
+ hookpref => $type1 eq '...' ? "va_list ${var}" : trim("$type1 $dereference$indir$var$array $type2"),
+ hookpostf => $type1 eq '...' ? "va_list ${var}" : trim("$type1 $indir$var$array $type2"),
+ hookprec => trim("$addressof$callvar"),
+ hookpostc => trim("$callvar"),
+ origc => trim($callvar),
+ pre => $pre_code,
+ post => $post_code,
});
$lastvar = $var;
}
- my $rtmemset = 0;
my $rtinit = '';
foreach ($rt) { # Decide initialization for the return value
my $x = $_;
@@ -237,13 +238,14 @@ sub parse($$) {
$rtinit = ' = HCS_STATUS_FAIL';
} elsif ($x =~ /^enum\s+bg_queue_types$/) { # Known enum bg_queue_types
$rtinit = ' = BGQT_INVALID';
+ } elsif ($x =~ /^enum\s+parsefunc_rcode$/) { # Known enum parsefunc_rcode
+ $rtinit = ' = PACKET_UNKNOWN';
} elsif ($x =~ /^(?:enum\s+)?DBOptions$/) { # Known enum DBOptions
$rtinit = ' = DB_OPT_BASE';
} elsif ($x eq 'DBComparator' or $x eq 'DBHasher' or $x eq 'DBReleaser') { # DB function pointers
$rtinit = ' = NULL';
- } elsif ($x =~ /^struct\s+.*$/ or $x eq 'DBData' or $x eq 'DBKey') { # Structs and unions
- $rtinit = '';
- $rtmemset = 1;
+ } elsif ($x =~ /^(?:struct|union)\s+.*$/) { # Structs and unions
+ $rtinit = ' = { 0 }';
} elsif ($x =~ /^float|double$/) { # Floating point variables
$rtinit = ' = 0.';
} elsif ($x =~ /^(?:(?:un)?signed\s+)?(?:char|int|long|short)$/
@@ -265,7 +267,6 @@ sub parse($$) {
vname => $variadic ? "v$name" : $name,
type => $rt,
typeinit => $rtinit,
- memset => $rtmemset,
variadic => $variadic,
args => \@args,
notes => $notes,
@@ -273,6 +274,7 @@ sub parse($$) {
}
my %key2original;
+my %key2pointer;
my @files = grep { -f } glob 'doxyoutput/xml/*interface*.xml';
my %ifs;
my %keys = (
@@ -308,8 +310,9 @@ foreach my $file (@files) { # Loop through the xml files
}
my @filepath = split(/[\/\\]/, $loc->{file});
my $foldername = uc($filepath[-2]);
- my $filename = uc($filepath[-1]); $filename =~ s/-/_/g; $filename =~ s/\.[^.]*$//;
- my $guardname = "${foldername}_${filename}_H";
+ my $filename = uc($filepath[-1]); $filename =~ s/[.-]/_/g; $filename =~ s/\.[^.]*$//;
+ my $guardname = "${foldername}_${filename}";
+ my $private = $key =~ /_interface_private$/ ? 1 : 0;
# Some known interfaces with different names
if ($key =~ /battleground/) {
@@ -344,6 +347,9 @@ foreach my $file (@files) { # Loop through the xml files
} else {
$key =~ s/_interface//;
}
+ $key =~ s/^(.*)_private$/PRIV__$1/ if $private;
+ my $pointername = $key;
+ $pointername =~ s/^PRIV__(.*)$/$1->p/ if $private;
my $sectiondef = $data->{compounddef}->{$filekey}->{sectiondef};
foreach my $v (@$sectiondef) { # Loop through the sections
@@ -354,9 +360,14 @@ foreach my $file (@files) { # Loop through the xml files
$astart <=> $bstart
} @$memberdef) { # Loop through the members
my $t = $f->{argsstring}->[0];
+ my $def = $f->{definition}->[0];
+ if ($f->{type}->[0] =~ /^\s*LoginParseFunc\s*\*\s*$/) {
+ $t = ')(int fd, struct login_session_data *sd)'; # typedef LoginParseFunc
+ $def =~ s/^LoginParseFunc\s*\*\s*(.*)$/enum parsefunc_rcode(* $1) (int fd, struct login_session_data *sd)/;
+ }
next unless ref $t ne 'HASH' and $t =~ /^[^\[]/; # If it's not a string, or if it starts with an array subscript, we can skip it
- my $if = parse($t, $f->{definition}->[0]);
+ my $if = parse($t, $def);
next unless scalar keys %$if; # If it returns an empty hash reference, an error must've occurred
# Skip variadic functions, we only allow hooks on their arglist equivalents.
@@ -407,10 +418,10 @@ foreach my $file (@files) { # Loop through the xml files
$if->{postcall} .= ', ';
}
$if->{handlerdef} .= $arg->{orig};
- $if->{predef} .= $arg->{hookf};
- $if->{precall} .= $arg->{hookc};
- $if->{postdef} .= $arg->{hookf};
- $if->{postcall} .= $arg->{hookc};
+ $if->{predef} .= $arg->{hookpref};
+ $if->{precall} .= $arg->{hookprec};
+ $if->{postdef} .= $arg->{hookpostf};
+ $if->{postcall} .= $arg->{hookpostc};
$if->{origcall} .= $arg->{origc};
$i++; $j++;
}
@@ -431,6 +442,7 @@ foreach my $file (@files) { # Loop through the xml files
$if->{origcall} .= ");";
$key2original{$key} = $original;
+ $key2pointer{$key} = $pointername;
$ifs{$key} = [] unless $ifs{$key};
push(@{ $ifs{$key} }, $if);
}
@@ -442,35 +454,18 @@ foreach my $file (@files) { # Loop through the xml files
$fileguards{$key} = {
guard => $guardname,
type => $servermask,
+ private => $private,
};
}
my $year = (localtime)[5] + 1900;
-foreach my $servertype (keys %keys) {
- my $keysref = $keys{$servertype};
- # Some interfaces use different names
- my %exportsymbols = map {
- $_ => &{ sub ($) {
- return 'battlegrounds' if $_ =~ /^bg$/;
- return 'pc_groups' if $_ =~ /^pcg$/;
- return $_;
- }}($_);
- } @$keysref;
-
- my ($maxlen, $idx) = (0, 0);
- my $fname;
-
- if ($servertype eq 'all') {
- $fname = "../../src/common/HPMSymbols.inc.h";
- open(FH, ">", $fname)
- or die "cannot open > $fname: $!";
- print FH <<"EOF";
+my $fileheader = <<"EOF";
/**
* This file is part of Hercules.
* http://herc.ws - http://github.com/HerculesWS/Hercules
*
- * Copyright (C) 2015-$year Hercules Dev Team
+ * Copyright (C) 2013-$year Hercules Dev Team
*
* Hercules is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -490,11 +485,34 @@ foreach my $servertype (keys %keys) {
* NOTE: This file was auto-generated and should never be manually edited,
* as it will get overwritten.
*/
+EOF
+
+foreach my $servertype (keys %keys) {
+ my $keysref = $keys{$servertype};
+ # Some interfaces use different names
+ my %exportsymbols = map {
+ $_ => &{ sub ($) {
+ return 'battlegrounds' if $_ =~ /^bg$/;
+ return 'pc_groups' if $_ =~ /^pcg$/;
+ return $_;
+ }}($_);
+ } @$keysref;
+
+ my ($maxlen, $idx) = (0, 0);
+ my $fname;
+
+ if ($servertype eq 'all') {
+ $fname = "../../src/common/HPMSymbols.inc.h";
+ open(FH, ">", $fname)
+ or die "cannot open > $fname: $!";
+ print FH <<"EOF";
+$fileheader
#if !defined(HERCULES_CORE)
EOF
foreach my $key (@$keysref) {
+ next if $fileguards{$key}->{private};
print FH <<"EOF";
#ifdef $fileguards{$key}->{guard} /* $key */
struct $key2original{$key} *$key;
@@ -510,6 +528,7 @@ HPExport const char *HPM_shared_symbols(int server_type)
EOF
foreach my $key (@$keysref) {
+ next if $fileguards{$key}->{private};
print FH <<"EOF";
#ifdef $fileguards{$key}->{guard} /* $key */
if ((server_type&($fileguards{$key}->{type})) && !HPM_SYMBOL("$exportsymbols{$key}", $key)) return "$exportsymbols{$key}";
@@ -522,6 +541,36 @@ EOF
}
EOF
close FH;
+
+ $fname = "../../src/plugins/HPMHooking/HPMHooking.Defs.inc";
+ open(FH, ">", $fname)
+ or die "cannot open > $fname: $!";
+
+ print FH <<"EOF";
+$fileheader
+EOF
+
+ foreach my $key (@$keysref) {
+ print FH <<"EOF";
+#ifdef $fileguards{$key}->{guard} /* $key */
+EOF
+
+ foreach my $if (@{ $ifs{$key} }) {
+ my ($predef, $postdef) = ($if->{predef}, $if->{postdef});
+ $predef =~ s/preHookFunc/HPMHOOK_pre_${key}_$if->{name}/;
+ $postdef =~ s/postHookFunc/HPMHOOK_post_${key}_$if->{name}/;
+
+ print FH <<"EOF";
+typedef $predef
+typedef $postdef
+EOF
+ }
+ print FH <<"EOF";
+#endif // $fileguards{$key}->{guard}
+EOF
+ }
+ close FH;
+
next;
}
@@ -530,39 +579,16 @@ EOF
or die "cannot open > $fname: $!";
print FH <<"EOF";
-/**
- * This file is part of Hercules.
- *
- * Copyright (C) 2013-$year Hercules Dev Team
- *
- * Hercules 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * NOTE: This file was auto-generated and should never be manually edited,
- * as it will get overwritten.
- */
-
+$fileheader
struct HookingPointData HookingPoints[] = {
EOF
foreach my $key (@$keysref) {
- print FH "/* ".$key." */\n";
+ print FH "/* $key2original{$key} */\n";
foreach my $if (@{ $ifs{$key} }) {
print FH <<"EOF";
- { HP_POP($key\->$if->{name}, $if->{hname}) },
+ { HP_POP($key2pointer{$key}\->$if->{name}, $if->{hname}) },
EOF
$idx += 2;
@@ -581,36 +607,12 @@ EOF
or die "cannot open > $fname: $!";
print FH <<"EOF";
-/**
- * This file is part of Hercules.
- * http://herc.ws - http://github.com/HerculesWS/Hercules
- *
- * Copyright (C) 2013-$year Hercules Dev Team
- *
- * Hercules 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * NOTE: This file was auto-generated and should never be manually edited,
- * as it will get overwritten.
- */
-
+$fileheader
EOF
foreach my $key (@$keysref) {
print FH <<"EOF";
-memcpy(&HPMHooks.source.$key, $key, sizeof(struct $key2original{$key}));
+memcpy(&HPMHooks.source.$key, $key2pointer{$key}, sizeof(struct $key2original{$key}));
EOF
}
close FH;
@@ -620,31 +622,7 @@ EOF
or die "cannot open > $fname: $!";
print FH <<"EOF";
-/**
- * This file is part of Hercules.
- * http://herc.ws - http://github.com/HerculesWS/Hercules
- *
- * Copyright (C) 2013-$year Hercules Dev Team
- *
- * Hercules 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * NOTE: This file was auto-generated and should never be manually edited,
- * as it will get overwritten.
- */
-
+$fileheader
struct {
EOF
@@ -695,36 +673,12 @@ EOF
or die "cannot open > $fname: $!";
print FH <<"EOF";
-/**
- * This file is part of Hercules.
- * http://herc.ws - http://github.com/HerculesWS/Hercules
- *
- * Copyright (C) 2013-$year Hercules Dev Team
- *
- * Hercules 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * NOTE: This file was auto-generated and should never be manually edited,
- * as it will get overwritten.
- */
-
+$fileheader
EOF
foreach my $key (@$keysref) {
print FH <<"EOF";
-/* $key */
+/* $key2original{$key} */
EOF
foreach my $if (@{ $ifs{$key} }) {
@@ -732,7 +686,6 @@ EOF
unless ($if->{type} eq 'void') {
$initialization = "\n\t$if->{type} retVal___$if->{typeinit};";
- $initialization .= "\n\tmemset(&retVal___, '\\0', sizeof($if->{type}));" if $if->{memset};
}
$beforeblock3 .= "\n\t\t\t$_" foreach (@{ $if->{before} });