1 package winapi_function;
6 use config qw($current_dir $wine_dir);
7 use modules qw($modules);
8 use util qw(&normalize_set);
9 use winapi qw($win16api $win32api @winapis);
11 ########################################################################
17 my $class = ref($proto) || $proto;
19 bless ($self, $class);
24 ########################################################################
28 sub is_win16 { my $self = shift; return defined($self->_module($win16api, @_)); }
29 sub is_win32 { my $self = shift; return defined($self->_module($win32api, @_)); }
31 ########################################################################
39 my $file = $self->file;
40 my $internal_name = $self->internal_name;
42 my $external_name = $winapi->function_external_name($internal_name);
43 my $module = $winapi->function_internal_module($internal_name);
45 if(!defined($external_name) && !defined($module)) {
49 my @external_names = split(/\s*&\s*/, $external_name);
50 my @modules = split(/\s*&\s*/, $module);
53 while(defined(my $external_name = shift @external_names) &&
54 defined(my $module = shift @modules))
56 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
57 push @external_names2, $external_name;
61 return join(" & ", @external_names2);
68 my $external_name = $self->_external_name($winapi);
70 if(defined($external_name)) {
71 return split(/\s*&\s*/, $external_name);
77 sub external_name16 { my $self = shift; return $self->_external_name($win16api, @_); }
78 sub external_name32 { my $self = shift; return $self->_external_name($win32api, @_); }
80 sub external_names16 { my $self = shift; return $self->_external_names($win16api, @_); }
81 sub external_names32 { my $self = shift; return $self->_external_names($win32api, @_); }
83 sub external_names { my $self = shift; return ($self->external_names16,$self->external_names32); }
85 ########################################################################
93 my $file = $self->file;
94 my $internal_name = $self->internal_name;
96 my $module = $winapi->function_internal_module($internal_name);
97 if(!defined($module)) {
102 foreach my $module (split(/\s*&\s*/, $module)) {
103 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
104 push @modules, $module;
108 return join(" & ", @modules);
115 my $module = $self->_module($winapi);
117 if(defined($module)) {
118 return split(/\s*&\s*/, $module);
124 sub module16 { my $self = shift; return $self->_module($win16api, @_); }
125 sub module32 { my $self = shift; return $self->_module($win32api, @_); }
127 sub module { my $self = shift; return join (" & ", $self->modules); }
129 sub modules16 { my $self = shift; return $self->_modules($win16api, @_); }
130 sub modules32 { my $self = shift; return $self->_modules($win32api, @_); }
132 sub modules { my $self = shift; return ($self->modules16, $self->modules32); }
134 ########################################################################
142 my $file = $self->file;
143 my $internal_name = $self->internal_name;
145 my $ordinal = $winapi->function_internal_ordinal($internal_name);
146 my $module = $winapi->function_internal_module($internal_name);
148 if(!defined($ordinal) && !defined($module)) {
152 my @ordinals = split(/\s*&\s*/, $ordinal);
153 my @modules = split(/\s*&\s*/, $module);
156 while(defined(my $ordinal = shift @ordinals) &&
157 defined(my $module = shift @modules))
159 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
160 push @ordinals2, $ordinal;
164 return join(" & ", @ordinals2);
171 my $ordinal = $self->_ordinal($winapi);
173 if(defined($ordinal)) {
174 return split(/\s*&\s*/, $ordinal);
180 sub ordinal16 { my $self = shift; return $self->_ordinal($win16api, @_); }
181 sub ordinal32 { my $self = shift; return $self->_ordinal($win32api, @_); }
183 sub ordinal { my $self = shift; return join (" & ", $self->ordinals); }
185 sub ordinals16 { my $self = shift; return $self->_ordinals($win16api, @_); }
186 sub ordinals32 { my $self = shift; return $self->_ordinals($win32api, @_); }
188 sub ordinals { my $self = shift; return ($self->ordinals16, $self->ordinals32); }
190 ########################################################################
196 my $module16 = $self->module16;
197 my $module32 = $self->module32;
199 my $file = $self->file;
200 my $function_line = $self->function_line;
201 my $return_type = $self->return_type;
202 my $internal_name = $self->internal_name;
203 my $calling_convention = $self->calling_convention;
204 my @argument_types = @{$self->argument_types};
206 if($#argument_types < 0) {
207 @argument_types = ("void");
214 foreach my $module ($self->modules) {
215 if($used{$module}) { next; }
216 push @modules, $module;
220 if(defined($function_line)) {
221 $prefix .= "$function_line: ";
226 $prefix .= join(" & ", @modules) . ": ";
230 $prefix .= "$return_type ";
231 $prefix .= "$calling_convention " if $calling_convention;
232 $prefix .= "$internal_name(" . join(",", @argument_types) . "): ";
237 ########################################################################
241 sub calling_convention16 {
243 my $return_kind16 = $self->return_kind16;
246 if(!defined($return_kind16)) {
248 } elsif($return_kind16 =~ /^(?:void|s_word|word)$/) {
250 } elsif($return_kind16 =~ /^(?:long|ptr|segptr|segstr|str|wstr)$/) {
256 local $_ = $self->calling_convention;
259 } elsif(/^VFWAPIV|WINAPIV$/) {
260 if(!defined($suffix)) { return undef; }
261 return "pascal$suffix"; # FIXME: Is this correct?
262 } elsif(/^__stdcall|VFWAPI|WINAPI|CALLBACK$/) {
263 if(!defined($suffix)) { return undef; }
264 return "pascal$suffix";
272 sub calling_convention32 {
275 local $_ = $self->calling_convention;
278 } elsif(/^VFWAPIV|WINAPIV$/) {
280 } elsif(/^__stdcall|VFWAPI|WINAPI|CALLBACK$/) {
289 sub get_all_module_ordinal16 {
291 my $internal_name = $self->internal_name;
293 return winapi::get_all_module_internal_ordinal16($internal_name);
296 sub get_all_module_ordinal32 {
298 my $internal_name = $self->internal_name;
300 return winapi::get_all_module_internal_ordinal32($internal_name);
303 sub get_all_module_ordinal {
305 my $internal_name = $self->internal_name;
307 return winapi::get_all_module_internal_ordinal($internal_name);
313 my $return_type = $self->return_type;
315 return $winapi->translate_argument($return_type);
319 my $self = shift; return $self->_return_kind($win16api, @_);
323 my $self = shift; return $self->_return_kind($win32api, @_);
326 sub _argument_kinds {
329 my @argument_types = @{$self->argument_types};
332 foreach my $argument_type (@argument_types) {
333 my $argument_kind = $winapi->translate_argument($argument_type);
335 if(defined($argument_kind) && $argument_kind eq "longlong") {
336 push @argument_kinds, ("long", "long");
338 push @argument_kinds, $argument_kind;
342 return [@argument_kinds];
345 sub argument_kinds16 {
346 my $self = shift; return $self->_argument_kinds($win16api, @_);
349 sub argument_kinds32 {
350 my $self = shift; return $self->_argument_kinds($win32api, @_);
353 ##############################################################################
357 sub function_called {
359 my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}};
363 $$called_function_names{$name}++;
366 sub function_called_by {
368 my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}};
372 $$called_by_function_names{$name}++;
375 sub called_function_names {
377 my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}};
379 return sort(keys(%$called_function_names));
382 sub called_by_function_names {
384 my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}};
386 return sort(keys(%$called_by_function_names));