Patch breaks under -D cond (+ fix)
Kevin Braunsdorf
ksb at mentor.cc.purdue.edu
Wed Sep 5 04:56:24 AEST 1990
[ This is an unofficial patch to patch by Larry Wall. I've contacted
Larry and he said I could send this out because he was busy with
other things. I'm sure an official patch will be out later. -- ksb ]
Priority: high (if you use `patch -D foo ...')
Description:
Patch will generate incorrect #if ... #else ... #endif
constructs given some new-style context diff hunks.
Version:
$Header: patch.c,v 2.0.1.6 88/06/22 20:46:39 lwall Locked $
Patch level: 12
Repeat-By:
Extract the shell archieve below then,
make
Note that unifdef exits with an error
unifdef: Error in test line 4: Premature EOF in ifdef.
(see broken.script for all the expected output).
Fix:
Apply the patch file (patch.c.patch) to patch.c with:
patch patch.c <patch.c.patch
rebuild and install patch. Then
make clean
make
and note that patch now passes this test (see OK.script).
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# bug
# This archive created: Tue Sep 4 13:46:34 1990
# By: Kevin Braunsdorf (Purdue UNIX Group)
mkdir bug
cd bug
sed 's/^K//' << \SHAR_EOF > patch.c.patch
K*** /usr/src/unsup/bin/patch/patch.c Thu Jun 23 16:35:06 1988
K--- ./patch.c Thu Aug 16 13:46:02 1990
K***************
K*** 402,422 ****
K }
K if (chdir(s) < 0)
K fatal2("Can't cd to %s.\n", s);
K break;
K case 'D':
K do_defines = TRUE;
K if (!*++s) {
K Argc--,Argv++;
K s = Argv[0];
K }
K! if (!isalpha(*s))
K fatal1("Argument to -D not an identifier.\n");
K Sprintf(if_defined, "#ifdef %s\n", s);
K Sprintf(not_defined, "#ifndef %s\n", s);
K Sprintf(end_defined, "#endif /* %s */\n", s);
K break;
K case 'e':
K diff_type = ED_DIFF;
K break;
K case 'f':
K force = TRUE;
K--- 402,422 ----
K }
K if (chdir(s) < 0)
K fatal2("Can't cd to %s.\n", s);
K break;
K case 'D':
K do_defines = TRUE;
K if (!*++s) {
K Argc--,Argv++;
K s = Argv[0];
K }
K! if (!isalpha(*s) && '_' != *s)
K fatal1("Argument to -D not an identifier.\n");
K Sprintf(if_defined, "#ifdef %s\n", s);
K Sprintf(not_defined, "#ifndef %s\n", s);
K Sprintf(end_defined, "#endif /* %s */\n", s);
K break;
K case 'e':
K diff_type = ED_DIFF;
K break;
K case 'f':
K force = TRUE;
K***************
K*** 595,672 ****
K }
K else if (def_state == IN_IFDEF) {
K fputs(else_defined, ofp);
K def_state = IN_ELSE;
K }
K fputs(pfetch(old), ofp);
K }
K last_frozen_line++;
K old++;
K }
K! else if (new > pat_end)
K break;
K else if (pch_char(new) == '+') {
K copy_till(where + old - 1);
K if (R_do_defines) {
K if (def_state == IN_IFNDEF) {
K fputs(else_defined, ofp);
K def_state = IN_ELSE;
K }
K else if (def_state == OUTSIDE) {
K fputs(if_defined, ofp);
K def_state = IN_IFDEF;
K }
K }
K fputs(pfetch(new), ofp);
K new++;
K }
K! else {
K! if (pch_char(new) != pch_char(old)) {
K! say3("Out-of-sync patch, lines %ld,%ld--mangled text or line numbers, maybe?\n",
K! pch_hunk_beg() + old,
K! pch_hunk_beg() + new);
K #ifdef DEBUGGING
K! say3("oldchar = '%c', newchar = '%c'\n",
K! pch_char(old), pch_char(new));
K #endif
K! my_exit(1);
K }
K! if (pch_char(new) == '!') {
K! copy_till(where + old - 1);
K if (R_do_defines) {
K! fputs(not_defined, ofp);
K! def_state = IN_IFNDEF;
K }
K! while (pch_char(old) == '!') {
K! if (R_do_defines) {
K! fputs(pfetch(old), ofp);
K! }
K! last_frozen_line++;
K! old++;
K! }
K! if (R_do_defines) {
K! fputs(else_defined, ofp);
K! def_state = IN_ELSE;
K! }
K! while (pch_char(new) == '!') {
K! fputs(pfetch(new), ofp);
K! new++;
K! }
K! if (R_do_defines) {
K! fputs(end_defined, ofp);
K! def_state = OUTSIDE;
K! }
K! }
K! else {
K! assert(pch_char(new) == ' ');
K old++;
K new++;
K }
K }
K }
K if (new <= pat_end && pch_char(new) == '+') {
K copy_till(where + old - 1);
K if (R_do_defines) {
K if (def_state == OUTSIDE) {
K fputs(if_defined, ofp);
K def_state = IN_IFDEF;
K }
K--- 595,671 ----
K }
K else if (def_state == IN_IFDEF) {
K fputs(else_defined, ofp);
K def_state = IN_ELSE;
K }
K fputs(pfetch(old), ofp);
K }
K last_frozen_line++;
K old++;
K }
K! else if (new > pat_end) {
K break;
K+ }
K else if (pch_char(new) == '+') {
K copy_till(where + old - 1);
K if (R_do_defines) {
K if (def_state == IN_IFNDEF) {
K fputs(else_defined, ofp);
K def_state = IN_ELSE;
K }
K else if (def_state == OUTSIDE) {
K fputs(if_defined, ofp);
K def_state = IN_IFDEF;
K }
K }
K fputs(pfetch(new), ofp);
K new++;
K }
K! else if (pch_char(new) != pch_char(old)) {
K! say3("Out-of-sync patch, lines %ld,%ld--mangled text or line numbers, maybe?\n",
K! pch_hunk_beg() + old,
K! pch_hunk_beg() + new);
K #ifdef DEBUGGING
K! say3("oldchar = '%c', newchar = '%c'\n",
K! pch_char(old), pch_char(new));
K #endif
K! my_exit(1);
K! }
K! else if (pch_char(new) == '!') {
K! copy_till(where + old - 1);
K! if (R_do_defines) {
K! fputs(not_defined, ofp);
K! def_state = IN_IFNDEF;
K }
K! while (pch_char(old) == '!') {
K if (R_do_defines) {
K! fputs(pfetch(old), ofp);
K }
K! last_frozen_line++;
K old++;
K+ }
K+ if (R_do_defines) {
K+ fputs(else_defined, ofp);
K+ def_state = IN_ELSE;
K+ }
K+ while (pch_char(new) == '!') {
K+ fputs(pfetch(new), ofp);
K new++;
K+ }
K+ }
K+ else {
K+ assert(pch_char(new) == ' ');
K+ old++;
K+ new++;
K+ if (R_do_defines && def_state != OUTSIDE) {
K+ fputs(end_defined, ofp);
K+ def_state = OUTSIDE;
K }
K }
K }
K if (new <= pat_end && pch_char(new) == '+') {
K copy_till(where + old - 1);
K if (R_do_defines) {
K if (def_state == OUTSIDE) {
K fputs(if_defined, ofp);
K def_state = IN_IFDEF;
K }
SHAR_EOF
sed 's/^K//' << \SHAR_EOF > file1
Kline 1
Kline 2
Kline 3
Kline 4
Kline 5
Kline 6
Kline 7
Kline 8
Kline 9
Kline 10
SHAR_EOF
sed 's/^K//' << \SHAR_EOF > file2
Kline 1
Kline 2
Kline 3
Kline 3a
Kline 3b
Kline 4
Kline 5
Kline 6
Kline 7
Kline 7a
Kline 8
Kline 9a
Kline 10
SHAR_EOF
sed 's/^K//' << \SHAR_EOF > Makefile
K
K#
K# handy Makefile to test patch before and after the ksb fix
K#
K
Kall: file1 file2 shouldbe1 shouldbe2
K cmp -s shouldbe1 file1 && echo defined side OK
K cmp -s shouldbe2 file2 && echo undefined side OK
K
Kclean: FRC
K rm -f shouldbe[12] file1.patch test test.orig test~
K
K
Kfile1.patch: file1 file2
K -diff -c file1 file2 >file1.patch
K
Ktest: file1 file1.patch
K cp file1 test
K patch -DKSB test <file1.patch
K
Kshouldbe1: test
K -unifdef -UKSB test >shouldbe1
K
Kshouldbe2: test
K -unifdef -DKSB test >shouldbe2
K
K
KFRC:
SHAR_EOF
sed 's/^K//' << \SHAR_EOF > broken.script
KScript started on Tue Sep 4 13:38:28 1990
Kmentor /userb/ksb/uxg/bug 358 make
K diff -c file1 file2 >file1.patch
K*** Error code 1 (ignored)
K cp file1 test
K patch -DKSB test <file1.patch
KHmm... Looks like a new-style context diff to me...
KThe text leading up to this was:
K--------------------------
K|*** file1 Tue Sep 4 13:01:09 1990
K|--- file2 Tue Sep 4 13:01:36 1990
K--------------------------
KPatching file test using Plan A...
KHunk #1 succeeded at 1.
Kdone
K unifdef -UKSB test >shouldbe1
Kunifdef: Error in test line 4: Premature EOF in ifdef.
K*** Error code 2
KMake: . Stop.
Kmentor /userb/ksb/uxg/bug 359 exit
K
Kscript done on Tue Sep 4 13:38:36 1990
SHAR_EOF
sed 's/^K//' << \SHAR_EOF > OK.script
KScript started on Tue Sep 4 13:44:58 1990
Kmentor /userb/ksb/uxg/bug 387 make clean
K rm -f shouldbe[12] file1.patch test test.orig test~
Kmentor /userb/ksb/uxg/bug 388 make
K diff -c file1 file2 >file1.patch
K*** Error code 1 (ignored)
K cp file1 test
K patch -DKSB test <file1.patch
KHmm... Looks like a new-style context diff to me...
KThe text leading up to this was:
K--------------------------
K|*** file1 Tue Sep 4 13:01:09 1990
K|--- file2 Tue Sep 4 13:01:36 1990
K--------------------------
KPatching file test using Plan A...
KHunk #1 succeeded at 1.
Kdone
K unifdef -UKSB test >shouldbe1
K*** Error code 1 (ignored)
K unifdef -DKSB test >shouldbe2
K*** Error code 1 (ignored)
K cmp -s shouldbe1 file1 && echo defined side OK
Kdefined side OK
K cmp -s shouldbe2 file2 && echo undefined side OK
Kundefined side OK
Kmentor /userb/ksb/uxg/bug 389 exit
K
Kscript done on Tue Sep 4 13:45:11 1990
SHAR_EOF
cd ..
# End of shell archive
exit 0
More information about the Comp.sources.bugs
mailing list