blob: 013a2d8dafe2ef9ddefe017e436a0b4a3ca7118c [file] [log] [blame]
Patrik Stridvall6a012e22001-06-13 19:38:29 +00001#!/usr/bin/perl -w
2
3# Copyright 2001 Patrik Stridvall
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00004#
5# This library is free software; you can redistribute it and/or
6# modify it under the terms of the GNU Lesser General Public
7# License as published by the Free Software Foundation; either
8# version 2.1 of the License, or (at your option) any later version.
9#
10# This library is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU Lesser General Public
16# License along with this library; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18#
Patrik Stridvall6a012e22001-06-13 19:38:29 +000019
20use strict;
21
22BEGIN {
23 $0 =~ m%^(.*?/?tools)/winapi/winapi_extract$%;
24 require "$1/winapi/setup.pm";
25}
26
27use config qw(
Patrik Stridvall027c7a12001-07-19 19:10:03 +000028 &file_type &files_skip &files_filter &get_spec_files
Patrik Stridvall6a012e22001-06-13 19:38:29 +000029 $current_dir $wine_dir $winapi_dir $winapi_check_dir
30);
Patrik Stridvall1c61b3b2001-07-23 23:20:56 +000031use output qw($output);
Patrik Stridvall67f0a702001-07-26 21:42:12 +000032use winapi_extract_options qw($options);
33
Patrik Stridvallaeb023f2001-08-22 18:09:15 +000034if($options->progress) {
35 $output->enable_progress;
36} else {
37 $output->disable_progress;
38}
39
Patrik Stridvall67f0a702001-07-26 21:42:12 +000040use function;
41use type;
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +000042use winapi_function;
Patrik Stridvall6a012e22001-06-13 19:38:29 +000043use winapi_parser;
Patrik Stridvall098883b2002-07-20 20:06:13 +000044use winapi qw($win16api $win32api @winapis);
Patrik Stridvall6a012e22001-06-13 19:38:29 +000045
Patrik Stridvallb6754d82002-01-21 17:36:35 +000046my %module2entries;
Patrik Stridvall6a012e22001-06-13 19:38:29 +000047my %module2spec_file;
Patrik Stridvallb6754d82002-01-21 17:36:35 +000048if($options->spec_files || $options->winetest) {
Patrik Stridvall6a012e22001-06-13 19:38:29 +000049 local $_;
50
Patrik Stridvalld07a6462001-07-18 20:09:12 +000051 foreach my $spec_file (get_spec_files("winelib")) {
Patrik Stridvallb6754d82002-01-21 17:36:35 +000052 my $entries = [];
53
Patrik Stridvall098883b2002-07-20 20:06:13 +000054 my $module = $spec_file;
55 $module =~ s/^.*?([^\/]*)\.spec$/$1/;
56
57 my $type = "win32";
Patrik Stridvall6a012e22001-06-13 19:38:29 +000058
59 open(IN, "< $wine_dir/$spec_file");
Patrik Stridvallb6754d82002-01-21 17:36:35 +000060
61 my $header = 1;
62 my $lookahead = 0;
63 while($lookahead || defined($_ = <IN>)) {
64 $lookahead = 0;
65
Patrik Stridvall6a012e22001-06-13 19:38:29 +000066 s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begining and end of line
67 s/^(.*?)\s*#.*$/$1/; # remove comments
68 /^$/ && next; # skip empty lines
69
Patrik Stridvallb6754d82002-01-21 17:36:35 +000070 if($header) {
Patrik Stridvall098883b2002-07-20 20:06:13 +000071 if(/^\d+|@/) {
Patrik Stridvallb6754d82002-01-21 17:36:35 +000072 $header = 0;
Alexandre Julliard7cae5582002-06-01 02:55:48 +000073 $lookahead = 1;
Patrik Stridvallb6754d82002-01-21 17:36:35 +000074 }
75 next;
76 }
77
78 if(/^(@|\d+)\s+stdcall\s+(\w+)\s*\(\s*([^\)]*)\s*\)/) {
79 my $ordinal = $1;
80 my $name = $2;
81 my @args = split(/\s+/, $3);
82
83 push @$entries, [$name, "undef", \@args];
Patrik Stridvall6a012e22001-06-13 19:38:29 +000084 }
85 }
86 close(IN);
Patrik Stridvallb6754d82002-01-21 17:36:35 +000087
Patrik Stridvall098883b2002-07-20 20:06:13 +000088 $module2spec_file{$module} = $spec_file;
Patrik Stridvallb6754d82002-01-21 17:36:35 +000089 $module2entries{$module} = $entries;
Patrik Stridvall6a012e22001-06-13 19:38:29 +000090 }
91}
92
Patrik Stridvall6a012e22001-06-13 19:38:29 +000093my %specifications;
94
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +000095sub documentation_specifications {
96 my $function = shift;
97
98 my @debug_channels = @{$function->debug_channels};
99 my $documentation = $function->documentation;
100 my $documentation_line = $function->documentation_line;
101 my $return_type = $function->return_type;
102 my $linkage = $function->linkage;
103 my $internal_name = $function->internal_name;
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000104
105 if($linkage eq "static") {
106 return;
107 }
108
109 local $_;
110 foreach (split(/\n/, $documentation)) {
111 if(/^\s*\*\s*(\S+)\s*[\(\[]\s*(\w+)\s*\.\s*(\S+)\s*[\)\]]/) {
112 my $external_name = $1;
113 my $module = lc($2);
114 my $ordinal = $3;
115
116 if($ordinal eq "@") {
117 if(1 || !exists($specifications{$module}{unfixed}{$external_name})) {
118 $specifications{$module}{unfixed}{$external_name}{ordinal} = $ordinal;
119 $specifications{$module}{unfixed}{$external_name}{external_name} = $external_name;
120 $specifications{$module}{unfixed}{$external_name}{function} = $function;
121 } else {
122 $output->write("$external_name ($module.$ordinal) already exists\n");
123 }
124 } elsif($ordinal =~ /^\d+$/) {
125 if(1 || !exists($specifications{$module}{fixed}{$ordinal})) {
126 $specifications{$module}{fixed}{$ordinal}{ordinal} = $ordinal;
127 $specifications{$module}{fixed}{$ordinal}{external_name} = $external_name;
128 $specifications{$module}{fixed}{$ordinal}{function} = $function;
129 } else {
130 $output->write("$external_name ($module.$ordinal) already exists\n");
131 }
132 } elsif($ordinal eq "init") {
133 if(!exists($specifications{$module}{init})) {
134 $specifications{$module}{init}{function} = $function;
135 } else {
136 $output->write("$external_name ($module.$ordinal) already exists\n");
137 }
138 } else {
139 if(!exists($specifications{$module}{unknown}{$external_name})) {
140 $specifications{$module}{unknown}{$external_name}{ordinal} = $ordinal;
141 $specifications{$module}{unknown}{$external_name}{external_name} = $external_name;
142 $specifications{$module}{unknown}{$external_name}{function} = $function;
143 } else {
144 $output->write("$external_name ($module.$ordinal) already exists\n");
145 }
146 }
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000147
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000148 if($options->debug) {
149 $output->write("$external_name ($module.$ordinal)\n");
150 }
151 }
152 }
153}
154
155my %module_pseudo_stub_count16;
156my %module_pseudo_stub_count32;
157
158sub statements_stub {
159 my $function = shift;
160
161 my $statements = $function->statements;
162 if(defined($statements) && $statements =~ /FIXME[^;]*stub/s) {
163 if($options->win16) {
164 foreach my $module16 ($function->modules16) {
165 $module_pseudo_stub_count16{$module16}++;
166 }
167 }
168 if($options->win32) {
169 foreach my $module32 ($function->modules32) {
170 $module_pseudo_stub_count32{$module32}++;
171 }
172 }
173 }
174}
175
Patrik Stridvalld07a6462001-07-18 20:09:12 +0000176my @c_files = $options->c_files;
177@c_files = files_skip(@c_files);
178@c_files = files_filter("winelib", @c_files);
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000179
180my $progress_output;
181my $progress_current = 0;
Patrik Stridvalld07a6462001-07-18 20:09:12 +0000182my $progress_max = scalar(@c_files);
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000183
Patrik Stridvalld07a6462001-07-18 20:09:12 +0000184foreach my $file (@c_files) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000185 my %functions;
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000186
187 $progress_current++;
Patrik Stridvallaeb023f2001-08-22 18:09:15 +0000188 $output->progress("$file (file $progress_current of $progress_max)");
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000189
Patrik Stridvall67f0a702001-07-26 21:42:12 +0000190 my $create_function = sub {
191 if($options->stub_statistics) {
192 return 'winapi_function'->new;
193 } else {
194 return 'function'->new;
195 }
196 };
197
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000198 my $found_function = sub {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000199 my $function = shift;
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000200
Patrik Stridvallaeb023f2001-08-22 18:09:15 +0000201 my $internal_name = $function->internal_name;
202 $functions{$internal_name} = $function;
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000203
Patrik Stridvallaeb023f2001-08-22 18:09:15 +0000204 $output->progress("$file (file $progress_current of $progress_max): $internal_name");
205 $output->prefix_callback(sub { return $function->prefix; });
206
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000207 my $documentation_line = $function->documentation_line;
208 my $documentation = $function->documentation;
209 my $function_line = $function->function_line;
210 my $linkage = $function->linkage;
211 my $return_type = $function->return_type;
212 my $calling_convention = $function->calling_convention;
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000213 my $statements = $function->statements;
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000214
Patrik Stridvallb6754d82002-01-21 17:36:35 +0000215 if($options->spec_files || $options->winetest) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000216 documentation_specifications($function);
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000217 }
218
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000219 if($options->stub_statistics) {
220 statements_stub($function);
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000221 }
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000222
223 $output->prefix("");
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000224 };
225
Patrik Stridvall67f0a702001-07-26 21:42:12 +0000226 my $create_type = sub {
227 return 'type'->new;
228 };
229
230 my $found_type = sub {
231 my $type = shift;
232 };
233
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000234 my $found_preprocessor = sub {
235 my $directive = shift;
236 my $argument = shift;
237 };
238
Patrik Stridvall098883b2002-07-20 20:06:13 +0000239 &winapi_parser::parse_c_file($file, {
240 # c_comment_found => $found_c_comment,
241 # cplusplus_comment_found => $found_cplusplus_comment,
242 function_create => $create_function,
243 function_found => $found_function,
244 type_create => $create_type,
245 type_found => $found_type,
246 preprocessor_found => $found_preprocessor
247 });
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000248
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000249 my @internal_names = keys(%functions);
250 if($#internal_names < 0) {
251 $output->write("$file: doesn't contain any functions\n");
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000252 }
253}
254
255sub output_function {
256 local *OUT = shift;
257 my $type = shift;
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000258 my $ordinal = shift;
259 my $external_name = shift;
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000260 my $function = shift;
261
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000262 my $internal_name = $function->internal_name;
Patrik Stridvall163652b2001-06-19 03:34:39 +0000263
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000264 my $return_kind;
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000265 my $calling_convention;
Patrik Stridvall1c61b3b2001-07-23 23:20:56 +0000266 my $refargument_kinds;
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000267 if($type eq "win16") {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000268 $return_kind = $function->return_kind16 || "undef";
269 $calling_convention = $function->calling_convention16 || "undef";
Patrik Stridvall1c61b3b2001-07-23 23:20:56 +0000270 $refargument_kinds = $function->argument_kinds16;
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000271 } elsif($type eq "win32") {
272 $return_kind = $function->return_kind32 || "undef";
273 $calling_convention = $function->calling_convention32 || "undef";
Patrik Stridvall1c61b3b2001-07-23 23:20:56 +0000274 $refargument_kinds = $function->argument_kinds32;
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000275 }
276
Patrik Stridvall1c61b3b2001-07-23 23:20:56 +0000277 if(defined($refargument_kinds)) {
278 my @argument_kinds = map { $_ || "undef"; } @$refargument_kinds;
279 print OUT "$ordinal $calling_convention $external_name(@argument_kinds) $internal_name\n";
280 } else {
281 print OUT "$ordinal $calling_convention $external_name() $internal_name # FIXME: arguments undefined\n";
282 }
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000283}
284
285if($options->spec_files) {
Patrik Stridvall098883b2002-07-20 20:06:13 +0000286 foreach my $winapi (@winapis) {
287 my $type = $winapi->name;
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000288
Patrik Stridvall098883b2002-07-20 20:06:13 +0000289 if($type eq "win16" && !$options->win16) { next; }
290 if($type eq "win32" && !$options->win32) { next; }
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000291
Patrik Stridvall098883b2002-07-20 20:06:13 +0000292 foreach my $module ($winapi->all_modules) {
293 my $spec_file = $module2spec_file{$module};
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000294
Patrik Stridvall098883b2002-07-20 20:06:13 +0000295 if(!defined($spec_file) || !defined($type)) {
296 $output->write("$module: doesn't exist\n");
297 next;
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000298 }
Patrik Stridvall098883b2002-07-20 20:06:13 +0000299
300 $spec_file .= "2";
301
302 $output->progress("$spec_file");
303 open(OUT, "> $wine_dir/$spec_file");
304
305 if(exists($specifications{$module}{init})) {
306 my $function = $specifications{$module}{init}{function};
307 print OUT "init " . $function->internal_name . "\n";
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000308 }
Patrik Stridvall098883b2002-07-20 20:06:13 +0000309 print OUT "\n";
310
311 my %debug_channels;
312 if(exists($specifications{$module}{init})) {
313 my $function = $specifications{$module}{init}{function};
314 foreach my $debug_channel (@{$function->debug_channels}) {
315 $debug_channels{$debug_channel}++;
316 }
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000317 }
Patrik Stridvall098883b2002-07-20 20:06:13 +0000318 foreach my $ordinal (sort {$a <=> $b} keys(%{$specifications{$module}{fixed}})) {
319 my $function = $specifications{$module}{fixed}{$ordinal}{function};
320 foreach my $debug_channel (@{$function->debug_channels}) {
321 $debug_channels{$debug_channel}++;
322 }
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000323 }
Patrik Stridvall098883b2002-07-20 20:06:13 +0000324 foreach my $name (sort(keys(%{$specifications{$module}{unfixed}}))) {
325 my $function = $specifications{$module}{unfixed}{$name}{function};
326 foreach my $debug_channel (@{$function->debug_channels}) {
327 $debug_channels{$debug_channel}++;
328 }
329 }
330 foreach my $name (sort(keys(%{$specifications{$module}{unknown}}))) {
331 my $function = $specifications{$module}{unknown}{$name}{function};
332 foreach my $debug_channel (@{$function->debug_channels}) {
333 $debug_channels{$debug_channel}++;
334 }
335 }
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000336
Patrik Stridvall098883b2002-07-20 20:06:13 +0000337 my @debug_channels = sort(keys(%debug_channels));
338 if($#debug_channels >= 0) {
339 print OUT "debug_channels (" . join(" ", @debug_channels) . ")\n";
340 print OUT "\n";
341 }
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000342
Patrik Stridvall098883b2002-07-20 20:06:13 +0000343 my $empty = 1;
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000344
Patrik Stridvall098883b2002-07-20 20:06:13 +0000345 if(!$empty) {
346 print OUT "\n";
347 $empty = 1;
348 }
349 foreach my $external_name (sort(keys(%{$specifications{$module}{unknown}}))) {
350 my $entry = $specifications{$module}{unknown}{$external_name};
351 my $ordinal = $entry->{ordinal};
352 my $function = $entry->{function};
353 print OUT "# ";
354 output_function(\*OUT, $type, $ordinal, $external_name, $function);
355 $empty = 0;
356 }
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000357
Patrik Stridvall098883b2002-07-20 20:06:13 +0000358 if(!$empty) {
359 print OUT "\n";
360 $empty = 1;
361 }
362 foreach my $ordinal (sort {$a <=> $b} keys(%{$specifications{$module}{fixed}})) {
363 my $entry = $specifications{$module}{fixed}{$ordinal};
364 my $external_name = $entry->{external_name};
365 my $function = $entry->{function};
366 output_function(\*OUT, $type, $ordinal, $external_name, $function);
367 $empty = 0;
368 }
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000369
Patrik Stridvall098883b2002-07-20 20:06:13 +0000370 if(!$empty) {
371 print OUT "\n";
372 $empty = 1;
373 }
374 foreach my $external_name (sort(keys(%{$specifications{$module}{unfixed}}))) {
375 my $entry = $specifications{$module}{unfixed}{$external_name};
376 my $ordinal = $entry->{ordinal};
377 my $function = $entry->{function};
378 output_function(\*OUT, $type, $ordinal, $external_name, $function);
379 $empty = 0;
380 }
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000381
Patrik Stridvall098883b2002-07-20 20:06:13 +0000382 close(OUT);
383 }
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000384 }
385}
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000386
387if($options->stub_statistics) {
388 foreach my $winapi (@winapis) {
Patrik Stridvall098883b2002-07-20 20:06:13 +0000389 my $type = $winapi->name;
390
391 if($type eq "win16" && !$options->win16) { next; }
392 if($type eq "win32" && !$options->win32) { next; }
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000393
394 my %module_stub_count;
395 my %module_total_count;
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000396
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000397 foreach my $internal_name ($winapi->all_internal_functions,$winapi->all_functions_stub) {
398 foreach my $module (split(/ \& /, $winapi->function_internal_module($internal_name))) {
Patrik Stridvall67f0a702001-07-26 21:42:12 +0000399 if($winapi->is_function_stub_in_module($module, $internal_name)) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000400 $module_stub_count{$module}++;
401 }
402 $module_total_count{$module}++;
403 }
404 }
405
406 foreach my $module ($winapi->all_modules) {
407 my $pseudo_stubs;
408 if($winapi->name eq "win16") {
409 $pseudo_stubs = $module_pseudo_stub_count16{$module};
410 } elsif($winapi->name eq "win32") {
411 $pseudo_stubs = $module_pseudo_stub_count32{$module};
412 }
413
414 my $real_stubs = $module_stub_count{$module};
415 my $total = $module_total_count{$module};
416
417 if(!defined($real_stubs)) { $real_stubs = 0; }
418 if(!defined($pseudo_stubs)) { $pseudo_stubs = 0; }
419 if(!defined($total)) { $total = 0;}
420
421 my $stubs = $real_stubs + $pseudo_stubs;
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000422
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000423 $output->write("*.c: $module: ");
424 $output->write("$stubs of $total functions are stubs ($real_stubs real, $pseudo_stubs pseudo)\n");
425 }
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000426 }
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000427}
428
Patrik Stridvallb6754d82002-01-21 17:36:35 +0000429if($options->winetest) {
Patrik Stridvall098883b2002-07-20 20:06:13 +0000430 foreach my $module ($win32api->all_modules) {
431 my $type = "win32";
Patrik Stridvallb6754d82002-01-21 17:36:35 +0000432
Patrik Stridvall098883b2002-07-20 20:06:13 +0000433 my $package = $module;
434 $package =~ s/\.dll$//;
435 $package =~ s/\./_/g;
Patrik Stridvallb6754d82002-01-21 17:36:35 +0000436
437 my @entries;
438
439 foreach my $external_name (sort(keys(%{$specifications{$module}{unknown}}))) {
440 my $entry = $specifications{$module}{unknown}{$external_name};
441 push @entries, $entry;
442 }
443
444 foreach my $ordinal (sort {$a <=> $b} keys(%{$specifications{$module}{fixed}})) {
445 my $entry = $specifications{$module}{fixed}{$ordinal};
446 push @entries, $entry;
447 }
448
449 foreach my $external_name (sort(keys(%{$specifications{$module}{unfixed}}))) {
450 my $entry = $specifications{$module}{unfixed}{$external_name};
451 push @entries, $entry;
452 }
453
454 my $n = 0;
455 foreach my $entry (@entries) {
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000456 my $external_name = $entry->{external_name};
457 my $ordinal = $entry->{ordinal};
458 my $function = $entry->{function};
Patrik Stridvallb6754d82002-01-21 17:36:35 +0000459
Patrik Stridvall098883b2002-07-20 20:06:13 +0000460 my $return_kind = $function->return_kind32 || "undef";
461 my $calling_convention = $function->calling_convention32 || "undef";
462 my $refargument_kinds = $function->argument_kinds32;
Patrik Stridvallb6754d82002-01-21 17:36:35 +0000463
464 my @argument_kinds;
465 if(defined($refargument_kinds)) {
466 @argument_kinds = map { $_ || "undef"; } @$refargument_kinds;
467 }
468
469 next if $calling_convention ne "stdcall";
470 next if $external_name eq "\@";
471
472 if($n == 0) {
Patrik Stridvall098883b2002-07-20 20:06:13 +0000473 open(OUT, "> $wine_dir/programs/winetest/include/${package}.pm");
Patrik Stridvallb6754d82002-01-21 17:36:35 +0000474
Patrik Stridvall098883b2002-07-20 20:06:13 +0000475 print OUT "package ${package};\n";
Patrik Stridvallb6754d82002-01-21 17:36:35 +0000476 print OUT "\n";
477
478 print OUT "use strict;\n";
479 print OUT "\n";
480
481 print OUT "require Exporter;\n";
482 print OUT "\n";
483
484 print OUT "use wine;\n";
485 print OUT "use vars qw(\@ISA \@EXPORT \@EXPORT_OK);\n";
486 print OUT "\n";
487
488 print OUT "\@ISA = qw(Exporter);\n";
489 print OUT "\@EXPORT = qw();\n";
490 print OUT "\@EXPORT_OK = qw();\n";
491 print OUT "\n";
492
493 print OUT "my \$module_declarations = {\n";
494 } elsif($n > 0) {
495 print OUT ",\n";
496 }
497
498 print OUT " \"\Q$external_name\E\" => [\"$return_kind\", [";
499 my $m = 0;
500 foreach my $argument_kind (@argument_kinds) {
501 if($m > 0) {
502 print OUT ", ";
503 }
504 print OUT "\"$argument_kind\"";
505 $m++;
506 }
507 print OUT "]]";
508 $n++;
509 }
510
511 if($n > 0) {
512 print OUT "\n";
513 print OUT "};\n";
514 print OUT "\n";
Patrik Stridvall098883b2002-07-20 20:06:13 +0000515 print OUT "&wine::declare(\"$module\",\%\$module_declarations);\n";
Patrik Stridvallb6754d82002-01-21 17:36:35 +0000516 print OUT "push \@EXPORT, map { \"&\" . \$_; } sort(keys(\%\$module_declarations));\n";
517 print OUT "1;\n";
518 close(OUT);
519 }
520 }
521}