Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 1 | package winapi_parser; |
| 2 | |
| 3 | use strict; |
| 4 | |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 5 | use winapi_function; |
| 6 | |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 7 | sub parse_c_file { |
| 8 | my $options = shift; |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 9 | my $output = shift; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 10 | my $file = shift; |
| 11 | my $function_found_callback = shift; |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 12 | my $preprocessor_found_callback = shift; |
| 13 | |
Patrik Stridvall | 41f99ba | 2001-06-11 20:13:21 +0000 | [diff] [blame] | 14 | # global |
| 15 | my $debug_channels = []; |
| 16 | |
| 17 | # local |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 18 | my $documentation_line; |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 19 | my $documentation; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 20 | my $function_line; |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 21 | my $linkage; |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 22 | my $return_type; |
| 23 | my $calling_convention; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 24 | my $internal_name = ""; |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 25 | my $argument_types; |
| 26 | my $argument_names; |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 27 | my $argument_documentations; |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 28 | my $statements; |
| 29 | |
| 30 | my $function_begin = sub { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 31 | $documentation_line = shift; |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 32 | $documentation = shift; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 33 | $function_line = shift; |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 34 | $linkage = shift; |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 35 | $return_type= shift; |
| 36 | $calling_convention = shift; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 37 | $internal_name = shift; |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 38 | $argument_types = shift; |
| 39 | $argument_names = shift; |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 40 | $argument_documentations = shift; |
| 41 | |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 42 | if($#$argument_names == -1) { |
| 43 | foreach my $n (0..$#$argument_types) { |
| 44 | push @$argument_names, ""; |
| 45 | } |
| 46 | } |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 47 | |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 48 | if($#$argument_documentations == -1) { |
| 49 | foreach my $n (0..$#$argument_documentations) { |
| 50 | push @$argument_documentations, ""; |
| 51 | } |
| 52 | } |
| 53 | |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 54 | $statements = undef; |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 55 | }; |
| 56 | my $function_end = sub { |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 57 | my $function = 'winapi_function'->new; |
| 58 | |
Patrik Stridvall | bda5074 | 2001-07-14 00:48:41 +0000 | [diff] [blame] | 59 | if(!defined($documentation_line)) { |
| 60 | $documentation_line = 0; |
| 61 | } |
| 62 | |
Patrik Stridvall | b59a9c7 | 2001-07-12 22:22:05 +0000 | [diff] [blame] | 63 | $function->file($file); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 64 | $function->debug_channels([@$debug_channels]); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 65 | $function->documentation_line($documentation_line); |
Patrik Stridvall | d07a646 | 2001-07-18 20:09:12 +0000 | [diff] [blame^] | 66 | $function->documentation($documentation); |
| 67 | $function->function_line($function_line); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 68 | $function->linkage($linkage); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 69 | $function->return_type($return_type); |
| 70 | $function->calling_convention($calling_convention); |
| 71 | $function->internal_name($internal_name); |
| 72 | $function->argument_types([@$argument_types]); |
| 73 | $function->argument_names([@$argument_names]); |
| 74 | $function->argument_documentations([@$argument_documentations]); |
| 75 | $function->statements($statements); |
| 76 | |
| 77 | &$function_found_callback($function); |
| 78 | $internal_name = ""; |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 79 | }; |
Patrik Stridvall | af1601b | 1999-12-11 23:01:45 +0000 | [diff] [blame] | 80 | my %regs_entrypoints; |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 81 | my @comment_lines = (); |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 82 | my @comments = (); |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 83 | my $level = 0; |
Patrik Stridvall | 6a4e8a5 | 2000-04-06 20:11:04 +0000 | [diff] [blame] | 84 | my $extern_c = 0; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 85 | my $again = 0; |
| 86 | my $lookahead = 0; |
| 87 | my $lookahead_count = 0; |
| 88 | |
| 89 | print STDERR "Processing file '$file' ... " if $options->verbose; |
| 90 | open(IN, "< $file") || die "<internal>: $file: $!\n"; |
| 91 | $/ = "\n"; |
| 92 | while($again || defined(my $line = <IN>)) { |
| 93 | if(!$again) { |
| 94 | chomp $line; |
| 95 | |
| 96 | if($lookahead) { |
| 97 | $lookahead = 0; |
| 98 | $_ .= "\n" . $line; |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 99 | $lookahead_count++; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 100 | } else { |
| 101 | $_ = $line; |
| 102 | $lookahead_count = 0; |
| 103 | } |
Patrik Stridvall | 6a4e8a5 | 2000-04-06 20:11:04 +0000 | [diff] [blame] | 104 | print " $level($lookahead_count): $line\n" if $options->debug >= 2; |
| 105 | print "*** $_\n" if $options->debug >= 3; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 106 | } else { |
| 107 | $lookahead_count = 0; |
| 108 | $again = 0; |
| 109 | } |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 110 | |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 111 | # CVS merge conflicts in file? |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 112 | if(/^(<<<<<<<|=======|>>>>>>>)/) { |
| 113 | $output->write("$file: merge conflicts in file\n"); |
| 114 | last; |
| 115 | } |
| 116 | |
Patrik Stridvall | 54e1552 | 2000-05-18 00:07:31 +0000 | [diff] [blame] | 117 | # remove C comments |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 118 | if(s/^(.*?)(\/\*.*?\*\/)(.*)$/$1 $3/s) { |
| 119 | push @comment_lines, $.; |
| 120 | push @comments, $2; |
| 121 | $again = 1; |
| 122 | next; |
| 123 | } |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 124 | if(/^(.*?)\/\*/s) { |
| 125 | $lookahead = 1; |
| 126 | next; |
| 127 | } |
| 128 | |
Patrik Stridvall | 54e1552 | 2000-05-18 00:07:31 +0000 | [diff] [blame] | 129 | # remove C++ comments |
| 130 | while(s/^(.*?)\/\/.*?$/$1\n/s) { $again = 1 } |
| 131 | if($again) { next; } |
| 132 | |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 133 | # remove empty rows |
| 134 | if(/^\s*$/) { next; } |
| 135 | |
| 136 | # remove preprocessor directives |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 137 | if(s/^\s*\#/\#/m) { |
| 138 | if(/^\\#.*?\\$/m) { |
| 139 | $lookahead = 1; |
| 140 | next; |
| 141 | } elsif(s/^\#\s*(.*?)(\s+(.*?))?\s*$//m) { |
| 142 | if(defined($3)) { |
| 143 | &$preprocessor_found_callback($1, $3); |
| 144 | } else { |
| 145 | &$preprocessor_found_callback($1, ""); |
| 146 | } |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 147 | next; |
| 148 | } |
| 149 | } |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 150 | |
Patrik Stridvall | 6a4e8a5 | 2000-04-06 20:11:04 +0000 | [diff] [blame] | 151 | # Remove extern "C" |
| 152 | if(s/^\s*extern\s+"C"\s+\{//m) { |
| 153 | $extern_c = 1; |
| 154 | $again = 1; |
| 155 | next; |
| 156 | } |
| 157 | |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 158 | my $documentation_line; |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 159 | my $documentation; |
Patrik Stridvall | 94a5077 | 2000-12-01 23:51:33 +0000 | [diff] [blame] | 160 | my @argument_documentations = (); |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 161 | { |
| 162 | my $n = $#comments; |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 163 | while($n >= 0 && ($comments[$n] !~ /^\/\*\*/ || |
Patrik Stridvall | 94a5077 | 2000-12-01 23:51:33 +0000 | [diff] [blame] | 164 | $comments[$n] =~ /^\/\*\*+\/$/)) |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 165 | { |
| 166 | $n--; |
| 167 | } |
| 168 | |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 169 | if(defined($comments[$n]) && $n >= 0) { |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 170 | my @lines = split(/\n/, $comments[$n]); |
| 171 | |
| 172 | $documentation_line = $comment_lines[$n] - scalar(@lines) + 1; |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 173 | $documentation = $comments[$n]; |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 174 | |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 175 | for(my $m=$n+1; $m <= $#comments; $m++) { |
Patrik Stridvall | 9086d42 | 2001-01-20 02:16:31 +0000 | [diff] [blame] | 176 | if($comments[$m] =~ /^\/\*\*+\/$/ || |
| 177 | $comments[$m] =~ /^\/\*\s*(?:\!)?defined/) # FIXME: Kludge |
| 178 | { |
Patrik Stridvall | 94a5077 | 2000-12-01 23:51:33 +0000 | [diff] [blame] | 179 | @argument_documentations = (); |
| 180 | next; |
| 181 | } |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 182 | push @argument_documentations, $comments[$m]; |
| 183 | } |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 184 | } else { |
| 185 | $documentation = ""; |
| 186 | } |
| 187 | } |
| 188 | |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 189 | if($level > 0) |
| 190 | { |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 191 | my $line = ""; |
| 192 | while(/^[^\{\}]/) { |
| 193 | s/^([^\{\}\'\"]*)//s; |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 194 | $line .= $1; |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 195 | if(s/^\'//) { |
| 196 | $line .= "\'"; |
| 197 | while(/^./ && !s/^\'//) { |
| 198 | s/^([^\'\\]*)//s; |
| 199 | $line .= $1; |
| 200 | if(s/^\\//) { |
| 201 | $line .= "\\"; |
| 202 | if(s/^(.)//s) { |
| 203 | $line .= $1; |
| 204 | if($1 eq "0") { |
| 205 | s/^(\d{0,3})//s; |
| 206 | $line .= $1; |
| 207 | } |
| 208 | } |
| 209 | } |
| 210 | } |
| 211 | $line .= "\'"; |
| 212 | } elsif(s/^\"//) { |
| 213 | $line .= "\""; |
| 214 | while(/^./ && !s/^\"//) { |
| 215 | s/^([^\"\\]*)//s; |
| 216 | $line .= $1; |
| 217 | if(s/^\\//) { |
| 218 | $line .= "\\"; |
| 219 | if(s/^(.)//s) { |
| 220 | $line .= $1; |
| 221 | if($1 eq "0") { |
| 222 | s/^(\d{0,3})//s; |
| 223 | $line .= $1; |
| 224 | } |
| 225 | } |
| 226 | } |
| 227 | } |
| 228 | $line .= "\""; |
| 229 | } |
| 230 | } |
| 231 | |
| 232 | if(s/^\{//) { |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 233 | $_ = $'; $again = 1; |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 234 | $line .= "{"; |
| 235 | print "+1: \{$_\n" if $options->debug >= 2; |
| 236 | $level++; |
| 237 | } elsif(s/^\}//) { |
| 238 | $_ = $'; $again = 1; |
| 239 | $line .= "}" if $level > 1; |
| 240 | print "-1: \}$_\n" if $options->debug >= 2; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 241 | $level--; |
Patrik Stridvall | 6a4e8a5 | 2000-04-06 20:11:04 +0000 | [diff] [blame] | 242 | if($level == -1 && $extern_c) { |
| 243 | $extern_c = 0; |
| 244 | $level = 0; |
| 245 | } |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 246 | } |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 247 | |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 248 | if(!defined($statements)) { |
| 249 | $statements = ""; |
| 250 | } |
| 251 | |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 252 | if($line !~ /^\s*$/) { |
| 253 | $statements .= "$line\n"; |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 254 | } |
| 255 | |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 256 | if($internal_name && $level == 0) { |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 257 | &$function_end; |
| 258 | } |
Patrik Stridvall | d07a646 | 2001-07-18 20:09:12 +0000 | [diff] [blame^] | 259 | next; |
| 260 | } elsif(/(extern\s+|static\s+)?((struct\s+|union\s+|enum\s+|signed\s+|unsigned\s+)?\w+((\s*\*)+\s*|\s+)) |
Patrik Stridvall | 360c3f2 | 2000-06-11 20:02:29 +0000 | [diff] [blame] | 261 | ((__cdecl|__stdcall|CDECL|VFWAPIV|VFWAPI|WINAPIV|WINAPI|CALLBACK)\s+)? |
| 262 | (\w+(\(\w+\))?)\s*\(([^\)]*)\)\s*(\{|\;)/sx) |
| 263 | { |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 264 | my @lines = split(/\n/, $&); |
| 265 | my $function_line = $. - scalar(@lines) + 1; |
| 266 | |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 267 | $_ = $'; $again = 1; |
Patrik Stridvall | 0e397fe | 2001-07-02 01:21:48 +0000 | [diff] [blame] | 268 | |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 269 | if($11 eq "{") { |
| 270 | $level++; |
| 271 | } |
Patrik Stridvall | 1932d40 | 2000-04-15 20:39:55 +0000 | [diff] [blame] | 272 | |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 273 | my $linkage = $1; |
| 274 | my $return_type = $2; |
| 275 | my $calling_convention = $7; |
| 276 | my $name = $8; |
| 277 | my $arguments = $10; |
| 278 | |
| 279 | if(!defined($linkage)) { |
| 280 | $linkage = ""; |
| 281 | } |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 282 | |
| 283 | if(!defined($calling_convention)) { |
| 284 | $calling_convention = ""; |
| 285 | } |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 286 | |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 287 | $linkage =~ s/\s*$//; |
| 288 | |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 289 | $return_type =~ s/\s*$//; |
| 290 | $return_type =~ s/\s*\*\s*/*/g; |
| 291 | $return_type =~ s/(\*+)/ $1/g; |
| 292 | |
Patrik Stridvall | af1601b | 1999-12-11 23:01:45 +0000 | [diff] [blame] | 293 | if($regs_entrypoints{$name}) { |
| 294 | $name = $regs_entrypoints{$name}; |
| 295 | } |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 296 | |
| 297 | $arguments =~ y/\t\n/ /; |
| 298 | $arguments =~ s/^\s*(.*?)\s*$/$1/; |
Patrik Stridvall | 20ca001 | 2001-06-19 03:34:52 +0000 | [diff] [blame] | 299 | if($arguments eq "") { $arguments = "..." } |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 300 | |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 301 | my @argument_types; |
| 302 | my @argument_names; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 303 | my @arguments = split(/,/, $arguments); |
| 304 | foreach my $n (0..$#arguments) { |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 305 | my $argument_type = ""; |
| 306 | my $argument_name = ""; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 307 | my $argument = $arguments[$n]; |
| 308 | $argument =~ s/^\s*(.*?)\s*$/$1/; |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 309 | # print " " . ($n + 1) . ": '$argument'\n"; |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 310 | $argument =~ s/^(IN OUT(?=\s)|IN(?=\s)|OUT(?=\s)|\s*)\s*//; |
Patrik Stridvall | af1601b | 1999-12-11 23:01:45 +0000 | [diff] [blame] | 311 | $argument =~ s/^(const(?=\s)|CONST(?=\s)|\s*)\s*//; |
Patrik Stridvall | 5dadbf3 | 2000-04-29 14:24:11 +0000 | [diff] [blame] | 312 | if($argument =~ /^\.\.\.$/) { |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 313 | $argument_type = "..."; |
| 314 | $argument_name = "..."; |
Patrik Stridvall | a896531 | 2000-11-30 01:31:44 +0000 | [diff] [blame] | 315 | } elsif($argument =~ /^ |
| 316 | ((?:struct\s+|union\s+|enum\s+|(?:signed\s+|unsigned\s+) |
| 317 | (?:short\s+(?=int)|long\s+(?=int))?)?\w+)\s* |
| 318 | ((?:const)?\s*(?:\*\s*?)*)\s* |
| 319 | (?:WINE_UNUSED\s+)?(\w*)\s*(?:\[\]|\s+OPTIONAL)?/x) |
| 320 | { |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 321 | $argument_type = "$1"; |
| 322 | if($2 ne "") { |
| 323 | $argument_type .= " $2"; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 324 | } |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 325 | $argument_name = $3; |
| 326 | |
| 327 | $argument_type =~ s/\s*const\s*/ /; |
| 328 | $argument_type =~ s/^\s*(.*?)\s*$/$1/; |
| 329 | |
| 330 | $argument_name =~ s/^\s*(.*?)\s*$/$1/; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 331 | } else { |
| 332 | die "$file: $.: syntax error: '$argument'\n"; |
| 333 | } |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 334 | $argument_types[$n] = $argument_type; |
| 335 | $argument_names[$n] = $argument_name; |
| 336 | # print " " . ($n + 1) . ": '" . $argument_types[$n] . "', '" . $argument_names[$n] . "'\n"; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 337 | } |
Patrik Stridvall | f93f998 | 2000-05-11 21:46:17 +0000 | [diff] [blame] | 338 | if($#argument_types == 0 && $argument_types[0] =~ /^void$/i) { |
| 339 | $#argument_types = -1; |
| 340 | $#argument_names = -1; |
| 341 | } |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 342 | |
| 343 | if($options->debug) { |
| 344 | print "$file: $return_type $calling_convention $name(" . join(",", @arguments) . ")\n"; |
| 345 | } |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 346 | |
| 347 | &$function_begin($documentation_line, $documentation, |
| 348 | $function_line, $linkage, $return_type, $calling_convention, $name, |
| 349 | \@argument_types,\@argument_names,\@argument_documentations); |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 350 | if($level == 0) { |
| 351 | &$function_end; |
| 352 | } |
Patrik Stridvall | 7d0f2ba | 2001-02-12 03:44:41 +0000 | [diff] [blame] | 353 | } elsif(/__ASM_GLOBAL_FUNC\(\s*(.*?)\s*,/s) { |
| 354 | $_ = $'; $again = 1; |
| 355 | my @arguments = (); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 356 | &$function_begin($documentation_line, $documentation, |
| 357 | $function_line, "", "void", "__asm", $1, \@arguments); |
Patrik Stridvall | 7d0f2ba | 2001-02-12 03:44:41 +0000 | [diff] [blame] | 358 | &$function_end; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 359 | } elsif(/DC_(GET_X_Y|GET_VAL_16)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) { |
| 360 | $_ = $'; $again = 1; |
| 361 | my @arguments = ("HDC16"); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 362 | &$function_begin($documentation_line, $documentation, |
| 363 | $function_line, "", $2, "WINAPI", $3, \@arguments); |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 364 | &$function_end; |
Patrik Stridvall | faf64aa | 2000-09-04 20:20:47 +0000 | [diff] [blame] | 365 | } elsif(/DC_(GET_VAL)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,.*?\)/s) { |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 366 | $_ = $'; $again = 1; |
Patrik Stridvall | faf64aa | 2000-09-04 20:20:47 +0000 | [diff] [blame] | 367 | my $return16 = $3 . "16"; |
| 368 | my $return32 = $3; |
| 369 | my $name16 = $2 . "16"; |
| 370 | my $name32 = $2; |
| 371 | my @arguments16 = ("HDC16"); |
| 372 | my @arguments32 = ("HDC"); |
| 373 | |
| 374 | if($name16 eq "COLORREF16") { $name16 = "COLORREF"; } |
| 375 | |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 376 | &$function_begin($documentation_line, $documentation, |
| 377 | $function_line, "", $name16, "WINAPI", $return16, \@arguments16); |
Patrik Stridvall | faf64aa | 2000-09-04 20:20:47 +0000 | [diff] [blame] | 378 | &$function_end; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 379 | &$function_begin($documentation_line, $documentation, |
| 380 | $function_line, "", $name32, "WINAPI", $return32, \@arguments32); |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 381 | &$function_end; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 382 | } elsif(/DC_(GET_VAL_EX)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) { |
| 383 | $_ = $'; $again = 1; |
| 384 | my @arguments16 = ("HDC16", "LP" . $5 . "16"); |
| 385 | my @arguments32 = ("HDC", "LP" . $5); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 386 | &$function_begin($documentation_line, $documentation, |
| 387 | $function_line, "", "BOOL16", "WINAPI", $2 . "16", \@arguments16); |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 388 | &$function_end; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 389 | &$function_begin($documentation_line, $documentation, |
| 390 | $function_line, "", "BOOL", "WINAPI", $2, \@arguments32); |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 391 | &$function_end; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 392 | } elsif(/DC_(SET_MODE)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) { |
| 393 | $_ = $'; $again = 1; |
| 394 | my @arguments16 = ("HDC16", "INT16"); |
| 395 | my @arguments32 = ("HDC", "INT"); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 396 | &$function_begin($documentation_line, $documentation, |
| 397 | $function_line, "", "INT16", "WINAPI", $2 . "16", \@arguments16); |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 398 | &$function_end; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 399 | &$function_begin($documentation_line, $documentation, |
| 400 | $function_line, "", "INT", "WINAPI", $2, \@arguments32); |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 401 | &$function_end; |
Patrik Stridvall | afe3b0c | 1999-09-29 10:22:00 +0000 | [diff] [blame] | 402 | } elsif(/WAVEIN_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) { |
| 403 | $_ = $'; $again = 1; |
| 404 | my @arguments16 = ("HWAVEIN16"); |
| 405 | my @arguments32 = ("HWAVEIN"); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 406 | &$function_begin($documentation_line, $documentation, |
| 407 | $function_line, "", "UINT16", "WINAPI", "waveIn" . $1 . "16", \@arguments16); |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 408 | &$function_end; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 409 | &$function_begin($documentation_line, $documentation, |
| 410 | $function_line, "", "UINT", "WINAPI", "waveIn" . $1, \@arguments32); |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 411 | &$function_end; |
Patrik Stridvall | afe3b0c | 1999-09-29 10:22:00 +0000 | [diff] [blame] | 412 | } elsif(/WAVEOUT_SHORTCUT_0\s*\(\s*(.*?)\s*,\s*(.*?)\s*\)/s) { |
| 413 | $_ = $'; $again = 1; |
| 414 | my @arguments16 = ("HWAVEOUT16"); |
| 415 | my @arguments32 = ("HWAVEOUT"); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 416 | &$function_begin($documentation_line, $documentation, |
| 417 | $function_line, "", "UINT16", "WINAPI", "waveOut" . $1 . "16", \@arguments16); |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 418 | &$function_end; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 419 | &$function_begin($documentation_line, $documentation, |
| 420 | $function_line, "", "UINT", "WINAPI", "waveOut" . $1, \@arguments32); |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 421 | &$function_end; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 422 | } elsif(/WAVEOUT_SHORTCUT_(1|2)\s*\(\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\)/s) { |
| 423 | $_ = $'; $again = 1; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 424 | if($1 eq "1") { |
| 425 | my @arguments16 = ("HWAVEOUT16", $4); |
| 426 | my @arguments32 = ("HWAVEOUT", $4); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 427 | &$function_begin($documentation_line, $documentation, |
| 428 | $function_line, "", "UINT16", "WINAPI", "waveOut" . $2 . "16", \@arguments16); |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 429 | &$function_end; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 430 | &$function_begin($documentation_line, $documentation, |
| 431 | $function_line, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32); |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 432 | &$function_end; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 433 | } elsif($1 eq 2) { |
| 434 | my @arguments16 = ("UINT16", $4); |
| 435 | my @arguments32 = ("UINT", $4); |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 436 | &$function_begin($documentation_line, $documentation, |
| 437 | $function_line, "", "UINT16", "WINAPI", "waveOut". $2 . "16", \@arguments16); |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 438 | &$function_end; |
Patrik Stridvall | c3e8ac3 | 2001-07-11 17:27:45 +0000 | [diff] [blame] | 439 | &$function_begin($documentation_line, $documentation, |
| 440 | $function_line, "", "UINT", "WINAPI", "waveOut" . $2, \@arguments32); |
Patrik Stridvall | 5b3b6d9 | 1999-10-24 21:45:39 +0000 | [diff] [blame] | 441 | &$function_end; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 442 | } |
Patrik Stridvall | af1601b | 1999-12-11 23:01:45 +0000 | [diff] [blame] | 443 | } elsif(/DEFINE_REGS_ENTRYPOINT_\d+\(\s*(\S*)\s*,\s*([^\s,\)]*).*?\)/s) { |
| 444 | $_ = $'; $again = 1; |
| 445 | $regs_entrypoints{$2} = $1; |
Patrik Stridvall | 41f99ba | 2001-06-11 20:13:21 +0000 | [diff] [blame] | 446 | } elsif(/DEFAULT_DEBUG_CHANNEL\s*\((\S+)\)/s) { |
| 447 | $_ = $'; $again = 1; |
| 448 | unshift @$debug_channels, $1; |
| 449 | } elsif(/(DEFAULT|DECLARE)_DEBUG_CHANNEL\s*\((\S+)\)/s) { |
| 450 | $_ = $'; $again = 1; |
| 451 | push @$debug_channels, $1; |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 452 | } elsif(/\'[^\']*\'/s) { |
| 453 | $_ = $'; $again = 1; |
| 454 | } elsif(/\"[^\"]*\"/s) { |
| 455 | $_ = $'; $again = 1; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 456 | } elsif(/;/s) { |
| 457 | $_ = $'; $again = 1; |
Patrik Stridvall | 6a4e8a5 | 2000-04-06 20:11:04 +0000 | [diff] [blame] | 458 | } elsif(/extern\s+"C"\s+{/s) { |
| 459 | $_ = $'; $again = 1; |
Patrik Stridvall | 4bb532e | 2000-03-24 20:39:51 +0000 | [diff] [blame] | 460 | } elsif(/\{/s) { |
| 461 | $_ = $'; $again = 1; |
| 462 | print "+1: $_\n" if $options->debug >= 2; |
| 463 | $level++; |
Patrik Stridvall | 37fd2d1 | 1999-09-23 15:14:20 +0000 | [diff] [blame] | 464 | } else { |
| 465 | $lookahead = 1; |
| 466 | } |
| 467 | } |
| 468 | close(IN); |
| 469 | print STDERR "done\n" if $options->verbose; |
Patrik Stridvall | 659fcd8 | 1999-10-31 02:08:38 +0000 | [diff] [blame] | 470 | $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] | 471 | } |
| 472 | |
| 473 | 1; |