Bug 60688 - patch with "-D" option wrongly inserts #ifdef instead of #ifndef
patch with "-D" option wrongly inserts #ifdef instead of #ifndef
Status: CLOSED RAWHIDE
Product: Red Hat Linux
Classification: Retired
Component: patch (Show other bugs)
7.1
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Tim Waugh
Brock Organ
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2002-03-04 15:50 EST by Need Real Name
Modified: 2007-04-18 12:40 EDT (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2002-03-04 15:50:29 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Need Real Name 2002-03-04 15:50:24 EST
From Bugzilla Helper:
User-Agent: Mozilla/4.77 [en] (X11; U; Linux 2.4.2-2 i686)

Description of problem:
When used with the "-D" option, patch-2.5.4-9 will insert "#ifdef" everywhere,
regardless whether "#ifdef" or "#ifndef" would have been correct. I sent bug
reports to bug-patch@gnu.org several months ago, but never saw any responses.
That email address is probably dead.

Version-Release number of selected component (if applicable):


How reproducible:
Always

Steps to Reproduce:
1. Let file1 contain the lines

x
hello
y
z

and let file2 contain the lines

x
y
goodbye
z

2. diff file1 file2 | patch -DTEST file1
	

Actual Results:  file1 now contains:

x
#ifdef TEST
hello
#endif /* TEST */
y
#ifdef TEST
goodbye
#endif /* TEST */
z


Expected Results:  should have been:

x
#ifdef TEST
hello
#endif /* TEST */
y
#ifndef TEST
goodbye
#endif /* not TEST */
z


Additional info:

The following patch fixes the problem:

diff -Naur patch-2.5.4/patch.c patch-2.5.4.fixed/patch.c
--- patch-2.5.4/patch.c Mon Aug 30 02:20:08 1999
+++ patch-2.5.4.fixed/patch.c   Mon Aug 27 20:13:22 2001
@@ -88,8 +88,9 @@
 
 static char const *do_defines; /* symbol to patch using ifdef, ifndef, etc. */
 static char const if_defined[] = "\n#ifdef %s\n";
-static char const not_defined[] = "#ifndef %s\n";
-static char const else_defined[] = "\n#else\n";
+static char const not_defined[] = "\n#ifndef %s\n";
+static char const elseis_defined[] = "\n#else /* %s */\n";
+static char const elsenot_defined[] = "\n#else /* not %s */\n";
 static char const end_defined[] = "\n#endif /* %s */\n";
 
 static int Argc;
@@ -1012,12 +1013,13 @@
                return FALSE;
            if (R_do_defines) {
                if (def_state == OUTSIDE) {
-                   fprintf (fp, outstate->after_newline + if_defined,
+                   fprintf (fp, outstate->after_newline + not_defined,
                             R_do_defines);
                    def_state = IN_IFNDEF;
                }
                else if (def_state == IN_IFDEF) {
-                   fprintf (fp, outstate->after_newline + else_defined);
+                   fprintf (fp, outstate->after_newline + elsenot_defined,
+                            R_do_defines);
                    def_state = IN_ELSE;
                }
                if (ferror (fp))
@@ -1036,7 +1038,8 @@
                return FALSE;
            if (R_do_defines) {
                if (def_state == IN_IFNDEF) {
-                   fprintf (fp, outstate->after_newline + else_defined);
+                   fprintf (fp, outstate->after_newline + elseis_defined,
+                            R_do_defines);
                    def_state = IN_ELSE;
                }
                else if (def_state == OUTSIDE) {
@@ -1067,7 +1070,8 @@
                return FALSE;
            assert (outstate->after_newline);
            if (R_do_defines) {
-              fprintf (fp, not_defined, R_do_defines);
+              fprintf (fp, outstate->after_newline + not_defined, 
+                       R_do_defines);
               if (ferror (fp))
                write_fatal ();
               def_state = IN_IFNDEF;
@@ -1084,7 +1088,8 @@
            while (pch_char (old) == '!');
 
            if (R_do_defines) {
-               fprintf (fp, outstate->after_newline + else_defined);
+               fprintf (fp, outstate->after_newline + elseis_defined,
+                        R_do_defines);
                if (ferror (fp))
                  write_fatal ();
                def_state = IN_ELSE;
@@ -1122,7 +1127,8 @@
                def_state = IN_IFDEF;
            }
            else if (def_state == IN_IFNDEF) {
-               fprintf (fp, outstate->after_newline + else_defined);
+               fprintf (fp, outstate->after_newline + elseis_defined,
+                        R_do_defines);
                def_state = IN_ELSE;
            }
            if (ferror (fp))
Comment 1 Tim Waugh 2002-03-05 04:57:59 EST
The change gives this:

x
#ifndef TEST
hello
#endif /* TEST */
y
#ifdef TEST
goodbye
#endif /* TEST */
z

which is different from the expected results you gave: the sense of 'TEST' is
inverted.  But I think this is the correct behaviour so I've applied the patch.

Thanks!  Fixed package is patch-2.5.4-11.
Comment 2 Need Real Name 2002-03-05 12:11:17 EST
Ah, yes, my mistake. I also think my patch was correct and the "expected
behavior" was reversed.

Note You need to log in before you can comment on or make changes to this bug.