- Minor API files fixes
- Use output prefix instead of high order functions that, for some
  reason, leaks memory. The memory usage of winapi_check is now greatly
  reduced. :-)
- Turned on argument kind checking of doubles by default

diff --git a/tools/winapi_check/modules.dat b/tools/winapi_check/modules.dat
index 25821f1..46812e5 100644
--- a/tools/winapi_check/modules.dat
+++ b/tools/winapi_check/modules.dat
@@ -148,10 +148,6 @@
 
 dlls/lzexpand
 
-% dlls/mouse/mouse.spec
-
-dlls/mouse
-
 % dlls/mpr/mpr.spec
 
 dlls/mpr
@@ -310,12 +306,6 @@
 
 dlls/urlmon
 
-% dlls/user/keyboard.spec
-
-dlls/user
-memory
-windows
-
 % dlls/user/ddeml.spec
 
 dlls/user
@@ -326,6 +316,16 @@
 dlls/user
 objects
 
+% dlls/user/keyboard.spec
+
+dlls/user
+memory
+windows
+
+% dlls/user/mouse.spec
+
+dlls/user
+
 % dlls/user/user.spec
 
 controls
diff --git a/tools/winapi_check/output.pm b/tools/winapi_check/output.pm
index 59a04ae..f5241af 100644
--- a/tools/winapi_check/output.pm
+++ b/tools/winapi_check/output.pm
@@ -11,10 +11,12 @@
     my $progress = \${$self->{PROGRESS}};
     my $last_progress = \${$self->{LAST_PROGRESS}};
     my $progress_count = \${$self->{PROGRESS_COUNT}};
+    my $prefix = \${$self->{PREFIX}};
 
     $$progress = "";
     $$last_progress = "";
-    $progress_count = 0;
+    $$progress_count = 0;
+    $$prefix = "";
 
     return $self;
 }
@@ -87,14 +89,22 @@
     $self->update_progress;
 }
 
+sub prefix {
+    my $self = shift;
+    my $prefix = \${$self->{PREFIX}};
+
+    $$prefix = shift;
+}
+
 sub write {
     my $self = shift;
 
     my $message = shift;
 
+    my $prefix = \${$self->{PREFIX}};
 
     $self->hide_progress;
-    print $message;
+    print $$prefix . $message;
     $self->show_progress;
 }
 
diff --git a/tools/winapi_check/win32/oleaut32.api b/tools/winapi_check/win32/oleaut32.api
index 7a0b5e1..230000b 100644
--- a/tools/winapi_check/win32/oleaut32.api
+++ b/tools/winapi_check/win32/oleaut32.api
@@ -1,6 +1,7 @@
 %double
 
 CY
+DATE
 double
 
 %long
@@ -8,7 +9,6 @@
 BOOL
 BYTE
 CHAR
-DATE
 DWORD
 FLOAT
 HCURSOR
diff --git a/tools/winapi_check/winapi.pm b/tools/winapi_check/winapi.pm
index cc96b70..ccf9bac 100644
--- a/tools/winapi_check/winapi.pm
+++ b/tools/winapi_check/winapi.pm
@@ -219,12 +219,14 @@
     my $function_stub = \%{$self->{FUNCTION_STUB}};
     my $function_module = \%{$self->{FUNCTION_MODULE}};
     my $modules = \%{$self->{MODULES}};
+    my $module_files = \%{$self->{MODULE_FILES}};
 
     my $file = shift;
 
     my %ordinals;
     my $type;
     my $module;
+    my $module_file;
 
     if($$options->progress) {
 	$$output->progress("$file");
@@ -242,6 +244,7 @@
 
 	if($header)  {
 	    if(/^name\s*(\S*)/) { $module = $1; }
+	    if(/^file\s*(\S*)/) { $module_file = $1; }
 	    if(/^type\s*(\w+)/) { $type = $1; }
 	    if(/^\d+|@/) { $header = 0; $lookahead = 1; }
 	    next;
@@ -338,6 +341,11 @@
     close(IN);
 
     $$modules{$module}++;
+    if(defined($module_file)) {
+	$$module_files{$module} = $module_file;
+    } else {
+	$$module_files{$module} = "$module.drv";
+    }
 }
 
 sub name {
@@ -526,6 +534,16 @@
     return $$modules{$name};
 }
 
+sub module_file {
+    my $self = shift;
+
+    my $module = shift;
+
+    my $module_files = \%{$self->{MODULE_FILES}};
+
+    return $$module_files{$module};
+}
+
 sub all_functions {
     my $self = shift;
     my $function_calling_convention = \%{$self->{FUNCTION_CALLING_CONVENTION}};
diff --git a/tools/winapi_check/winapi_check b/tools/winapi_check/winapi_check
index 1f51857..f5cedac 100755
--- a/tools/winapi_check/winapi_check
+++ b/tools/winapi_check/winapi_check
@@ -311,17 +311,21 @@
 	    $function->module16($module16);
 	    $function->module32($module32);
 
-	    my $output_module = sub { 
-		my $module = shift;
-		return sub {
-		    my $msg = shift;
-		    $output->write("$file: $module: $return_type ");
-		    $output->write("$calling_convention ") if $calling_convention;
-		    $output->write("$internal_name(" . join(",", @argument_types) . "): $msg\n");
-		}
-	    };
-	    my $output16 = &$output_module($module16);
-	    my $output32 = &$output_module($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);
 
 	    if($options->local && $options->misplaced &&
 	       $linkage ne "extern" && $statements) 
@@ -336,7 +340,7 @@
 			}
 		    }
 		    if(!$match) {
-			&$output16("is misplaced\n");
+			$output->write("is misplaced\n");
 		    }
 		}
 
@@ -350,7 +354,7 @@
 			}
 		    }
 		    if(!$match) {
-			&$output32("is misplaced");
+			$output->write("is misplaced\n");
 		    }
 		}
 	    }
@@ -364,7 +368,7 @@
 			    $internal_name !~ /^I(?:Malloc|Storage)16_fn/ &&
 			    $internal_name !~ /^(?:\Q$module16\E|THUNK|WIN16)_\Q$external_name16\E(?:16)?$/))
 			{
-			    &$output16("no prototype");
+			    $output->write("no prototype\n");
 			}
 		    }
 		}
@@ -378,7 +382,7 @@
 			   $internal_name !~ /^COMCTL32_Str/ &&
 			   $internal_name !~ /^(?:\Q$module32\E|wine)_(?:\Q$external_name32\E|\d+)$/))
 			{
-			    &$output32("no prototype");
+			    $output->write("no prototype\n");
 			}
 		    }
 		}
@@ -386,22 +390,22 @@
 
 	    if($options->local && $options->argument) {
 		if($options->win16 && $options->report_module($module16)) {
-		  winapi_local::check_function $options, $output16,
+		  winapi_local::check_function $options, $output,
 		    $return_type, $calling_convention, $external_name16, $internal_name, [@argument_types], $nativeapi, $win16api;
 		}	
 		if($options->win32 && $options->report_module($module32)) {
-		  winapi_local::check_function $options, $output32,
+		  winapi_local::check_function $options, $output,
 		    $return_type, $calling_convention, $external_name32, $internal_name, [@argument_types], $nativeapi, $win32api;
 		}
 	    }
 
 	    if($options->local && $options->statements) {
 		if($options->win16 && $options->report_module($module16)) {
-		  winapi_local::check_statements $options, $output16, $win16api, \%functions, $function;
+		  winapi_local::check_statements $options, $output, $win16api, \%functions, $function;
 		}
 
 		if($options->win32 && $options->report_module($module32)) {
-		  winapi_local::check_statements $options, $output32, $win32api, \%functions, $function;
+		  winapi_local::check_statements $options, $output, $win32api, \%functions, $function;
 		}
 	    }
 
@@ -463,8 +467,7 @@
 		}
 
 		if($documentation !~ /\b($internal_name|$name1|$name2)\b/) {
-		    $output->write("$file: $internal_name: \\\n");
-		    $output->write("$documentation\n");
+		    $output->write("\\\n$documentation\n");
 		}
 
 		if($options->documentation_width) {		
@@ -473,11 +476,12 @@
 			
 			$comment_width{$width}++;
 			if($width <= 65 || $width >= 81) {
-			    $output->write("$file: $internal_name: comment is $width columns wide\n");
+			    $output->write("comment is $width columns wide\n");
 			}
 		    }
 		}
 	    }
+	    $output->prefix("");
 	}
     };
 
diff --git a/tools/winapi_check/winapi_local.pm b/tools/winapi_check/winapi_local.pm
index 73248c2..d9d3268 100644
--- a/tools/winapi_check/winapi_local.pm
+++ b/tools/winapi_check/winapi_local.pm
@@ -21,18 +21,18 @@
 	$name16 =~ s/16$//;
 	if($name16 ne $internal_name && $winapi->function_stub($name16)) {
 	    if($options->implemented) {
-		&$output("function implemented but declared as stub in .spec file");
+		$output->write("function implemented but declared as stub in .spec file\n");
 	    }
 	    return;
 	} elsif($winapi->function_stub($internal_name)) {
 	    if($options->implemented_win32) {
-		&$output("32-bit variant of function implemented but declared as stub in .spec file");
+		$output->write("32-bit variant of function implemented but declared as stub in .spec file\n");
 	    }
 	    return;
 	}
     } elsif($winapi->function_stub($internal_name)) {
 	if($options->implemented) {
-	    &$output("function implemented but declared as stub in .spec file");
+	    $output->write("function implemented but declared as stub in .spec file\n");
 	}
 	return;
     }
@@ -42,12 +42,12 @@
     $winapi->type_used_in_module($return_type,$module);
     if(!defined($implemented_return_kind = $winapi->translate_argument($return_type))) {
 	if($return_type ne "") {
-	    &$output("no translation defined: " . $return_type);
+	    $output->write("no translation defined: " . $return_type . "\n");
 	}
     } elsif(!$winapi->is_allowed_kind($implemented_return_kind) || !$winapi->allowed_type_in_module($return_type,$module)) {
 	$forbidden_return_type = 1;
 	if($options->report_argument_forbidden($return_type)) {
-	    &$output("forbidden return type: $return_type ($implemented_return_kind)");
+	    $output->write("forbidden return type: $return_type ($implemented_return_kind)" . "\n");
 	}
     }
     
@@ -102,7 +102,7 @@
             ($options->calling_convention_win32 && $winapi->name eq "win32")) &&
 	    !$nativeapi->is_function($internal_name))
         {
-	    &$output("calling convention mismatch: $implemented_calling_convention != $declared_calling_convention");
+	    $output->write("calling convention mismatch: $implemented_calling_convention != $declared_calling_convention\n");
 	}
     }
 
@@ -110,10 +110,10 @@
 	if($#argument_types != -1 && $argument_types[$#argument_types] eq "...") {
 	    pop @argument_types;
 	} else {
-	    &$output("function not implemented as vararg");
+	    $output->write("function not implemented as vararg\n");
 	}
     } elsif($#argument_types != -1 && $argument_types[$#argument_types] eq "...") {
-	&$output("function not declared as vararg");
+	$output->write("function not declared as vararg\n");
     }
 
     if($#argument_types != -1 && $argument_types[$#argument_types] eq "CONTEXT *" &&
@@ -131,11 +131,11 @@
 	    my $kind = "unknown";
 	    $winapi->type_used_in_module($type,$module);
 	    if(!defined($kind = $winapi->translate_argument($type))) {
-		&$output("no translation defined: " . $type);
+		$output->write("no translation defined: " . $type . "\n");
 	    } elsif(!$winapi->is_allowed_kind($kind) ||
 		    !$winapi->allowed_type_in_module($type, $module)) {
 		if($options->report_argument_forbidden($type)) {
-		    &$output("forbidden argument " . ($n + 1) . " type " . $type . " (" . $kind . ")");
+		    $output->write("forbidden argument " . ($n + 1) . " type " . $type . " (" . $kind . ")\n");
 		}
 	    }
 	    if(defined($kind) && $kind eq "longlong") {
@@ -160,21 +160,24 @@
 		if($options->report_argument_kind($argument_kinds[$n]) ||
 		   $options->report_argument_kind($declared_argument_kinds[$n]))
 		{
-		    &$output("argument " . ($n + 1) . " type mismatch: " .
-			     $argument_types[$n] . " ($argument_kinds[$n]) != " . $declared_argument_kinds[$n]);
+		    $output->write("argument " . ($n + 1) . " type mismatch: " .
+			     $argument_types[$n] . " ($argument_kinds[$n]) != " . 
+			     $declared_argument_kinds[$n] . "\n");
 		}
 	    }
 	}
         if($#argument_kinds != $#declared_argument_kinds) {
 	    if($options->argument_count) {
-		&$output("argument count differs: " . ($#argument_types + 1) . " != " . ($#declared_argument_kinds + 1));
+		$output->write("argument count differs: " . 
+		    ($#argument_types + 1) . " != " . 
+		    ($#declared_argument_kinds + 1) . "\n");
 	    }
 	}
 
     }
 
     if($segmented && $options->shared_segmented && $winapi->is_shared_function($internal_name)) {
-	&$output("function using segmented pointers shared between Win16 och Win32");
+	$output->write("function using segmented pointers shared between Win16 och Win32\n");
     }
 }
 
@@ -225,15 +228,15 @@
 			    $format =~ s/^\\\"(.*?)\\\"$/$1/;
 
 			    if($argument !~ /$name/) {
-				&$output("$called_name: argument $n is wrong ($name != '$argument')");
+				$output->write("$called_name: argument $n is wrong ($name != '$argument')\n");
 			    } elsif(!$winapi->is_allowed_type_format($module, $type, $format)) {
-				&$output("$called_name: argument $n ($type $name) has illegal format ($format)");
+				$output->write("$called_name: argument $n ($type $name) has illegal format ($format)\n");
 			    }
 			}
 
 			my $count = $#{$function->argument_types} + 1; 
 			if($n != $count) {
-			    &$output("$called_name: argument count mismatch ($n != $count)");
+			    $output->write("$called_name: argument count mismatch ($n != $count)\n");
 			}
 		    }
 		}
diff --git a/tools/winapi_check/winapi_options.pm b/tools/winapi_check/winapi_options.pm
index 1f15aeb..589424a 100644
--- a/tools/winapi_check/winapi_options.pm
+++ b/tools/winapi_check/winapi_options.pm
@@ -53,7 +53,7 @@
 	description => "argument forbidden checking"
     },
     "argument-kind" => {
-	default => { active => 0, filter => 0, hash => {} },
+	default => { active => 1, filter => 1, hash => { double => 1 } },
 	parent => "argument",
 	parser => \&parser_comma_list,
 	description => "argument kind checking"
diff --git a/tools/winapi_check/winapi_parser.pm b/tools/winapi_check/winapi_parser.pm
index 37f75bc..5a4749b 100644
--- a/tools/winapi_check/winapi_parser.pm
+++ b/tools/winapi_check/winapi_parser.pm
@@ -191,7 +191,10 @@
 		&$function_end;
 	    }
 	    next;	    
-	} elsif(/(extern\s+|static\s+)?((struct\s+|union\s+|enum\s+)?\w+((\s*\*)+\s*|\s+))((__cdecl|__stdcall|VFWAPIV|VFWAPI|WINAPIV|WINAPI|CALLBACK)\s+)?(\w+(\(\w+\))?)\s*\(([^\)]*)\)\s*(\{|\;)/s) {
+	} elsif(/(extern\s+|static\s+)?((struct\s+|union\s+|enum\s+)?\w+((\s*\*)+\s*|\s+))
+            ((__cdecl|__stdcall|CDECL|VFWAPIV|VFWAPI|WINAPIV|WINAPI|CALLBACK)\s+)?
+	    (\w+(\(\w+\))?)\s*\(([^\)]*)\)\s*(\{|\;)/sx)
+        {
 	    $_ = $'; $again = 1;
 	    
 	    if($11 eq "{")  {