Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 1 | # |
| 2 | # Copyright 1999, 2000, 2001 Patrik Stridvall |
| 3 | # |
| 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. |
| 8 | # |
| 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. |
| 13 | # |
| 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 |
Jonathan Ernst | 360a3f9 | 2006-05-18 14:49:52 +0200 | [diff] [blame] | 16 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 17 | # |
| 18 | |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 19 | package winapi_function; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 20 | use base qw(function); |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 21 | |
| 22 | use strict; |
| 23 | |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 24 | use config qw($current_dir $wine_dir); |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 25 | use util qw(normalize_set); |
Patrik Stridvall | a40a4f7 | 2002-10-01 18:10:54 +0000 | [diff] [blame] | 26 | |
| 27 | my $import = 0; |
| 28 | use vars qw($modules $win16api $win32api @winapis); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 29 | |
| 30 | ######################################################################## |
| 31 | # constructor |
| 32 | # |
| 33 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 34 | sub new($) { |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 35 | my $proto = shift; |
| 36 | my $class = ref($proto) || $proto; |
| 37 | my $self = {}; |
| 38 | bless ($self, $class); |
| 39 | |
Patrik Stridvall | a40a4f7 | 2002-10-01 18:10:54 +0000 | [diff] [blame] | 40 | if (!$import) { |
| 41 | require modules; |
| 42 | import modules qw($modules); |
| 43 | |
| 44 | require winapi; |
| 45 | import winapi qw($win16api $win32api @winapis); |
| 46 | |
| 47 | $import = 1; |
| 48 | } |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 49 | return $self; |
| 50 | } |
| 51 | |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 52 | ######################################################################## |
Patrik Stridvall | d07a646 | 2001-07-18 20:09:12 +0000 | [diff] [blame] | 53 | # is_win |
| 54 | # |
| 55 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 56 | sub is_win16($) { my $self = shift; return defined($self->_module($win16api, @_)); } |
| 57 | sub is_win32($) { my $self = shift; return defined($self->_module($win32api, @_)); } |
Patrik Stridvall | d07a646 | 2001-07-18 20:09:12 +0000 | [diff] [blame] | 58 | |
| 59 | ######################################################################## |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 60 | # external_name |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 61 | # |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 62 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 63 | sub _external_name($$) { |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 64 | my $self = shift; |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 65 | my $winapi = shift; |
| 66 | |
| 67 | my $file = $self->file; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 68 | my $internal_name = $self->internal_name; |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 69 | |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 70 | my $external_name = $winapi->function_external_name($internal_name); |
| 71 | my $module = $winapi->function_internal_module($internal_name); |
| 72 | |
| 73 | if(!defined($external_name) && !defined($module)) { |
| 74 | return undef; |
| 75 | } |
| 76 | |
| 77 | my @external_names = split(/\s*&\s*/, $external_name); |
| 78 | my @modules = split(/\s*&\s*/, $module); |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 79 | |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 80 | my @external_names2; |
| 81 | while(defined(my $external_name = shift @external_names) && |
| 82 | defined(my $module = shift @modules)) |
| 83 | { |
| 84 | if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) { |
| 85 | push @external_names2, $external_name; |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | return join(" & ", @external_names2); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 90 | } |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 91 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 92 | sub _external_names($$) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 93 | my $self = shift; |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 94 | my $winapi = shift; |
| 95 | |
| 96 | my $external_name = $self->_external_name($winapi); |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 97 | |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 98 | if(defined($external_name)) { |
| 99 | return split(/\s*&\s*/, $external_name); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 100 | } else { |
| 101 | return (); |
| 102 | } |
Patrik Stridvall | 0d97481 | 2000-05-23 23:37:51 +0000 | [diff] [blame] | 103 | } |
| 104 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 105 | sub external_name($) { |
Patrik Stridvall | 1c61b3b | 2001-07-23 23:20:56 +0000 | [diff] [blame] | 106 | my $self = shift; |
| 107 | |
| 108 | foreach my $winapi (@winapis) { |
| 109 | my $external_name = $self->_external_name($winapi, @_); |
| 110 | |
| 111 | if(defined($external_name)) { |
| 112 | return $external_name; |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | return undef; |
| 117 | } |
| 118 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 119 | sub external_name16($) { my $self = shift; return $self->_external_name($win16api, @_); } |
| 120 | sub external_name32($) { my $self = shift; return $self->_external_name($win32api, @_); } |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 121 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 122 | sub external_names16($) { my $self = shift; return $self->_external_names($win16api, @_); } |
| 123 | sub external_names32($) { my $self = shift; return $self->_external_names($win32api, @_); } |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 124 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 125 | sub external_names($) { my $self = shift; return ($self->external_names16, $self->external_names32); } |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 126 | |
| 127 | ######################################################################## |
| 128 | # module |
| 129 | # |
| 130 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 131 | sub _module($$) { |
Patrik Stridvall | 0d97481 | 2000-05-23 23:37:51 +0000 | [diff] [blame] | 132 | my $self = shift; |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 133 | my $winapi = shift; |
| 134 | |
| 135 | my $file = $self->file; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 136 | my $internal_name = $self->internal_name; |
Patrik Stridvall | 0d97481 | 2000-05-23 23:37:51 +0000 | [diff] [blame] | 137 | |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 138 | my $module = $winapi->function_internal_module($internal_name); |
| 139 | if(!defined($module)) { |
| 140 | return undef; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 141 | } |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 142 | |
Patrik Stridvall | 14fa659 | 2002-11-11 19:55:11 +0000 | [diff] [blame] | 143 | if(!defined($file)) { |
| 144 | return undef; |
| 145 | } |
| 146 | |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 147 | my @modules; |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 148 | foreach my $module (split(/\s*&\s*/, $module)) { |
| 149 | if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) { |
| 150 | push @modules, $module; |
| 151 | } |
| 152 | } |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 153 | |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 154 | return join(" & ", @modules); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 155 | } |
| 156 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 157 | sub _modules($$) { |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 158 | my $self = shift; |
| 159 | my $winapi = shift; |
| 160 | |
| 161 | my $module = $self->_module($winapi); |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 162 | |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 163 | if(defined($module)) { |
| 164 | return split(/\s*&\s*/, $module); |
| 165 | } else { |
| 166 | return (); |
| 167 | } |
| 168 | } |
| 169 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 170 | sub module16($) { my $self = shift; return $self->_module($win16api, @_); } |
| 171 | sub module32($) { my $self = shift; return $self->_module($win32api, @_); } |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 172 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 173 | sub module($) { my $self = shift; return join (" & ", $self->modules); } |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 174 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 175 | sub modules16($) { my $self = shift; return $self->_modules($win16api, @_); } |
| 176 | sub modules32($) { my $self = shift; return $self->_modules($win32api, @_); } |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 177 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 178 | sub modules($) { my $self = shift; return ($self->modules16, $self->modules32); } |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 179 | |
| 180 | ######################################################################## |
| 181 | # ordinal |
| 182 | # |
| 183 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 184 | sub _ordinal($$) { |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 185 | my $self = shift; |
| 186 | my $winapi = shift; |
| 187 | |
| 188 | my $file = $self->file; |
| 189 | my $internal_name = $self->internal_name; |
| 190 | |
| 191 | my $ordinal = $winapi->function_internal_ordinal($internal_name); |
| 192 | my $module = $winapi->function_internal_module($internal_name); |
| 193 | |
| 194 | if(!defined($ordinal) && !defined($module)) { |
| 195 | return undef; |
| 196 | } |
| 197 | |
| 198 | my @ordinals = split(/\s*&\s*/, $ordinal); |
| 199 | my @modules = split(/\s*&\s*/, $module); |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 200 | |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 201 | my @ordinals2; |
| 202 | while(defined(my $ordinal = shift @ordinals) && |
| 203 | defined(my $module = shift @modules)) |
| 204 | { |
| 205 | if($modules->is_allowed_module_in_file($module, "$current_dir/$file")) { |
| 206 | push @ordinals2, $ordinal; |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | return join(" & ", @ordinals2); |
| 211 | } |
| 212 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 213 | sub _ordinals($$) { |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 214 | my $self = shift; |
| 215 | my $winapi = shift; |
| 216 | |
| 217 | my $ordinal = $self->_ordinal($winapi); |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 218 | |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 219 | if(defined($ordinal)) { |
| 220 | return split(/\s*&\s*/, $ordinal); |
| 221 | } else { |
| 222 | return (); |
| 223 | } |
| 224 | } |
| 225 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 226 | sub ordinal16($) { my $self = shift; return $self->_ordinal($win16api, @_); } |
| 227 | sub ordinal32($) { my $self = shift; return $self->_ordinal($win32api, @_); } |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 228 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 229 | sub ordinal($) { my $self = shift; return join (" & ", $self->ordinals); } |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 230 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 231 | sub ordinals16($) { my $self = shift; return $self->_ordinals($win16api, @_); } |
| 232 | sub ordinals32($) { my $self = shift; return $self->_ordinals($win32api, @_); } |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 233 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 234 | sub ordinals($) { my $self = shift; return ($self->ordinals16, $self->ordinals32); } |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 235 | |
| 236 | ######################################################################## |
| 237 | # prefix |
| 238 | # |
| 239 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 240 | sub prefix($) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 241 | my $self = shift; |
| 242 | my $module16 = $self->module16; |
| 243 | my $module32 = $self->module32; |
| 244 | |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 245 | my $file = $self->file; |
Patrik Stridvall | d07a646 | 2001-07-18 20:09:12 +0000 | [diff] [blame] | 246 | my $function_line = $self->function_line; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 247 | my $return_type = $self->return_type; |
| 248 | my $internal_name = $self->internal_name; |
| 249 | my $calling_convention = $self->calling_convention; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 250 | |
Patrik Stridvall | 1c61b3b | 2001-07-23 23:20:56 +0000 | [diff] [blame] | 251 | my $refargument_types = $self->argument_types; |
| 252 | my @argument_types = (); |
| 253 | if(defined($refargument_types)) { |
| 254 | @argument_types = @$refargument_types; |
| 255 | if($#argument_types < 0) { |
| 256 | @argument_types = ("void"); |
| 257 | } |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 258 | } |
| 259 | |
| 260 | my $prefix = ""; |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 261 | |
| 262 | my @modules = (); |
| 263 | my %used; |
| 264 | foreach my $module ($self->modules) { |
| 265 | if($used{$module}) { next; } |
| 266 | push @modules, $module; |
| 267 | $used{$module}++; |
| 268 | } |
Patrik Stridvall | d07a646 | 2001-07-18 20:09:12 +0000 | [diff] [blame] | 269 | $prefix .= "$file:"; |
| 270 | if(defined($function_line)) { |
| 271 | $prefix .= "$function_line: "; |
| 272 | } else { |
| 273 | $prefix .= "<>: "; |
| 274 | } |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 275 | if($#modules >= 0) { |
| 276 | $prefix .= join(" & ", @modules) . ": "; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 277 | } else { |
| 278 | $prefix .= "<>: "; |
| 279 | } |
| 280 | $prefix .= "$return_type "; |
| 281 | $prefix .= "$calling_convention " if $calling_convention; |
| 282 | $prefix .= "$internal_name(" . join(",", @argument_types) . "): "; |
| 283 | |
| 284 | return $prefix; |
| 285 | } |
| 286 | |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 287 | ######################################################################## |
| 288 | # calling_convention |
| 289 | # |
| 290 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 291 | sub calling_convention16($) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 292 | my $self = shift; |
| 293 | my $return_kind16 = $self->return_kind16; |
| 294 | |
| 295 | my $suffix; |
| 296 | if(!defined($return_kind16)) { |
| 297 | $suffix = undef; |
| 298 | } elsif($return_kind16 =~ /^(?:void|s_word|word)$/) { |
| 299 | $suffix = "16"; |
| 300 | } elsif($return_kind16 =~ /^(?:long|ptr|segptr|segstr|str|wstr)$/) { |
| 301 | $suffix = ""; |
| 302 | } else { |
| 303 | $suffix = undef; |
| 304 | } |
| 305 | |
| 306 | local $_ = $self->calling_convention; |
Francois Gouget | b4df241 | 2004-10-22 19:55:42 +0000 | [diff] [blame] | 307 | if($_ eq "__cdecl") { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 308 | return "cdecl"; |
Francois Gouget | b4df241 | 2004-10-22 19:55:42 +0000 | [diff] [blame] | 309 | } elsif(/^(?:VFWAPIV|WINAPIV)$/) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 310 | if(!defined($suffix)) { return undef; } |
| 311 | return "pascal$suffix"; # FIXME: Is this correct? |
Vincent Béron | 74ce0d3 | 2005-11-30 12:03:03 +0100 | [diff] [blame] | 312 | } elsif(/^(?:__stdcall|__RPC_STUB|__RPC_USER|NET_API_FUNCTION|RPC_ENTRY|VFWAPI|WINAPI|CALLBACK)$/) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 313 | if(!defined($suffix)) { return undef; } |
| 314 | return "pascal$suffix"; |
Francois Gouget | b4df241 | 2004-10-22 19:55:42 +0000 | [diff] [blame] | 315 | } elsif($_ eq "__asm") { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 316 | return "asm"; |
| 317 | } else { |
| 318 | return "cdecl"; |
| 319 | } |
| 320 | } |
| 321 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 322 | sub calling_convention32($) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 323 | my $self = shift; |
| 324 | |
| 325 | local $_ = $self->calling_convention; |
Francois Gouget | b4df241 | 2004-10-22 19:55:42 +0000 | [diff] [blame] | 326 | if($_ eq "__cdecl") { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 327 | return "cdecl"; |
Francois Gouget | b4df241 | 2004-10-22 19:55:42 +0000 | [diff] [blame] | 328 | } elsif(/^(?:VFWAPIV|WINAPIV)$/) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 329 | return "varargs"; |
Vincent Béron | 74ce0d3 | 2005-11-30 12:03:03 +0100 | [diff] [blame] | 330 | } elsif(/^(?:__stdcall|__RPC_STUB|__RPC_USER|NET_API_FUNCTION|RPC_ENTRY|VFWAPI|WINAPI|CALLBACK)$/) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 331 | return "stdcall"; |
Francois Gouget | b4df241 | 2004-10-22 19:55:42 +0000 | [diff] [blame] | 332 | } elsif($_ eq "__asm") { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 333 | return "asm"; |
| 334 | } else { |
| 335 | return "cdecl"; |
| 336 | } |
| 337 | } |
| 338 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 339 | sub get_all_module_ordinal16($) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 340 | my $self = shift; |
| 341 | my $internal_name = $self->internal_name; |
| 342 | |
| 343 | return winapi::get_all_module_internal_ordinal16($internal_name); |
| 344 | } |
| 345 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 346 | sub get_all_module_ordinal32($) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 347 | my $self = shift; |
| 348 | my $internal_name = $self->internal_name; |
| 349 | |
| 350 | return winapi::get_all_module_internal_ordinal32($internal_name); |
| 351 | } |
| 352 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 353 | sub get_all_module_ordinal($) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 354 | my $self = shift; |
| 355 | my $internal_name = $self->internal_name; |
| 356 | |
| 357 | return winapi::get_all_module_internal_ordinal($internal_name); |
| 358 | } |
| 359 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 360 | sub _return_kind($$) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 361 | my $self = shift; |
| 362 | my $winapi = shift; |
| 363 | my $return_type = $self->return_type; |
| 364 | |
| 365 | return $winapi->translate_argument($return_type); |
| 366 | } |
| 367 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 368 | sub return_kind16($) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 369 | my $self = shift; return $self->_return_kind($win16api, @_); |
| 370 | } |
| 371 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 372 | sub return_kind32($) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 373 | my $self = shift; return $self->_return_kind($win32api, @_); |
| 374 | } |
| 375 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 376 | sub _argument_kinds($$) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 377 | my $self = shift; |
| 378 | my $winapi = shift; |
Patrik Stridvall | 1c61b3b | 2001-07-23 23:20:56 +0000 | [diff] [blame] | 379 | my $refargument_types = $self->argument_types; |
| 380 | |
| 381 | if(!defined($refargument_types)) { |
| 382 | return undef; |
| 383 | } |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 384 | |
| 385 | my @argument_kinds; |
Patrik Stridvall | 1c61b3b | 2001-07-23 23:20:56 +0000 | [diff] [blame] | 386 | foreach my $argument_type (@$refargument_types) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 387 | my $argument_kind = $winapi->translate_argument($argument_type); |
| 388 | |
| 389 | if(defined($argument_kind) && $argument_kind eq "longlong") { |
Francois Gouget | 9714802 | 2005-09-26 09:52:09 +0000 | [diff] [blame] | 390 | push @argument_kinds, "double"; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 391 | } else { |
| 392 | push @argument_kinds, $argument_kind; |
| 393 | } |
| 394 | } |
| 395 | |
| 396 | return [@argument_kinds]; |
| 397 | } |
| 398 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 399 | sub argument_kinds16($) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 400 | my $self = shift; return $self->_argument_kinds($win16api, @_); |
| 401 | } |
| 402 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 403 | sub argument_kinds32($) { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 404 | my $self = shift; return $self->_argument_kinds($win32api, @_); |
| 405 | } |
| 406 | |
| 407 | ############################################################################## |
| 408 | # Accounting |
| 409 | # |
| 410 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 411 | sub function_called($$) { |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 412 | my $self = shift; |
| 413 | my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}}; |
| 414 | |
| 415 | my $name = shift; |
| 416 | |
| 417 | $$called_function_names{$name}++; |
| 418 | } |
| 419 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 420 | sub function_called_by($$) { |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 421 | my $self = shift; |
| 422 | my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}}; |
| 423 | |
| 424 | my $name = shift; |
| 425 | |
| 426 | $$called_by_function_names{$name}++; |
| 427 | } |
| 428 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 429 | sub called_function_names($) { |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 430 | my $self = shift; |
| 431 | my $called_function_names = \%{$self->{CALLED_FUNCTION_NAMES}}; |
| 432 | |
| 433 | return sort(keys(%$called_function_names)); |
| 434 | } |
| 435 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 436 | sub called_by_function_names($) { |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 437 | my $self = shift; |
| 438 | my $called_by_function_names = \%{$self->{CALLED_BY_FUNCTION_NAMES}}; |
| 439 | |
| 440 | return sort(keys(%$called_by_function_names)); |
| 441 | } |
| 442 | |
| 443 | |
| 444 | 1; |