bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Change "patch" to output unified-diff rejects


From: Paul Eggert
Subject: Re: Change "patch" to output unified-diff rejects
Date: 31 Jan 2004 22:27:03 -0800
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3

Thanks for that patch.  A few questions / points:

Why does abort_hunk_unified test for '!' or '='?  Seems to me that
this should be impossible.  Perhaps just a legacy from the old
abort_hunk routine?

If the hunk contains just 1 "old" or "new" line, the ",count" part of
the header should be surpressed, as "diff" does.  Also, "diff" uses
funky line numbering if the count is 0 (the line number is wrong in my
opinion, but I think it's too late to change this), and "patch" should
be consistent.

Also, the code in abort_hunk_unified has two places where it
outputs "+" lines; it'd be simpler if it had one place.

Also, the change should be documented.

How about this patch instead?

--- NEWS        2003/05/18 08:41:03     1.36
+++ NEWS        2004/02/01 06:22:49
@@ -1,3 +1,6 @@
+* If the input patch is in unified format, any .rej output is now
+  in unified format as well.  Formerly it was in context format.
+
 Changes in versions 2.5.8 and 2.5.9: bug fixes only.
 
 Changes in version 2.5.7:
@@ -216,7 +219,7 @@ Changes in version 2.0.12g8:
 
 
 
-Copyright (C) 1992, 1993, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+Copyright (C) 1992, 1993, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
 Free Software Foundation, Inc.
 
 This file is part of GNU Patch.
--- patch.man   2002/05/25 10:36:44     1.31
+++ patch.man   2004/02/01 06:22:38
@@ -111,8 +111,8 @@ would generate a file name that is too l
 makes the file name too long, then
 .B #
 replaces the file name's last character).
-(The rejected hunk comes out in ordinary context diff form regardless of
-the input patch's form.
+(The rejected hunk comes out in unified diff format if the input patch
+was of that format, otherwise in ordinary context diff form.
 If the input was a normal diff, many of the contexts are simply null.)
 The line numbers on the hunks in the reject file may be different than
 in the patch file: they reflect the approximate location patch thinks the
@@ -1132,7 +1132,7 @@ Copyright
 .ie t \(co
 .el (C)
 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-2000, 2001, 2002 Free Software Foundation, Inc.
+2000, 2001, 2002, 2004 Free Software Foundation, Inc.
 .PP
 Permission is granted to make and distribute verbatim copies of
 this manual provided the copyright notice and this permission notice
--- patch.c     2003/09/11 18:36:17     1.45
+++ patch.c     2004/02/01 06:18:15
@@ -5,7 +5,7 @@
 /* Copyright (C) 1984, 1985, 1986, 1987, 1988 Larry Wall
 
    Copyright (C) 1989, 1990, 1991, 1992, 1993, 1997, 1998, 1999, 2002,
-   2003 Free Software Foundation, Inc.
+   2003, 2004 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -932,10 +932,76 @@ locate_hunk (LINENUM fuzz)
     return 0;
 }
 
-/* We did not find the pattern, dump out the hunk so they can handle it. */
+/* Output a line number range in unified format.  */
 
 static void
-abort_hunk (void)
+print_unidiff_range (FILE *fp, LINENUM start, LINENUM count)
+{
+  char numbuf0[LINENUM_LENGTH_BOUND + 1];
+  char numbuf1[LINENUM_LENGTH_BOUND + 1];
+
+  switch (count)
+    {
+    case 0:
+      fprintf (fp, "%s,0", format_linenum (numbuf0, start - 1));
+      break;
+
+    case 1:
+      fprintf (fp, "%s", format_linenum (numbuf0, start));
+      break;
+
+    default:
+      fprintf (fp, "%s,%s",
+              format_linenum (numbuf0, start),
+              format_linenum (numbuf1, count));
+      break;
+    }
+}
+
+/* Output the rejected patch in unified format.  */
+
+static void
+abort_hunk_unified (void)
+{
+  FILE *fp = rejfp;
+  LINENUM old;
+  LINENUM new;
+  LINENUM lastline = pch_ptrn_lines ();
+  LINENUM pat_end = pch_end ();
+
+  /* Add last_offset to guess the same as the previous successful hunk.  */
+  fprintf (fp, "@@ -");
+  print_unidiff_range (fp, pch_first () + last_offset, lastline);
+  fprintf (fp, " +");
+  print_unidiff_range (fp, pch_newfirst () + last_offset, pch_repl_lines ());
+  fprintf (fp, " @@\n");
+
+  for (old = 1, new = lastline + 2;  ;  old++, new++)
+    {
+      for (;  old <= lastline && pch_char (old) == '-';  old++)
+       {
+         fputc ('-', fp);
+         pch_write_line (old, fp);
+       }
+
+      for (;  new <= pat_end && pch_char (new) == '+';  new++)
+       {
+         fputc ('+', fp);
+         pch_write_line (new, fp);
+       }
+
+      if (! (old <= lastline))
+       break;
+
+      fputc (' ', fp);
+      pch_write_line (old, fp);
+    }
+}
+
+/* Output the rejected patch in context format.  */
+
+static void
+abort_hunk_context (void)
 {
     register LINENUM i;
     register LINENUM pat_end = pch_end ();
@@ -990,6 +1056,17 @@ abort_hunk (void)
     }
 }
 
+/* Output the rejected hunk.  */
+
+static void
+abort_hunk (void)
+{
+  if (diff_type == UNI_DIFF)
+    abort_hunk_unified ();
+  else
+    abort_hunk_context ();
+}
+
 /* We found where to apply it (we hope), so do it. */
 
 static bool




reply via email to

[Prev in Thread] Current Thread [Next in Thread]