# # Copyright 1999, 2000, 2001 Patrik Stridvall # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # package winapi_fixup_editor; use strict; use options qw($options); use output qw($output); use winapi qw($win16api $win32api @winapis); use util; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = {}; bless ($self, $class); my $file = \${$self->{FILE}}; $$file = shift; return $self; } sub add_trigger { my $self = shift; my $triggers = \%{$self->{TRIGGERS}}; my $line = shift; my $action = shift; if(!defined($$triggers{$line})) { $$triggers{$line} = []; } push @{$$triggers{$line}}, $action; } sub replace { my $self = shift; my $begin_line = shift; my $begin_column = shift; my $end_line = shift; my $end_column = shift; my $replace = shift; my $file = \${$self->{FILE}}; my $line = $begin_line; my $action = {}; $self->add_trigger($begin_line, { type => "replace", begin_line => $begin_line, begin_column => $begin_column, end_line => $end_line, end_column => $end_column, replace => $replace }); } sub flush { my $self = shift; my $file = \${$self->{FILE}}; my $triggers = \%{$self->{TRIGGERS}}; my $editor = sub { local *IN = shift; local *OUT = shift; my $modified = 0; my $again = 0; my $lookahead = 0; my $lookahead_count = 0; LINE: while($again || defined(my $current = )) { if(!$again) { chomp $current; if($lookahead) { $lookahead = 0; $_ .= "\n" . $current; $lookahead_count++; } else { $_ = $current; $lookahead_count = 0; } } else { $lookahead_count = 0; $again = 0; } my $line = $. - $lookahead_count; foreach my $action (@{$$triggers{$line}}) { if($. < $action->{end_line}) { $lookahead = 1; next LINE; } my $type = $action->{type}; my $begin_line = $action->{begin_line}; my $begin_column = $action->{begin_column}; my $end_line = $action->{end_line}; my $end_column = $action->{end_column}; if($type eq "replace") { my $replace = $action->{replace}; my @lines = split(/\n/, $_); if($#lines < 0) { @lines = ($_); } my $begin = ""; my $column = 0; $_ = $lines[0]; while($column < $begin_column - 1 && s/^.//) { $begin .= $&; if($& eq "\t") { $column = $column + 8 - $column % 8; } else { $column++; } } my $column2 = 0; $_ = $lines[$#lines]; while($column2 < $end_column && s/^.//) { if($& eq "\t") { $column2 = $column2 + 8 - $column2 % 8; } else { $column2++; } } my $end = $_; $_ = "$begin$replace$end"; if($options->modify) { $modified = 1; } else { $output->write("$$file:$begin_line.$begin_column-$end_line.$end_column: $replace\n"); } } } print OUT "$_\n"; } return $modified; }; my $modified = 0; if(1) { $modified = edit_file($$file, $editor); } if(!$modified) { $self->flush_old; } } ######################################################################## # Hack for backward compabillity # my %insert_line; my %substitute_line; my %delete_line; my %spec_file; sub flush_old { my $self = shift; my $file = ${$self->{FILE}}; my $editor = sub { local *IN = shift; local *OUT = shift; my $modified = 0; while() { chomp; my $line; $line = $insert_line{$.}; if(defined($line)) { if($options->modify) { $_ = "$line$_"; $modified = 1; } else { my $line2 = $line; chomp($line2); my @line2 = split(/\n/, $line2); if($#line2 > 0) { $output->write("$file: $.: insert: \\\n"); foreach my $line2 (@line2) { $output->write("'$line2'\n"); } } else { $output->write("$file: $.: insert: '$line2'\n"); } } } my $search = $substitute_line{$.}{search}; my $replace = $substitute_line{$.}{replace}; if(defined($search) && defined($replace)) { my $modified2 = 0; if(s/$search/$replace/) { if($options->modify) { $modified = 1; } $modified2 = 1; } if(!$options->modify || !$modified2) { my $search2; my $replace2; if(!$modified2) { $search2 = "unmatched search"; $replace2 = "unmatched replace"; } else { $search2 = "search"; $replace2 = "replace"; } $output->write("$file: $.: $search2 : '$search'\n"); my @replace2 = split(/\n/, $replace); if($#replace2 > 0) { $output->write("$file: $.: $replace2: \\\n"); foreach my $replace2 (@replace2) { $output->write("'$replace2'\n"); } } else { $output->write("$file: $.: $replace2: '$replace'\n"); } } } $line = $delete_line{$.}; if(defined($line)) { if(/$line/) { if($options->modify) { $modified = 1; next; } else { $output->write("$file: $.: delete: '$line'\n"); } } else { $output->write("$file: $.: unmatched delete: '$line'\n"); } } print OUT "$_\n"; } return $modified; }; my $n = 0; while(defined(each %insert_line)) { $n++; } while(defined(each %substitute_line)) { $n++; } while(defined(each %delete_line)) { $n++; } if($n > 0) { edit_file($file, $editor); } foreach my $module (sort(keys(%spec_file))) { my $file; foreach my $winapi (@winapis) { $file = ($winapi->module_file($module) || $file); } if(defined($file)) { $file = file_normalize($file); } my @substitutes = @{$spec_file{$module}}; my $editor = sub { local *IN = shift; local *OUT = shift; my $modified = 0; while() { chomp; my @substitutes2 = (); foreach my $substitute (@substitutes) { my $search = $substitute->{search}; my $replace = $substitute->{replace}; if(s/$search/$replace/) { if($options->modify) { $modified = 1; } else { $output->write("$file: search : '$search'\n"); $output->write("$file: replace: '$replace'\n"); } next; } else { push @substitutes2, $substitute; } } @substitutes = @substitutes2; print OUT "$_\n"; } return $modified; }; if(defined($file)) { edit_file($file, $editor); } else { $output->write("$module: doesn't have any spec file\n"); } if($#substitutes >= 0) { foreach my $substitute (@substitutes) { my $search = $substitute->{search}; my $replace = $substitute->{replace}; $output->write("$file: unmatched search : '$search'\n"); $output->write("$file: unmatched replace: '$replace'\n"); } } } %insert_line = (); %substitute_line = (); %delete_line = (); %spec_file = (); } sub delete_line { my $self = shift; my $line = shift; my $pattern = shift; $delete_line{$line} = $pattern; } sub insert_line { my $self = shift; my $line = shift; my $insert = shift; $insert_line{$line} = $insert; } sub substitute_line { my $self = shift; my $line = shift; my $search = shift; my $replace = shift; $substitute_line{$line}{search} = $search; $substitute_line{$line}{replace} = $replace; } sub replace_spec_file { my $self = shift; my $module = shift; my $search = shift; my $replace = shift; my $substitute = {}; $substitute->{search} = $search; $substitute->{replace} = $replace; if(!defined($spec_file{$module})) { $spec_file{$module} = []; } push @{$spec_file{$module}}, $substitute; } 1;