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