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);
80 foreach my $winapi (@winapis) {
81 my $external_name = $self->_external_name($winapi, @_);
83 if(defined($external_name)) {
84 return $external_name;
91 sub external_name16 { my $self = shift; return $self->_external_name($win16api, @_); }
92 sub external_name32 { my $self = shift; return $self->_external_name($win32api, @_); }
94 sub external_names16 { my $self = shift; return $self->_external_names($win16api, @_); }
95 sub external_names32 { my $self = shift; return $self->_external_names($win32api, @_); }
97 sub external_names { my $self = shift; return ($self->external_names16, $self->external_names32); }
99 ########################################################################
107 my $file = $self->file;
108 my $internal_name = $self->internal_name;
110 my $module = $winapi->function_internal_module($internal_name);
111 if(!defined($module)) {
116 foreach my $module (split(/\s*&\s*/, $module)) {
117 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
118 push @modules, $module;
122 return join(" & ", @modules);
129 my $module = $self->_module($winapi);
131 if(defined($module)) {
132 return split(/\s*&\s*/, $module);
138 sub module16 { my $self = shift; return $self->_module($win16api, @_); }
139 sub module32 { my $self = shift; return $self->_module($win32api, @_); }
141 sub module { my $self = shift; return join (" & ", $self->modules); }
143 sub modules16 { my $self = shift; return $self->_modules($win16api, @_); }
144 sub modules32 { my $self = shift; return $self->_modules($win32api, @_); }
146 sub modules { my $self = shift; return ($self->modules16, $self->modules32); }
148 ########################################################################
156 my $file = $self->file;
157 my $internal_name = $self->internal_name;
159 my $ordinal = $winapi->function_internal_ordinal($internal_name);
160 my $module = $winapi->function_internal_module($internal_name);
162 if(!defined($ordinal) && !defined($module)) {
166 my @ordinals = split(/\s*&\s*/, $ordinal);
167 my @modules = split(/\s*&\s*/, $module);
170 while(defined(my $ordinal = shift @ordinals) &&
171 defined(my $module = shift @modules))
173 if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) {
174 push @ordinals2, $ordinal;
178 return join(" & ", @ordinals2);
185 my $ordinal = $self->_ordinal($winapi);
187 if(defined($ordinal)) {
188 return split(/\s*&\s*/, $ordinal);
194 sub ordinal16 { my $self = shift; return $self->_ordinal($win16api, @_); }
195 sub ordinal32 { my $self = shift; return $self->_ordinal($win32api, @_); }
197 sub ordinal { my $self = shift; return join (" & ", $self->ordinals); }
199 sub ordinals16 { my $self = shift; return $self->_ordinals($win16api, @_); }
200 sub ordinals32 { my $self = shift; return $self->_ordinals($win32api, @_); }
202 sub ordinals { my $self = shift; return ($self->ordinals16, $self->ordinals32); }
204 ########################################################################
210 my $module16 = $self->module16;
211 my $module32 = $self->module32;
213 my $file = $self->file;
214 my $function_line = $self->function_line;
215 my $return_type = $self->return_type;
216 my $internal_name = $self->internal_name;
217 my $calling_convention = $self->calling_convention;
219 my $refargument_types = $self->argument_types;
220 my @argument_types = ();
221 if(defined($refargument_types)) {
222 @argument_types = @$refargument_types;
223 if($#argument_types < 0) {
224 @argument_types = ("void");
232 foreach my $module ($self->modules) {
233 if($used{$module}) { next; }
234 push @modules, $module;
238 if(defined($function_line)) {
239 $prefix .= "$function_line: ";
244 $prefix .= join(" & ", @modules) . ": ";
248 $prefix .= "$return_type ";
249 $prefix .= "$calling_convention " if $calling_convention;
250 $prefix .= "$internal_name(" . join(",", @argument_types) . "): ";
255 ########################################################################
259 sub calling_convention16 {
261 my $return_kind16 = $self->return_kind16;
264 if(!defined($return_kind16)) {
266 } elsif($return_kind16 =~ /^(?:void|s_word|word)$/) {
268 } elsif($return_kind16 =~ /^(?:long|ptr|segptr|segstr|str|wstr)$/) {
274 local $_ = $self->calling_convention;
277 } elsif(/^VFWAPIV|WINAPIV$/) {
278 if(!defined($suffix)) { return undef; }
279 return "pascal$suffix"; # FIXME: Is this correct?
280 } elsif(/^__stdcall|VFWAPI|WINAPI|CALLBACK$/) {
281 if(!defined($suffix)) { return undef; }
282 return "pascal$suffix";
290 sub calling_convention32 {
293 local $_ = $self->calling_convention;
296 } elsif(/^VFWAPIV|WINAPIV$/) {
298 } elsif(/^__stdcall|VFWAPI|WINAPI|CALLBACK$/) {
307 sub get_all_module_ordinal16 {
309 my $internal_name = $self->internal_name;
311 return winapi::get_all_module_internal_ordinal16($internal_name);
314 sub get_all_module_ordinal32 {
316 my $internal_name = $self->internal_name;
318 return winapi::get_all_module_internal_ordinal32($internal_name);
321 sub get_all_module_ordinal {
323 my $internal_name = $self->internal_name;
325 return winapi::get_all_module_internal_ordinal($internal_name);
331 my $return_type = $self->return_type;
333 return $winapi->translate_argument($return_type);
337 my $self = shift; return $self->_return_kind($win16api, @_);
341 my $self = shift; return $self->_return_kind($win32api, @_);
344 sub _argument_kinds {
347 my $refargument_types = $self->argument_types;
349 if(!defined($refargument_types)) {
354 foreach my $argument_type (@$refargument_types) {
355 my $argument_kind = $winapi->translate_argument($argument_type);
357 if(defined($argument_kind) && $argument_kind eq "longlong") {
358 push @argument_kinds, ("long", "long");
360 push @argument_kinds, $argument_kind;
364 return [@argument_kinds];
367 sub argument_kinds16 {
368 my $self = shift; return $self->_argument_kinds($win16api, @_);
371 sub argument_kinds32 {
372 my $self = shift; return $self->_argument_kinds($win32api, @_);
375 ##############################################################################
379 sub function_called {
381 my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}};
385 $$called_function_names{$name}++;
388 sub function_called_by {
390 my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}};
394 $$called_by_function_names{$name}++;
397 sub called_function_names {
399 my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}};
401 return sort(keys(%$called_function_names));
404 sub called_by_function_names {
406 my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}};
408 return sort(keys(%$called_by_function_names));