- Continued on the new C parser.
[wine/hacks.git] / tools / winapi / winapi_fixup_editor.pm
blob49f0bde2f8d8eedcbda31f84c2331c5d0f18bb20
1 package winapi_fixup_editor;
3 use strict;
5 use options qw($options);
6 use output qw($output);
7 use winapi qw($win16api $win32api @winapis);
9 use util;
11 sub new {
12 my $proto = shift;
13 my $class = ref($proto) || $proto;
14 my $self = {};
15 bless ($self, $class);
17 my $file = \${$self->{FILE}};
19 $$file = shift;
21 return $self;
24 sub add_trigger {
25 my $self = shift;
27 my $triggers = \%{$self->{TRIGGERS}};
29 my $line = shift;
30 my $action = shift;
32 if(!defined($$triggers{$line})) {
33 $$triggers{$line} = [];
36 push @{$$triggers{$line}}, $action;
39 sub replace {
40 my $self = shift;
42 my $begin_line = shift;
43 my $begin_column = shift;
44 my $end_line = shift;
45 my $end_column = shift;
46 my $replace = shift;
48 my $file = \${$self->{FILE}};
50 my $line = $begin_line;
51 my $action = {};
53 $self->add_trigger($begin_line, {
54 type => "replace",
55 begin_line => $begin_line,
56 begin_column => $begin_column,
57 end_line => $end_line,
58 end_column => $end_column,
59 replace => $replace
60 });
63 sub flush {
64 my $self = shift;
66 my $file = \${$self->{FILE}};
67 my $triggers = \%{$self->{TRIGGERS}};
69 my $editor = sub {
70 local *IN = shift;
71 local *OUT = shift;
73 my $modified = 0;
75 my $again = 0;
76 my $lookahead = 0;
77 my $lookahead_count = 0;
78 LINE: while($again || defined(my $current = <IN>)) {
79 if(!$again) {
80 chomp $current;
82 if($lookahead) {
83 $lookahead = 0;
84 $_ .= "\n" . $current;
85 $lookahead_count++;
86 } else {
87 $_ = $current;
88 $lookahead_count = 0;
90 } else {
91 $lookahead_count = 0;
92 $again = 0;
95 my $line = $. - $lookahead_count;
96 foreach my $action (@{$$triggers{$line}}) {
97 if($. < $action->{end_line}) {
98 $lookahead = 1;
99 next LINE;
102 my $type = $action->{type};
103 my $begin_line = $action->{begin_line};
104 my $begin_column = $action->{begin_column};
105 my $end_line = $action->{end_line};
106 my $end_column = $action->{end_column};
108 if($type eq "replace") {
109 my $replace = $action->{replace};
111 my @lines = split(/\n/, $_);
112 if($#lines < 0) {
113 @lines = ($_);
116 my $begin = "";
117 my $column = 0;
118 $_ = $lines[0];
119 while($column < $begin_column - 1 && s/^.//) {
120 $begin .= $&;
121 if($& eq "\t") {
122 $column = $column + 8 - $column % 8;
123 } else {
124 $column++;
128 my $column2 = 0;
129 $_ = $lines[$#lines];
130 while($column2 < $end_column && s/^.//) {
131 if($& eq "\t") {
132 $column2 = $column2 + 8 - $column2 % 8;
133 } else {
134 $column2++;
137 my $end = $_;
139 $_ = "$begin$replace$end";
140 if($options->modify) {
141 $modified = 1;
142 } else {
143 $output->write("$$file:$begin_line.$begin_column-$end_line.$end_column: $replace\n");
148 print OUT "$_\n";
151 return $modified;
154 my $modified = 0;
155 if(1) {
156 $modified = edit_file($$file, $editor);
159 if(!$modified) {
160 $self->flush_old;
164 ########################################################################
165 # Hack for backward compabillity
168 my %insert_line;
169 my %substitute_line;
170 my %delete_line;
172 my %spec_file;
174 sub flush_old {
175 my $self = shift;
177 my $file = ${$self->{FILE}};
179 my $editor = sub {
180 local *IN = shift;
181 local *OUT = shift;
183 my $modified = 0;
184 while(<IN>) {
185 chomp;
187 my $line;
189 $line = $insert_line{$.};
190 if(defined($line)) {
191 if($options->modify) {
192 $_ = "$line$_";
193 $modified = 1;
194 } else {
195 my $line2 = $line; chomp($line2);
196 my @line2 = split(/\n/, $line2);
197 if($#line2 > 0) {
198 $output->write("$file: $.: insert: \\\n");
199 foreach my $line2 (@line2) {
200 $output->write("'$line2'\n");
202 } else {
203 $output->write("$file: $.: insert: '$line2'\n");
208 my $search = $substitute_line{$.}{search};
209 my $replace = $substitute_line{$.}{replace};
211 if(defined($search) && defined($replace)) {
212 my $modified2 = 0;
213 if(s/$search/$replace/) {
214 if($options->modify) {
215 $modified = 1;
217 $modified2 = 1;
220 if(!$options->modify || !$modified2) {
221 my $search2;
222 my $replace2;
223 if(!$modified2) {
224 $search2 = "unmatched search";
225 $replace2 = "unmatched replace";
226 } else {
227 $search2 = "search";
228 $replace2 = "replace";
230 $output->write("$file: $.: $search2 : '$search'\n");
232 my @replace2 = split(/\n/, $replace);
233 if($#replace2 > 0) {
234 $output->write("$file: $.: $replace2: \\\n");
235 foreach my $replace2 (@replace2) {
236 $output->write("'$replace2'\n");
238 } else {
239 $output->write("$file: $.: $replace2: '$replace'\n");
244 $line = $delete_line{$.};
245 if(defined($line)) {
246 if(/$line/) {
247 if($options->modify) {
248 $modified = 1;
249 next;
250 } else {
251 $output->write("$file: $.: delete: '$line'\n");
253 } else {
254 $output->write("$file: $.: unmatched delete: '$line'\n");
258 print OUT "$_\n";
261 return $modified;
264 my $n = 0;
265 while(defined(each %insert_line)) { $n++; }
266 while(defined(each %substitute_line)) { $n++; }
267 while(defined(each %delete_line)) { $n++; }
268 if($n > 0) {
269 edit_file($file, $editor);
272 foreach my $module (sort(keys(%spec_file))) {
273 my $file;
274 foreach my $winapi (@winapis) {
275 $file = ($winapi->module_file($module) || $file);
278 if(defined($file)) {
279 $file = file_normalize($file);
282 my @substitutes = @{$spec_file{$module}};
284 my $editor = sub {
285 local *IN = shift;
286 local *OUT = shift;
288 my $modified = 0;
289 while(<IN>) {
290 chomp;
292 my @substitutes2 = ();
293 foreach my $substitute (@substitutes) {
294 my $search = $substitute->{search};
295 my $replace = $substitute->{replace};
297 if(s/$search/$replace/) {
298 if($options->modify) {
299 $modified = 1;
300 } else {
301 $output->write("$file: search : '$search'\n");
302 $output->write("$file: replace: '$replace'\n");
304 next;
305 } else {
306 push @substitutes2, $substitute;
309 @substitutes = @substitutes2;
311 print OUT "$_\n";
314 return $modified;
317 if(defined($file)) {
318 edit_file($file, $editor);
319 } else {
320 $output->write("$module: doesn't have any spec file\n");
323 if($#substitutes >= 0) {
324 foreach my $substitute (@substitutes) {
325 my $search = $substitute->{search};
326 my $replace = $substitute->{replace};
328 $output->write("$file: unmatched search : '$search'\n");
329 $output->write("$file: unmatched replace: '$replace'\n");
335 %insert_line = ();
336 %substitute_line = ();
337 %delete_line = ();
339 %spec_file = ();
342 sub delete_line {
343 my $self = shift;
345 my $line = shift;
346 my $pattern = shift;
348 $delete_line{$line} = $pattern;
351 sub insert_line {
352 my $self = shift;
354 my $line = shift;
355 my $insert = shift;
357 $insert_line{$line} = $insert;
360 sub substitute_line {
361 my $self = shift;
363 my $line = shift;
364 my $search = shift;
365 my $replace = shift;
367 $substitute_line{$line}{search} = $search;
368 $substitute_line{$line}{replace} = $replace;
371 sub replace_spec_file {
372 my $self = shift;
374 my $module = shift;
375 my $search = shift;
376 my $replace = shift;
378 my $substitute = {};
379 $substitute->{search} = $search;
380 $substitute->{replace} = $replace;
382 if(!defined($spec_file{$module})) {
383 $spec_file{$module} = [];
386 push @{$spec_file{$module}}, $substitute;