Major reorganization and cleanup.

diff --git a/tools/winapi_check/win32/wow32.api b/tools/winapi_check/win32/wow32.api
index e69de29..8b13789 100644
--- a/tools/winapi_check/win32/wow32.api
+++ b/tools/winapi_check/win32/wow32.api
@@ -0,0 +1 @@
+
diff --git a/tools/winapi_check/winapi.pm b/tools/winapi_check/winapi.pm
index a4b769d..87657b0 100644
--- a/tools/winapi_check/winapi.pm
+++ b/tools/winapi_check/winapi.pm
@@ -2,7 +2,14 @@
 
 use strict;
 
-my @winapis;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
+require Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT = qw();
+@EXPORT_OK = qw($win16api $win32api @winapis);
+
+use vars qw($win16api $win32api @winapis);
 
 sub new {
     my $proto = shift;
@@ -30,11 +37,25 @@
 	$self->parse_api_file($file,$module);
     }   
 
+    if($$name eq "win16") {
+	$win16api = $self;
+    } elsif($$name eq "win32") {
+	$win32api = $self;
+    }
+
     push @winapis, $self;
 
     return $self;
 }
 
+sub win16api {
+    return $win16api;
+}
+
+sub win32api {
+    return $win32api;
+}
+
 sub parse_api_file {
     my $self = shift;
 
@@ -202,6 +223,17 @@
 	    }
 	}
     }
+
+    for my $internal_name ($win32api->all_internal_functions) {
+	my $module16 = $win16api->function_internal_module($internal_name);
+	if(defined($module16) &&
+	   !$win16api->function_stub($internal_name) && 
+	   !$win32api->function_stub($internal_name))
+	{
+	    $win16api->found_shared_internal_function($internal_name);
+	    $win32api->found_shared_internal_function($internal_name);
+	}
+    }
 }
 
 sub read_all_spec_files {
@@ -733,7 +765,14 @@
     return $$function_internal_calling_convention{$name};
 }
 
-sub is_shared_function {
+sub all_shared_internal_functions {
+    my $self = shift;
+    my $function_shared = \%{$self->{FUNCTION_SHARED}};
+
+    return sort(keys(%$function_shared));
+}
+
+sub is_shared_internal_function {
     my $self = shift;
     my $function_shared = \%{$self->{FUNCTION_SHARED}};
 
@@ -742,7 +781,7 @@
     return $$function_shared{$name};
 }
 
-sub found_shared_function {
+sub found_shared_internal_function {
     my $self = shift;
     my $function_shared = \%{$self->{FUNCTION_SHARED}};
 
@@ -818,79 +857,117 @@
 # class methods
 #
 
-sub get_all_module_internal_ordinal {
+sub _get_all_module_internal_ordinal {
+    my $winapi = shift;
     my $internal_name = shift;
 
     my @entries = ();
-    foreach my $winapi (@winapis) {
-	my @name = (); {
-	    my $name = $winapi->function_external_name($internal_name);
-	    if(defined($name)) {
-		@name = split(/ & /, $name);
-	    }
-	}
-	my @module = (); {
-	    my $module = $winapi->function_internal_module($internal_name);
-	    if(defined($module)) {
-		@module = split(/ & /, $module);
-	    }
-	}
-	my @ordinal = (); {
-	    my $ordinal = $winapi->function_internal_ordinal($internal_name);
-	    if(defined($ordinal)) {
-		@ordinal = split(/ & /, $ordinal);
-	    }
-	}
 
-	my $name;
-	my $module;
-	my $ordinal;
-	while(defined($name = shift @name) &&
-	      defined($module = shift @module) &&
-	      defined($ordinal = shift @ordinal)) 
-	{
-	    push @entries, [$name, $module, $ordinal];
+    my @name = (); {
+	my $name = $winapi->function_external_name($internal_name);
+	if(defined($name)) {
+	    @name = split(/ & /, $name);
 	}
     }
 
+    my @module = (); {
+	my $module = $winapi->function_internal_module($internal_name);
+	if(defined($module)) {
+	    @module = split(/ & /, $module);
+	}
+    }
+
+    my @ordinal = (); {
+	my $ordinal = $winapi->function_internal_ordinal($internal_name);
+	if(defined($ordinal)) {
+	    @ordinal = split(/ & /, $ordinal);
+	}
+    }
+
+    my $name;
+    my $module;
+    my $ordinal;
+    while(defined($name = shift @name) &&
+	  defined($module = shift @module) &&
+	  defined($ordinal = shift @ordinal)) 
+    {
+	push @entries, [$name, $module, $ordinal];
+    }
+
     return @entries;
 }
 
-sub get_all_module_external_ordinal {
+sub get_all_module_internal_ordinal16 {
+    return _get_all_module_internal_ordinal($win16api, @_);
+}
+
+sub get_all_module_internal_ordinal32 {
+    return _get_all_module_internal_ordinal($win32api, @_);
+}
+
+sub get_all_module_internal_ordinal {
+    my @entries = ();
+    foreach my $winapi (@winapis) {
+	push @entries, _get_all_module_internal_ordinal($winapi, @_);
+    }
+
+    return @entries;
+}
+
+sub _get_all_module_external_ordinal {
+    my $winapi = shift;
     my $external_name = shift;
 
     my @entries = ();
-    foreach my $winapi (@winapis) {
-	my @name = (); {
-	    my $name = $winapi->function_internal_name($external_name);
-	    if(defined($name)) {
-		@name = split(/ & /, $name);
-	    }
-	}
-	my @module = (); {
-	    my $module = $winapi->function_external_module($external_name);
-	    if(defined($module)) {
-		@module = split(/ & /, $module);
-	    }
-	}
-	my @ordinal = (); {
-	    my $ordinal = $winapi->function_external_ordinal($external_name);
-	    if(defined($ordinal)) {
-		@ordinal = split(/ & /, $ordinal);
-	    }
-	}
 
-	my $name;
-	my $module;
-	my $ordinal;
-	while(defined($name = shift @name) &&
-	      defined($module = shift @module) &&
-	      defined($ordinal = shift @ordinal)) 
-	{
-	    push @entries, [$name, $module, $ordinal];
+    my @name = (); {
+	my $name = $winapi->function_internal_name($external_name);
+	if(defined($name)) {
+	    @name = split(/ & /, $name);
 	}
     }
 
+    my @module = (); {
+	my $module = $winapi->function_external_module($external_name);
+	if(defined($module)) {
+	    @module = split(/ & /, $module);
+	}
+    }
+
+    my @ordinal = (); {
+	my $ordinal = $winapi->function_external_ordinal($external_name);
+	if(defined($ordinal)) {
+	    @ordinal = split(/ & /, $ordinal);
+	}
+    }
+    
+    my $name;
+    my $module;
+    my $ordinal;
+    while(defined($name = shift @name) &&
+	  defined($module = shift @module) &&
+	  defined($ordinal = shift @ordinal)) 
+    {
+	push @entries, [$name, $module, $ordinal];
+    }
+ 
+    return @entries;
+}
+
+sub get_all_module_external_ordinal16 {
+    return _get_all_module_external_ordinal($win16api, @_);
+}
+
+sub get_all_module_external_ordinal32 {
+    return _get_all_module_external_ordinal($win32api, @_);
+}
+
+sub get_all_module_external_ordinal {
+    my @entries = ();
+    foreach my $winapi (@winapis) {
+	push @entries, _get_all_module_external_ordinal($winapi, @_);
+    }
+
     return @entries;
 }
 
diff --git a/tools/winapi_check/winapi_check b/tools/winapi_check/winapi_check
index c67233c..6c7f512 100755
--- a/tools/winapi_check/winapi_check
+++ b/tools/winapi_check/winapi_check
@@ -14,71 +14,30 @@
 
 use strict;
 
-my $wine_dir;
-my $winapi_dir;
-my $winapi_check_dir;
-my $tool;
-
 BEGIN {
-
-    if($0 =~ m%^((.*?)/?tools/([^/]+))/winapi_check$%)
-    {
-        $winapi_dir = $1;
-        $winapi_check_dir = $1;
-	$tool = $3;
-
-        if(defined($2) && $2 ne "")
-        {
-            $wine_dir = $2;
-        } else {
-            $wine_dir = ".";
-        } 
-	
-	$winapi_dir =~ s%^\./%%;
-        $winapi_dir =~ s/$tool/winapi/;
-
-	$winapi_check_dir =~ s%^\./%%;
-    } else {
-	print STDERR "$tool: You must run this tool in the main Wine directory or a sub directory\n";
-	exit 1;
-    }
-    @INC = ($winapi_check_dir, $winapi_dir);
-
-    require "modules.pm";
-    require "nativeapi.pm";
-    require "output.pm";
-    require "preprocessor.pm";
-    require "winapi.pm";
-    require "winapi_documentation.pm";
-    require "winapi_function.pm";
-    require "winapi_local.pm";
-    require "winapi_global.pm";
-    require "winapi_options.pm";
-    require "winapi_parser.pm";
-
-    import modules;
-    import nativeapi;
-    import output;
-    import preprocessor;
-    import winapi;
-    import winapi_documentation;
-    import winapi_function;
-    import winapi_local;
-    import winapi_global;
-    import winapi_options;
-    import winapi_parser;
+    $0 =~ m%^(.*?/?tools)/winapi_check/winapi_check$%;
+    require "$1/winapi/setup.pm";
 }
 
-my $current_dir = ".";
-if(length($wine_dir) != 1) {
-    my $pwd; chomp($pwd = `pwd`);
-    foreach my $n (1..((length($wine_dir) + 1) / 3)) {
-	$pwd =~ s/\/([^\/]*)$//;
-	$current_dir = "$1/$current_dir";
-    }
-    $current_dir =~ s%/\.$%%;
-    $current_dir =~ s%^\./%%;
-}
+use config qw(
+    &file_absolutize &file_normalize
+    &file_type &files_filter
+    &file_skip &files_skip 
+    &get_spec_files
+    $current_dir $wine_dir $winapi_dir $winapi_check_dir
+);
+use modules;
+use nativeapi;
+use output;
+use preprocessor;
+use util qw(&is_subset);
+use winapi;
+use winapi_documentation;
+use winapi_function;
+use winapi_local;
+use winapi_global;
+use winapi_options;
+use winapi_parser;
 
 my $output = 'output'->new;
 
@@ -92,69 +51,6 @@
     exit;
 }
 
-sub file_absolutize {
-    local $_ = shift;
-
-    $_ = file_normalize($_);
-    if(!s%^$wine_dir/%%) {
-	$_ = "$current_dir/$_";
-    }
-    s%^\./%%;
-
-    return $_;
-}
-
-sub file_normalize {
-    local $_ = shift;
-
-    foreach my $dir (split(m%/%, $current_dir)) {
-	s%^(\.\./)*\.\./$dir/%%;
-	if(defined($1)) {
-	    $_ = "$1$_";
-	}
-    }
-
-    return $_;
-}
-
-sub file_type {
-    local $_ = shift;
-
-    $_ = file_absolutize($_);
-
-    m%^(?:libtest|rc|server|tests|tools)/% && return "";
-    m%^(?:programs|debugger|miscemu)/% && return "wineapp";
-    m%^(?:library|tsx11|unicode)/% && return "library";
-    m%^windows/x11drv/wineclipsrv.c% && return "application";
-
-    return "winelib";
-}
-
-sub file_skip {
-    local $_ = shift;
-
-    $_ = file_absolutize($_);
-
-    m%^(?:libtest|programs|rc|server|tests|tools)/% && return 1;
-    m%^(?:debugger|miscemu|tsx11|unicode)/% && return 1;
-    m%^dlls/wineps/data/% && return 1;
-    m%^windows/x11drv/wineclipsrv.c% && return 1;
-    m%^dlls/winmm/wineoss/midipatch.c% && return 1;
-
-    return 0;
-}
-
-sub files_skip {
-    my @files;
-    foreach my $file (@_) {
-	if(!file_skip($file)) {
-	    push @files, $file;
-	}
-    }
-
-    return @files;
-}
-
 my $modules = 'modules'->new($options, $output, $wine_dir, $current_dir, \&file_type, "$winapi_check_dir/modules.dat");
 
 my $win16api = 'winapi'->new($options, $output, "win16", "$winapi_check_dir/win16");
@@ -170,20 +66,6 @@
 
 my $nativeapi = 'nativeapi'->new($options, $output, "$winapi_check_dir/nativeapi.dat", "$wine_dir/configure.in", "$wine_dir/include/config.h.in");
 
-for my $internal_name ($win32api->all_internal_functions) {
-    my $module16 = $win16api->function_internal_module($internal_name);
-    my $module32 = $win32api->function_internal_module($internal_name);
-	
-    if(defined($module16)) {
-	$win16api->found_shared_function($internal_name);
-	$win32api->found_shared_function($internal_name);
-
-	if($options->shared) {
-	    $output->write("*.spec: $internal_name: is shared between $module16 (Win16) and $module32 (Win32)\n");
-	}
-    }
-}
-
 my %includes;
 {   
     my @files = map {
@@ -245,22 +127,20 @@
 	}
 	
 	my $found_function = sub {
-	    my $line = shift;
-	    my $refdebug_channels = shift;
-	    my @debug_channels = @$refdebug_channels;
-	    my $documentation = shift;
-	    my $linkage = shift;
-	    my $return_type = shift;
-	    my $calling_convention = shift;
-	    my $internal_name = shift;
-	    my $refargument_types = shift;
-	    my @argument_types = @$refargument_types;
-	    my $refargument_names = shift;
-	    my @argument_names = @$refargument_names;
-	    my $refargument_documentations = shift;
-	    my @argument_documentations = @$refargument_documentations;
-	    my $statements = shift;
+	    my $function = shift;
 
+	    my $documentation_line = $function->documentation_line;
+	    my $documentation = $function->documentation;
+	    my $function_line = $function->function_line;
+	    my $linkage = $function->linkage;
+	    my $return_type = $function->return_type;
+	    my $calling_convention = $function->calling_convention;
+	    my $internal_name = $function->internal_name;
+	    my @argument_types = @{$function->argument_types};
+	    my @argument_names = @{$function->argument_names};
+	    my @argument_documentations = @{$function->argument_documentations};
+	    my $statements = $function->statements;
+	    
 	    foreach my $winapi (@winapis) {
 		my $module = $winapi->function_internal_module($internal_name);
 		if(!defined($module)) { next }
@@ -314,9 +194,6 @@
     }
 }
 
-my %module_pseudo_stub_count16;
-my %module_pseudo_stub_count32;
-
 foreach my $file (@c_files) {
     my %functions = ();
 
@@ -336,26 +213,23 @@
     my $file_type = file_type($file);
 
     my $found_function = sub {
-	my $line = shift;
-	my $refdebug_channels = shift;
-	my @debug_channels = @$refdebug_channels;
-	my $documentation = shift;
-	my $linkage = shift;
-	my $return_type = shift;
-	my $calling_convention = shift;
-	my $internal_name = shift;
-	my $refargument_types = shift;
-	my @argument_types = @$refargument_types;
-	my $refargument_names = shift;
-	my @argument_names = @$refargument_names;
-	my $refargument_documentations = shift;
-	my @argument_documentations = @$refargument_documentations;
-	my $statements = shift;
+	my $function = shift;
 
-	my $documentation_line = $line;
+	my $internal_name = $function->internal_name;
+	$functions{$internal_name} = $function;
 
-	my $external_name16 = $win16api->function_external_name($internal_name);
-	my $external_name32 = $win32api->function_external_name($internal_name);
+	my $documentation_line = $function->documentation_line;
+	my $documentation = $function->documentation;
+	my $linkage = $function->linkage;
+	my $return_type = $function->return_type;
+	my $calling_convention = $function->calling_convention;
+	my @argument_types = @{$function->argument_types};
+	my @argument_names = @{$function->argument_names};
+	my @argument_documentations = @{$function->argument_documentations};
+	my $statements = $function->statements;
+
+	my $external_name16 = $function->external_name16;
+	my $external_name32 = $function->external_name32;
 
 	if($options->global) {
 	    $win16api->found_type($return_type) if $options->win16;
@@ -370,59 +244,22 @@
 	}
 
 	if($file_type eq "winelib") {
-	    my $module16 = $win16api->function_internal_module($internal_name);
-	    my $module32 = $win32api->function_internal_module($internal_name);
+	    my $module16 = $function->module16;
+	    my $module32 = $function->module32;
 
-	    if(defined($module16)) {
-		foreach my $module (split(/ & /, $module16)) {
-		    $modules->found_module_in_dir($module, $file_dir);
+	    foreach my $module ($function->modules) {
+		$modules->found_module_in_dir($module, $file_dir);
+	    }
+
+	    $output->prefix("$file: " . $function->prefix);
+
+	    if($options->shared) {
+		if($win16api->is_shared_internal_function($internal_name) || 
+		   $win32api->is_shared_internal_function($internal_name)) 
+		{
+		    $output->write("is shared between Win16 and Win32\n");
 		}
 	    }
-	    if(defined($module32)) {
-		foreach my $module (split(/ & /, $module32)) {
-		    $modules->found_module_in_dir($module, $file_dir);
-		}
-	    }
-
-	    my $previous_function;	    
-	    if(defined($functions{$internal_name})) {
-		$previous_function = $functions{$internal_name};
-	    }
-
-	    my $function = 'winapi_function'->new;
-	    $functions{$internal_name} = $function;
-	   
- 	    $function->documentation($documentation);
- 	    $function->documentation_line($documentation_line);
-	    $function->linkage($linkage);
-	    $function->file($file);
-	    $function->return_type($return_type); 
-	    $function->calling_convention($calling_convention);
-	    $function->external_name16($external_name16);
-	    $function->external_name32($external_name32);
-	    $function->internal_name($internal_name);
-	    $function->argument_types([@argument_types]);
-	    $function->argument_names([@argument_names]);
- 	    $function->argument_documentations([@argument_documentations]);
-	    $function->statements($statements);
-	    $function->module16($module16);
-	    $function->module32($module32);
-
-	    my $prefix = "";
-	    $prefix .= "$file: ";
-	    if(defined($module16) && !defined($module32)) {
-		$prefix .= "$module16: ";
-	    } elsif(!defined($module16) && defined($module32)) {
-		$prefix .= "$module32: ";
-	    } elsif(defined($module16) && defined($module32)) {
-		$prefix .= "$module16 & $module32: ";
-	    } else {
-		$prefix .= "<>: ";
-	    }
-            $prefix .= "$return_type ";
-	    $prefix .= "$calling_convention " if $calling_convention;
-	    $prefix .= "$internal_name(" . join(",", @argument_types) . "): ";
-	    $output->prefix($prefix);
 
 	    # FIXME: Not correct
 	    if(defined($external_name16)) {
@@ -437,44 +274,25 @@
 	    if($options->local && $options->misplaced &&
 	       $linkage ne "extern" && defined($statements)) 
 	    {
-		if($options->win16 && $options->report_module($module16)) {
-		    foreach my $module (split(/ & /, $module16)) {
-			my $match = 0;
-			foreach my $file_module (split(/ & /, $file_module16)) {
-			    if($module eq $file_module) {
-				$match = 1;
-			    }
-			}
-			if(!$match) {
-			    if($file ne "library/port.c" && 
-			       !$nativeapi->is_function($internal_name) &&
-			       !$win16api->function_stub($internal_name)) 
-			    {
-				$output->write("is misplaced ($module)\n");
-			    }
-			    last;
-			}
-
+		if($options->win16 && $options->report_module($module16))
+		{
+		    if($file ne "library/port.c" && 
+		       !$nativeapi->is_function($internal_name) &&
+		       !$win16api->function_stub($internal_name) &&
+		       !is_subset($module16, $file_module16))
+		    {
+			$output->write("is misplaced\n");
 		    }
 		}
 
-		if($options->win32 && $options->report_module($module32)) {
-		    foreach my $module (split(/ & /, $module32)) {
-			my $match = 0;
-			foreach my $file_module (split(/ & /, $file_module32)) {
-			    if($module eq $file_module) {
-				$match = 1;
-			    }
-			}
-			if(!$match) {
-			    if($file ne "library/port.c" && 
-			       !$nativeapi->is_function($internal_name) &&
-			       !$win32api->function_stub($internal_name)) 
-			    {
-				$output->write("is misplaced ($module)\n");
-			    }
-			    last;
-			}
+		if($options->win32 && $options->report_module($module32))
+		{
+		    if($file ne "library/port.c" && 
+		       !$nativeapi->is_function($internal_name) &&
+		       !$win32api->function_stub($internal_name) &&
+		       !is_subset($module32, $file_module32))
+		    {
+			$output->write("is misplaced\n");
 		    }
 		}
 	    }
@@ -529,23 +347,7 @@
 		}
 	    }
 
-	    if($options->stubs) {
-		if(defined($statements) && $statements =~ /FIXME[^;]*stub/) {
-		    if($options->win16 && $options->report_module($module16)) {
-			foreach my $module (split(/ \& /, $module16)) {
-			    $module_pseudo_stub_count16{$module}++;
-			}
-		    }
-		    if($options->win32 && $options->report_module($module32)) {
-			foreach my $module (split(/ \& /, $module32)) {
-			    $module_pseudo_stub_count32{$module}++;
-			}
-		    }
-		}
-	    }
-	    
 	    if($options->local && $options->documentation &&
-	       !defined($previous_function) &&
 	       (defined($module16) || defined($module32)) &&
 	       $linkage ne "extern" && defined($statements))
 	    {
@@ -683,72 +485,6 @@
 if($options->global) {
     winapi_documentation::report_documentation $options, $output;
 
-    if($options->stubs) {
-	if($options->win16) {
-	    my %module_stub_count16;
-	    my %module_total_count16;
-
-	    foreach my $internal_name ($win16api->all_internal_functions,$win16api->all_functions_stub) {
-		foreach my $module (split(/ \& /, $win16api->function_internal_module($internal_name))) {
-		    if($win16api->function_stub($internal_name)) {
-			$module_stub_count16{$module}++;
-		    }
-		    $module_total_count16{$module}++;
-		}
-	    }
-
-	    foreach my $module ($win16api->all_modules) {
-		if($options->report_module($module)) {
-		    my $real_stubs = $module_stub_count16{$module};
-		    my $pseudo_stubs = $module_pseudo_stub_count16{$module};
-
-		    if(!defined($real_stubs)) { $real_stubs = 0; }
-		    if(!defined($pseudo_stubs)) { $pseudo_stubs = 0; }
-
-		    my $stubs = $real_stubs + $pseudo_stubs;
-		    my $total = $module_total_count16{$module};
-
-		    if(!defined($total)) { $total = 0;}
-
-		    $output->write("*.c: $module: ");
-		    $output->write("$stubs of $total functions are stubs ($real_stubs real, $pseudo_stubs pseudo)\n");
-		}
-	    }
-	}
-	
-	if($options->win32) {
-	    my %module_stub_count32;
-	    my %module_total_count32;
-
-	    foreach my $internal_name ($win32api->all_internal_functions,$win32api->all_functions_stub) {
-		foreach my $module (split(/ \& /, $win32api->function_internal_module($internal_name))) {
-		    if($win32api->function_stub($internal_name)) {
-			$module_stub_count32{$module}++;
-		    }
-		    $module_total_count32{$module}++;
-		}
-	    }
-
-	    foreach my $module ($win32api->all_modules) {
-		if($options->report_module($module)) {
-		    my $real_stubs = $module_stub_count32{$module};
-		    my $pseudo_stubs = $module_pseudo_stub_count32{$module};
-
-		    if(!defined($real_stubs)) { $real_stubs = 0; }
-		    if(!defined($pseudo_stubs)) { $pseudo_stubs = 0; }
-
-		    my $stubs = $real_stubs + $pseudo_stubs;
-		    my $total = $module_total_count32{$module};
-
-		    if(!defined($total)) { $total = 0;}
-
-		    $output->write("*.c: $module: ");
-		    $output->write("$stubs of $total functions are stubs ($real_stubs real, $pseudo_stubs pseudo)\n");
-		}
-	    }
-	}
-    }
-
     if($options->headers) {
 	foreach my $name (sort(keys(%includes))) {
 	    if(!$includes{$name}{used}) {
diff --git a/tools/winapi_check/winapi_documentation.pm b/tools/winapi_check/winapi_documentation.pm
index 682c4a6..c28560c 100644
--- a/tools/winapi_check/winapi_documentation.pm
+++ b/tools/winapi_check/winapi_documentation.pm
@@ -24,6 +24,8 @@
     my $documentation_line = $function->documentation_line;
     my @argument_documentations = @{$function->argument_documentations};
 
+    my $documentation_error = 0;
+    my $documentation_warning = 0;
     if($options->documentation_name || 
        $options->documentation_ordinal ||
        $options->documentation_pedantic) 
@@ -74,17 +76,19 @@
 		if(($options->documentation_name && !$found_name) || 
 		   ($options->documentation_ordinal && !$found_ordinal))
 		{
+		    $documentation_error = 1;
 		    $output->write("documentation: expected $external_name (\U$module\E.$ordinal): \\\n$documentation\n");
 		}
 		
 	    }
 	    if($options->documentation_pedantic && $pedantic_failed) {
+		$documentation_warning = 1;
 		$output->write("documentation: pedantic failed: \\\n$documentation\n");
 	    }
 	}
     }
 
-    if($options->documentation_wrong) {
+    if(!$documentation_error && $options->documentation_wrong) {
 	foreach (split(/\n/, $documentation)) {
 	    if(/^\s*\*\s*(\S+)\s*[\(\[]\s*(\w+)\s*\.\s*([^\s\)\]]*)\s*[\)\]].*?$/) {
 		my $external_name = $1;
@@ -110,24 +114,23 @@
     }
 
     if($options->documentation_comment_indent) {
-	if($documentation =~ /^ \*(\s*)\w+(\s*)([\(\[])\s*\w+\.\s*(?:\@|\d+)\s*([\)\]])/m) {
-	    my $indent = $1;
-	    my $spacing = $2;
-	    my $left = $3;
-	    my $right = $4;
-
-	    $indent =~ s/\t/        /g;
-	    $indent = length($indent);
-
-	    $spacing =~ s/\t/        /g;
-	    $spacing = length($spacing);
-
-	    $comment_indent{$indent}++;
-	    if($indent >= 20) {
-		$output->write("documentation: comment indent is $indent\n");
+	foreach (split(/\n/, $documentation)) {
+	    if(/^\s*\*(\s*)\S+(\s*)[\(\[]\s*\w+\s*\.\s*[^\s\)\]]*\s*[\)\]].*?$/) {
+		my $indent = $1;
+		my $spacing = $2;
+		
+		$indent =~ s/\t/        /g;
+		$indent = length($indent);
+		
+		$spacing =~ s/\t/        /g;
+		$spacing = length($spacing);
+		
+		$comment_indent{$indent}++;
+		if($indent >= 20) {
+		    $output->write("documentation: comment indent is $indent\n");
+		}
+		$comment_spacing{$spacing}++;
 	    }
-
-	    $comment_spacing{$spacing}++;
 	}
     }
 
diff --git a/tools/winapi_check/winapi_function.pm b/tools/winapi_check/winapi_function.pm
index 85f1761..37c73e8 100644
--- a/tools/winapi_check/winapi_function.pm
+++ b/tools/winapi_check/winapi_function.pm
@@ -1,7 +1,15 @@
 package winapi_function;
+use base qw(function);
 
 use strict;
 
+use util qw(&normalize_set);
+use winapi qw($win16api $win32api @winapis);
+
+########################################################################
+# constructor
+#
+
 sub new {
     my $proto = shift;
     my $class = ref($proto) || $proto;
@@ -11,186 +19,266 @@
     return $self;
 }
 
-sub file {
-    my $self = shift;
-    my $file = \${$self->{FILE}};
-
-    local $_ = shift;
-
-    if(defined($_)) { $$file = $_; }
-    
-    return $$file;
-}
-
-sub documentation {
-    my $self = shift;
-    my $documentation = \${$self->{DOCUMENTATION}};
-
-    local $_ = shift;
-
-    if(defined($_)) { $$documentation = $_; }
-    
-    return $$documentation;
-}
-
-sub documentation_line {
-    my $self = shift;
-    my $documentation_line = \${$self->{DOCUMENTATION_LINE}};
-
-    local $_ = shift;
-
-    if(defined($_)) { $$documentation_line = $_; }
-    
-    return $$documentation_line;
-}
-
-sub linkage {
-    my $self = shift;
-    my $linkage = \${$self->{LINKAGE}};
-
-    local $_ = shift;
-
-    if(defined($_)) { $$linkage = $_; }
-    
-    return $$linkage;
-}
-
-sub return_type {
-    my $self = shift;
-    my $return_type = \${$self->{RETURN_TYPE}};
-
-    local $_ = shift;
-
-    if(defined($_)) { $$return_type = $_; }
-    
-    return $$return_type;
-}
-
-sub calling_convention {
-    my $self = shift;
-    my $calling_convention = \${$self->{CALLING_CONVENTION}};
-
-    local $_ = shift;
-
-    if(defined($_)) { $$calling_convention = $_; }
-    
-    return $$calling_convention;
-}
+########################################################################
+# winapi
+#
 
 sub external_name16 {
     my $self = shift;
-    my $external_name16 = \${$self->{EXTERNAL_NAME16}};
+    my $internal_name = $self->internal_name;
 
-    local $_ = shift;
+    return $win16api->function_external_name($internal_name);
+}
 
-    if(defined($_)) { $$external_name16 = $_; }
+sub external_names16 {
+    my $self = shift;
+    my $external_name16 = $self->external_name16;
     
-    return $$external_name16;
+    if(defined($external_name16)) {
+	return split(/\s*&\s*/, $external_name16);
+    } else {
+	return ();
+    }
 }
 
 sub external_name32 {
     my $self = shift;
-    my $external_name32 = \${$self->{EXTERNAL_NAME32}};
+    my $internal_name = $self->internal_name;
 
-    local $_ = shift;
-
-    if(defined($_)) { $$external_name32 = $_; }
-    
-    return $$external_name32;
+    return $win32api->function_external_name($internal_name);
 }
 
-sub internal_name {
+sub external_names32 {
     my $self = shift;
-    my $internal_name = \${$self->{INTERNAL_NAME}};
-
-    local $_ = shift;
-
-    if(defined($_)) { $$internal_name = $_; }
+    my $external_name32 = $self->external_name32;
     
-    return $$internal_name;
+    if(defined($external_name32)) {
+	return split(/\s*&\s*/, $external_name32);
+    } else {
+	return ();
+    }
 }
 
-sub argument_types {
+sub external_names {
     my $self = shift;
-    my $argument_types = \${$self->{ARGUMENT_TYPES}};
 
-    local $_ = shift;
+    my @external_names;
+    push @external_names, $self->external_names16;
+    push @external_names, $self->external_names32;
 
-    if(defined($_)) { $$argument_types = $_; }
-    
-    return $$argument_types;
-}
-
-sub argument_names {
-    my $self = shift;
-    my $argument_names = \${$self->{ARGUMENT_NAMES}};
-
-    local $_ = shift;
-
-    if(defined($_)) { $$argument_names = $_; }
-    
-    return $$argument_names;
-}
-
-sub argument_documentations {
-    my $self = shift;
-    my $argument_documentations = \${$self->{ARGUMENT_DOCUMENTATIONS}};
-
-    local $_ = shift;
-
-    if(defined($_)) { $$argument_documentations = $_; }
-    
-    return $$argument_documentations;
+    return @external_names;
 }
 
 sub module16 {
     my $self = shift;
-    my $module16 = \${$self->{MODULE16}};
+    my $internal_name = $self->internal_name;
 
-    local $_ = shift;
+    return $win16api->function_internal_module($internal_name);
+}
 
-    if(defined($_)) { $$module16 = $_; }
-    return $$module16;
+sub modules16 {
+    my $self = shift;
+    my $module16 = $self->module16;
+    
+    if(defined($module16)) {
+	return split(/\s*&\s*/, $module16);
+    } else {
+	return ();
+    }
 }
 
 sub module32 {
     my $self = shift;
-    my $module32 = \${$self->{MODULE32}};
+    my $internal_name = $self->internal_name;
 
-    local $_ = shift;
-    
-    if(defined($_)) { $$module32 = $_; }	
-    return $$module32;
+    return $win32api->function_internal_module($internal_name);
 }
 
-sub statements {
+sub modules32 {
     my $self = shift;
-    my $statements = \${$self->{STATEMENTS}};
-
-    local $_ = shift;
-
-    if(defined($_)) { $$statements = $_; }
+    my $module32 = $self->module32;
     
-    return $$statements;
+    if(defined($module32)) {
+	return split(/\s*&\s*/, $module32);
+    } else {
+	return ();
+    }
 }
 
 sub module {
     my $self = shift;
-    my $module16 = \${$self->{MODULE16}};
-    my $module32 = \${$self->{MODULE32}};
+    my $module16 = $self->module16;
+    my $module32 = $self->module32;
 
     my $module;
-    if(defined($$module16) && defined($$module32)) {
-	$module = "$$module16 & $$module32";
-    } elsif(defined($$module16)) {
-	$module = $$module16;
-    } elsif(defined($$module32)) {
-	$module = $$module32;
+    if(defined($module16) && defined($module32)) {
+	$module = "$module16 & $module32";
+    } elsif(defined($module16)) {
+	$module = $module16;
+    } elsif(defined($module32)) {
+	$module = $module32;
     } else {
 	$module = "";
     }
 }
 
+sub modules {
+    my $self = shift;
+
+    my @modules;
+    push @modules, $self->modules16;
+    push @modules, $self->modules32;
+
+    return @modules;
+}
+
+sub prefix {
+    my $self = shift;
+    my $module16 = $self->module16;
+    my $module32 = $self->module32;
+
+    my $return_type = $self->return_type;
+    my $internal_name = $self->internal_name;
+    my $calling_convention = $self->calling_convention;
+    my @argument_types = @{$self->argument_types};
+
+    if($#argument_types < 0) {
+	@argument_types = ("void");
+    }
+
+    my $prefix = "";
+    if(defined($module16) && !defined($module32)) {
+	$prefix .= normalize_set($module16) . ": ";
+    } elsif(!defined($module16) && defined($module32)) {
+	$prefix .= normalize_set($module32) . ": ";
+    } elsif(defined($module16) && defined($module32)) {
+	$prefix .= normalize_set($module16) . " & " . normalize_set($module32) . ": ";
+    } else {
+	$prefix .= "<>: ";
+    }
+    $prefix .= "$return_type ";
+    $prefix .= "$calling_convention " if $calling_convention;
+    $prefix .= "$internal_name(" . join(",", @argument_types) . "): ";
+
+    return $prefix;
+}
+
+sub calling_convention16 {
+    my $self = shift;
+    my $return_kind16 = $self->return_kind16;
+
+    my $suffix;
+    if(!defined($return_kind16)) {
+	$suffix = undef;
+    } elsif($return_kind16 =~ /^(?:void|s_word|word)$/) {
+	$suffix = "16";
+    } elsif($return_kind16 =~ /^(?:long|ptr|segptr|segstr|str|wstr)$/) {
+	$suffix = "";
+    } else {
+	$suffix = undef;
+    }
+
+    local $_ = $self->calling_convention;
+    if(/^__cdecl$/) {
+	return "cdecl";
+    } elsif(/^VFWAPIV|WINAPIV$/) {
+	if(!defined($suffix)) { return undef; }
+	return "pascal$suffix"; # FIXME: Is this correct?
+    } elsif(/^__stdcall|VFWAPI|WINAPI|CALLBACK$/) {
+	if(!defined($suffix)) { return undef; }
+	return "pascal$suffix";
+    } elsif(/^__asm$/) {
+	return "asm";
+    } else {
+	return "cdecl";
+    }
+}
+
+sub calling_convention32 {
+    my $self = shift;
+
+    local $_ = $self->calling_convention;
+    if(/^__cdecl$/) {
+	return "cdecl";
+    } elsif(/^VFWAPIV|WINAPIV$/) {
+	return "varargs";
+    } elsif(/^__stdcall|VFWAPI|WINAPI|CALLBACK$/) {
+	return "stdcall";
+    } elsif(/^__asm$/) {
+	return "asm";
+    } else {
+	return "cdecl";
+    }
+}
+
+sub get_all_module_ordinal16 {
+    my $self = shift;
+    my $internal_name = $self->internal_name;
+
+    return winapi::get_all_module_internal_ordinal16($internal_name);
+}
+
+sub get_all_module_ordinal32 {
+    my $self = shift;
+    my $internal_name = $self->internal_name;
+
+    return winapi::get_all_module_internal_ordinal32($internal_name);
+}
+
+sub get_all_module_ordinal {
+    my $self = shift;
+    my $internal_name = $self->internal_name;
+
+    return winapi::get_all_module_internal_ordinal($internal_name);
+}
+
+sub _return_kind {
+    my $self = shift;
+    my $winapi = shift;
+    my $return_type = $self->return_type;
+
+    return $winapi->translate_argument($return_type);
+}
+
+sub return_kind16 {
+    my $self = shift; return $self->_return_kind($win16api, @_);
+}
+
+sub return_kind32 {
+    my $self = shift; return $self->_return_kind($win32api, @_);
+}
+
+sub _argument_kinds {   
+    my $self = shift;
+    my $winapi = shift;
+    my @argument_types = @{$self->argument_types};
+
+    my @argument_kinds;
+    foreach my $argument_type (@argument_types) {
+	my $argument_kind = $winapi->translate_argument($argument_type);
+
+	if(defined($argument_kind) && $argument_kind eq "longlong") {
+	    push @argument_kinds, ("long", "long");
+	} else {
+	    push @argument_kinds, $argument_kind;
+	}
+    }
+
+    return [@argument_kinds];
+}
+
+sub argument_kinds16 {
+    my $self = shift; return $self->_argument_kinds($win16api, @_);
+}
+
+sub argument_kinds32 {
+    my $self = shift; return $self->_argument_kinds($win32api, @_);
+}
+
+##############################################################################
+# Accounting
+#
+
 sub function_called {    
     my $self = shift;
     my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}};
diff --git a/tools/winapi_check/winapi_local.pm b/tools/winapi_check/winapi_local.pm
index c4f7972..224dbd7 100644
--- a/tools/winapi_check/winapi_local.pm
+++ b/tools/winapi_check/winapi_local.pm
@@ -206,7 +206,7 @@
 
     }
 
-    if($segmented && $options->shared_segmented && $winapi->is_shared_function($internal_name)) {
+    if($segmented && $options->shared_segmented && $winapi->is_shared_internal_function($internal_name)) {
 	$output->write("function using segmented pointers shared between Win16 och Win32\n");
     }
 }
diff --git a/tools/winapi_check/winapi_options.pm b/tools/winapi_check/winapi_options.pm
index 60df0d5..e137f00 100644
--- a/tools/winapi_check/winapi_options.pm
+++ b/tools/winapi_check/winapi_options.pm
@@ -121,7 +121,6 @@
     "headers" => { default => 0, parent => "global", description => "headers checking" },
     "headers-duplicated" => { default => 0, parent => "headers", description => "duplicated function declarations checking" },
     "headers-misplaced" => { default => 0, parent => "headers", description => "misplaced function declarations checking" },
-    "stubs" => { default => 0, parent => "global", description => "stubs checking" }
 );
 
 my %short_options = (
diff --git a/tools/winapi_check/winapi_parser.pm b/tools/winapi_check/winapi_parser.pm
index b484407..75e63d8 100644
--- a/tools/winapi_check/winapi_parser.pm
+++ b/tools/winapi_check/winapi_parser.pm
@@ -2,6 +2,8 @@
 
 use strict;
 
+use winapi_function;
+
 sub parse_c_file {
     my $options = shift;
     my $output = shift;
@@ -13,23 +15,26 @@
     my $debug_channels = [];
 
     # local
-    my $line_number = 0;
+    my $documentation_line;
     my $documentation;
+    my $function_line;
     my $linkage;
     my $return_type;
     my $calling_convention;
-    my $function = "";
+    my $internal_name = "";
     my $argument_types;
     my $argument_names;
     my $argument_documentations;
     my $statements;
 
     my $function_begin = sub {
+	$documentation_line = shift;
 	$documentation = shift;
+	$function_line = shift;
 	$linkage = shift;
 	$return_type= shift;
 	$calling_convention = shift;
-	$function = shift;
+	$internal_name = shift;
 	$argument_types = shift;
 	$argument_names = shift;
 	$argument_documentations = shift;
@@ -49,10 +54,23 @@
 	$statements = undef;
     };
     my $function_end = sub {
-	&$function_found_callback($line_number,$debug_channels,$documentation,$linkage,$return_type,
-				  $calling_convention,$function,$argument_types,
-				  $argument_names,$argument_documentations,$statements);
-	$function = "";
+	my $function = 'winapi_function'->new;
+
+	$function->debug_channels([@$debug_channels]);
+	$function->documentation($documentation);
+	$function->documentation_line($documentation_line);
+	$function->linkage($linkage);
+	$function->file($file);
+	$function->return_type($return_type); 
+	$function->calling_convention($calling_convention);
+	$function->internal_name($internal_name);
+	$function->argument_types([@$argument_types]);
+	$function->argument_names([@$argument_names]);
+	$function->argument_documentations([@$argument_documentations]);
+	$function->statements($statements);
+
+	&$function_found_callback($function);
+	$internal_name = "";
     };
     my %regs_entrypoints;
     my @comment_lines = ();
@@ -85,7 +103,7 @@
 	    $again = 0;
 	}
 
-	# Merge conflicts in file?
+	# CVS merge conflicts in file?
 	if(/^(<<<<<<<|=======|>>>>>>>)/) {
 	    $output->write("$file: merge conflicts in file\n");
 	    last;
@@ -230,7 +248,7 @@
 		$statements .= "$line\n";
 	    }
 
-	    if($function && $level == 0) {
+	    if($internal_name && $level == 0) {
 		&$function_end;
 	    }
 	    next;	    
@@ -241,9 +259,6 @@
 	    my @lines = split(/\n/, $&);
 	    my $function_line = $. - scalar(@lines) + 1;
 
-	    # FIXME: Should be separate for documentation and function
-	    $line_number = $documentation_line;
-
 	    $_ = $'; $again = 1;
 
 	    if($11 eq "{")  {
@@ -323,20 +338,24 @@
 	    if($options->debug) {
 		print "$file: $return_type $calling_convention $name(" . join(",", @arguments) . ")\n";
 	    }
-	    
-	    &$function_begin($documentation,$linkage,$return_type,$calling_convention,$name,\@argument_types,\@argument_names,\@argument_documentations);
+
+	    &$function_begin($documentation_line, $documentation,
+			     $function_line, $linkage, $return_type, $calling_convention, $name,
+			     \@argument_types,\@argument_names,\@argument_documentations);
 	    if($level == 0) {
 		&$function_end;
 	    }
 	} elsif(/__ASM_GLOBAL_FUNC\(\s*(.*?)\s*,/s) {
 	    $_ = $'; $again = 1;
 	    my @arguments = ();
-	    &$function_begin($documentation, "", "void", "__asm", $1, \@arguments);
+	    &$function_begin($documentation_line, $documentation,
+			     $function_line, "", "void", "__asm", $1, \@arguments);
 	    &$function_end;
 	} elsif(/DC_(GET_X_Y|GET_VAL_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
 	    $_ = $'; $again = 1;
 	    my @arguments = ("HDC16");
-	    &$function_begin($documentation, "", $2, "WINAPI", $3, \@arguments);
+	    &$function_begin($documentation_line, $documentation,
+			     $function_line, "", $2, "WINAPI", $3, \@arguments);
 	    &$function_end;
 	} elsif(/DC_(GET_VAL)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,.*?\)/s) {
 	    $_ = $'; $again = 1;
@@ -349,57 +368,71 @@
 
 	    if($name16 eq "COLORREF16") { $name16 = "COLORREF"; }
 
-	    &$function_begin($documentation, "", $name16, "WINAPI", $return16, \@arguments16);
+	    &$function_begin($documentation_line, $documentation,
+			     $function_line, "", $name16, "WINAPI", $return16, \@arguments16);
 	    &$function_end;
-	    &$function_begin($documentation, "", $name32, "WINAPI", $return32, \@arguments32);
+	    &$function_begin($documentation_line, $documentation,
+			     $function_line, "", $name32, "WINAPI", $return32, \@arguments32);
 	    &$function_end;
 	} elsif(/DC_(GET_VAL_EX)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
 	    $_ = $'; $again = 1;
 	    my @arguments16 = ("HDC16", "LP" . $5 . "16");
 	    my @arguments32 = ("HDC", "LP" . $5);
-	    &$function_begin($documentation, "", "BOOL16", "WINAPI", $2 . "16", \@arguments16);
+	    &$function_begin($documentation_line, $documentation,
+			     $function_line, "", "BOOL16", "WINAPI", $2 . "16", \@arguments16);
 	    &$function_end;
-	    &$function_begin($documentation, "", "BOOL", "WINAPI", $2, \@arguments32);
+	    &$function_begin($documentation_line, $documentation,
+			     $function_line, "", "BOOL", "WINAPI", $2, \@arguments32);
 	    &$function_end;
 	} elsif(/DC_(SET_MODE)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
 	    $_ = $'; $again = 1;
 	    my @arguments16 = ("HDC16", "INT16");
 	    my @arguments32 = ("HDC", "INT");
-	    &$function_begin($documentation, "", "INT16", "WINAPI", $2 . "16", \@arguments16);
+	    &$function_begin($documentation_line, $documentation,
+			     $function_line, "", "INT16", "WINAPI", $2 . "16", \@arguments16);
 	    &$function_end;
-	    &$function_begin($documentation, "", "INT", "WINAPI", $2, \@arguments32);
+	    &$function_begin($documentation_line, $documentation,
+			     $function_line, "", "INT", "WINAPI", $2, \@arguments32);
 	    &$function_end;
 	} elsif(/WAVEIN_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
 	    $_ = $'; $again = 1;
 	    my @arguments16 = ("HWAVEIN16");
 	    my @arguments32 = ("HWAVEIN");
-	    &$function_begin($documentation, "", "UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16);
+	    &$function_begin($documentation_line, $documentation,
+			     $function_line,  "", "UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16);
 	    &$function_end;
-	    &$function_begin($documentation, "", "UINT", "WINAPI", "waveIn" . $1, \@arguments32);
+	    &$function_begin($documentation_line, $documentation,
+			     $function_line, "", "UINT", "WINAPI", "waveIn" . $1, \@arguments32);
 	    &$function_end;	    
 	} elsif(/WAVEOUT_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
 	    $_ = $'; $again = 1;
 	    my @arguments16 = ("HWAVEOUT16");
 	    my @arguments32 = ("HWAVEOUT");
-	    &$function_begin($documentation, "", "UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16);
+	    &$function_begin($documentation_line, $documentation,
+			     $function_line, "", "UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16);
 	    &$function_end;
-	    &$function_begin($documentation, "", "UINT", "WINAPI", "waveOut" . $1, \@arguments32);	    
+	    &$function_begin($documentation_line, $documentation,
+			     $function_line, "", "UINT", "WINAPI", "waveOut" . $1, \@arguments32);	    
 	    &$function_end;
 	} elsif(/WAVEOUT_SHORTCUT_(1|2)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) {
 	    $_ = $'; $again = 1;
 	    if($1 eq "1") {
 		my @arguments16 = ("HWAVEOUT16", $4);
 		my @arguments32 = ("HWAVEOUT", $4);
-		&$function_begin($documentation, "", "UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16);
+		&$function_begin($documentation_line, $documentation,
+				 $function_line, "", "UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16);
 		&$function_end;
-		&$function_begin($documentation, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32);
+		&$function_begin($documentation_line, $documentation,
+				 $function_line, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32);
 		&$function_end;
 	    } elsif($1 eq 2) {
 		my @arguments16 = ("UINT16", $4);
 		my @arguments32 = ("UINT", $4);
-		&$function_begin($documentation, "", "UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16);
+		&$function_begin($documentation_line, $documentation,
+				 $function_line, "", "UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16);
 		&$function_end;
-		&$function_begin($documentation, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32);
+		&$function_begin($documentation_line, $documentation, 
+				 $function_line, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32);
 		&$function_end;
 	    }
         } elsif(/DEFINE_REGS_ENTRYPOINT_\d+\(\s*(\S*)\s*,\s*([^\s,\)]*).*?\)/s) {