Subject: bug#64485: closed (Re: [bug-diffutils] bug#64485: "diff -y" broken since yesterday)

From: [email-masked] (GNU bug Tracking System)
Date: Wed, 05 Jul 2023 17:41:02 +0000

Your bug report

#64485: "diff -y" broken since yesterday

which was filed against the diffutils package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
64485: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=64485
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: [bug-diffutils] bug#64485: "diff -y" broken since yesterday
From: Paul Eggert <[email-masked]>
To: Bruno Haible <[email-masked]>
Cc: [email-masked]
Date: Wed, 5 Jul 2023 10:40:26 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

Thanks, I installed that.

Subject: "diff -y" broken since yesterday
From: Bruno Haible <[email-masked]>
To: [email-masked]
Date: Wed, 05 Jul 2023 19:30:31 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi Paul,

I'm trying to understand the meaning of 'in_position' and 'out_position' in
function 'print_half_line'. While doing this, I spotted a bug:

$ cat foo1.txt
a
ab
abc
$ cat foo2.txt
ab
abcd
$ src/diff -t -y foo1.txt foo2.txt
a                                                                <
ab                                                                   ab
abc                                                                |  abcd

This is obviously not how it's intended to be. The attached patch fixes it.
The cause is that in the case of a character of width 1, the assignment

  out_position = in_position;

was lost in commit 05cdf3102ef3fb261db311a3e5d090fb63dbc792 (yesterday).
With this patch, the result is again as it should be:

$ src/diff -t -y foo1.txt foo2.txt
a                                                               <
ab                                                                 ab
abc                                                             |  abcd

The patch also improves comments in this function. So that next time,
I (or anyone else) don't spent 30 minutes to understand the difference
between 'in_position' and 'out_position'.

Bruno

>From 9826aa322e65815288ae63c3a0bb81c1c1267cd8 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email-masked]>
Date: Wed, 5 Jul 2023 19:26:52 +0200
Subject: [PATCH] diff: Fix "diff -y" output

This fixes a regression from 2023-07-04.

* src/side.c (print_half_line): Restore the assignment to out_position.
---
 src/side.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/src/side.c b/src/side.c
index 8404c3a..49c7fe5 100644
--- a/src/side.c
+++ b/src/side.c
@@ -66,14 +66,19 @@ tab_from_to (intmax_t from, intmax_t to)
 }
 
 /* Print the text for half an sdiff line.  This means truncate to
-   width observing tabs, and trim a trailing newline.  Return the
-   last column written (not the number of chars).  */
+   OUT_BOUND columns, observing tabs, and trim a trailing newline.
+   Return the presumed column position on the output device after
+   the write (not the number of chars).  */
 
 static intmax_t
 print_half_line (char const *const *line, intmax_t indent, intmax_t out_bound)
 {
   FILE *out = outfile;
+  /* IN_POSITION is the current column position if we were outputting the
+     entire line, i.e. ignoring OUT_BOUND.  */
   intmax_t in_position = 0;
+  /* OUT_POSITION is the current column position.  It stays <= OUT_BOUND
+     at any moment.  */
   intmax_t out_position = 0;
   char const *text_pointer = line[0];
   char const *text_limit = line[1];
@@ -188,9 +193,14 @@ print_half_line (char const *const *line, intmax_t indent, intmax_t out_bound)
         case 'z': case '{': case '|': case '}': case '~':
 	  if (ckd_add (&in_position, in_position, 1))
 	    return out_position;
-	  FALLTHROUGH;
+	  if (in_position <= out_bound)
+	    {
+	      out_position = in_position;
+	      putc (c, out);
+	    }
+	  break;
 
-	/* Print width already handled.  */
+	/* Print width 0.  */
 	case '\0': case '\f': case '\v':
 	  if (in_position <= out_bound)
 	    putc (c, out);
-- 
2.34.1