blob: e10ba0f617cbb6c9bbd137f37004f7e0cd231f6c [file] [log] [blame]
Patrik Stridvall6a012e22001-06-13 19:38:29 +00001#!/usr/bin/perl -w
2
3# Copyright 2001 Patrik Stridvall
4
5use strict;
6
7BEGIN {
8 $0 =~ m%^(.*?/?tools)/winapi/winapi_fixup$%;
9 require "$1/winapi/setup.pm";
10}
11
12use config qw(
Patrik Stridvall35a723b2001-06-20 22:53:21 +000013 &file_type &files_filter
14 &file_skip &files_skip
15 &file_normalize
Patrik Stridvall163652b2001-06-19 03:34:39 +000016 &get_spec_files
Patrik Stridvall6a012e22001-06-13 19:38:29 +000017 $current_dir $wine_dir $winapi_dir $winapi_check_dir
18);
19use output;
20use options;
21use modules;
22use util;
23use winapi;
24use winapi_parser;
25
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +000026my $output = 'output'->new;
Patrik Stridvall6a012e22001-06-13 19:38:29 +000027
28my %options_long = (
29 "debug" => { default => 0, description => "debug mode" },
30 "help" => { default => 0, description => "help mode" },
31 "verbose" => { default => 0, description => "verbose mode" },
32
33 "progress" => { default => 1, description => "show progress" },
34
35 "win16" => { default => 1, description => "Win16 fixup" },
36 "win32" => { default => 1, description => "Win32 fixup" },
37
38 "local" => { default => 1, description => "local fixup" },
Patrik Stridvall35a723b2001-06-20 22:53:21 +000039 "documentation" => { default => 1, parent => "local", description => "documentation fixup" },
Patrik Stridvall47a99e12001-07-08 20:33:20 +000040 "documentation-missing" => { default => 1, parent => "documentation", description => "documentation missing fixup" },
Patrik Stridvallf20beca2001-06-28 18:01:39 +000041 "documentation-name" => { default => 1, parent => "documentation", description => "documentation name fixup" },
Patrik Stridvall47a99e12001-07-08 20:33:20 +000042 "documentation-ordinal" => { default => 1, parent => "documentation", description => "documentation ordinal fixup" },
43 "documentation-wrong" => { default => 1, parent => "documentation", description => "documentation wrong fixup" },
Patrik Stridvall163652b2001-06-19 03:34:39 +000044 "stub" => { default => 0, parent => "local", description => "stub fixup" },
Patrik Stridvall35a723b2001-06-20 22:53:21 +000045
Patrik Stridvall6a012e22001-06-13 19:38:29 +000046 "global" => { default => 1, description => "global fixup" },
47
Patrik Stridvall35a723b2001-06-20 22:53:21 +000048 "modify" => { default => 0, description => "actually perform the fixups" },
Patrik Stridvall6a012e22001-06-13 19:38:29 +000049);
50
51my %options_short = (
52 "d" => "debug",
53 "?" => "help",
54 "v" => "verbose"
55);
56
57my $options_usage = "usage: winapi_fixup [--help] [<files>]\n";
58
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +000059my $options = 'options'->new(\%options_long, \%options_short, $options_usage);
Patrik Stridvall6a012e22001-06-13 19:38:29 +000060
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +000061my $modules = 'modules'->new($options, $output, $wine_dir, $current_dir, \&file_type, "$winapi_check_dir/modules.dat");
Patrik Stridvall6a012e22001-06-13 19:38:29 +000062
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +000063my $win16api = 'winapi'->new($options, $output, "win16", "$winapi_check_dir/win16");
64my $win32api = 'winapi'->new($options, $output, "win32", "$winapi_check_dir/win32");
Patrik Stridvall6a012e22001-06-13 19:38:29 +000065my @winapis = ($win16api, $win32api);
66
67if($wine_dir eq ".") {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +000068 'winapi'->read_all_spec_files($modules, $wine_dir, $current_dir, \&file_type, $win16api, $win32api);
Patrik Stridvall6a012e22001-06-13 19:38:29 +000069} else {
70 my @spec_files = $modules->allowed_spec_files($wine_dir, $current_dir);
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +000071 'winapi'->read_spec_files($modules, $wine_dir, $current_dir, \@spec_files, $win16api, $win32api);
Patrik Stridvall6a012e22001-06-13 19:38:29 +000072}
73
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +000074my @c_files = $options->c_files;
Patrik Stridvall35a723b2001-06-20 22:53:21 +000075@c_files = files_skip(@c_files);
76@c_files = files_filter("winelib", @c_files);
Patrik Stridvall6a012e22001-06-13 19:38:29 +000077
78my $progress_output;
79my $progress_current = 0;
80my $progress_max = scalar(@c_files);
81
82foreach my $file (@c_files) {
Patrik Stridvall163652b2001-06-19 03:34:39 +000083 my %insert_line;
Patrik Stridvall47a99e12001-07-08 20:33:20 +000084 my %substitute_line;
85 my %delete_line;
Patrik Stridvall163652b2001-06-19 03:34:39 +000086
87 my %spec_file;
88
Patrik Stridvall6a012e22001-06-13 19:38:29 +000089 $progress_current++;
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +000090 if($options->progress) {
91 $output->progress("$file: file $progress_current of $progress_max");
Patrik Stridvall6a012e22001-06-13 19:38:29 +000092 }
Patrik Stridvall35a723b2001-06-20 22:53:21 +000093
Patrik Stridvall6a012e22001-06-13 19:38:29 +000094 my $found_function = sub {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +000095 my $function = shift;
96
97 my $documentation_line = $function->documentation_line;
98 my $documentation = $function->documentation;
99 my $function_line = $function->function_line;
100 my $linkage = $function->linkage;
101 my $return_type = $function->return_type;
102 my $calling_convention = $function->calling_convention;
103 my $internal_name = $function->internal_name;
104 my @argument_types = @{$function->argument_types};
105 my @argument_names = @{$function->argument_names};
106 my @argument_documentations = @{$function->argument_documentations};
107 my $statements = $function->statements;
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000108
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000109 if($linkage eq "static" || $linkage eq "extern" || !defined($statements)) {
110 return;
111 }
112
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000113 my @external_names = $function->external_names;
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000114 if($#external_names < 0) {
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000115 return;
116 }
117
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000118 $output->prefix("$file: " . $function->prefix);
Patrik Stridvall163652b2001-06-19 03:34:39 +0000119
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000120 my @module_ordinal_entries = $function->get_all_module_ordinal;
Patrik Stridvall163652b2001-06-19 03:34:39 +0000121
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000122 my $spec_modified = 0;
Patrik Stridvallf20beca2001-06-28 18:01:39 +0000123
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000124 if($options->stub && $documentation) {
125 my $calling_convention16 = $function->calling_convention16;
126 my $calling_convention32 = $function->calling_convention32;
127
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000128 foreach my $winapi (@winapis) {
129 my @entries = ();
130 if($winapi->function_stub($internal_name)) {
131 my $module = $winapi->function_internal_module($internal_name);
132 my $ordinal = $winapi->function_internal_ordinal($internal_name);
133
134 my $external_name = $internal_name;
135 if($winapi->name eq "win16") {
136 $external_name =~ s/(?:_)?16([AW]?)$//;
137 if(defined($1)) {
138 $external_name .= $1;
139 }
140 }
141 push @entries, [$external_name, $module, $ordinal];
142 }
143
144 foreach (split(/\n/, $documentation)) {
145 if(/^\s*\*\s*(\S+)\s*[\(\[]\s*(\w+)\s*\.\s*([^\s\)\]]*)\s*[\)\]].*?$/) {
146 my $external_name = $1;
147 my $module = lc($2);
148 my $ordinal = $3;
149
150 if($external_name ne "@" &&
151 $winapi->is_module($module) &&
152 $winapi->function_stub($external_name) &&
153 $internal_name !~ /^\U$module\E_\Q$external_name\E$/)
154 {
155 push @entries, [$external_name, $module, $ordinal];
156 }
157 }
158 }
159
160 foreach my $entry (@entries) {
161 (my $external_name, my $module, my $ordinal) = @$entry;
162
163 my $abort = 0;
164 my $n;
165 my @argument_kinds = map {
166 my $type = $_;
167 my $kind;
168 if($type ne "..." && !defined($kind = $winapi->translate_argument($type))) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000169 $output->write("no translation defined: " . $type . "\n");
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000170 }
171
172 # FIXME: Kludge
173 if(defined($kind) && $kind eq "longlong") {
174 $n += 2;
175 ("long", "long");
176 } elsif(defined($kind)) {
177 $n++;
178 $kind;
179 } elsif($type eq "...") {
180 if($winapi->name eq "win16") {
181 $calling_convention16 = "pascal"; # FIXME: Is this correct?
182 } else {
183 $calling_convention32 = "varargs";
184 }
185 ();
186 } else {
187 $abort = 1;
188 $n++;
189 "undef";
190 }
191 } @argument_types;
192
193 my $substitute = {};
194 $substitute->{search} = "^\\s*$ordinal\\s+stub\\s+$external_name\\s*(?:#.*?)?\$";
195
196 if($winapi->name eq "win16") {
197 $substitute->{replace} = "$ordinal $calling_convention16 $external_name(@argument_kinds) $internal_name";
198 } else {
199 $substitute->{replace} = "$ordinal $calling_convention32 $external_name(@argument_kinds) $internal_name";
200 }
201
202 if(!defined($spec_file{$module})) {
203 $spec_file{$module} = [];
204 }
205
206 if(!$abort) {
207 $spec_modified = 1;
208 push @{$spec_file{$module}}, $substitute;
209 }
210 }
211 }
212 }
213
214 my %found_external_names;
215 foreach my $external_name (@external_names) {
216 $found_external_names{$external_name} = {};
217 }
218
219 my $documentation_modified = 0;
220
221 if(!$spec_modified &&
222 ($documentation && !$documentation_modified) &&
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000223 ($options->documentation_name || $options->documentation_ordinal ||
224 $options->documentation_missing))
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000225 {
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000226 local $_;
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000227
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000228 my $line3;
229 my $search;
230 my $replace;
231
232 my $count = 0;
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000233 my $line2 = $documentation_line - 1;
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000234 foreach (split(/\n/, $documentation)) {
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000235 $line2++;
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000236 if(/^(\s*\*\s*(\S+)\s*)((?:\s*[\(\[]\s*\w+(?:\s*\.\s*[^\s\)\]]*\s*)?[\)\]])+)(.*?)$/) {
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000237 my $part1 = $1;
238 my $external_name = $2;
239 my $part3 = $3;
240 my $part4 = $4;
241
242 $part4 =~ s/\s*$//;
243
244 my @entries = ();
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000245 while($part3 =~ s/^\s*([\(\[]\s*(\w+)(?:\s*\.\s*([^\s\)\]]*)\s*)?[\)\]])//) {
246 push @entries, [$1, $2, $3];
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000247 }
248
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000249 my $found = 0;
250 foreach my $external_name2 (@external_names) {
251 if($external_name eq $external_name2) {
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000252 foreach my $entry (@entries) {
253 (undef, my $module, undef) = @$entry;
254 $found_external_names{$external_name2}{$module} = 1;
255 }
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000256 $found = 1;
Patrik Stridvallf20beca2001-06-28 18:01:39 +0000257 last;
258 }
259 }
260
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000261 my $replaced = 0;
262 my $replace2 = "";
263 foreach my $entry (@entries) {
264 my $part12 = $part1;
265 (my $part32, my $module, my $ordinal) = @$entry;
Patrik Stridvallf20beca2001-06-28 18:01:39 +0000266
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000267 foreach my $entry2 (@module_ordinal_entries) {
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000268 (my $external_name2, my $module2, my $ordinal2) = @$entry2;
Patrik Stridvallf20beca2001-06-28 18:01:39 +0000269
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000270 if($options->documentation_name && lc($module) eq $module2 &&
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000271 $external_name ne $external_name2)
272 {
273 if(!$found && $part12 =~ s/\b\Q$external_name\E\b/$external_name2/) {
274 $external_name = $external_name2;
275 $replaced++;
Patrik Stridvallf20beca2001-06-28 18:01:39 +0000276 }
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000277 }
Patrik Stridvallf20beca2001-06-28 18:01:39 +0000278
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000279 if($options->documentation_ordinal &&
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000280 $external_name eq $external_name2 &&
281 lc($module) eq $module2 &&
282 ($#entries > 0 || !defined($ordinal) || ($ordinal ne $ordinal2)))
283 {
284 if(defined($ordinal)) {
285 if($part32 =~ s/\Q$module\E\s*.\s*\Q$ordinal\E/\U$module2\E.$ordinal2/ || $#entries > 0) {
286 $replaced++;
287 }
288 } else {
289 if($part32 =~ s/\Q$module\E/\U$module2\E.$ordinal2/ || $#entries > 0) {
290 $replaced++;
291 }
Patrik Stridvallf20beca2001-06-28 18:01:39 +0000292 }
293 }
294
295 }
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000296 if($replace2) { $replace2 .= "\n"; }
297 $replace2 .= "$part12$part32$part4";
Patrik Stridvallf20beca2001-06-28 18:01:39 +0000298 }
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000299
300 if($replaced > 0) {
301 $line3 = $line2;
302 $search = "^\Q$_\E\$";
303 $replace = $replace2;
304 }
305 $count++;
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000306 } elsif(/^(\s*\*\s*)([^\s\(]+)(?:\(\))?\s*$/) {
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000307 my $part1 = $1;
308 my $external_name = $2;
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000309
310 if($internal_name =~ /^(?:\S+_)?\Q$external_name\E(?:16)?$/) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000311 foreach my $entry (@module_ordinal_entries) {
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000312 (my $external_name2, my $module, my $ordinal) = @$entry;
313
314 $line3 = $line2;
315 $search = "^\Q$_\E\$";
316 $replace = "$part1$external_name2 (\U$module\E.$ordinal)";
317 }
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000318 $count++;
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000319 }
Patrik Stridvallf20beca2001-06-28 18:01:39 +0000320 }
321 }
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000322
323 if(defined($line3) && defined($search) && defined($replace)) {
324 if($count > 1 || $#external_names >= 1) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000325 $output->write("multiple entries (fixup not supported)\n");
326 # $output->write("s/$search/$replace/\n");
327 # $output->write("@external_names\n");
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000328 } else {
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000329 $documentation_modified = 1;
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000330 $substitute_line{$line3}{search} = $search;
331 $substitute_line{$line3}{replace} = $replace;
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000332
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000333 }
334 }
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000335 }
336
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000337 if(!$spec_modified && !$documentation_modified &&
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000338 $options->documentation_missing && $documentation)
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000339 {
340 my $part1;
341 my $part2;
342 my $part3;
343 my $part4;
344 my $line3 = 0;
345
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000346 my $line2 = $documentation_line - 1;
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000347 foreach (split(/\n/, $documentation)) {
348 $line2++;
349 if(/^(\s*\*\s*)(\S+\s*)([\(\[])\s*\w+\s*\.\s*[^\s\)\]]*\s*([\)\]]).*?$/) {
350 $part1 = $1;
351 $part2 = $2;
352 $part3 = $3;
353 $part4 = $4;
354
355 $part2 =~ s/\S/ /g;
356
357 $line3 = $line2 + 1;
358 }
359 }
360
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000361 foreach my $entry2 (@module_ordinal_entries) {
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000362 (my $external_name2, my $module2, my $ordinal2) = @$entry2;
363
364 my $found = 0;
365 foreach my $external_name (keys(%found_external_names)) {
366 foreach my $module3 (keys(%{$found_external_names{$external_name}})) {
367 if($external_name eq $external_name2 && uc($module2) eq $module3) {
368 $found = 1;
369 }
370 }
371 }
372 # FIXME: Not 100% correct
373 if(!$found &&
374 !$win16api->function_stub($internal_name) &&
375 !$win32api->function_stub($internal_name))
376 {
377 if($line3 > 0) {
378 $part2 = $external_name2 . " " x (length($part2) - length($external_name2));
379 $insert_line{$line3} = "$part1$part2$part3\U$module2\E.$ordinal2$part4\n";
380 } else {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000381 $output->write("$external_name2 (\U$module2\E.$ordinal2) missing (fixup not supported)\n");
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000382 }
383 }
384 }
385 }
386
387 if(!$documentation_modified &&
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000388 $options->documentation_wrong)
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000389 {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000390 my $line2 = $documentation_line - 1;
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000391 foreach (split(/\n/, $documentation)) {
392 $line2++;
393 if(/^\s*\*\s*(\S+)\s*[\(\[]\s*(\w+)\s*\.\s*([^\s\)\]]*)\s*[\)\]].*?$/) {
394 my $external_name = $1;
395 my $module = $2;
396 my $ordinal = $3;
397
398 my $found = 0;
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000399 foreach my $entry2 (@module_ordinal_entries) {
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000400 (my $external_name2, my $module2, my $ordinal2) = @$entry2;
401
402 if($external_name eq $external_name2 &&
403 lc($module) eq $module2 &&
404 $ordinal eq $ordinal2)
405 {
406 $found = 1;
407 }
408 }
409 if(!$found) {
410 if(1) {
411 $delete_line{$line2} = "^\Q$_\E\$";
412 } else {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000413 $output->write("$external_name (\U$module\E.$ordinal) wrong (fixup not supported)\n");
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000414 };
415 }
416 }
417 }
418 }
419
420 if(0) # !$spec_modified && !$documentation
421 {
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000422 # FIXME: Not correct
423
Patrik Stridvall163652b2001-06-19 03:34:39 +0000424 my $external_name;
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000425 my $module;
426 my $ordinal;
427 foreach my $winapi (@winapis) {
Patrik Stridvall163652b2001-06-19 03:34:39 +0000428 $external_name = ($winapi->function_external_name($internal_name) || $external_name);
429 $module = ($winapi->function_internal_module($internal_name) || $module);
430 $ordinal = ($winapi->function_internal_ordinal($internal_name) || $ordinal);
431 if(defined($external_name) || defined($module) || defined($ordinal)) { last; }
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000432 }
433
Patrik Stridvall163652b2001-06-19 03:34:39 +0000434 if(defined($external_name) && defined($module) && defined($ordinal)) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000435 $insert_line{$function_line} =
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000436 "/" . "*" x 71 . "\n" .
Patrik Stridvall163652b2001-06-19 03:34:39 +0000437 " *\t\t$external_name (\U$module\E.$ordinal)\n" .
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000438 " */\n";
439 }
440 }
Patrik Stridvall163652b2001-06-19 03:34:39 +0000441
Patrik Stridvall163652b2001-06-19 03:34:39 +0000442 $output->prefix("");
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000443 };
444
445 my $found_preprocessor = sub {
446 my $directive = shift;
447 my $argument = shift;
448 };
449
450 winapi_parser::parse_c_file $options, $output, $file, $found_function, $found_preprocessor;
451
452 my $editor = sub {
453 local *IN = shift;
454 local *OUT = shift;
455
456 my $modified = 0;
457 while(<IN>) {
458 chomp;
459
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000460 my $line;
461
462 $line = $insert_line{$.};
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000463 if(defined($line)) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000464 if($options->modify) {
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000465 $_ = "$line$_";
466 $modified = 1;
467 } else {
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000468 my $line2 = $line; chomp($line2);
469 my @line2 = split(/\n/, $line2);
470 if($#line2 > 0) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000471 $output->write("$file: $.: insert: \\\n");
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000472 foreach my $line2 (@line2) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000473 $output->write("'$line2'\n");
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000474 }
475 } else {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000476 $output->write("$file: $.: insert: '$line2'\n");
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000477 }
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000478 }
479 }
480
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000481 my $search = $substitute_line{$.}{search};
482 my $replace = $substitute_line{$.}{replace};
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000483
484 if(defined($search) && defined($replace)) {
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000485 my $modified2 = 0;
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000486 if(s/$search/$replace/) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000487 if($options->modify) {
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000488 $modified = 1;
489 }
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000490 $modified2 = 1;
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000491 }
492
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000493 if(!$options->modify || !$modified2) {
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000494 my $search2;
495 my $replace2;
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000496 if(!$modified2) {
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000497 $search2 = "unmatched search";
498 $replace2 = "unmatched replace";
499 } else {
500 $search2 = "search";
501 $replace2 = "replace";
502 }
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000503 $output->write("$file: $.: $search2 : '$search'\n");
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000504
505 my @replace2 = split(/\n/, $replace);
506 if($#replace2 > 0) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000507 $output->write("$file: $.: $replace2: \\\n");
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000508 foreach my $replace2 (@replace2) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000509 $output->write("'$replace2'\n");
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000510 }
511 } else {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000512 $output->write("$file: $.: $replace2: '$replace'\n");
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000513 }
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000514 }
515 }
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000516
517 $line = $delete_line{$.};
518 if(defined($line)) {
519 if(/$line/) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000520 if($options->modify) {
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000521 $modified = 1;
522 next;
523 } else {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000524 $output->write("$file: $.: delete: '$line'\n");
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000525 }
526 } else {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000527 $output->write("$file: $.: unmatched delete: '$line'\n");
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000528 }
529 }
530
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000531 print OUT "$_\n";
532 }
533
534 return $modified;
535 };
536
Patrik Stridvall47a99e12001-07-08 20:33:20 +0000537 my $n = 0;
538 while(defined(each %insert_line)) { $n++; }
539 while(defined(each %substitute_line)) { $n++; }
540 while(defined(each %delete_line)) { $n++; }
Patrik Stridvall163652b2001-06-19 03:34:39 +0000541 if($n > 0) {
542 edit_file($file, $editor);
543 }
544
545 foreach my $module (sort(keys(%spec_file))) {
546 my $file;
547 foreach my $winapi (@winapis) {
548 $file = ($winapi->module_file($module) || $file);
549 }
550
551 if(defined($file)) {
552 $file = file_normalize($file);
553 }
554
555 my @substitutes = @{$spec_file{$module}};
556
557 my $editor = sub {
558 local *IN = shift;
559 local *OUT = shift;
560
561 my $modified = 0;
562 while(<IN>) {
563 chomp;
564
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000565 my @substitutes2 = ();
Patrik Stridvall163652b2001-06-19 03:34:39 +0000566 foreach my $substitute (@substitutes) {
567 my $search = $substitute->{search};
568 my $replace = $substitute->{replace};
569
570 if(s/$search/$replace/) {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000571 if($options->modify) {
Patrik Stridvall163652b2001-06-19 03:34:39 +0000572 $modified = 1;
Patrik Stridvall0e397fe2001-07-02 01:21:48 +0000573 } else {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000574 $output->write("$file: search : '$search'\n");
575 $output->write("$file: replace: '$replace'\n");
Patrik Stridvall163652b2001-06-19 03:34:39 +0000576 }
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000577 next;
578 } else {
579 push @substitutes2, $substitute;
Patrik Stridvall163652b2001-06-19 03:34:39 +0000580 }
581 }
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000582 @substitutes = @substitutes2;
Patrik Stridvall163652b2001-06-19 03:34:39 +0000583
584 print OUT "$_\n";
585 }
586
587 return $modified;
588 };
589
590 if(defined($file)) {
591 edit_file($file, $editor);
592 } else {
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000593 $output->write("$module: doesn't have any spec file\n");
Patrik Stridvall163652b2001-06-19 03:34:39 +0000594 }
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000595
596 if($#substitutes >= 0) {
597 foreach my $substitute (@substitutes) {
598 my $search = $substitute->{search};
599 my $replace = $substitute->{replace};
600
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000601 $output->write("$file: unmatched search : '$search'\n");
602 $output->write("$file: unmatched replace: '$replace'\n");
Patrik Stridvall35a723b2001-06-20 22:53:21 +0000603 }
604 }
605
Patrik Stridvall163652b2001-06-19 03:34:39 +0000606 }
Patrik Stridvall6a012e22001-06-13 19:38:29 +0000607}
608
Patrik Stridvallc3e8ac32001-07-11 17:27:45 +0000609$output->hide_progress;
Patrik Stridvall163652b2001-06-19 03:34:39 +0000610
611