diff options
author | Haru <haru@dotalux.com> | 2013-10-08 20:55:27 +0200 |
---|---|---|
committer | Haru <haru@dotalux.com> | 2013-10-09 05:49:04 +0200 |
commit | 5fdbee45f634d5d5b29ffa3144c8ac4881c10578 (patch) | |
tree | 87ff7e5bab40749666f44d69b24da3b75a1c1f12 /tools/HPMHookGen | |
parent | 540c7071234d44875bf397fb80d2f18c4f4db1bf (diff) | |
download | hercules-5fdbee45f634d5d5b29ffa3144c8ac4881c10578.tar.gz hercules-5fdbee45f634d5d5b29ffa3144c8ac4881c10578.tar.bz2 hercules-5fdbee45f634d5d5b29ffa3144c8ac4881c10578.tar.xz hercules-5fdbee45f634d5d5b29ffa3144c8ac4881c10578.zip |
Added HPMHookGen tool, to re-generate hooks include files
- Slightly reformatted the include files (as produced by the new tool)
- You normally won't need to use the generation tool, but in case you
do, the software requirements are:
* A Unix-compatible system (cygwin may work, or may not), capable to
use the Hercules configure/make build system
* perl (the perl executable must be in your $PATH)
* doxygen (the command-line doxygen executable must be in your $PATH)
- The generation tool was developed in collaboration with Ind
(originally in php, the file here included is a tweaked version ported
to perl)
Signed-off-by: Haru <haru@dotalux.com>
Diffstat (limited to 'tools/HPMHookGen')
-rwxr-xr-x | tools/HPMHookGen/HPMHookGen.pl | 568 | ||||
-rw-r--r-- | tools/HPMHookGen/Makefile.in | 68 | ||||
-rw-r--r-- | tools/HPMHookGen/doxygen.conf | 253 |
3 files changed, 889 insertions, 0 deletions
diff --git a/tools/HPMHookGen/HPMHookGen.pl b/tools/HPMHookGen/HPMHookGen.pl new file mode 100755 index 000000000..5333f3f03 --- /dev/null +++ b/tools/HPMHookGen/HPMHookGen.pl @@ -0,0 +1,568 @@ +#!/usr/bin/perl + +# Copyright (c) Hercules Dev Team, licensed under GNU GPL. +# See the LICENSE file + +use strict; +use warnings; +use XML::Simple; + +sub trim($) { + my $s = $_[0]; + $s =~ s/^\s+//; $s =~ s/\s+$//; + return $s; +} + +sub parse($$) { + my ($p, $d) = @_; + $p =~ s/^.*?\)\((.*)\).*$/$1/; # Clean up extra parentheses )(around the arglist) + + # Retrieve return type + unless ($d =~ /^(.+)\(\*\s*[a-zA-Z0-9_]+_interface::([^\)]+)\s*\)\(.*\)$/) { + print "Error: unable to parse '$d'\n"; + return {}; + } + my $rt = trim($1); #return type + my $name = trim($2); #function name + + my @args; + my ($anonvars, $variadic) = (0, 0); + my ($lastvar, $notes) = ('', ''); + + $p = ' ' unless $p; # ensure there's at least one character (we don't want a do{} block) + while ($p) { # Scan the string for variables + my $current = ''; + my ($paren, $needspace) = (0, 0); + + while ($p) { # Parse tokens + $p =~ s|^(?:\s*(?:/\*.*?\*/)?)*||; # strip heading whitespace and c-style comments + last unless $p; + + if ($p =~ s/^([a-zA-Z0-9_]+)//) { # Word (variable, type) + $current .= ' ' if $needspace; + $current .= $1; + $needspace = 1; + next; + } + if ($p =~ s/^(,)//) { # Comma + last unless $paren; # Argument terminator unless inside parentheses + $current .= $1; + $needspace = 1; + next; + } + if ($p =~ s/^(\*)//) { # Pointer + $current .= ' ' if $needspace; + $current .= $1; + $needspace = 0; + next; + } + if ($p =~ s/^([\[\].])//) { # Array subscript + $current .= $1; + $needspace = 0; + next; + } + if ($p =~ s/^(\()//) { # Open parenthesis + $current .= ' ' if $needspace; + $current .= $1; + $needspace = 0; + $paren++; + next; + } + if ($p =~ s/^(\))//) { # Closed parenthesis + $current .= $1; + $needspace = 1; + if (!$paren) { + $notes .= "\n/* Error: unexpected ')' */"; + print "Error: unexpected ')' at '$p'\n"; + } else { + $paren--; + } + next; + } + $p =~ s/^(.)//; # Any other symbol + $notes .= "\n/* Error: Unexpected character '$1' */"; + print "Error: Unexpected character '$1' at '$p'\n"; + $current .= $1; + $needspace = 0; + } + + $current =~ s/^\s+//; $current =~ s/\s+$//g; # trim + + next if (!$current or $current =~ /^void$/); # Skip if empty + + my ($array, $type1, $var, $type2, $indir) = ('', '', '', '', ''); + if ($current =~ qr/^ + ([\w\s\[\]*]+\() # Capture words, spaces, array subscripts, up to the first '(' (return type) + \s* # Skip spaces + (\*) # Capture the '*' from the function name + \s* # Skip spaces + ([\w]*) # Capture words (function name) + \s* # Skip spaces + (\)\s*\([\w\s\[\]*,]*\)) # Capture first ')' followed by a '( )' block containing arguments + \s* # Skip spaces + $/x + ) { # Match a function pointer + $type1 = trim($1); + $indir = $2; + $var = trim($3 // ''); + $type2 = trim($4); + } elsif ($current eq '...') { # Match a '...' variadic argument + $type1 = '...'; + $indir = ''; + $var = ''; + $type2 = ''; + } else { # Match a "regular" variable + $type1 = ''; + while(1) { + if ($current =~ /^(const)\s+(.*)$/) { # const modifier + $type1 .= "$1 "; + $current = $2 // ''; + next; + } + if ($current =~ /^((?:un)?signed)\s+((?:char|int|long|short)[*\s]+.*)$/ + or $current =~ /^(long|short)\s+((?:int|long)[*\s]+.*)$/ + ) { # signed/unsigned/long/short modifiers + $current = $2; + $type1 .= "$1 "; + next; + } + if ($current =~ /^(struct|enum)\s+(.*)$/) { # enum and struct names + $current = $2 // ''; + $type1 .= "$1 "; + } + last; # No other modifiers + } + if ($current =~ /^\s*(\w+)([*\s]*)(\w*)\s*((?:\[\])?)$/) { # Variable type and name + $type1 .= trim($1); + $indir = trim($2 // ''); + $var = trim($3 // ''); + $array = trim($4 // ''); + $type2 = ''; + } else { # Unsupported + $notes .= "\n/* Error: Unhandled var type '$current' */"; + print "Error: Unhandled var type '$current'\n"; + push(@args, {$current}); + next; + } + } + unless ($var) { + $anonvars++; + $var = "p$anonvars"; + } + my ($callvar, $pre_code, $post_code, $dereference, $addressof) = ($var, '', '', '', ''); + my $indirectionlvl = () = $indir =~ /\*/; + if ($type1 eq 'va_list') { # Special handling for argument-list variables + $callvar = "${var}___copy"; + $pre_code = "va_list ${callvar}; va_copy(${callvar}, ${var});"; + $post_code = "va_end(${callvar});"; + } elsif ($type1 eq '...') { # Special handling for variadic arguments + unless ($lastvar) { + $notes .= "\n/* Error: Variadic function with no fixed arguments */"; + print "Error: Variadic function with no fixed arguments\n"; + next; + } + $pre_code = "va_list ${callvar}; va_start(${callvar}, ${lastvar});"; + $post_code = "va_end(${callvar});"; + $var = ''; + $variadic = 1; + } elsif (!$indirectionlvl) { # 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, + }); + $lastvar = $var; + } + + my $rtmemset = 0; + my $rtinit = ''; + foreach ($rt) { # Decide initialization for the return value + my $x = $_; + if ($x =~ /^const\s+(.+)$/) { # Strip const modifier + $x = $1; + } + if ($x =~ /\*/g) { # Pointer + $rtinit = ' = NULL'; + } elsif ($x eq 'void') { # void + $rtinit = ''; + } elsif ($x eq 'bool') { # bool + $rtinit = ' = false'; + } elsif ($x =~ /^(?:enum\s+)?damage_lv$/) { # Known enum damage_lv + $rtinit = ' = ATK_NONE'; + } elsif ($x =~ /^(?:enum\s+)?sc_type$/) { # Known enum sc_type + $rtinit = ' = SC_NONE'; + } elsif ($x =~/^(?:enum\s+)?c_op$/) { # Known enum c_op + $rtinit = ' = C_NOP'; + } elsif ($x =~ /^enum\s+BATTLEGROUNDS_QUEUE_ACK$/) { # Known enum BATTLEGROUNDS_QUEUE_ACK + $rtinit = ' = BGQA_SUCCESS'; + } elsif ($x =~ /^enum\s+bl_type$/) { # Known enum bl_type + $rtinit = ' = BL_NUL'; + } elsif ($x =~ /^enum\s+homun_type$/) { # Known enum homun_type + $rtinit = ' = HT_INVALID'; + } elsif ($x =~ /^struct\s+.*$/ or $x eq 'DBData') { # Structs + $rtinit = ''; + $rtmemset = 1; + } elsif ($x =~ /^(?:(?:un)?signed\s+)?(?:char|int|long|short)$/ + or $x =~ /^(?:long|short)\s+(?:int|long)$/ + or $x =~ /^u?int(?:8|16|32|64)$/ + or $x eq 'defType' + ) { # Numeric variables + $rtinit = ' = 0'; + } else { # Anything else + $notes .= "\n/* Unknown return type '$rt'. Initializing to '0'. */"; + print "Unknown return type '$rt'. Initializing to '0'.\n"; + $rtinit = ' = 0'; + } + } + + return { + name => $name, + vname => $variadic ? "v$name" : $name, + type => $rt, + typeinit => $rtinit, + memset => $rtmemset, + variadic => $variadic, + args => \@args, + notes => $notes, + }; +} + +my %key2original; +my @files = grep { -f } glob 'doxyoutput/xml/*interface*.xml'; +my %ifs; +my @keys; +foreach my $file (@files) { # Loop through the xml files + + my $xml = new XML::Simple; + my $data = $xml->XMLin($file); + + my $loc = $data->{compounddef}->{location}; + next unless $loc->{file} =~ /src\/map\//; # We only handle mapserver for the time being + + my $key = $data->{compounddef}->{compoundname}; + my $original = $key; + + # Some known interfaces with different names + if ($key =~ /battleground/) { + $key = "bg"; + } elsif ($key =~ /guild_storage/) { + $key = "gstorage"; + } elsif ($key =~ /homunculus/) { + $key = "homun"; + } elsif ($key =~ /irc_bot/) { + $key = "ircbot"; + } elsif ($key =~ /log_interface/) { + $key = "logs"; + } else { + $key =~ s/_interface//; + } + + foreach my $v ($data->{compounddef}->{sectiondef}) { # Loop through the sections + my $memberdef = $v->{memberdef}; + foreach my $fk (sort { # Sort the members in declaration order according to what the xml says + my $astart = $memberdef->{$a}->{location}->{bodystart} || $memberdef->{$a}->{location}->{line}; + my $bstart = $memberdef->{$b}->{location}->{bodystart} || $memberdef->{$b}->{location}->{line}; + $astart <=> $bstart + } keys %$memberdef) { # Loop through the members + my $f = $memberdef->{$fk}; + + my $t = $f->{argsstring}; + 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}); + 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. + # i.e. you can't hook on map->foreachinmap, but you hook on map->vforeachinmap + # (foreachinmap is guaranteed to do nothing other than call vforeachinmap) + next if ($if->{variadic}); + + # Some preprocessing + $if->{hname} = "HP_${key}_$if->{name}"; + $if->{hvname} = "HP_${key}_$if->{vname}"; + + $if->{handlerdef} = "$if->{type} $if->{hname}("; + $if->{predef} = "$if->{type} (*preHookFunc) ("; + $if->{postdef} = "$if->{type} (*postHookFunc) ("; + if ($if->{type} eq 'void') { + $if->{precall} = ''; + $if->{postcall} = ''; + $if->{origcall} = ''; + } else { + $if->{precall} = "retVal___ = "; + $if->{postcall} = "retVal___ = "; + $if->{origcall} = "retVal___ = "; + } + $if->{precall} .= "preHookFunc("; + $if->{postcall} .= "postHookFunc("; + $if->{origcall} .= "HPMHooks.source.$key.$if->{vname}("; + $if->{before} = []; $if->{after} = []; + + my ($i, $j) = (0, 0); + + if ($if->{type} ne 'void') { + $j++; + $if->{postdef} .= "$if->{type} retVal___"; + $if->{postcall} .= "retVal___"; + } + + foreach my $arg (@{ $if->{args} }) { + push(@{ $if->{before} }, $arg->{pre}) if ($arg->{pre}); + push(@{ $if->{after} }, $arg->{post}) if ($arg->{post}); + if ($i) { + $if->{handlerdef} .= ', '; + $if->{predef} .= ', '; + $if->{precall} .= ', '; + $if->{origcall} .= ', '; + } + if ($j) { + $if->{postdef} .= ', '; + $if->{postcall} .= ', '; + } + $if->{handlerdef} .= $arg->{orig}; + $if->{predef} .= $arg->{hookf}; + $if->{precall} .= $arg->{hookc}; + $if->{postdef} .= $arg->{hookf}; + $if->{postcall} .= $arg->{hookc}; + $if->{origcall} .= $arg->{origc}; + $i++; $j++; + } + + if (!$i) { + $if->{predef} .= 'void'; + $if->{handlerdef} .= 'void'; + } + if (!$j) { + $if->{postdef} .= 'void'; + } + + $if->{handlerdef} .= ')'; + $if->{predef} .= ");"; + $if->{precall} .= ");"; + $if->{postdef} .= ");"; + $if->{postcall} .= ");"; + $if->{origcall} .= ");"; + + $key2original{$key} = $original; + $ifs{$key} = [] unless $ifs{$key}; + push(@{ $ifs{$key} }, $if); + } + } + push(@keys, $key) if $key2original{$key}; +} + +# Some interfaces use different names +my %exportsymbols = map { + $_ => &{ sub ($) { + return 'battlegrounds' if $_ =~ /^bg$/; + return $_; + }}($_); +} @keys; + +my ($maxlen, $idx) = (0, 0); +my $fname; +$fname = "../../src/plugins/HPMHooking/HPMHooking.HookingPoints.inc"; +open(FH, ">", $fname) + or die "cannot open > $fname: $!"; + +print FH <<"EOF"; +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// +// NOTE: This file was auto-generated and should never be manually edited, +// as it will get overwritten. + +struct HookingPointData HookingPoints[] = { +EOF + +foreach my $key (@keys) { + print FH "/* ".$key." */\n"; + foreach my $if (@{ $ifs{$key} }) { + + print FH <<"EOF"; + { HP_POP($key\->$if->{name}), HP_POP2($if->{hname}), $idx }, +EOF + + $idx += 2; + $maxlen = length($key."->".$if->{name}) if( length($key."->".$if->{name}) > $maxlen ) + } +} +print FH <<"EOF"; +}; + +int HookingPointsLenMax = $maxlen; +EOF +close FH; + +$fname = "../../src/plugins/HPMHooking/HPMHooking.sources.inc"; +open(FH, ">", $fname) + or die "cannot open > $fname: $!"; + +print FH <<"EOF"; +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// +// NOTE: This file was auto-generated and should never be manually edited, +// as it will get overwritten. + +EOF +foreach my $key (@keys) { + + print FH <<"EOF"; +memcpy(&HPMHooks.source.$key, $key, sizeof(struct $key2original{$key})); +EOF +} +close FH; + +$fname = "../../src/plugins/HPMHooking/HPMHooking.GetSymbol.inc"; +open(FH, ">", $fname) + or die "cannot open > $fname: $!"; + +print FH <<"EOF"; +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// +// NOTE: This file was auto-generated and should never be manually edited, +// as it will get overwritten. + +EOF +foreach my $key (@keys) { + + print FH <<"EOF"; +if( !($key = GET_SYMBOL("$exportsymbols{$key}") ) ) return false; +EOF +} +close FH; + +$fname = "../../src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc"; +open(FH, ">", $fname) + or die "cannot open > $fname: $!"; + +print FH <<"EOF"; +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// +// NOTE: This file was auto-generated and should never be manually edited, +// as it will get overwritten. + +struct { +EOF + +foreach my $key (@keys) { + foreach my $if (@{ $ifs{$key} }) { + + print FH <<"EOF"; + struct HPMHookPoint *$if->{hname}_pre; + struct HPMHookPoint *$if->{hname}_post; +EOF + } +} +print FH <<"EOF"; +} list; + +struct { +EOF + +foreach my $key (@keys) { + foreach my $if (@{ $ifs{$key} }) { + + print FH <<"EOF"; + int $if->{hname}_pre; + int $if->{hname}_post; +EOF + } +} +print FH <<"EOF"; +} count; + +struct { +EOF + +foreach my $key (@keys) { + + print FH <<"EOF"; + struct $key2original{$key} $key; +EOF +} + +print FH <<"EOF"; +} source; +EOF +close FH; + +$fname = "../../src/plugins/HPMHooking/HPMHooking.Hooks.inc"; +open(FH, ">", $fname) + or die "cannot open > $fname: $!"; + +print FH <<"EOF"; +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// +// NOTE: This file was auto-generated and should never be manually edited, +// as it will get overwritten. + +EOF +foreach my $key (@keys) { + + print FH <<"EOF"; +/* $key */ +EOF + + foreach my $if (@{ $ifs{$key} }) { + my ($initialization, $beforeblock3, $beforeblock2, $afterblock3, $afterblock2, $retval) = ('', '', '', '', '', ''); + + 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} }); + $afterblock3 .= "\n\t\t\t$_" foreach (@{ $if->{after} }); + $beforeblock2 .= "\n\t\t$_" foreach (@{ $if->{before} }); + $afterblock2 .= "\n\t\t$_" foreach (@{ $if->{after} }); + $retval = ' retVal___' unless $if->{type} eq 'void'; + + print FH <<"EOF"; +$if->{handlerdef} {$if->{notes} + int hIndex = 0;${initialization} + if( HPMHooks.count.$if->{hname}_pre ) { + $if->{predef} + for(hIndex = 0; hIndex < HPMHooks.count.$if->{hname}_pre; hIndex++ ) {$beforeblock3 + preHookFunc = HPMHooks.list.$if->{hname}_pre[hIndex].func; + $if->{precall}$afterblock3 + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return$retval; + } + } + {$beforeblock2 + $if->{origcall}$afterblock2 + } + if( HPMHooks.count.$if->{hname}_post ) { + $if->{postdef} + for(hIndex = 0; hIndex < HPMHooks.count.$if->{hname}_post; hIndex++ ) {$beforeblock3 + postHookFunc = HPMHooks.list.$if->{hname}_post[hIndex].func; + $if->{postcall}$afterblock3 + } + } + return$retval; +} +EOF + } +} + +close FH; + diff --git a/tools/HPMHookGen/Makefile.in b/tools/HPMHookGen/Makefile.in new file mode 100644 index 000000000..10a3c55ba --- /dev/null +++ b/tools/HPMHookGen/Makefile.in @@ -0,0 +1,68 @@ +@SET_MAKE@ + +COMMON_C = $(shell ls ../../src/common/*.c) +COMMON_H = $(shell ls ../../src/common/*.h) +MAP_C = $(shell ls ../../src/map/*.c) +MAP_H = $(shell ls ../../src/map/*.h) +CHAR_C = $(shell ls ../../src/char/*.c) +CHAR_H = $(shell ls ../../src/char/*.h) +LOGIN_C = $(shell ls ../../src/login/*.c) +LOGIN_H = $(shell ls ../../src/login/*.h) +ALL_C = $(COMMON_C) $(MAP_C) $(CHAR_C) $(LOGIN_C) +ALL_H = $(COMMON_H) $(MAP_H) $(CHAR_H) $(LOGIN_H) + +HOOK_INC = $(addprefix ../../src/plugins/HPMHooking., \ + $(addsuffix .inc, HookingPoints sources GetSymbol HPMHooksCore Hooks)) + +HAVE_DOXYGEN=@HAVE_DOXYGEN@ +HAVE_PERL=@HAVE_PERL@ +ifeq ($(HAVE_DOXYGEN)$(HAVE_PERL),yesyes) + ALL_DEPENDS = hooks +else + ifeq ($(HAVE_PERL),no) + ALL_DEPENDS = needs_perl + else + ifeq ($(HAVE_DOXYGEN),no) + ALL_DEPENDS = needs_doxygen + endif + endif +endif + +##################################################################### +.PHONY: hooks clean buildclean generate + +all: $(ALL_DEPENDS) + +buildclean: + +clean: buildclean + @echo " CLEAN HPMHookGen" + @rm -rf doxyoutput + +Makefile: Makefile.in + @$(MAKE) -C ../.. tools/HPMHookGen/Makefile + +hooks: $(HOOK_INC) + +##################################################################### + +$(HOOK_INC): generate + +generate: doxyoutput + @echo " Regenerating hook definitions..." + @perl HPMHookGen.pl + +doxyoutput: $(ALL_C) $(ALL_H) doxygen.conf + @echo " Extracting functions information..." + @doxygen doxygen.conf + +##################################################################### + +needs_doxygen: + @echo "doxygen not found or disabled by the configure script" + @exit 1 + +needs_perl: + @echo "perl not found or disabled by the configure script" + @exit 1 + diff --git a/tools/HPMHookGen/doxygen.conf b/tools/HPMHookGen/doxygen.conf new file mode 100644 index 000000000..2f3d1d4f9 --- /dev/null +++ b/tools/HPMHookGen/doxygen.conf @@ -0,0 +1,253 @@ +# Doxyfile 1.8.4 + +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = "Hercules HPMHookGen" +PROJECT_NUMBER = +PROJECT_BRIEF = +PROJECT_LOGO = +OUTPUT_DIRECTORY = doxyoutput +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = NO +REPEAT_BRIEF = NO +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = NO +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +TCL_SUBST = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = h=C +MARKDOWN_SUPPORT = NO +AUTOLINK_SUPPORT = NO +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = NO +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = NO +LOOKUP_CACHE_SIZE = 0 +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = YES +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = NO +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = NO +GENERATE_TESTLIST = NO +GENERATE_BUGLIST = NO +GENERATE_DEPRECATEDLIST= NO +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 0 +SHOW_USED_FILES = NO +SHOW_FILES = NO +SHOW_NAMESPACES = NO +FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = +QUIET = YES +WARNINGS = YES +WARN_IF_UNDOCUMENTED = NO +WARN_IF_DOC_ERROR = NO +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +INPUT = ../../src/map ../../src/common ../../src/char ../../src/login +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.c *.h +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = NO +USE_HTAGS = NO +VERBATIM_HEADERS = NO +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +GENERATE_HTML = NO +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_EXTRA_STYLESHEET = +HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = YES +HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_EXTENSIONS = +MATHJAX_CODEFILE = +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHENGINE_URL = +SEARCHDATA_FILE = searchdata.xml +EXTERNAL_SEARCH_ID = +EXTRA_SEARCH_MAPPINGS = +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4 +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +LATEX_EXTRA_FILES = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +GENERATE_XML = YES +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = NO +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook +GENERATE_AUTOGEN_DEF = NO +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = NO +EXTERNAL_PAGES = NO +PERL_PATH = /usr/bin/perl +CLASS_DIAGRAMS = NO +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = NO +COLLABORATION_GRAPH = NO +GROUP_GRAPHS = NO +UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = NO +INCLUDED_BY_GRAPH = NO +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = NO +DIRECTORY_GRAPH = NO +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = NO +DOT_CLEANUP = YES |