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 | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 19 | package winapi_parser; |
| 20 | |
| 21 | use strict; |
| 22 | |
Patrik Stridvall | 1c61b3b | 2001-07-23 23:20:56 +0000 | [diff] [blame] | 23 | use output qw($output); |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 24 | use options qw($options); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 25 | |
Francois Gouget | 9139fd1 | 2006-05-12 00:19:54 +0200 | [diff] [blame] | 26 | # Defined a couple common regexp tidbits |
| 27 | my $CALL_CONVENTION="__cdecl|__stdcall|" . |
| 28 | "__RPC_API|__RPC_STUB|__RPC_USER|RPC_ENTRY|" . |
| 29 | "RPC_VAR_ENTRY|STDMETHODCALLTYPE|NET_API_FUNCTION|" . |
| 30 | "CALLBACK|CDECL|NTAPI|PASCAL|APIENTRY|" . |
| 31 | "VFWAPI|VFWAPIV|WINAPI|WINAPIV|"; |
| 32 | |
Francois Gouget | 493d60f | 2004-10-07 18:53:56 +0000 | [diff] [blame] | 33 | sub parse_c_file($$) { |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 34 | my $file = shift; |
Patrik Stridvall | c56ed50 | 2002-04-29 18:45:12 +0000 | [diff] [blame] | 35 | my $callbacks = shift; |
| 36 | |
| 37 | my $empty_callback = sub { }; |
| 38 | |
| 39 | my $c_comment_found_callback = $$callbacks{c_comment_found} || $empty_callback; |
| 40 | my $cplusplus_comment_found_callback = $$callbacks{cplusplus_comment_found} || $empty_callback; |
| 41 | my $function_create_callback = $$callbacks{function_create} || $empty_callback; |
| 42 | my $function_found_callback = $$callbacks{function_found} || $empty_callback; |
| 43 | my $type_create_callback = $$callbacks{type_create} || $empty_callback; |
| 44 | my $type_found_callback = $$callbacks{type_found} || $empty_callback; |
| 45 | my $preprocessor_found_callback = $$callbacks{preprocessor_found} || $empty_callback; |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 46 | |
Patrik Stridvall | 41f99ba | 2001-06-11 20:13:21 +0000 | [diff] [blame] | 47 | # global |
| 48 | my $debug_channels = []; |
| 49 | |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 50 | my $in_function = 0; |
| 51 | my $function_begin; |
| 52 | my $function_end; |
| 53 | { |
| 54 | my $documentation_line; |
| 55 | my $documentation; |
| 56 | my $function_line; |
| 57 | my $linkage; |
| 58 | my $return_type; |
| 59 | my $calling_convention; |
| 60 | my $internal_name = ""; |
| 61 | my $argument_types; |
| 62 | my $argument_names; |
| 63 | my $argument_documentations; |
Patrik Stridvall | 4b33b13 | 2001-08-09 21:35:38 +0000 | [diff] [blame] | 64 | my $statements_line; |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 65 | my $statements; |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 66 | |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 67 | $function_begin = sub { |
| 68 | $documentation_line = shift; |
| 69 | $documentation = shift; |
| 70 | $function_line = shift; |
| 71 | $linkage = shift; |
| 72 | $return_type= shift; |
| 73 | $calling_convention = shift; |
| 74 | $internal_name = shift; |
| 75 | $argument_types = shift; |
| 76 | $argument_names = shift; |
| 77 | $argument_documentations = shift; |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 78 | |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 79 | if(defined($argument_names) && defined($argument_types) && |
| 80 | $#$argument_names == -1) |
| 81 | { |
| 82 | foreach my $n (0..$#$argument_types) { |
| 83 | push @$argument_names, ""; |
| 84 | } |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 85 | } |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 86 | |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 87 | if(defined($argument_documentations) && |
| 88 | $#$argument_documentations == -1) |
| 89 | { |
| 90 | foreach my $n (0..$#$argument_documentations) { |
| 91 | push @$argument_documentations, ""; |
| 92 | } |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 93 | } |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 94 | |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 95 | $in_function = 1; |
| 96 | }; |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 97 | |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 98 | $function_end = sub { |
Patrik Stridvall | 4b33b13 | 2001-08-09 21:35:38 +0000 | [diff] [blame] | 99 | $statements_line = shift; |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 100 | $statements = shift; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 101 | |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 102 | my $function = &$function_create_callback(); |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 103 | |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 104 | if(!defined($documentation_line)) { |
| 105 | $documentation_line = 0; |
| 106 | } |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 107 | |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 108 | $function->file($file); |
| 109 | $function->debug_channels([@$debug_channels]); |
| 110 | $function->documentation_line($documentation_line); |
| 111 | $function->documentation($documentation); |
| 112 | $function->function_line($function_line); |
| 113 | $function->linkage($linkage); |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 114 | $function->return_type($return_type); |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 115 | $function->calling_convention($calling_convention); |
| 116 | $function->internal_name($internal_name); |
| 117 | if(defined($argument_types)) { |
| 118 | $function->argument_types([@$argument_types]); |
| 119 | } |
| 120 | if(defined($argument_names)) { |
| 121 | $function->argument_names([@$argument_names]); |
| 122 | } |
| 123 | if(defined($argument_documentations)) { |
| 124 | $function->argument_documentations([@$argument_documentations]); |
| 125 | } |
Patrik Stridvall | 4b33b13 | 2001-08-09 21:35:38 +0000 | [diff] [blame] | 126 | $function->statements_line($statements_line); |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 127 | $function->statements($statements); |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 128 | |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 129 | &$function_found_callback($function); |
Patrik Stridvall | bda5074 | 2001-07-14 00:48:41 +0000 | [diff] [blame] | 130 | |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 131 | $in_function = 0; |
| 132 | }; |
| 133 | } |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 134 | |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 135 | my $in_type = 0; |
| 136 | my $type_begin; |
| 137 | my $type_end; |
| 138 | { |
| 139 | my $type; |
| 140 | |
| 141 | $type_begin = sub { |
| 142 | $type = shift; |
| 143 | $in_type = 1; |
| 144 | }; |
| 145 | |
| 146 | $type_end = sub { |
| 147 | my $names = shift; |
| 148 | |
| 149 | foreach my $name (@$names) { |
Vincent Béron | 2f8f459 | 2005-12-02 11:27:13 +0100 | [diff] [blame] | 150 | if($type =~ /^(?:enum|interface|struct|union)/) { |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 151 | # $output->write("typedef $type {\n"); |
| 152 | # $output->write("} $name;\n"); |
| 153 | } else { |
| 154 | # $output->write("typedef $type $name;\n"); |
| 155 | } |
| 156 | } |
| 157 | $in_type = 0; |
| 158 | }; |
| 159 | } |
| 160 | |
Patrik Stridvall | af1601b | 1999-12-11 23:01:45 +0000 | [diff] [blame] | 161 | my %regs_entrypoints; |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 162 | my @comment_lines = (); |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 163 | my @comments = (); |
Patrik Stridvall | 4b33b13 | 2001-08-09 21:35:38 +0000 | [diff] [blame] | 164 | my $statements_line; |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 165 | my $statements; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 166 | my $level = 0; |
Patrik Stridvall | 6a4e8a5 | 2000-04-06 20:11:04 +0000 | [diff] [blame] | 167 | my $extern_c = 0; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 168 | my $again = 0; |
| 169 | my $lookahead = 0; |
| 170 | my $lookahead_count = 0; |
| 171 | |
| 172 | print STDERR "Processing file '$file' ... " if $options->verbose; |
| 173 | open(IN, "< $file") || die "<internal>: $file: $!\n"; |
Patrik Stridvall | bd68e06 | 2002-10-02 01:23:55 +0000 | [diff] [blame] | 174 | local $_ = ""; |
Francois Gouget | bd3b696 | 2004-10-21 19:56:04 +0000 | [diff] [blame] | 175 | readmore: while($again || defined(my $line = <IN>)) { |
Patrik Stridvall | bd68e06 | 2002-10-02 01:23:55 +0000 | [diff] [blame] | 176 | $_ = "" if !defined($_); |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 177 | if(!$again) { |
| 178 | chomp $line; |
| 179 | |
| 180 | if($lookahead) { |
| 181 | $lookahead = 0; |
| 182 | $_ .= "\n" . $line; |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 183 | $lookahead_count++; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 184 | } else { |
| 185 | $_ = $line; |
| 186 | $lookahead_count = 0; |
| 187 | } |
Patrik Stridvall | bd68e06 | 2002-10-02 01:23:55 +0000 | [diff] [blame] | 188 | $output->write(" $level($lookahead_count): $line\n") if $options->debug >= 2; |
| 189 | $output->write("*** $_\n") if $options->debug >= 3; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 190 | } else { |
| 191 | $lookahead_count = 0; |
| 192 | $again = 0; |
| 193 | } |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 194 | |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 195 | # CVS merge conflicts in file? |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 196 | if(/^(<<<<<<<|=======|>>>>>>>)/) { |
| 197 | $output->write("$file: merge conflicts in file\n"); |
| 198 | last; |
| 199 | } |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 200 | |
Francois Gouget | bd3b696 | 2004-10-21 19:56:04 +0000 | [diff] [blame] | 201 | my $prefix=""; |
| 202 | while ($_ ne "") |
| 203 | { |
| 204 | if (s/^([^\"\/]+|\"(?:[^\\\"]*|\\.)*\")//) |
| 205 | { |
| 206 | $prefix.=$1; |
| 207 | } |
| 208 | elsif (/^\/\*/) |
| 209 | { |
| 210 | # remove C comments |
| 211 | if(s/^(\/\*.*?\*\/)//s) { |
| 212 | my @lines = split(/\n/, $1); |
| 213 | push @comment_lines, $.; |
| 214 | push @comments, $1; |
| 215 | &$c_comment_found_callback($. - $#lines, $., $1); |
| 216 | if($#lines <= 0) { |
| 217 | $_ = "$prefix $_"; |
| 218 | } else { |
| 219 | $_ = $prefix . ("\n" x $#lines) . $_; |
| 220 | } |
| 221 | $again = 1; |
| 222 | } else { |
| 223 | $_ = "$prefix$_"; |
| 224 | $lookahead = 1; |
| 225 | } |
| 226 | next readmore; |
| 227 | } |
| 228 | elsif (s/^(\/\/.*)$//) |
| 229 | { |
| 230 | # remove C++ comments |
| 231 | &$cplusplus_comment_found_callback($., $1); |
| 232 | $again = 1; |
| 233 | } |
| 234 | elsif (s/^(.)//) |
| 235 | { |
| 236 | $prefix.=$1; |
| 237 | } |
| 238 | } |
| 239 | $_=$prefix; |
Patrik Stridvall | 54e1552 | 2000-05-18 00:07:31 +0000 | [diff] [blame] | 240 | |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 241 | # remove preprocessor directives |
Patrik Stridvall | 4b33b13 | 2001-08-09 21:35:38 +0000 | [diff] [blame] | 242 | if(s/^\s*\#/\#/s) { |
Patrik Stridvall | c5f834c | 2003-08-08 21:04:17 +0000 | [diff] [blame] | 243 | if(/^(\#.*?)\\$/s) { |
| 244 | $_ = "$1\n"; |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 245 | $lookahead = 1; |
| 246 | next; |
Patrik Stridvall | 4b33b13 | 2001-08-09 21:35:38 +0000 | [diff] [blame] | 247 | } elsif(s/^\#\s*(\w+)((?:\s+(.*?))?\s*)$//s) { |
| 248 | my @lines = split(/\n/, $2); |
| 249 | if($#lines > 0) { |
| 250 | $_ = "\n" x $#lines; |
| 251 | } |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 252 | if(defined($3)) { |
| 253 | &$preprocessor_found_callback($1, $3); |
| 254 | } else { |
| 255 | &$preprocessor_found_callback($1, ""); |
| 256 | } |
Patrik Stridvall | 4b33b13 | 2001-08-09 21:35:38 +0000 | [diff] [blame] | 257 | $again = 1; |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 258 | next; |
| 259 | } |
| 260 | } |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 261 | |
Patrik Stridvall | 6a4e8a5 | 2000-04-06 20:11:04 +0000 | [diff] [blame] | 262 | # Remove extern "C" |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 263 | if(s/^\s*extern\s+"C"\s+\{//m) { |
Patrik Stridvall | 6a4e8a5 | 2000-04-06 20:11:04 +0000 | [diff] [blame] | 264 | $extern_c = 1; |
| 265 | $again = 1; |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 266 | next; |
Patrik Stridvall | 6a4e8a5 | 2000-04-06 20:11:04 +0000 | [diff] [blame] | 267 | } |
| 268 | |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 269 | my $documentation_line; |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 270 | my $documentation; |
Patrik Stridvall | 94a5077 | 2000-12-01 23:51:33 +0000 | [diff] [blame] | 271 | my @argument_documentations = (); |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 272 | { |
| 273 | my $n = $#comments; |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 274 | while($n >= 0 && ($comments[$n] !~ /^\/\*\*/ || |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 275 | $comments[$n] =~ /^\/\*\*+\/$/)) |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 276 | { |
| 277 | $n--; |
| 278 | } |
| 279 | |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 280 | if(defined($comments[$n]) && $n >= 0) { |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 281 | my @lines = split(/\n/, $comments[$n]); |
| 282 | |
| 283 | $documentation_line = $comment_lines[$n] - scalar(@lines) + 1; |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 284 | $documentation = $comments[$n]; |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 285 | |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 286 | for(my $m=$n+1; $m <= $#comments; $m++) { |
Patrik Stridvall | 9086d42 | 2001-01-20 02:16:31 +0000 | [diff] [blame] | 287 | if($comments[$m] =~ /^\/\*\*+\/$/ || |
| 288 | $comments[$m] =~ /^\/\*\s*(?:\!)?defined/) # FIXME: Kludge |
| 289 | { |
Patrik Stridvall | 94a5077 | 2000-12-01 23:51:33 +0000 | [diff] [blame] | 290 | @argument_documentations = (); |
| 291 | next; |
| 292 | } |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 293 | push @argument_documentations, $comments[$m]; |
| 294 | } |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 295 | } else { |
| 296 | $documentation = ""; |
| 297 | } |
| 298 | } |
| 299 | |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 300 | if($level > 0) |
| 301 | { |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 302 | my $line = ""; |
| 303 | while(/^[^\{\}]/) { |
| 304 | s/^([^\{\}\'\"]*)//s; |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 305 | $line .= $1; |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 306 | if(s/^\'//) { |
| 307 | $line .= "\'"; |
| 308 | while(/^./ && !s/^\'//) { |
| 309 | s/^([^\'\\]*)//s; |
| 310 | $line .= $1; |
| 311 | if(s/^\\//) { |
| 312 | $line .= "\\"; |
| 313 | if(s/^(.)//s) { |
| 314 | $line .= $1; |
| 315 | if($1 eq "0") { |
| 316 | s/^(\d{0,3})//s; |
| 317 | $line .= $1; |
| 318 | } |
| 319 | } |
| 320 | } |
| 321 | } |
| 322 | $line .= "\'"; |
| 323 | } elsif(s/^\"//) { |
| 324 | $line .= "\""; |
| 325 | while(/^./ && !s/^\"//) { |
| 326 | s/^([^\"\\]*)//s; |
| 327 | $line .= $1; |
| 328 | if(s/^\\//) { |
| 329 | $line .= "\\"; |
| 330 | if(s/^(.)//s) { |
| 331 | $line .= $1; |
| 332 | if($1 eq "0") { |
| 333 | s/^(\d{0,3})//s; |
| 334 | $line .= $1; |
| 335 | } |
| 336 | } |
| 337 | } |
| 338 | } |
| 339 | $line .= "\""; |
| 340 | } |
| 341 | } |
| 342 | |
| 343 | if(s/^\{//) { |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 344 | $_ = $'; $again = 1; |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 345 | $line .= "{"; |
| 346 | print "+1: \{$_\n" if $options->debug >= 2; |
| 347 | $level++; |
Patrik Stridvall | 4b33b13 | 2001-08-09 21:35:38 +0000 | [diff] [blame] | 348 | $statements .= $line; |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 349 | } elsif(s/^\}//) { |
| 350 | $_ = $'; $again = 1; |
| 351 | $line .= "}" if $level > 1; |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 352 | print "-1: \}$_\n" if $options->debug >= 2; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 353 | $level--; |
Patrik Stridvall | 6a4e8a5 | 2000-04-06 20:11:04 +0000 | [diff] [blame] | 354 | if($level == -1 && $extern_c) { |
| 355 | $extern_c = 0; |
| 356 | $level = 0; |
| 357 | } |
Patrik Stridvall | 4b33b13 | 2001-08-09 21:35:38 +0000 | [diff] [blame] | 358 | $statements .= $line; |
| 359 | } else { |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 360 | $statements .= "$line\n"; |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 361 | } |
| 362 | |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 363 | if($level == 0) { |
| 364 | if($in_function) { |
Patrik Stridvall | 4b33b13 | 2001-08-09 21:35:38 +0000 | [diff] [blame] | 365 | &$function_end($statements_line, $statements); |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 366 | $statements = undef; |
| 367 | } elsif($in_type) { |
Vincent Béron | 7257b70 | 2005-08-08 11:06:24 +0000 | [diff] [blame] | 368 | if(/^\s*((?:(?:FAR\s*)?\*\s*(?:RESTRICTED_POINTER\s+)?)? |
Vincent Béron | 78039be | 2005-11-04 11:39:58 +0000 | [diff] [blame] | 369 | (?:volatile\s+)? |
Vincent Béron | 7257b70 | 2005-08-08 11:06:24 +0000 | [diff] [blame] | 370 | (?:\w+|WS\(\w+\))\s* |
Vincent Béron | 78039be | 2005-11-04 11:39:58 +0000 | [diff] [blame] | 371 | (?:\s*,\s*(?:(?:FAR\s*)?\*+\s*(?:RESTRICTED_POINTER\s+)?)?(?:volatile\s+)?(?:\w+|WS\(\w+\)))*\s*);/sx) { |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 372 | my @parts = split(/\s*,\s*/, $1); |
| 373 | &$type_end([@parts]); |
| 374 | } elsif(/;/s) { |
| 375 | die "$file: $.: syntax error: '$_'\n"; |
| 376 | } else { |
| 377 | $lookahead = 1; |
| 378 | } |
| 379 | } |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 380 | } |
Patrik Stridvall | d07a646 | 2001-07-18 20:09:12 +0000 | [diff] [blame] | 381 | next; |
Vincent Béron | 2f8f459 | 2005-12-02 11:27:13 +0100 | [diff] [blame] | 382 | } elsif(/(extern\s+|static\s+)?((interface\s+|struct\s+|union\s+|enum\s+|signed\s+|unsigned\s+)?\w+((\s*\*)+\s*|\s+)) |
Francois Gouget | 9139fd1 | 2006-05-12 00:19:54 +0200 | [diff] [blame] | 383 | (($CALL_CONVENTION)\s+)? |
Patrik Stridvall | ae9cf77 | 2004-05-17 20:50:24 +0000 | [diff] [blame] | 384 | (\w+(\(\w+\))?)\s*\((.*?)\)\s*(\{|\;)/sx) |
Patrik Stridvall | 360c3f2 | 2000-06-11 20:02:29 +0000 | [diff] [blame] | 385 | { |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 386 | my @lines = split(/\n/, $&); |
| 387 | my $function_line = $. - scalar(@lines) + 1; |
| 388 | |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 389 | $_ = $'; $again = 1; |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 390 | |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 391 | if($11 eq "{") { |
| 392 | $level++; |
| 393 | } |
Patrik Stridvall | 1932d40 | 2000-04-15 20:39:55 +0000 | [diff] [blame] | 394 | |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 395 | my $linkage = $1; |
| 396 | my $return_type = $2; |
| 397 | my $calling_convention = $7; |
| 398 | my $name = $8; |
| 399 | my $arguments = $10; |
| 400 | |
| 401 | if(!defined($linkage)) { |
| 402 | $linkage = ""; |
| 403 | } |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 404 | |
| 405 | if(!defined($calling_convention)) { |
| 406 | $calling_convention = ""; |
| 407 | } |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 408 | |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 409 | $linkage =~ s/\s*$//; |
| 410 | |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 411 | $return_type =~ s/\s*$//; |
| 412 | $return_type =~ s/\s*\*\s*/*/g; |
| 413 | $return_type =~ s/(\*+)/ $1/g; |
| 414 | |
Patrik Stridvall | af1601b | 1999-12-11 23:01:45 +0000 | [diff] [blame] | 415 | if($regs_entrypoints{$name}) { |
| 416 | $name = $regs_entrypoints{$name}; |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 417 | } |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 418 | |
| 419 | $arguments =~ y/\t\n/ /; |
| 420 | $arguments =~ s/^\s*(.*?)\s*$/$1/; |
Patrik Stridvall | 20ca001 | 2001-06-19 03:34:52 +0000 | [diff] [blame] | 421 | if($arguments eq "") { $arguments = "..." } |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 422 | |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 423 | my @argument_types; |
| 424 | my @argument_names; |
Patrik Stridvall | ae9cf77 | 2004-05-17 20:50:24 +0000 | [diff] [blame] | 425 | my @arguments; |
| 426 | my $n = 0; |
| 427 | while ($arguments =~ s/^((?:[^,\(\)]*|(?:\([^\)]*\))?)+)(?:,|$)// && $1) { |
| 428 | my $argument = $1; |
| 429 | push @arguments, $argument; |
| 430 | |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 431 | my $argument_type = ""; |
| 432 | my $argument_name = ""; |
Patrik Stridvall | ae9cf77 | 2004-05-17 20:50:24 +0000 | [diff] [blame] | 433 | |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 434 | $argument =~ s/^\s*(.*?)\s*$/$1/; |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 435 | # print " " . ($n + 1) . ": '$argument'\n"; |
Francois Gouget | 964cbcb | 2006-05-10 18:53:41 +0200 | [diff] [blame] | 436 | $argument =~ s/^(?:IN OUT|IN|OUT)?\s+//; |
Francois Gouget | 8304759 | 2007-06-21 11:15:26 +0200 | [diff] [blame] | 437 | $argument =~ s/^(?:const|CONST|GDIPCONST|volatile)?\s+//; |
Patrik Stridvall | 5dadbf3 | 2000-04-29 14:24:11 +0000 | [diff] [blame] | 438 | if($argument =~ /^\.\.\.$/) { |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 439 | $argument_type = "..."; |
| 440 | $argument_name = "..."; |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 441 | } elsif($argument =~ /^ |
Francois Gouget | 964cbcb | 2006-05-10 18:53:41 +0200 | [diff] [blame] | 442 | ((?:interface\s+|struct\s+|union\s+|enum\s+|register\s+|(?:signed\s+|unsigned\s+)? |
Vincent Béron | 7257b70 | 2005-08-08 11:06:24 +0000 | [diff] [blame] | 443 | (?:short\s+(?=int)|long\s+(?=int))?)?(?:\w+|ElfW\(\w+\)|WS\(\w+\)))\s* |
Francois Gouget | 8304759 | 2007-06-21 11:15:26 +0200 | [diff] [blame] | 444 | ((?:__RPC_FAR|const|CONST|GDIPCONST|volatile)?\s*(?:\*\s*(?:__RPC_FAR|const|CONST|volatile)?\s*?)*)\s* |
Vincent Béron | 7257b70 | 2005-08-08 11:06:24 +0000 | [diff] [blame] | 445 | (\w*)\s*(\[\])?(?:\s+OPTIONAL)?$/x) |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 446 | { |
Patrik Stridvall | ae9cf77 | 2004-05-17 20:50:24 +0000 | [diff] [blame] | 447 | $argument_type = $1; |
| 448 | if ($2) { |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 449 | $argument_type .= " $2"; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 450 | } |
Vincent Béron | 7257b70 | 2005-08-08 11:06:24 +0000 | [diff] [blame] | 451 | if ($4) { |
| 452 | $argument_type .= "$4"; |
| 453 | } |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 454 | $argument_name = $3; |
Patrik Stridvall | ae9cf77 | 2004-05-17 20:50:24 +0000 | [diff] [blame] | 455 | } elsif ($argument =~ /^ |
Francois Gouget | 964cbcb | 2006-05-10 18:53:41 +0200 | [diff] [blame] | 456 | ((?:interface\s+|struct\s+|union\s+|enum\s+|register\s+|(?:signed\s+|unsigned\s+)? |
Patrik Stridvall | ae9cf77 | 2004-05-17 20:50:24 +0000 | [diff] [blame] | 457 | (?:short\s+(?=int)|long\s+(?=int))?)?\w+)\s* |
Francois Gouget | 09108ed | 2005-09-06 09:23:46 +0000 | [diff] [blame] | 458 | ((?:const|volatile)?\s*(?:\*\s*(?:const|volatile)?\s*?)*)\s* |
Francois Gouget | 9139fd1 | 2006-05-12 00:19:54 +0200 | [diff] [blame] | 459 | (?:(?:$CALL_CONVENTION)\s+)? |
| 460 | \(\s*(?:$CALL_CONVENTION)?\s*\*\s*((?:\w+)?)\s*\)\s* |
Patrik Stridvall | ae9cf77 | 2004-05-17 20:50:24 +0000 | [diff] [blame] | 461 | \(\s*(.*?)\s*\)$/x) |
| 462 | { |
| 463 | my $return_type = $1; |
| 464 | if($2) { |
| 465 | $return_type .= " $2"; |
| 466 | } |
| 467 | $argument_name = $3; |
| 468 | my $arguments = $4; |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 469 | |
Patrik Stridvall | ae9cf77 | 2004-05-17 20:50:24 +0000 | [diff] [blame] | 470 | $return_type =~ s/\s+/ /g; |
| 471 | $arguments =~ s/\s*,\s*/,/g; |
| 472 | |
| 473 | $argument_type = "$return_type (*)($arguments)"; |
| 474 | } elsif ($argument =~ /^ |
Vincent Béron | 2f8f459 | 2005-12-02 11:27:13 +0100 | [diff] [blame] | 475 | ((?:interface\s+|struct\s+|union\s+|enum\s+|register\s+|(?:signed\s+|unsigned\s+) |
Patrik Stridvall | ae9cf77 | 2004-05-17 20:50:24 +0000 | [diff] [blame] | 476 | (?:short\s+(?=int)|long\s+(?=int))?)?\w+)\s* |
Francois Gouget | 09108ed | 2005-09-06 09:23:46 +0000 | [diff] [blame] | 477 | ((?:const|volatile)?\s*(?:\*\s*(?:const|volatile)?\s*?)*)\s* |
Patrik Stridvall | ae9cf77 | 2004-05-17 20:50:24 +0000 | [diff] [blame] | 478 | (\w+)\s*\[\s*(.*?)\s*\](?:\[\s*(.*?)\s*\])?$/x) |
| 479 | { |
| 480 | my $return_type = $1; |
| 481 | if($2) { |
| 482 | $return_type .= " $2"; |
| 483 | } |
| 484 | $argument_name = $3; |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 485 | |
Patrik Stridvall | ae9cf77 | 2004-05-17 20:50:24 +0000 | [diff] [blame] | 486 | $argument_type = "$return_type\[$4\]"; |
| 487 | |
| 488 | if (defined($5)) { |
| 489 | $argument_type .= "\[$5\]"; |
| 490 | } |
| 491 | |
| 492 | # die "$file: $.: syntax error: '$argument_type':'$argument_name'\n"; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 493 | } else { |
| 494 | die "$file: $.: syntax error: '$argument'\n"; |
| 495 | } |
Patrik Stridvall | ae9cf77 | 2004-05-17 20:50:24 +0000 | [diff] [blame] | 496 | |
Francois Gouget | 09108ed | 2005-09-06 09:23:46 +0000 | [diff] [blame] | 497 | $argument_type =~ s/\s*(?:const|volatile)\s*/ /g; # Remove const/volatile |
Patrik Stridvall | ae9cf77 | 2004-05-17 20:50:24 +0000 | [diff] [blame] | 498 | $argument_type =~ s/([^\*\(\s])\*/$1 \*/g; # Assure whitespace between non-* and * |
| 499 | $argument_type =~ s/,([^\s])/, $1/g; # Assure whitespace after , |
| 500 | $argument_type =~ s/\*\s+\*/\*\*/g; # Remove whitespace between * and * |
| 501 | $argument_type =~ s/([\(\[])\s+/$1/g; # Remove whitespace after ( and [ |
| 502 | $argument_type =~ s/\s+([\)\]])/$1/g; # Remove whitespace before ] and ) |
| 503 | $argument_type =~ s/\s+/ /; # Remove multiple whitespace |
| 504 | $argument_type =~ s/^\s*(.*?)\s*$/$1/; # Remove leading and trailing whitespace |
| 505 | |
| 506 | $argument_name =~ s/^\s*(.*?)\s*$/$1/; # Remove leading and trailing whitespace |
| 507 | |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 508 | $argument_types[$n] = $argument_type; |
| 509 | $argument_names[$n] = $argument_name; |
| 510 | # print " " . ($n + 1) . ": '" . $argument_types[$n] . "', '" . $argument_names[$n] . "'\n"; |
Patrik Stridvall | ae9cf77 | 2004-05-17 20:50:24 +0000 | [diff] [blame] | 511 | |
| 512 | $n++; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 513 | } |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 514 | if($#argument_types == 0 && $argument_types[0] =~ /^void$/i) { |
| 515 | $#argument_types = -1; |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 516 | $#argument_names = -1; |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 517 | } |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 518 | |
| 519 | if($options->debug) { |
| 520 | print "$file: $return_type $calling_convention $name(" . join(",", @arguments) . ")\n"; |
| 521 | } |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 522 | |
| 523 | &$function_begin($documentation_line, $documentation, |
| 524 | $function_line, $linkage, $return_type, $calling_convention, $name, |
| 525 | \@argument_types,\@argument_names,\@argument_documentations); |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 526 | if($level == 0) { |
Patrik Stridvall | 4b33b13 | 2001-08-09 21:35:38 +0000 | [diff] [blame] | 527 | &$function_end(undef, undef); |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 528 | } |
Patrik Stridvall | 4b33b13 | 2001-08-09 21:35:38 +0000 | [diff] [blame] | 529 | $statements_line = $.; |
Patrik Stridvall | cec294e | 2001-07-30 18:49:10 +0000 | [diff] [blame] | 530 | $statements = ""; |
Patrik Stridvall | 7d0f2ba | 2001-02-12 03:44:41 +0000 | [diff] [blame] | 531 | } elsif(/__ASM_GLOBAL_FUNC\(\s*(.*?)\s*,/s) { |
Patrik Stridvall | 1c61b3b | 2001-07-23 23:20:56 +0000 | [diff] [blame] | 532 | my @lines = split(/\n/, $&); |
| 533 | my $function_line = $. - scalar(@lines) + 1; |
| 534 | |
Patrik Stridvall | 7d0f2ba | 2001-02-12 03:44:41 +0000 | [diff] [blame] | 535 | $_ = $'; $again = 1; |
Patrik Stridvall | 1c61b3b | 2001-07-23 23:20:56 +0000 | [diff] [blame] | 536 | |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 537 | &$function_begin($documentation_line, $documentation, |
Patrik Stridvall | 1c61b3b | 2001-07-23 23:20:56 +0000 | [diff] [blame] | 538 | $function_line, "", "void", "__asm", $1); |
Patrik Stridvall | 4b33b13 | 2001-08-09 21:35:38 +0000 | [diff] [blame] | 539 | &$function_end($., ""); |
Patrik Stridvall | 9c39156 | 2004-02-20 19:57:42 +0000 | [diff] [blame] | 540 | } elsif(/DEFINE_THISCALL_WRAPPER\((\S*)\)/s) { |
| 541 | my @lines = split(/\n/, $&); |
| 542 | my $function_line = $. - scalar(@lines) + 1; |
| 543 | |
| 544 | $_ = $'; $again = 1; |
| 545 | |
| 546 | &$function_begin($documentation_line, $documentation, |
| 547 | $function_line, "", "void", "", "__thiscall_" . $1, \()); |
| 548 | &$function_end($function_line, ""); |
Patrik Stridvall | af1601b | 1999-12-11 23:01:45 +0000 | [diff] [blame] | 549 | } elsif(/DEFINE_REGS_ENTRYPOINT_\d+\(\s*(\S*)\s*,\s*([^\s,\)]*).*?\)/s) { |
| 550 | $_ = $'; $again = 1; |
| 551 | $regs_entrypoints{$2} = $1; |
Patrik Stridvall | 41f99ba | 2001-06-11 20:13:21 +0000 | [diff] [blame] | 552 | } elsif(/DEFAULT_DEBUG_CHANNEL\s*\((\S+)\)/s) { |
| 553 | $_ = $'; $again = 1; |
| 554 | unshift @$debug_channels, $1; |
| 555 | } elsif(/(DEFAULT|DECLARE)_DEBUG_CHANNEL\s*\((\S+)\)/s) { |
| 556 | $_ = $'; $again = 1; |
| 557 | push @$debug_channels, $1; |
Vincent Béron | 2f8f459 | 2005-12-02 11:27:13 +0100 | [diff] [blame] | 558 | } elsif(/typedef\s+(enum|interface|struct|union)(?:\s+(\w+))?\s*\{/s) { |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 559 | $_ = $'; $again = 1; |
| 560 | $level++; |
| 561 | my $type = $1; |
| 562 | if(defined($2)) { |
| 563 | $type .= " $2"; |
| 564 | } |
| 565 | &$type_begin($type); |
| 566 | } elsif(/typedef\s+ |
Vincent Béron | 2f8f459 | 2005-12-02 11:27:13 +0100 | [diff] [blame] | 567 | ((?:const\s+|CONST\s+|enum\s+|interface\s+|long\s+|signed\s+|short\s+|struct\s+|union\s+|unsigned\s+|volatile\s+)*?) |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 568 | (\w+) |
Francois Gouget | 09108ed | 2005-09-06 09:23:46 +0000 | [diff] [blame] | 569 | (?:\s+const|\s+volatile)? |
Vincent Béron | 7257b70 | 2005-08-08 11:06:24 +0000 | [diff] [blame] | 570 | ((?:\s*(?:(?:FAR|__RPC_FAR|TW_HUGE)?\s*)?\*+\s*|\s+)(?:volatile\s+|DECLSPEC_ALIGN\(\d+\)\s+)?\w+\s*(?:\[[^\]]*\])* |
Vincent Béron | 0615309 | 2005-07-24 17:09:37 +0000 | [diff] [blame] | 571 | (?:\s*,\s*(?:\s*(?:(?:FAR|__RPC_FAR|TW_HUGE)?\s*)?\*+\s*|\s+)\w+\s*(?:\[[^\]]*\])?)*) |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 572 | \s*;/sx) |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 573 | { |
| 574 | $_ = $'; $again = 1; |
| 575 | |
| 576 | my $type = "$1 $2"; |
| 577 | |
| 578 | my @names; |
| 579 | my @parts = split(/\s*,\s*/, $2); |
| 580 | foreach my $part (@parts) { |
Vincent Béron | 0615309 | 2005-07-24 17:09:37 +0000 | [diff] [blame] | 581 | if($part =~ /(?:\s*((?:(?:FAR|__RPC_FAR|TW_HUGE)?\s*)?\*+)\s*|\s+)(\w+)\s*(\[[^\]]*\])?/) { |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 582 | my $name = $2; |
| 583 | if(defined($1)) { |
| 584 | $name = "$1$2"; |
| 585 | } |
| 586 | if(defined($3)) { |
| 587 | $name .= $3; |
| 588 | } |
| 589 | push @names, $name; |
| 590 | } |
| 591 | } |
| 592 | &$type_begin($type); |
| 593 | &$type_end([@names]); |
| 594 | } elsif(/typedef\s+ |
Vincent Béron | 2f8f459 | 2005-12-02 11:27:13 +0100 | [diff] [blame] | 595 | (?:(?:const\s+|enum\s+|interface\s+|long\s+|signed\s+|short\s+|struct\s+|union\s+|unsigned\s+|volatile\s+)*?) |
Vincent Béron | 7257b70 | 2005-08-08 11:06:24 +0000 | [diff] [blame] | 596 | (\w+(?:\s*\*+\s*)?)\s* |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 597 | (?:(\w+)\s*)? |
Vincent Béron | 7257b70 | 2005-08-08 11:06:24 +0000 | [diff] [blame] | 598 | \((?:(\w+)\s*)?\s*(?:\*\s*(\w+)|_ATL_CATMAPFUNC)\s*\)\s* |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 599 | (?:\(([^\)]*)\)|\[([^\]]*)\])\s*;/sx) |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 600 | { |
Alexandre Julliard | 7cae558 | 2002-06-01 02:55:48 +0000 | [diff] [blame] | 601 | $_ = $'; $again = 1; |
Patrik Stridvall | 67f0a70 | 2001-07-26 21:42:12 +0000 | [diff] [blame] | 602 | my $type; |
| 603 | if(defined($2) || defined($3)) { |
| 604 | my $cc = $2 || $3; |
| 605 | if(defined($5)) { |
| 606 | $type = "$1 ($cc *)($5)"; |
| 607 | } else { |
| 608 | $type = "$1 ($cc *)[$6]"; |
| 609 | } |
| 610 | } else { |
| 611 | if(defined($5)) { |
| 612 | $type = "$1 (*)($5)"; |
| 613 | } else { |
| 614 | $type = "$1 (*)[$6]"; |
| 615 | } |
| 616 | } |
| 617 | my $name = $4; |
| 618 | &$type_begin($type); |
| 619 | &$type_end([$name]); |
| 620 | } elsif(/typedef[^\{;]*;/s) { |
| 621 | $_ = $'; $again = 1; |
| 622 | $output->write("$file: $.: can't parse: '$&'\n"); |
| 623 | } elsif(/typedef[^\{]*\{[^\}]*\}[^;];/s) { |
| 624 | $_ = $'; $again = 1; |
| 625 | $output->write("$file: $.: can't parse: '$&'\n"); |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 626 | } elsif(/\'[^\']*\'/s) { |
| 627 | $_ = $'; $again = 1; |
Francois Gouget | bd3b696 | 2004-10-21 19:56:04 +0000 | [diff] [blame] | 628 | } elsif(/\"(?:[^\\\"]*|\\.)*\"/s) { |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 629 | $_ = $'; $again = 1; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 630 | } elsif(/;/s) { |
| 631 | $_ = $'; $again = 1; |
Patrik Stridvall | 6a4e8a5 | 2000-04-06 20:11:04 +0000 | [diff] [blame] | 632 | } elsif(/extern\s+"C"\s+{/s) { |
| 633 | $_ = $'; $again = 1; |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 634 | } elsif(/\{/s) { |
| 635 | $_ = $'; $again = 1; |
| 636 | print "+1: $_\n" if $options->debug >= 2; |
| 637 | $level++; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 638 | } else { |
| 639 | $lookahead = 1; |
| 640 | } |
| 641 | } |
| 642 | close(IN); |
| 643 | print STDERR "done\n" if $options->verbose; |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 644 | $output->write("$file: not at toplevel at end of file\n") unless $level == 0; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 645 | } |
| 646 | |
| 647 | 1; |