sxs: Add tests for IAssemblyCache::QueryAssemblyInfo.
[wine/multimedia.git] / tools / winapi / winapi_function.pm
blob023fbf5fa0527b0939965f51f41d88c3b188edbd
2 # Copyright 1999, 2000, 2001 Patrik Stridvall
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 package winapi_function;
20 use base qw(function);
22 use strict;
24 use config qw($current_dir $wine_dir);
25 use util qw(normalize_set);
27 my $import = 0;
28 use vars qw($modules $win16api $win32api @winapis);
30 ########################################################################
31 # constructor
34 sub new($) {
35 my $proto = shift;
36 my $class = ref($proto) || $proto;
37 my $self = {};
38 bless ($self, $class);
40 if (!$import) {
41 require modules;
42 import modules qw($modules);
44 require winapi;
45 import winapi qw($win16api $win32api @winapis);
47 $import = 1;
49 return $self;
52 ########################################################################
53 # is_win
56 sub is_win16($) { my $self = shift; return defined($self->_module($win16api, @_)); }
57 sub is_win32($) { my $self = shift; return defined($self->_module($win32api, @_)); }
59 ########################################################################
60 # external_name
63 sub _external_name($$) {
64 my $self = shift;
65 my $winapi = shift;
67 my $file = $self->file;
68 my $internal_name = $self->internal_name;
70 my $external_name = $winapi->function_external_name($internal_name);
71 my $module = $winapi->function_internal_module($internal_name);
73 if(!defined($external_name) && !defined($module)) {
74 return undef;
77 my @external_names = split(/\s*&\s*/, $external_name);
78 my @modules = split(/\s*&\s*/, $module);
80 my @external_names2;
81 while(defined(my $external_name = shift @external_names) &&
82 defined(my $module = shift @modules))
84 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
85 push @external_names2, $external_name;
89 return join(" & ", @external_names2);
92 sub _external_names($$) {
93 my $self = shift;
94 my $winapi = shift;
96 my $external_name = $self->_external_name($winapi);
98 if(defined($external_name)) {
99 return split(/\s*&\s*/, $external_name);
100 } else {
101 return ();
105 sub external_name($) {
106 my $self = shift;
108 foreach my $winapi (@winapis) {
109 my $external_name = $self->_external_name($winapi, @_);
111 if(defined($external_name)) {
112 return $external_name;
116 return undef;
119 sub external_name16($) { my $self = shift; return $self->_external_name($win16api, @_); }
120 sub external_name32($) { my $self = shift; return $self->_external_name($win32api, @_); }
122 sub external_names16($) { my $self = shift; return $self->_external_names($win16api, @_); }
123 sub external_names32($) { my $self = shift; return $self->_external_names($win32api, @_); }
125 sub external_names($) { my $self = shift; return ($self->external_names16, $self->external_names32); }
127 ########################################################################
128 # module
131 sub _module($$) {
132 my $self = shift;
133 my $winapi = shift;
135 my $file = $self->file;
136 my $internal_name = $self->internal_name;
138 my $module = $winapi->function_internal_module($internal_name);
139 if(!defined($module)) {
140 return undef;
143 if(!defined($file)) {
144 return undef;
147 my @modules;
148 foreach my $module (split(/\s*&\s*/, $module)) {
149 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
150 push @modules, $module;
154 return join(" & ", @modules);
157 sub _modules($$) {
158 my $self = shift;
159 my $winapi = shift;
161 my $module = $self->_module($winapi);
163 if(defined($module)) {
164 return split(/\s*&\s*/, $module);
165 } else {
166 return ();
170 sub module16($) { my $self = shift; return $self->_module($win16api, @_); }
171 sub module32($) { my $self = shift; return $self->_module($win32api, @_); }
173 sub module($) { my $self = shift; return join (" & ", $self->modules); }
175 sub modules16($) { my $self = shift; return $self->_modules($win16api, @_); }
176 sub modules32($) { my $self = shift; return $self->_modules($win32api, @_); }
178 sub modules($) { my $self = shift; return ($self->modules16, $self->modules32); }
180 ########################################################################
181 # ordinal
184 sub _ordinal($$) {
185 my $self = shift;
186 my $winapi = shift;
188 my $file = $self->file;
189 my $internal_name = $self->internal_name;
191 my $ordinal = $winapi->function_internal_ordinal($internal_name);
192 my $module = $winapi->function_internal_module($internal_name);
194 if(!defined($ordinal) && !defined($module)) {
195 return undef;
198 my @ordinals = split(/\s*&\s*/, $ordinal);
199 my @modules = split(/\s*&\s*/, $module);
201 my @ordinals2;
202 while(defined(my $ordinal = shift @ordinals) &&
203 defined(my $module = shift @modules))
205 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
206 push @ordinals2, $ordinal;
210 return join(" & ", @ordinals2);
213 sub _ordinals($$) {
214 my $self = shift;
215 my $winapi = shift;
217 my $ordinal = $self->_ordinal($winapi);
219 if(defined($ordinal)) {
220 return split(/\s*&\s*/, $ordinal);
221 } else {
222 return ();
226 sub ordinal16($) { my $self = shift; return $self->_ordinal($win16api, @_); }
227 sub ordinal32($) { my $self = shift; return $self->_ordinal($win32api, @_); }
229 sub ordinal($) { my $self = shift; return join (" & ", $self->ordinals); }
231 sub ordinals16($) { my $self = shift; return $self->_ordinals($win16api, @_); }
232 sub ordinals32($) { my $self = shift; return $self->_ordinals($win32api, @_); }
234 sub ordinals($) { my $self = shift; return ($self->ordinals16, $self->ordinals32); }
236 ########################################################################
237 # prefix
240 sub prefix($) {
241 my $self = shift;
242 my $module16 = $self->module16;
243 my $module32 = $self->module32;
245 my $file = $self->file;
246 my $function_line = $self->function_line;
247 my $return_type = $self->return_type;
248 my $internal_name = $self->internal_name;
249 my $calling_convention = $self->calling_convention;
251 my $refargument_types = $self->argument_types;
252 my @argument_types = ();
253 if(defined($refargument_types)) {
254 @argument_types = @$refargument_types;
255 if($#argument_types < 0) {
256 @argument_types = ("void");
260 my $prefix = "";
262 my @modules = ();
263 my %used;
264 foreach my $module ($self->modules) {
265 if($used{$module}) { next; }
266 push @modules, $module;
267 $used{$module}++;
269 $prefix .= "$file:";
270 if(defined($function_line)) {
271 $prefix .= "$function_line: ";
272 } else {
273 $prefix .= "<>: ";
275 if($#modules >= 0) {
276 $prefix .= join(" & ", @modules) . ": ";
277 } else {
278 $prefix .= "<>: ";
280 $prefix .= "$return_type ";
281 $prefix .= "$calling_convention " if $calling_convention;
282 $prefix .= "$internal_name(" . join(",", @argument_types) . "): ";
284 return $prefix;
287 ########################################################################
288 # calling_convention
291 sub calling_convention16($) {
292 my $self = shift;
293 my $return_kind16 = $self->return_kind16;
295 my $suffix;
296 if(!defined($return_kind16)) {
297 $suffix = undef;
298 } elsif($return_kind16 =~ /^(?:void|s_word|word)$/) {
299 $suffix = "16";
300 } elsif($return_kind16 =~ /^(?:long|ptr|segptr|segstr|str|wstr)$/) {
301 $suffix = "";
302 } else {
303 $suffix = undef;
306 local $_ = $self->calling_convention;
307 if($_ eq "__cdecl") {
308 return "cdecl";
309 } elsif(/^(?:VFWAPIV|WINAPIV)$/) {
310 if(!defined($suffix)) { return undef; }
311 return "pascal$suffix"; # FIXME: Is this correct?
312 } elsif(/^(?:__stdcall|__RPC_STUB|__RPC_USER|NET_API_FUNCTION|RPC_ENTRY|VFWAPI|WINAPI|CALLBACK)$/) {
313 if(!defined($suffix)) { return undef; }
314 return "pascal$suffix";
315 } elsif($_ eq "__asm") {
316 return "asm";
317 } else {
318 return "cdecl";
322 sub calling_convention32($) {
323 my $self = shift;
325 local $_ = $self->calling_convention;
326 if($_ eq "__cdecl") {
327 return "cdecl";
328 } elsif(/^(?:VFWAPIV|WINAPIV)$/) {
329 return "varargs";
330 } elsif(/^(?:__stdcall|__RPC_STUB|__RPC_USER|NET_API_FUNCTION|RPC_ENTRY|VFWAPI|WINAPI|CALLBACK)$/) {
331 return "stdcall";
332 } elsif($_ eq "__asm") {
333 return "asm";
334 } else {
335 return "cdecl";
339 sub get_all_module_ordinal16($) {
340 my $self = shift;
341 my $internal_name = $self->internal_name;
343 return winapi::get_all_module_internal_ordinal16($internal_name);
346 sub get_all_module_ordinal32($) {
347 my $self = shift;
348 my $internal_name = $self->internal_name;
350 return winapi::get_all_module_internal_ordinal32($internal_name);
353 sub get_all_module_ordinal($) {
354 my $self = shift;
355 my $internal_name = $self->internal_name;
357 return winapi::get_all_module_internal_ordinal($internal_name);
360 sub _return_kind($$) {
361 my $self = shift;
362 my $winapi = shift;
363 my $return_type = $self->return_type;
365 return $winapi->translate_argument($return_type);
368 sub return_kind16($) {
369 my $self = shift; return $self->_return_kind($win16api, @_);
372 sub return_kind32($) {
373 my $self = shift; return $self->_return_kind($win32api, @_);
376 sub _argument_kinds($$) {
377 my $self = shift;
378 my $winapi = shift;
379 my $refargument_types = $self->argument_types;
381 if(!defined($refargument_types)) {
382 return undef;
385 my @argument_kinds;
386 foreach my $argument_type (@$refargument_types) {
387 my $argument_kind = $winapi->translate_argument($argument_type);
389 if(defined($argument_kind) && $argument_kind eq "longlong") {
390 push @argument_kinds, "double";
391 } else {
392 push @argument_kinds, $argument_kind;
396 return [@argument_kinds];
399 sub argument_kinds16($) {
400 my $self = shift; return $self->_argument_kinds($win16api, @_);
403 sub argument_kinds32($) {
404 my $self = shift; return $self->_argument_kinds($win32api, @_);
407 ##############################################################################
408 # Accounting
411 sub function_called($$) {
412 my $self = shift;
413 my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}};
415 my $name = shift;
417 $$called_function_names{$name}++;
420 sub function_called_by($$) {
421 my $self = shift;
422 my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}};
424 my $name = shift;
426 $$called_by_function_names{$name}++;
429 sub called_function_names($) {
430 my $self = shift;
431 my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}};
433 return sort(keys(%$called_function_names));
436 sub called_by_function_names($) {
437 my $self = shift;
438 my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}};
440 return sort(keys(%$called_by_function_names));