Author: sparky Date: Thu Nov 23 03:22:31 2006 GMT Module: SOURCES Tag: HEAD ---- Log message: - script for making patch look pretty, and minimizing diff between updated and in-CVS file
---- Files affected: SOURCES: patch_minimizer (NONE -> 1.1) (NEW) ---- Diffs: ================================================================ Index: SOURCES/patch_minimizer diff -u /dev/null SOURCES/patch_minimizer:1.1 --- /dev/null Thu Nov 23 04:22:31 2006 +++ SOURCES/patch_minimizer Thu Nov 23 04:22:26 2006 @@ -0,0 +1,193 @@ +#!/usr/bin/perl +# +# If this script works for you, tell me ! +# If it doesn't, don't bother. +# +# Licensed under GPL +# (c) 2006 PLD Linux Distribution +# Main author: [EMAIL PROTECTED] +# +use strict; +use warnings; + +my @cvs_cmd = qw(cvs -z9 -q up -p); +my (@branch, @force_branch); +my $file; + +sub strip_suffix($) { + my ($n) = @_; + my @r = ($n); + push @r, $1 if $n =~ m#^(.*)~$#; + push @r, $1 if $n =~ m#^(.*)\.new$#; + push @r, $1 if $n =~ m#^(.*)\.orig$#; + push @r, $1 if $n =~ m#^(.*)~[^/]*?$#; + push @r, $1 if $n =~ m#^(.*)\.[^/]*?$#; + push @r, $1 if $n =~ m#^(.*)~[^/]*?~[^/]*?$#; + push @r, $1 if $n =~ m#^(.*)\.[^/]*?\.[^/]*?$#; + return @r; +} + +sub find_common($$) { + my ($f1, $f2) = @_; + $f2 =~ s#^.*?/##; + return $f2 if $f1 eq "/dev/null"; + $f1 =~ s#^.*?/##; + foreach my $s1 (strip_suffix($f1)) { + foreach my $s2 (strip_suffix($f2)) { + return $s1 if $s1 eq $s2; + } + } + warn "Matching file name not found, using '$f2'\n"; + return $f2; +} + +sub find_file_common($$) { + my ($l1, $l2) = @_; + $l1 =~ /^--- (.*)\t(.*?)$/; + my $f = $1; + $l2 =~ /^\+\+\+ (.*)\t(.*?)$/; + my $ret = find_common($f, $1); + #warn "FILES: $f, $1 -> $ret\n"; + return $ret; +} + +sub get_files($) { + my ($file) = @_; + open CVS_IN, "-|", (@cvs_cmd, @branch, $file); + my @old_files = grep /^(\+\+\+|---) /, <CVS_IN>; + close CVS_IN; + my @ret; + + my $f1; + while ($f1 = shift @old_files) { + redo unless ($f1 =~ /^-/ and $old_files[0] =~ /^\+/); + my $f2 = shift @old_files; + my $common = find_file_common( $f1, $f2 ); + push @ret, [$common, $f1, $f2]; + } + + return [EMAIL PROTECTED]; +} + +sub split_patch($) { + my ($file) = @_; + open F_IN, $file; + my @patch = <F_IN>; + close F_IN; + + my @split_patch; + # = ([comment body] , [+,-,body], [+,-,body],...) + + my @comment; + while (my $l = shift @patch) { + if ($l =~ /^---/) { + unshift @patch, $l; + pop @comment while scalar @comment and + $comment[$#comment] =~ /^(diff .*|Index: .*|={67}|)$/; + last; + } + push @comment, $l; + } + $split_patch[0] = [EMAIL PROTECTED]; + + my @chunk = (undef, undef, undef); + my $l; + while ($l = shift @patch) { + if ($l =~ /^--- /) { + if (defined $chunk[2]) { + push @split_patch, [EMAIL PROTECTED]; + @chunk = (undef, undef, undef); + } + $chunk[0] = find_file_common($l, $chunk[2]) + if defined $chunk[2]; + $chunk[1] = $l; + next; + } + if ($l =~ /^\+\+\+ / and defined $chunk[1]) { + $chunk[2] = $l; + $chunk[0] = find_file_common($chunk[1], $chunk[2]); + next; + } + next unless defined $chunk[0]; + if ($l !~ /^[+-@ ]/) { + push @split_patch, [EMAIL PROTECTED]; + @chunk = (undef, undef, undef); + redo; + } + push @chunk, $l; + } + push @split_patch, [EMAIL PROTECTED] if defined $chunk[0]; + + return [EMAIL PROTECTED] +} + +sub sort_chunks($$) { + my ($new, $old_files) = @_; + my $diff; + local $" = ""; + $diff .= "@{$new->[0]}\n" if scalar @{$new->[0]}; + shift @{$new}; + my %new_hash = map { $_->[0] => $_ } @{$new}; + + foreach my $oldchunk (@{$old_files}) { + my $f = $oldchunk->[0]; + next unless exists $new_hash{$f}; + my $newchunk = $new_hash{$f}; + $diff .= "$oldchunk->[1]"; + $diff .= "$oldchunk->[2]"; + + shift @{$newchunk}; + shift @{$newchunk}; + shift @{$newchunk}; + $diff .= "@{$newchunk}"; + delete $new_hash{$f}; + } + + foreach my $f (sort keys %new_hash) { + my $newchunk = $new_hash{$f}; + shift @{$newchunk}; + $diff .= "@{$newchunk}"; + } + return $diff; +} + +sub clean_diff($) { + my ($file) = @_; + my $old_files = get_files($file); + my $splat = split_patch($file); + my $new_diff = sort_chunks($splat, $old_files); + rename $file, $file.".bak" or die "Can't rename file\n"; + open F_OUT, ">", $file or die "Dupa: $!\n"; + print F_OUT $new_diff; + close F_OUT; +} + +sub set_branch($) { + open F_IN, "CVS/Entries"; + my ($b, @ent) = grep { + my ($f,$b) = (split m#/#, $_)[1,5]; $f eq $_[0] and $_ = $b + } grep m#/#, <F_IN>; + close F_IN; + + @branch = ("-r", (substr $b,1)) if defined $b; + @branch = qw(-A); +} + +while (my $a = shift @ARGV) { + if ($a eq "-r") { + @force_branch = ("-r", + (shift @ARGV or die "Branch not specified\n") + ); + } elsif ($a eq "-A") { + @force_branch = qw(-A); + } else { + if (scalar @force_branch) { + @branch = @force_branch; + } else { + set_branch($a); + } + clean_diff($a); + } +} + +# vim: ts=4:sw=4 ================================================================ _______________________________________________ pld-cvs-commit mailing list pld-cvs-commit@lists.pld-linux.org http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit