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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 package winapi_function
;
20 use base
qw(function);
24 use config
qw($current_dir $wine_dir);
25 use util qw(&normalize_set);
28 use vars
qw($modules $win16api $win32api @winapis);
30 ########################################################################
36 my $class = ref($proto) || $proto;
38 bless ($self, $class);
42 import modules qw($modules);
45 import winapi qw($win16api $win32api @winapis);
52 ########################################################################
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 ########################################################################
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)) {
77 my @external_names = split(/\s*&\s*/, $external_name);
78 my @modules = split(/\s*&\s*/, $module);
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);
96 my $external_name = $self->_external_name($winapi);
98 if(defined($external_name)) {
99 return split(/\s*&\s*/, $external_name);
108 foreach my $winapi (@winapis) {
109 my $external_name = $self->_external_name($winapi, @_);
111 if(defined($external_name)) {
112 return $external_name;
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 ########################################################################
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)) {
144 foreach my $module (split(/\s*&\s*/, $module)) {
145 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
146 push @modules, $module;
150 return join(" & ", @modules);
157 my $module = $self->_module($winapi);
159 if(defined($module)) {
160 return split(/\s*&\s*/, $module);
166 sub module16 { my $self = shift; return $self->_module($win16api, @_); }
167 sub module32 { my $self = shift; return $self->_module($win32api, @_); }
169 sub module { my $self = shift; return join (" & ", $self->modules); }
171 sub modules16 { my $self = shift; return $self->_modules($win16api, @_); }
172 sub modules32 { my $self = shift; return $self->_modules($win32api, @_); }
174 sub modules { my $self = shift; return ($self->modules16, $self->modules32); }
176 ########################################################################
184 my $file = $self->file;
185 my $internal_name = $self->internal_name;
187 my $ordinal = $winapi->function_internal_ordinal($internal_name);
188 my $module = $winapi->function_internal_module($internal_name);
190 if(!defined($ordinal) && !defined($module)) {
194 my @ordinals = split(/\s*&\s*/, $ordinal);
195 my @modules = split(/\s*&\s*/, $module);
198 while(defined(my $ordinal = shift @ordinals) &&
199 defined(my $module = shift @modules))
201 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
202 push @ordinals2, $ordinal;
206 return join(" & ", @ordinals2);
213 my $ordinal = $self->_ordinal($winapi);
215 if(defined($ordinal)) {
216 return split(/\s*&\s*/, $ordinal);
222 sub ordinal16 { my $self = shift; return $self->_ordinal($win16api, @_); }
223 sub ordinal32 { my $self = shift; return $self->_ordinal($win32api, @_); }
225 sub ordinal { my $self = shift; return join (" & ", $self->ordinals); }
227 sub ordinals16 { my $self = shift; return $self->_ordinals($win16api, @_); }
228 sub ordinals32 { my $self = shift; return $self->_ordinals($win32api, @_); }
230 sub ordinals { my $self = shift; return ($self->ordinals16, $self->ordinals32); }
232 ########################################################################
238 my $module16 = $self->module16;
239 my $module32 = $self->module32;
241 my $file = $self->file;
242 my $function_line = $self->function_line;
243 my $return_type = $self->return_type;
244 my $internal_name = $self->internal_name;
245 my $calling_convention = $self->calling_convention;
247 my $refargument_types = $self->argument_types;
248 my @argument_types = ();
249 if(defined($refargument_types)) {
250 @argument_types = @$refargument_types;
251 if($#argument_types < 0) {
252 @argument_types = ("void");
260 foreach my $module ($self->modules) {
261 if($used{$module}) { next; }
262 push @modules, $module;
266 if(defined($function_line)) {
267 $prefix .= "$function_line: ";
272 $prefix .= join(" & ", @modules) . ": ";
276 $prefix .= "$return_type ";
277 $prefix .= "$calling_convention " if $calling_convention;
278 $prefix .= "$internal_name(" . join(",", @argument_types) . "): ";
283 ########################################################################
287 sub calling_convention16 {
289 my $return_kind16 = $self->return_kind16;
292 if(!defined($return_kind16)) {
294 } elsif($return_kind16 =~ /^(?:void|s_word|word)$/) {
296 } elsif($return_kind16 =~ /^(?:long|ptr|segptr|segstr|str|wstr)$/) {
302 local $_ = $self->calling_convention;
305 } elsif(/^VFWAPIV|WINAPIV$/) {
306 if(!defined($suffix)) { return undef; }
307 return "pascal$suffix"; # FIXME: Is this correct?
308 } elsif(/^__stdcall|VFWAPI|WINAPI|CALLBACK$/) {
309 if(!defined($suffix)) { return undef; }
310 return "pascal$suffix";
318 sub calling_convention32 {
321 local $_ = $self->calling_convention;
324 } elsif(/^VFWAPIV|WINAPIV$/) {
326 } elsif(/^__stdcall|VFWAPI|WINAPI|CALLBACK$/) {
335 sub get_all_module_ordinal16 {
337 my $internal_name = $self->internal_name;
339 return winapi::get_all_module_internal_ordinal16($internal_name);
342 sub get_all_module_ordinal32 {
344 my $internal_name = $self->internal_name;
346 return winapi::get_all_module_internal_ordinal32($internal_name);
349 sub get_all_module_ordinal {
351 my $internal_name = $self->internal_name;
353 return winapi::get_all_module_internal_ordinal($internal_name);
359 my $return_type = $self->return_type;
361 return $winapi->translate_argument($return_type);
365 my $self = shift; return $self->_return_kind($win16api, @_);
369 my $self = shift; return $self->_return_kind($win32api, @_);
372 sub _argument_kinds {
375 my $refargument_types = $self->argument_types;
377 if(!defined($refargument_types)) {
382 foreach my $argument_type (@$refargument_types) {
383 my $argument_kind = $winapi->translate_argument($argument_type);
385 if(defined($argument_kind) && $argument_kind eq "longlong") {
386 push @argument_kinds, ("long", "long");
388 push @argument_kinds, $argument_kind;
392 return [@argument_kinds];
395 sub argument_kinds16 {
396 my $self = shift; return $self->_argument_kinds($win16api, @_);
399 sub argument_kinds32 {
400 my $self = shift; return $self->_argument_kinds($win32api, @_);
403 ##############################################################################
407 sub function_called {
409 my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}};
413 $$called_function_names{$name}++;
416 sub function_called_by {
418 my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}};
422 $$called_by_function_names{$name}++;
425 sub called_function_names {
427 my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}};
429 return sort(keys(%$called_function_names));
432 sub called_by_function_names {
434 my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}};
436 return sort(keys(%$called_by_function_names));