webengine/osswebengine/WebKitTools/S60Tools/svn-create-patch.bat
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 @rem = '--*-Perl-*--
       
     2 @echo off
       
     3 if "%OS%" == "Windows_NT" goto WinNT
       
     4 perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9
       
     5 goto endofperl
       
     6 :WinNT
       
     7 perl -x -S %0 %*
       
     8 if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl
       
     9 if %errorlevel% == 9009 echo You do not have Perl in your PATH.
       
    10 if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul
       
    11 goto endofperl
       
    12 @rem ';
       
    13 #!/usr/bin/perl -w
       
    14 #line 15
       
    15 
       
    16 # Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
       
    17 #
       
    18 # Redistribution and use in source and binary forms, with or without
       
    19 # modification, are permitted provided that the following conditions
       
    20 # are met:
       
    21 #
       
    22 # 1.  Redistributions of source code must retain the above copyright
       
    23 #     notice, this list of conditions and the following disclaimer. 
       
    24 # 2.  Redistributions in binary form must reproduce the above copyright
       
    25 #     notice, this list of conditions and the following disclaimer in the
       
    26 #     documentation and/or other materials provided with the distribution. 
       
    27 # 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
       
    28 #     its contributors may be used to endorse or promote products derived
       
    29 #     from this software without specific prior written permission. 
       
    30 #
       
    31 # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
       
    32 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    33 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
       
    34 # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
       
    35 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
       
    36 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       
    37 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
       
    38 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    39 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
       
    40 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    41 
       
    42 # Extended "svn diff" script for WebKit Open Source Project, used to make patches.
       
    43 
       
    44 # Differences from standard "svn diff":
       
    45 #
       
    46 #   Uses the real diff, not svn's built-in diff.
       
    47 #   Always passes "-p" to diff so it will try to include function names.
       
    48 #   Handles binary files (encoded as a base64 chunk of text).
       
    49 #   Sorts the diffs alphabetically by text files, then binary files.
       
    50 #
       
    51 # Missing features:
       
    52 #
       
    53 #   Handle moved files.
       
    54 
       
    55 use strict;
       
    56 use warnings;
       
    57 
       
    58 use Config;
       
    59 use Cwd;
       
    60 use File::Basename;
       
    61 use File::Spec;
       
    62 use File::stat;
       
    63 use Getopt::Long;
       
    64 use MIME::Base64;
       
    65 use POSIX qw(:errno_h);
       
    66 use Time::gmtime;
       
    67 
       
    68 sub canonicalizePath($);
       
    69 sub generateDiff($);
       
    70 sub generateFileList($\%\%);
       
    71 sub numericcmp($$);
       
    72 sub outputBinaryContent($);
       
    73 sub pathcmp($$);
       
    74 sub processPaths(\@);
       
    75 sub splitpath($);
       
    76 
       
    77 my $showHelp;
       
    78 if (!GetOptions("help" => \$showHelp) || $showHelp) {
       
    79     print STDERR basename($0) . " [-h|--help] [svndir1 [svndir2 ...]]\n";
       
    80     exit 1;
       
    81 }
       
    82 
       
    83 my %paths = processPaths(@ARGV);
       
    84 
       
    85 # Generate a list of files requiring diffs
       
    86 my %textFiles;
       
    87 my %binaryFiles;
       
    88 for my $path (keys %paths) {
       
    89     generateFileList($path, %textFiles, %binaryFiles);
       
    90 }
       
    91 
       
    92 # Generate the diff for text files, then binary files, for easy reviewing
       
    93 for my $file (sort pathcmp keys %textFiles) {
       
    94     generateDiff($file);
       
    95 }
       
    96 for my $file (sort pathcmp keys %binaryFiles) {
       
    97     generateDiff($file);
       
    98 }
       
    99 
       
   100 exit 0;
       
   101 
       
   102 
       
   103 sub canonicalizePath($)
       
   104 {
       
   105     my ($file) = @_;
       
   106 
       
   107     # Remove extra slashes and '.' directories in path
       
   108     $file = File::Spec->canonpath($file);
       
   109 
       
   110     # Remove '..' directories in path
       
   111     my @dirs = ();
       
   112     foreach my $dir (File::Spec->splitdir($file)) {
       
   113         if ($dir eq '..' && $#dirs >= 0 && $dirs[$#dirs] ne '..') {
       
   114             pop(@dirs);
       
   115         } else {
       
   116             push(@dirs, $dir);
       
   117         }
       
   118     }
       
   119     return ($#dirs >= 0) ? File::Spec->catdir(@dirs) : ".";
       
   120 }
       
   121 
       
   122 sub generateDiff($)
       
   123 {
       
   124     my ($file) = @_;
       
   125     my $errors = "";
       
   126     my $isBinary;
       
   127     my $lastLine;
       
   128     open DIFF, "svn diff --diff-cmd diff -x -uNp $file |" or die;
       
   129     while (<DIFF>) {
       
   130         $isBinary = 1 if (/^Cannot display: file marked as a binary type\.$/);
       
   131         print;
       
   132         $lastLine = $_;
       
   133     }
       
   134     close DIFF;
       
   135     print "\n" if ($isBinary && $lastLine =~ m/\S+/);
       
   136     outputBinaryContent($file) if ($isBinary);
       
   137     print STDERR $errors;
       
   138 }
       
   139 
       
   140 sub generateFileList($\%\%)
       
   141 {
       
   142     my ($path, $textFiles, $binaryFiles) = @_;
       
   143     my $indexPath;
       
   144     my $isBinary;
       
   145     open DIFF, "svn diff --diff-cmd diff -x -uNp $path |" or die;
       
   146     while (<DIFF>) {
       
   147         if (/^Index: (.*)/) {
       
   148             my $newIndexPath = $1;
       
   149             if ($indexPath) {
       
   150                 if ($isBinary) {
       
   151                     $binaryFiles->{$indexPath} = 1;
       
   152                 } else {
       
   153                     $textFiles->{$indexPath} = 1;
       
   154                 }
       
   155             }
       
   156             $indexPath = $newIndexPath;
       
   157             $isBinary = 0;
       
   158         }
       
   159         if (/^Cannot display: file marked as a binary type\.$/) {
       
   160             $isBinary = 1;
       
   161         }
       
   162     }
       
   163     close DIFF;
       
   164     # Handle last patch
       
   165     if ($indexPath) {
       
   166         if ($isBinary) {
       
   167             $binaryFiles->{$indexPath} = 1;
       
   168         } else {
       
   169             $textFiles->{$indexPath} = 1;
       
   170         }
       
   171     }
       
   172     # check files for tabs
       
   173     foreach my $file ( keys %$textFiles ) {
       
   174         next if $file =~ /(\.mmp|\.mk)$/; # makefiles need them
       
   175         open (INPUT, $file) || die "can't open $file: $!";
       
   176         while (<INPUT>) {
       
   177            /\t/ and die "Error: $file contains tab characters, please remove.\n";
       
   178         }
       
   179         close(INPUT)    || die "can't close $file: $!";
       
   180     }
       
   181 }
       
   182 
       
   183 # Sort numeric parts of strings as numbers, other parts as strings.
       
   184 # Makes 1.33 come after 1.3, which is cool.
       
   185 sub numericcmp($$)
       
   186 {
       
   187     my ($aa, $bb) = @_;
       
   188 
       
   189     my @a = split /(\d+)/, $aa;
       
   190     my @b = split /(\d+)/, $bb;
       
   191 
       
   192     # Compare one chunk at a time.
       
   193     # Each chunk is either all numeric digits, or all not numeric digits.
       
   194     while (@a && @b) {
       
   195         my $a = shift @a;
       
   196         my $b = shift @b;
       
   197         
       
   198         # Use numeric comparison if chunks are non-equal numbers.
       
   199         return $a <=> $b if $a =~ /^\d/ && $b =~ /^\d/ && $a != $b;
       
   200 
       
   201         # Use string comparison if chunks are any other kind of non-equal string.
       
   202         return $a cmp $b if $a ne $b;
       
   203     }
       
   204     
       
   205     # One of the two is now empty; compare lengths for result in this case.
       
   206     return @a <=> @b;
       
   207 }
       
   208 
       
   209 sub outputBinaryContent($)
       
   210 {
       
   211     my ($path) = @_;
       
   212     # Deletion
       
   213     return if (! -e $path);
       
   214     # Addition or Modification
       
   215     my $buffer;
       
   216     open BINARY, $path  or die;
       
   217     while (read(BINARY, $buffer, 60*57)) {
       
   218         print encode_base64($buffer);
       
   219     }
       
   220     close BINARY;
       
   221     print "\n";
       
   222 }
       
   223 
       
   224 # Sort first by directory, then by file, so all paths in one directory are grouped
       
   225 # rather than being interspersed with items from subdirectories.
       
   226 # Use numericcmp to sort directory and filenames to make order logical.
       
   227 sub pathcmp($$)
       
   228 {
       
   229     my ($patha, $pathb) = @_;
       
   230 
       
   231     my ($dira, $namea) = splitpath($patha);
       
   232     my ($dirb, $nameb) = splitpath($pathb);
       
   233 
       
   234     return numericcmp($dira, $dirb) if $dira ne $dirb;
       
   235     return numericcmp($namea, $nameb);
       
   236 }
       
   237 
       
   238 sub processPaths(\@)
       
   239 {
       
   240     my ($paths) = @_;
       
   241     return ("." => 1) if (!@{$paths});
       
   242 
       
   243     my %result = ();
       
   244 
       
   245     for my $file (@{$paths}) {
       
   246         die "can't handle absolute paths like \"$file\"\n" if File::Spec->file_name_is_absolute($file);
       
   247         die "can't handle empty string path\n" if $file eq "";
       
   248         die "can't handle path with single quote in the name like \"$file\"\n" if $file =~ /'/; # ' (keep Xcode syntax highlighting happy)
       
   249 
       
   250         my $untouchedFile = $file;
       
   251 
       
   252         $file = canonicalizePath($file);
       
   253 
       
   254         die "can't handle paths with .. like \"$untouchedFile\"\n" if $file =~ m|/\.\./|;
       
   255 
       
   256         $result{$file} = 1;
       
   257     }
       
   258 
       
   259     return ("." => 1) if ($result{"."});
       
   260 
       
   261     # Remove any paths that also have a parent listed.
       
   262     for my $path (keys %result) {
       
   263         for (my $parent = dirname($path); $parent ne '.'; $parent = dirname($parent)) {
       
   264             if ($result{$parent}) {
       
   265                 delete $result{$path};
       
   266                 last;
       
   267             }
       
   268         }
       
   269     }
       
   270 
       
   271     return %result;
       
   272 }
       
   273 
       
   274 # Break up a path into the directory (with slash) and base name.
       
   275 sub splitpath($)
       
   276 {
       
   277     my ($path) = @_;
       
   278 
       
   279     my $pathSeparator = "/";
       
   280     my $dirname = dirname($path) . $pathSeparator;
       
   281     $dirname = "" if $dirname eq "." . $pathSeparator;
       
   282 
       
   283     return ($dirname, basename($path));
       
   284 }
       
   285 
       
   286 __END__
       
   287 :endofperl