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 ########################################################################
32 my $file = $self->file;
33 my $internal_name = $self->internal_name;
35 my $external_name = $winapi->function_external_name($internal_name);
36 my $module = $winapi->function_internal_module($internal_name);
38 if(!defined($external_name) && !defined($module)) {
42 my @external_names = split(/\s*&\s*/, $external_name);
43 my @modules = split(/\s*&\s*/, $module);
46 while(defined(my $external_name = shift @external_names) &&
47 defined(my $module = shift @modules))
49 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
50 push @external_names2, $external_name;
54 return join(" & ", @external_names2);
61 my $external_name = $self->_external_name($winapi);
63 if(defined($external_name)) {
64 return split(/\s*&\s*/, $external_name);
70 sub external_name16 { my $self = shift; return $self->_external_name($win16api, @_); }
71 sub external_name32 { my $self = shift; return $self->_external_name($win32api, @_); }
73 sub external_names16 { my $self = shift; return $self->_external_names($win16api, @_); }
74 sub external_names32 { my $self = shift; return $self->_external_names($win32api, @_); }
76 sub external_names { my $self = shift; return ($self->external_names16,$self->external_names32); }
78 ########################################################################
86 my $file = $self->file;
87 my $internal_name = $self->internal_name;
89 my $module = $winapi->function_internal_module($internal_name);
90 if(!defined($module)) {
95 foreach my $module (split(/\s*&\s*/, $module)) {
96 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
97 push @modules, $module;
101 return join(" & ", @modules);
108 my $module = $self->_module($winapi);
110 if(defined($module)) {
111 return split(/\s*&\s*/, $module);
117 sub module16 { my $self = shift; return $self->_module($win16api, @_); }
118 sub module32 { my $self = shift; return $self->_module($win32api, @_); }
120 sub module { my $self = shift; return join (" & ", $self->modules); }
122 sub modules16 { my $self = shift; return $self->_modules($win16api, @_); }
123 sub modules32 { my $self = shift; return $self->_modules($win32api, @_); }
125 sub modules { my $self = shift; return ($self->modules16, $self->modules32); }
127 ########################################################################
135 my $file = $self->file;
136 my $internal_name = $self->internal_name;
138 my $ordinal = $winapi->function_internal_ordinal($internal_name);
139 my $module = $winapi->function_internal_module($internal_name);
141 if(!defined($ordinal) && !defined($module)) {
145 my @ordinals = split(/\s*&\s*/, $ordinal);
146 my @modules = split(/\s*&\s*/, $module);
149 while(defined(my $ordinal = shift @ordinals) &&
150 defined(my $module = shift @modules))
152 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
153 push @ordinals2, $ordinal;
157 return join(" & ", @ordinals2);
164 my $ordinal = $self->_ordinal($winapi);
166 if(defined($ordinal)) {
167 return split(/\s*&\s*/, $ordinal);
173 sub ordinal16 { my $self = shift; return $self->_ordinal($win16api, @_); }
174 sub ordinal32 { my $self = shift; return $self->_ordinal($win32api, @_); }
176 sub ordinal { my $self = shift; return join (" & ", $self->ordinals); }
178 sub ordinals16 { my $self = shift; return $self->_ordinals($win16api, @_); }
179 sub ordinals32 { my $self = shift; return $self->_ordinals($win32api, @_); }
181 sub ordinals { my $self = shift; return ($self->ordinals16, $self->ordinals32); }
183 ########################################################################
189 my $module16 = $self->module16;
190 my $module32 = $self->module32;
192 my $file = $self->file;
193 my $return_type = $self->return_type;
194 my $internal_name = $self->internal_name;
195 my $calling_convention = $self->calling_convention;
196 my @argument_types = @{$self->argument_types};
198 if($#argument_types < 0) {
199 @argument_types = ("void");
206 foreach my $module ($self->modules) {
207 if($used{$module}) { next; }
208 push @modules, $module;
211 $prefix .= "$file: ";
213 $prefix .= join(" & ", @modules) . ": ";
217 $prefix .= "$return_type ";
218 $prefix .= "$calling_convention " if $calling_convention;
219 $prefix .= "$internal_name(" . join(",", @argument_types) . "): ";
224 ########################################################################
228 sub calling_convention16 {
230 my $return_kind16 = $self->return_kind16;
233 if(!defined($return_kind16)) {
235 } elsif($return_kind16 =~ /^(?:void|s_word|word)$/) {
237 } elsif($return_kind16 =~ /^(?:long|ptr|segptr|segstr|str|wstr)$/) {
243 local $_ = $self->calling_convention;
246 } elsif(/^VFWAPIV|WINAPIV$/) {
247 if(!defined($suffix)) { return undef; }
248 return "pascal$suffix"; # FIXME: Is this correct?
249 } elsif(/^__stdcall|VFWAPI|WINAPI|CALLBACK$/) {
250 if(!defined($suffix)) { return undef; }
251 return "pascal$suffix";
259 sub calling_convention32 {
262 local $_ = $self->calling_convention;
265 } elsif(/^VFWAPIV|WINAPIV$/) {
267 } elsif(/^__stdcall|VFWAPI|WINAPI|CALLBACK$/) {
276 sub get_all_module_ordinal16 {
278 my $internal_name = $self->internal_name;
280 return winapi::get_all_module_internal_ordinal16($internal_name);
283 sub get_all_module_ordinal32 {
285 my $internal_name = $self->internal_name;
287 return winapi::get_all_module_internal_ordinal32($internal_name);
290 sub get_all_module_ordinal {
292 my $internal_name = $self->internal_name;
294 return winapi::get_all_module_internal_ordinal($internal_name);
300 my $return_type = $self->return_type;
302 return $winapi->translate_argument($return_type);
306 my $self = shift; return $self->_return_kind($win16api, @_);
310 my $self = shift; return $self->_return_kind($win32api, @_);
313 sub _argument_kinds {
316 my @argument_types = @{$self->argument_types};
319 foreach my $argument_type (@argument_types) {
320 my $argument_kind = $winapi->translate_argument($argument_type);
322 if(defined($argument_kind) && $argument_kind eq "longlong") {
323 push @argument_kinds, ("long", "long");
325 push @argument_kinds, $argument_kind;
329 return [@argument_kinds];
332 sub argument_kinds16 {
333 my $self = shift; return $self->_argument_kinds($win16api, @_);
336 sub argument_kinds32 {
337 my $self = shift; return $self->_argument_kinds($win32api, @_);
340 ##############################################################################
344 sub function_called {
346 my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}};
350 $$called_function_names{$name}++;
353 sub function_called_by {
355 my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}};
359 $$called_by_function_names{$name}++;
362 sub called_function_names {
364 my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}};
366 return sort(keys(%$called_function_names));
369 sub called_by_function_names {
371 my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}};
373 return sort(keys(%$called_by_function_names));