Subject: bin/34938: --directory argument to patch does not work
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <dieter.NetBSD@pandora.be>
List: netbsd-bugs
Date: 10/29/2006 16:40:00
>Number: 34938
>Category: bin
>Synopsis: --directory argument to patch does not work
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Oct 29 16:40:00 +0000 2006
>Originator: dieter roelants
>Release: NetBSD 4.99.2
>Organization:
>Environment:
System: NetBSD simult.amelgem.be 4.99.2 NetBSD 4.99.2 (SIMULT) #15: Sat Sep 23 22:35:00 CEST 2006 dieter@simult.amelgem.be:/build/obj.i386.current/sys/arch/i386/compile/SIMULT i386
Architecture: i386
Machine: i386
>Description:
According to the man page, patch has an option --directory
which should do the same as -d. Only, it doesn't work. This
has probably been broken since it was added more then 10
years ago. Now somebody (me) noticed because it is used by
pkgsrc/devel/meld. Well, that's almost true, because meld
uses --directory=<dir> (that is '=' instead of ' '), which
is what gnu patch provides.
The same applies to some (all?) of the other long-options.
The attached patch splits long options on '='. I don't
think it breaks anything. I only changed the explanations
in the man page for fuzz and directory, because I verified
these didn't work as documented. Before I continue, I want
to know what the right way to do so is. I'll query
tech-userlevel for this.
PS. I'm not sure I like the patch, perhaps there is a nicer way.
>How-To-Repeat:
mkdir /tmp/patches
sed 's,0,1,g' /etc/fstab | diff -u /etc/fstab - > /tmp/patches/1
mkdir /tmp/apply
cp /etc/fstab /tmp/apply/
patch --directory /tmp/apply < /tmp/patches/1
patch: **** can't cd to unexpected *** at line %d: %s: No such file or directory
>Fix:
Index: patch.1
===================================================================
RCS file: /cvsroot/src/usr.bin/patch/patch.1,v
retrieving revision 1.12
diff -u -r1.12 patch.1
--- patch.1 25 Mar 2005 23:55:02 -0000 1.12
+++ patch.1 29 Oct 2006 15:42:06 -0000
@@ -241,11 +241,10 @@
.B \-D
and the argument.
.TP 5
-.B \-d or \-\-directory
+.B \-d\*[Lt]directory\*[Gt] or \-\-directory=\*[Lt]directory\*[Gt]
causes
.I patch
-to interpret the next argument as a directory, and cd to it before doing
-anything else.
+to cd to this directory before doing anything else.
.TP 5
.B \-E or \-\-remove-empty-files
causes
@@ -257,7 +256,7 @@
.I patch
to interpret the patch file as an ed script.
.TP 5
-.B \-F\*[Lt]number\*[Gt] or \-\-fuzz \*[Lt]number\*[Gt]
+.B \-F\*[Lt]number\*[Gt] or \-\-fuzz=\*[Lt]number\*[Gt]
sets the maximum fuzz factor.
This switch only applies to context diffs, and causes
.I patch
Index: patch.c
===================================================================
RCS file: /cvsroot/src/usr.bin/patch/patch.c,v
retrieving revision 1.24
diff -u -r1.24 patch.c
--- patch.c 25 Mar 2005 23:55:02 -0000 1.24
+++ patch.c 29 Oct 2006 15:42:06 -0000
@@ -38,6 +38,7 @@
#include "backupfile.h"
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
/* procedures */
@@ -440,7 +441,7 @@
static void
get_some_switches(void)
{
- char *s;
+ char *s, *t;
rejname[0] = '\0';
if (!Argc)
@@ -462,8 +463,16 @@
char opt;
if (*(s + 1) == '-') {
- opt = decode_long_option(s + 2);
- s = "";
+ t = strtok(s, "=");
+ opt = decode_long_option(t + 2);
+ t = strtok(NULL, "");
+ if (t == NULL)
+ s = "";
+ else {
+ t--;
+ t[0] = opt;
+ s = t;
+ }
}
else
opt = *++s;