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
;
24 use base
qw(function);
26 use config
qw($current_dir $wine_dir);
27 use util qw(normalize_set);
30 use vars
qw($modules $win16api $win32api @winapis);
32 ########################################################################
38 my $class = ref($proto) || $proto;
40 bless ($self, $class);
44 import modules qw($modules);
47 import winapi qw($win16api $win32api @winapis);
54 ########################################################################
58 sub is_win16($) { my $self = shift; return defined($self->_module($win16api, @_)); }
59 sub is_win32($) { my $self = shift; return defined($self->_module($win32api, @_)); }
61 ########################################################################
65 sub _external_name($$) {
69 my $file = $self->file;
70 my $internal_name = $self->internal_name;
72 my $external_name = $winapi->function_external_name($internal_name);
73 my $module = $winapi->function_internal_module($internal_name);
75 if(!defined($external_name) && !defined($module)) {
79 my @external_names = split(/\s*&\s*/, $external_name);
80 my @modules = split(/\s*&\s*/, $module);
83 while(defined(my $external_name = shift @external_names) &&
84 defined(my $module = shift @modules))
86 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
87 push @external_names2, $external_name;
91 return join(" & ", @external_names2);
94 sub _external_names($$) {
98 my $external_name = $self->_external_name($winapi);
100 if(defined($external_name)) {
101 return split(/\s*&\s*/, $external_name);
107 sub external_name($) {
110 foreach my $winapi (@winapis) {
111 my $external_name = $self->_external_name($winapi, @_);
113 if(defined($external_name)) {
114 return $external_name;
121 sub external_name16($) { my $self = shift; return $self->_external_name($win16api, @_); }
122 sub external_name32($) { my $self = shift; return $self->_external_name($win32api, @_); }
124 sub external_names16($) { my $self = shift; return $self->_external_names($win16api, @_); }
125 sub external_names32($) { my $self = shift; return $self->_external_names($win32api, @_); }
127 sub external_names($) { my $self = shift; return ($self->external_names16, $self->external_names32); }
129 ########################################################################
137 my $file = $self->file;
138 my $internal_name = $self->internal_name;
140 my $module = $winapi->function_internal_module($internal_name);
141 if(!defined($module)) {
145 if(!defined($file)) {
150 foreach my $module (split(/\s*&\s*/, $module)) {
151 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
152 push @modules, $module;
156 return join(" & ", @modules);
163 my $module = $self->_module($winapi);
165 if(defined($module)) {
166 return split(/\s*&\s*/, $module);
172 sub module16($) { my $self = shift; return $self->_module($win16api, @_); }
173 sub module32($) { my $self = shift; return $self->_module($win32api, @_); }
175 sub module($) { my $self = shift; return join (" & ", $self->modules); }
177 sub modules16($) { my $self = shift; return $self->_modules($win16api, @_); }
178 sub modules32($) { my $self = shift; return $self->_modules($win32api, @_); }
180 sub modules($) { my $self = shift; return ($self->modules16, $self->modules32); }
182 ########################################################################
190 my $file = $self->file;
191 my $internal_name = $self->internal_name;
193 my $ordinal = $winapi->function_internal_ordinal($internal_name);
194 my $module = $winapi->function_internal_module($internal_name);
196 if(!defined($ordinal) && !defined($module)) {
200 my @ordinals = split(/\s*&\s*/, $ordinal);
201 my @modules = split(/\s*&\s*/, $module);
204 while(defined(my $ordinal = shift @ordinals) &&
205 defined(my $module = shift @modules))
207 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
208 push @ordinals2, $ordinal;
212 return join(" & ", @ordinals2);
219 my $ordinal = $self->_ordinal($winapi);
221 if(defined($ordinal)) {
222 return split(/\s*&\s*/, $ordinal);
228 sub ordinal16($) { my $self = shift; return $self->_ordinal($win16api, @_); }
229 sub ordinal32($) { my $self = shift; return $self->_ordinal($win32api, @_); }
231 sub ordinal($) { my $self = shift; return join (" & ", $self->ordinals); }
233 sub ordinals16($) { my $self = shift; return $self->_ordinals($win16api, @_); }
234 sub ordinals32($) { my $self = shift; return $self->_ordinals($win32api, @_); }
236 sub ordinals($) { my $self = shift; return ($self->ordinals16, $self->ordinals32); }
238 ########################################################################
244 my $module16 = $self->module16;
245 my $module32 = $self->module32;
247 my $file = $self->file;
248 my $function_line = $self->function_line;
249 my $return_type = $self->return_type;
250 my $internal_name = $self->internal_name;
251 my $calling_convention = $self->calling_convention;
253 my $refargument_types = $self->argument_types;
254 my @argument_types = ();
255 if(defined($refargument_types)) {
256 @argument_types = @$refargument_types;
257 if($#argument_types < 0) {
258 @argument_types = ("void");
266 foreach my $module ($self->modules) {
267 if($used{$module}) { next; }
268 push @modules, $module;
272 if(defined($function_line)) {
273 $prefix .= "$function_line: ";
278 $prefix .= join(" & ", @modules) . ": ";
282 $prefix .= "$return_type ";
283 $prefix .= "$calling_convention " if $calling_convention;
284 $prefix .= "$internal_name(" . join(",", @argument_types) . "): ";
289 ########################################################################
293 sub calling_convention16($) {
295 my $return_kind16 = $self->return_kind16;
298 if(!defined($return_kind16)) {
300 } elsif($return_kind16 =~ /^(?:void|s_word|word)$/) {
302 } elsif($return_kind16 =~ /^(?:long|ptr|segptr|segstr|str|wstr)$/) {
308 local $_ = $self->calling_convention;
309 if($_ eq "__cdecl") {
311 } elsif(/^(?:VFWAPIV|WINAPIV)$/) {
312 if(!defined($suffix)) { return undef; }
313 return "pascal$suffix"; # FIXME: Is this correct?
314 } elsif(/^(?:__stdcall|__RPC_STUB|__RPC_USER|NET_API_FUNCTION|RPC_ENTRY|SEC_ENTRY|VFWAPI|WINGDIPAPI|WMIAPI|WINAPI|CALLBACK)$/) {
315 if(!defined($suffix)) { return undef; }
316 return "pascal$suffix";
317 } elsif($_ eq "__asm") {
324 sub calling_convention32($) {
327 local $_ = $self->calling_convention;
328 if($_ eq "__cdecl") {
330 } elsif(/^(?:VFWAPIV|WINAPIV)$/) {
332 } elsif(/^(?:__stdcall|__RPC_STUB|__RPC_USER|NET_API_FUNCTION|RPC_ENTRY|SEC_ENTRY|VFWAPI|WINGDIPAPI|WMIAPI|WINAPI|CALLBACK)$/) {
334 } elsif($_ eq "__asm") {
341 sub get_all_module_ordinal16($) {
343 my $internal_name = $self->internal_name;
345 return winapi::get_all_module_internal_ordinal16($internal_name);
348 sub get_all_module_ordinal32($) {
350 my $internal_name = $self->internal_name;
352 return winapi::get_all_module_internal_ordinal32($internal_name);
355 sub get_all_module_ordinal($) {
357 my $internal_name = $self->internal_name;
359 return winapi::get_all_module_internal_ordinal($internal_name);
362 sub _return_kind($$) {
365 my $return_type = $self->return_type;
367 return $winapi->translate_argument($return_type);
370 sub return_kind16($) {
371 my $self = shift; return $self->_return_kind($win16api, @_);
374 sub return_kind32($) {
375 my $self = shift; return $self->_return_kind($win32api, @_);
378 sub _argument_kinds($$) {
381 my $refargument_types = $self->argument_types;
383 if(!defined($refargument_types)) {
388 foreach my $argument_type (@$refargument_types) {
389 my $argument_kind = $winapi->translate_argument($argument_type);
391 if(defined($argument_kind) && $argument_kind eq "longlong") {
392 push @argument_kinds, "double";
394 push @argument_kinds, $argument_kind;
398 return [@argument_kinds];
401 sub argument_kinds16($) {
402 my $self = shift; return $self->_argument_kinds($win16api, @_);
405 sub argument_kinds32($) {
406 my $self = shift; return $self->_argument_kinds($win32api, @_);
409 ##############################################################################
413 sub function_called($$) {
415 my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}};
419 $$called_function_names{$name}++;
422 sub function_called_by($$) {
424 my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}};
428 $$called_by_function_names{$name}++;
431 sub called_function_names($) {
433 my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}};
435 return sort(keys(%$called_function_names));
438 sub called_by_function_names($) {
440 my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}};
442 return sort(keys(%$called_by_function_names));