i was looking for a different issue in patch when i found this.
patch(1) fails to recognize the reversal application of a patch that
creates a file (this is test t3).

since an empty context always matches, the idea is to run the dwim code
also when locate_hunk succeeds, but only if the patch would create a
file (pch_ptrn_lines() == 0) and the match is on the first line.

regress now passes completely.

ok?

diff /usr/src
commit - faf550173e173cd2ef8642601dc48202a09fd44f
path + /usr/src
blob - 73781e33724010ac3ce470e6c079eaa17c3d6365
file + regress/usr.bin/patch/Makefile
--- regress/usr.bin/patch/Makefile
+++ regress/usr.bin/patch/Makefile
@@ -7,10 +7,6 @@ CLEANFILES=    *.copy *.orig *.rej t5 d19/*
 REGRESS_TARGETS=     t1  t2  t3  t4  t5  t6  t7  t8  t9 \
                t10 t11 t12 t13 t14 t15 t16 t17 t18 t19
 
-t3:
-       @echo ${*} currently fails
-       @echo DISABLED
-
 # .in: input file
 # .diff: patch
 # .out: desired result after patching
@@ -18,7 +14,7 @@ t3:
 # t1: diff contains invalid line number 0.
 # t2: diff contains invalid line numbers beyond end of input file.
 # t3: a case where patch should detect a previously applied patch.
-#     Diff transform an empty file into a single line one. Currently fails.
+#     Diff transform an empty file into a single line one.
 # t4: a case where patch has to detect a previously applied patch.
 #     Diff transform a file with a single line with an eol into a single
 #     line without eol.
@@ -47,6 +43,7 @@ t3:
        @(! ${PATCH} ${PATCHFLAGS} ${*}.copy ${.CURDIR}/${*}.diff)
        @cmp -s ${*}.copy ${.CURDIR}/${*}.out || \
                (echo "XXX ${*} failed" && false)
+
 t4:
        @echo ${*}
        @cp ${.CURDIR}/${*}.in ${*}.copy
blob - 1d9070b01842d982b3b3ce6d5f810913a739813e
file + usr.bin/patch/patch.c
--- usr.bin/patch/patch.c
+++ usr.bin/patch/patch.c
@@ -260,7 +260,8 @@ main(int argc, char *argv[])
                        if (!skip_rest_of_patch) {
                                do {
                                        where = locate_hunk(fuzz);
-                                       if (hunk == 1 && where == 0 && !force) {
+                                       if ((hunk == 1 && where == 0 && !force) 
||
+                                           (where == 1 && pch_ptrn_lines() == 
0 && !force)) {
                                                /* dwim for reversed patch? */
                                                if (!pch_swap()) {
                                                        if (fuzz == 0)
@@ -276,6 +277,10 @@ main(int argc, char *argv[])
                                                                /* put it back 
to normal */
                                                                fatal("lost 
hunk on alloc error!\n");
                                                        reverse = !reverse;
+
+                                                       /* restore position if 
this patch creates a file */
+                                                       if (pch_ptrn_lines() == 
0)
+                                                               where = 1;
                                                } else if (noreverse) {
                                                        if (!pch_swap())
                                                                /* put it back 
to normal */

Reply via email to