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

Reply via email to