patchfs update

Adam Byrtek / alpha alpha at student.uci.agh.edu.pl
Wed Feb 26 15:36:59 UTC 2003


On Wed, Feb 26, 2003 at 04:21:21PM +0100, Adam Byrtek / alpha wrote:
> I've sent this patch to Andrew privately for review, it is the feature
> Arpi asked for. As is has been accepted I'm sending the patch to the
> list - could you please test it?

Forgotten to attach the patch...

-- 

  _.|._ |_  _.   :  Adam Byrtek /alpha/
 (_|||_)| |(_|   :  email  alpha@(irc.pl|debian.org)
     |           :  jabber alpha.pl(at)jabber.org, pgp 0xB25952C0
-------------- next part --------------
Index: patchfs.in
===================================================================
RCS file: /cvs/gnome/mc/vfs/extfs/patchfs.in,v
retrieving revision 1.12
diff -u -r1.12 patchfs.in
--- extfs/patchfs.in	13 Jan 2003 12:07:46 -0000	1.12
+++ extfs/patchfs.in	23 Feb 2003 22:57:26 -0000
@@ -7,11 +7,12 @@
 use bytes;
 use strict;
 use POSIX;
+use File::Temp "tempfile";
 
 # standard binaries
-my $bzip = 'bzip2';
-my $gzip = 'gzip';
-my $file = 'file';
+my $bzip = "bzip2";
+my $gzip = "gzip";
+my $file = "file";
 
 # date parsing requires Date::Parse from TimeDate module
 my $parsedates = eval "require Date::Parse";
@@ -55,6 +56,96 @@
     exit 1;
 }
 
+# (compressed) input
+sub myin
+{
+    my ($qfname)=(quotemeta $_[0]);
+    
+    $_=`$file $qfname`;
+    if (/bzip/) {
+	return "$bzip -dc $qfname";
+    } elsif (/gzip/) {
+	return "$gzip -dc $qfname";
+    } else {
+	return "cat $qfname";
+    }
+}
+
+# (compressed) output
+sub myout
+{
+    my ($qfname,$append)=(quotemeta $_[0],$_[1]);
+    my ($sep);
+    
+    if ($append) {
+      $sep=">>";
+    } else {
+      $sep=">";
+    }
+    
+    $_=`$file $qfname`;
+    if (/bzip/) {
+	return "$bzip -c $sep $qfname";
+    } elsif (/gzip/) {
+	return "$gzip -c $sep $qfname";
+    } else {
+	return "cat $sep $qfname";
+    }
+}
+
+# select diff filename conforming with rules found in diff.info
+sub diff_filename
+{
+    my ($fsrc,$fdst)=@_;
+    
+    if (!$fdst && !$fsrc) {
+	error 'Index: not yet implemented';
+    } elsif (!$fsrc || $fsrc eq '/dev/null') {
+	return ($fdst,"PATCH-CREATE/");
+    } elsif (!$fdst || $fdst eq '/dev/null') {
+	return ($fsrc,"PATCH-REMOVE/");
+    } elsif (($fdst eq "/dev/null") && ($fsrc eq "/dev/null")) {
+	error "Malformed diff";
+    } else {
+	# fewest path name components
+	if ($fdst=~s|/|/|g < $fsrc=~s|/|/|g) {
+	    return ($fdst,"");
+	} elsif ($fdst=~s|/|/|g > $fsrc=~s|/|/|g) {
+	    return ($fsrc,"");
+	} else {
+	    # shorter base name
+	    if (($fdst=~/$basename/,length $2) < ($fsrc=~/$basename/,length $2)) {
+		return ($fdst,"");
+	    } elsif (($fdst=~/$basename/,length $2) > ($fsrc=~/$basename/,length $2)) {
+		return ($fsrc,"");
+	    } else {
+		# shortest names
+		if (length $fdst < length $fsrc) {
+		    return ($fdst,"");
+		} else {
+		    return ($fsrc,"");
+		}
+	    }
+	}
+    }
+}
+
+# parse unified or context header
+sub parse_header
+{
+    my ($unified,$context,$buf)=@_;
+    
+    if ($unified) {
+	error "Can't parse unified diff header"
+	  unless ((($$buf.=<I>).=<I>)=~/$unified_header/);
+	return $$buf=~/$unified_extract/;
+    } elsif ($context) {
+	error "Can't parse context diff header"
+	  unless ((($$buf.=<I>).=<I>)=~/$context_header/);
+	return $$buf=~/$context_extract/;
+    }
+}
+
 # list files affected by patch
 sub list
 {
@@ -69,7 +160,7 @@
     import Date::Parse if ($parsedates);
     
     # state==1 means diff contents, state==0 means comments
-    $state=0; $len=0; $f='';
+    $state=0; $len=0; $f="";
     while (<I>) {
 
 	# recognize diff type
@@ -91,49 +182,8 @@
 	    }
 	    $state=1;
 
-	    # parse diff header
-	    if ($unified) {
-		error "Can't parse unified diff header"
-		  unless ((($_.=<I>).=<I>)=~/$unified_header/);
-		($fsrc,$fdst,$time)=/$unified_extract/;
-	    } elsif ($context) {
-		error "Can't parse context diff header"
-		  unless ((($_.=<I>).=<I>)=~/$context_header/);
-		($fsrc,$fdst,$time)=/$context_extract/;
-	    }
-
-	    # select filename, conform with (diff.info)Multiple patches
-	    $prefix="";
-	    if (!$fdst && !$fsrc) {
-		error 'Index: not yet implemented';
-	    } elsif (!$fsrc || $fsrc eq '/dev/null') {
-		$f=$fdst; $prefix="PATCH-CREATE/";
-	    } elsif (!$fdst || $fdst eq '/dev/null') {
-		$f=$fsrc; $prefix="PATCH-REMOVE/";
-	    } elsif (($fdst eq "/dev/null") && ($fsrc eq "/dev/null")) {
-		error "Malformed diff";
-	    } else {
-		# fewest path name components
-		if ($fdst=~s|/|/|g < $fsrc=~s|/|/|g) {
-		    $f=$fdst;
-		} elsif ($fdst=~s|/|/|g > $fsrc=~s|/|/|g) {
-		    $f=$fsrc;
-		} else {
-		    # shorter base name
-		    if (($fdst=~/$basename/,length $2) < ($fsrc=~/$basename/,length $2)) {
-			$f=$fdst;
-		    } elsif (($fdst=~/$basename/,length $2) > ($fsrc=~/$basename/,length $2)) {
-			$f=$fsrc;
-		    } else {
-			# shortest names
-			if (length $fdst < length $fsrc) {
-			    $f=$fdst;
-			} else {
-			    $f=$fsrc;
-			}
-		    }
-		}
-	    }
+	    ($fsrc,$fdst,$time)=parse_header($unified,$context,\$_);
+	    ($f,$prefix)=diff_filename($fsrc,$fdst);
 	    $f=$f.".diff";
 
 	} elsif ($state==1 && (($unified && !/$unified_contents/) || ($context && !/$context_contents/))) {
@@ -146,7 +196,7 @@
 	$len+=length;
     }
     printf "-rw-r--r-- 1 %s %s %d %s %s%s\n", $uid, $gid, $len, datetime($time), $prefix, $f
-      if $f;
+      if ($f && $state==1);
 }
 
 # extract diff from patch
@@ -159,7 +209,7 @@
     $file=~s/^(PATCH-(CREATE|REMOVE)\/)?(.*)\.diff$/$3/;
     
     # state==1 means diff contents, state==0 mens comments
-    $state=0; $found=0; $buf='';
+    $state=0; $found=0; $buf="";
     while (<I>) {
 
 	# recognize diff type
@@ -176,16 +226,7 @@
 	    last if ($state==1 && $found);
 	    $state=1;
 
-	    # parse diff header
-	    if ($unified) {
-		error "Can't parse unified diff header"
-		  unless ((($_.=<I>).=<I>)=~/$unified_header/);
-		($fsrc,$fdst)=/$unified_extract/;
-	    } elsif ($context) {
-		error "Can't parse context diff header"
-		  unless ((($_.=<I>).=<I>)=~/$context_header/);
-		($fsrc,$fdst)=/$context_extract/;
-	    }
+	    ($fsrc,$fdst,)=parse_header($unified,$context,\$_);
 	    $found=1 if (($fsrc eq $file) || ($fdst eq $file));
 
 	} elsif ($state==1 && (($unified && !/$unified_contents/) || ($context && !/$context_contents/))) {
@@ -204,57 +245,128 @@
     }
 }
 
-# append diff to archive
-sub copyin
+# remove diff(s) from patch
+sub rm
 {
-    my ($archive,$name,$f)=(quotemeta $_[0],$_[1],quotemeta $_[2]);
-    my ($cmd);
+    my ($archive)=(shift);
+    my ($fsrc,$fdst,$found,$state,$buf);
+    my ($tmp,$tmpname)=tempfile();
+    my ($unified,$context)=(0,0);
 
-    error "File must have .diff or .patch extension"
-      unless $name=~/\.(diff|patch)(\.(bz|bz2|gz|z|Z))?$/;
+    @_=map {scalar(s/^(PATCH-(CREATE|REMOVE)\/)?(.*)\.diff$/$3/,$_)} @_;
+    
+    # state==1 means diff contents, state==0 mens comments
+    $state=0; $found=0; $buf="";
+    while (<I>) {
 
-    $_=`$file $f`;
-    if (/bzip/) {
-	$cmd="$bzip -dc $f";
-    } elsif (/gzip/) {
-	$cmd="$gzip -dc $f";
-    } else {
-	$cmd="cat $f";
-    }
+	# recognize diff type
+	if (!$unified && !$context) {
+	    $unified=1 if (/^--- /);
+	    $context=1 if (/^\*\*\* /);
+	    if (!$unified && !$context) {
+		$buf.=$_;
+		next;
+	    }
+	}
 
-    $_=`$file $archive`;
-    if (/bzip/) {
-	system "$cmd | $bzip -c >> $archive";
-    } elsif (/gzip/) {
-	system "$cmd | $gzip -c >> $archive";
-    } else {
-	system "$cmd >> $archive";
+	if (($unified && /^--- /) || ($context && /^\*\*\* [^\*]*$/)) {
+	    $state=1;
+
+	    ($fsrc,$fdst,)=parse_header($unified,$context,\$_);
+	    
+	    # remove listed files
+	    foreach (@_) {
+		if (($fsrc eq $_) || ($fdst eq $_)) {
+		    $found=1;
+		    last;
+		}
+	    }
+	    if (!$found) {
+		print $tmp $buf;
+		$buf="";
+	    }
+
+	} elsif ($state==1 && (($unified && !/$unified_contents/) || ($context && !/$context_contents/))) {
+	    # start of comments, end of diff contents
+	    $found=0;
+	    $state=0;
+	    $buf="";
+	}
+
+	if ($state==0) {
+	    $buf.=$_;
+	} elsif (!$found) {
+	    print $tmp $_;
+	}
     }
+    print $tmp $buf if (!$found);
+    close $tmp;
+    close I;
+
+    # replace archive with temporary file
+    $buf=myout($archive,0);
+    system("cat ".quotemeta($tmpname)."|$buf")==0 
+      or error "Can't write to archive";
+    system "rm -f ".quotemeta($tmpname);
 }
 
-# open (compressed) archive for reading
-sub openread
+# append diff to archive
+sub copyin
 {
-    my ($archive) = (quotemeta $_[0]);
+    my ($archive,$name,$src)=(@_);
+    my ($fsrc,$fdst,$f, at files);
+    my ($unified,$context)=(0,0);
+    my ($cmd1,$cmd2);
 
-    $_=`$file $archive`;
-    if (/bzip/) {
-	open I, "$bzip -dc $archive |";
-    } elsif (/gzip/) {
-	open I, "$gzip -dc $archive |";
-    } else {
-	open I, "< $ARGV[1]";
+    error "File must have .diff or .patch extension"
+      unless $name=~/\.(diff|patch)(\.(bz|bz2|gz|z|Z))?$/;
+
+    $file=~s/^(PATCH-(CREATE|REMOVE)\/)?(.*)\.diff$/$3/;
+    
+    # build filelist
+    open I, myin($src)."|";
+    while (<I>) {
+	# recognize diff type
+	if (!$unified && !$context) {
+	    $unified=1 if (/^--- /);
+	    $context=1 if (/^\*\*\* /);
+	}
+
+	if (($unified && /^--- /) || ($context && /^\*\*\* [^\*]*$/)) {
+	    ($fsrc,$fdst,)=parse_header($unified,$context,\$_);
+	    ($f,)=diff_filename($fsrc,$fdst);
+	    push(@files,$f);
+	}
     }
+    close I;
+
+    # remove overwrited files
+    open I, myin($archive)."|";
+    rm ($archive, map($_.".diff", at files));
+    close I;
+
+    $cmd1=myin($src);
+    $cmd2=myout($archive,1);
+    system("$cmd1 | $cmd2")==0
+      or error "Can't write to archive";
 }
 
 
 if ($ARGV[0] eq 'list') {
-    openread $ARGV[1];
+    open I, myin($ARGV[1])."|";
     list $ARGV[1];
     exit 0;
 } if ($ARGV[0] eq 'copyout') {
-    openread $ARGV[1];
+    open I, myin($ARGV[1])."|";
     copyout ($ARGV[2], $ARGV[3]);
+    exit 0;
+} if ($ARGV[0] eq 'rm') {
+    open I, myin($ARGV[1])."|";
+    rm ($ARGV[1], $ARGV[2]);
+    exit 0;
+} if ($ARGV[0] eq 'rmdir') {
+    exit 0;
+} if ($ARGV[0] eq 'mkdir') {
     exit 0;
 } if ($ARGV[0] eq 'copyin') {
     copyin ($ARGV[1], $ARGV[2], $ARGV[3]);
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/mc/vfs/ChangeLog,v
retrieving revision 1.583
diff -u -u -0 -r1.583 ChangeLog
--- ChangeLog	19 Feb 2003 14:04:35 -0000	1.583
+++ ChangeLog	23 Feb 2003 23:16:28 -0000
@@ -0,0 +1,5 @@
+2003-02-24  Adam Byrtek  <alpha at debian.org>
+
+	* extfs/patchfs.in: rm and proper copyin support, more
+	functions to make code more clear
+


More information about the mc-devel mailing list