GNU bug report logs - #15774
rfc/pre-patch: automatic diff width from the terminal

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: diffutils; Severity: wishlist; Reported by: "Dr. David Alan Gilbert" <dave@HIDDEN>; Keywords: patch; dated Fri, 1 Nov 2013 01:32:02 UTC; Maintainer for diffutils is bug-diffutils@HIDDEN.
Severity set to 'wishlist' from 'normal' Request was from Paul Eggert <eggert@HIDDEN> to control <at> debbugs.gnu.org. Full text available.
Added tag(s) patch. Request was from Paul Eggert <eggert@HIDDEN> to control <at> debbugs.gnu.org. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 1 Nov 2013 01:31:09 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Oct 31 21:31:09 2013
Received: from localhost ([127.0.0.1]:55980 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.80)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1Vc3Zs-0002tq-PY
	for submit <at> debbugs.gnu.org; Thu, 31 Oct 2013 21:31:09 -0400
Received: from eggs.gnu.org ([208.118.235.92]:47562)
 by debbugs.gnu.org with esmtp (Exim 4.80)
 (envelope-from <dg@HIDDEN>) id 1Vc37u-0002Bu-Tj
 for submit <at> debbugs.gnu.org; Thu, 31 Oct 2013 21:02:15 -0400
Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
 (envelope-from <dg@HIDDEN>) id 1Vc37k-0004Oc-0u
 for submit <at> debbugs.gnu.org; Thu, 31 Oct 2013 21:02:09 -0400
X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org
X-Spam-Level: *
X-Spam-Status: No, score=1.8 required=5.0 tests=BAYES_50,HK_NAME_DR
 autolearn=disabled version=3.3.2
Received: from lists.gnu.org ([2001:4830:134:3::11]:52183)
 by eggs.gnu.org with esmtp (Exim 4.71)
 (envelope-from <dg@HIDDEN>) id 1Vc37j-0004OY-UM
 for submit <at> debbugs.gnu.org; Thu, 31 Oct 2013 21:02:03 -0400
Received: from eggs.gnu.org ([2001:4830:134:3::10]:49257)
 by lists.gnu.org with esmtp (Exim 4.71)
 (envelope-from <dg@HIDDEN>) id 1Vc37e-0003sj-W3
 for bug-diffutils@HIDDEN; Thu, 31 Oct 2013 21:02:03 -0400
Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
 (envelope-from <dg@HIDDEN>) id 1Vc37U-0004Lc-P7
 for bug-diffutils@HIDDEN; Thu, 31 Oct 2013 21:01:58 -0400
Received: from mx.treblig.org ([80.68.94.177]:57921)
 by eggs.gnu.org with esmtp (Exim 4.71)
 (envelope-from <dg@HIDDEN>) id 1Vc37U-0004LX-JG
 for bug-diffutils@HIDDEN; Thu, 31 Oct 2013 21:01:48 -0400
Received: from dg by mx.treblig.org with local (Exim 4.80)
 (envelope-from <dg@HIDDEN>) id 1Vc2tA-0001I5-Tq
 for bug-diffutils@HIDDEN; Fri, 01 Nov 2013 00:47:00 +0000
Date: Fri, 1 Nov 2013 00:47:00 +0000
From: "Dr. David Alan Gilbert" <dave@HIDDEN>
To: bug-diffutils@HIDDEN
Subject: rfc/pre-patch: automatic diff width from the terminal
Message-ID: <20131101004700.GD24298@gallifrey>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
X-Chocolate: 70 percent or better cocoa solids preferably
X-Operating-System: Linux/3.2.2-kvm-i386-20120306 (i686)
X-Uptime: 00:28:38 up 4 days, 9:21, 2 users, load average: 0.00, 0.01, 0.05
User-Agent: Mutt/1.5.21 (2010-09-15)
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic]
X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address
 (bad octet value).
X-Received-From: 2001:4830:134:3::11
X-Spam-Score: -4.0 (----)
X-Debbugs-Envelope-To: submit
X-Mailman-Approved-At: Thu, 31 Oct 2013 21:31:06 -0400
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <http://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <http://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <http://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -4.0 (----)

Hi,
  The patch below is a rough 1st cut of an attempt to make diff use the
terminal width as the default width.

It pinches the code from coreutils ls.c that does the same thing, and so
uses the terminal width, failing that reads the COLUMNS env variable,
and failing that falls back to the default (all of which can still be
over ridden with -w/-W).

  Other than glue, all the actual code comes straight out of ls.c

Now given that this is a first cut, is this basically the right approach,
and are people happy to change the default behaviour?

I know that there are some things I need to do:
  - figure out the autoconf magic so it works when termios isn't available
    and the 'WINSIZE_IN_PTEM' def that coreutils picks up
  - Probably more docs fixing
  - some tests
  - (Copyright assignment? Or is the code so close to coreutils it isn't
an issue?)

It's the side by side diff that I'm most interested in this for,
having nice wide cheap 1920 monitors is great for side by side diffs
and I normally want to fill whatever terminal I have.

Thanks in advance for all comments,

Dave

-----------------------
diff --git a/bootstrap.conf b/bootstrap.conf
index ac85adf..10be643 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -56,6 +56,7 @@ mkstemp
 mktime
 progname
 propername
+quotearg
 rawmemchr
 readme-release
 regex
@@ -82,6 +83,7 @@ wcwidth
 xalloc
 xfreopen
 xreadlink
+xstrtol
 xstrtoumax
 xvasprintf
 '
diff --git a/doc/diffutils.texi b/doc/diffutils.texi
index 2d238dc..09dae68 100644
--- a/doc/diffutils.texi
+++ b/doc/diffutils.texi
@@ -3967,8 +3967,10 @@ Ignore white space when comparing lines.  @xref{White Space}.
 
 @item -W @var{columns}
 @itemx --width=@var{columns}
-Output at most @var{columns} (default 130) print columns per line in
-side by side format.  @xref{Side by Side Format}.
+Output at most @var{columns} print columns per line in side by side format.
+The default is taken from the terminal settings if possible; otherwise the
+environment variable @env{COLUMNS} is used if it is set; otherwise the default
+is 130 columns.  @xref{Side by Side Format}.
 
 @item -x @var{pattern}
 @itemx --exclude=@var{pattern}
diff --git a/src/diff.c b/src/diff.c
index 50d0365..8d283d3 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -34,13 +34,23 @@
 #include <hard-locale.h>
 #include <prepargs.h>
 #include <progname.h>
+#include <quotearg.h>
 #include <sh-quote.h>
 #include <stat-time.h>
+#include <xstrtol.h>
 #include <timespec.h>
 #include <version-etc.h>
 #include <xalloc.h>
 #include <xreadlink.h>
 #include <binary-io.h>
+#include <termios.h>
+
+#include <sys/ioctl.h>
+#ifdef WINSIZE_IN_PTEM
+# include <sys/stream.h>
+# include <sys/ptem.h>
+#endif
+
 
 /* The official name of this program (e.g., no 'g' prefix).  */
 #define PROGRAM_NAME "diff"
@@ -255,6 +265,51 @@ exclude_options (void)
 {
   return EXCLUDE_WILDCARDS | (ignore_file_name_case ? FNM_CASEFOLD : 0);
 }
+
+/* Return the number of columns to use, based on:
+ *   a default (130)
+ *   the COLUMNS env variable
+ *   the terminal width
+ * The code is based on coreutils/ls.c - except diff has always defaulted
+ * to 130 rather than ls's 80.   I'd probably say it's better to allow
+ * overriding terminal width by COLUMNS but decided to keep it consistent
+ * with coreutils.
+ */
+static size_t
+get_default_width (void)
+{
+  size_t line_length = 130;
+
+  char const *p = getenv ("COLUMNS");
+  if (p && *p)
+    {
+      unsigned long int tmp_ulong;
+      if (xstrtoul (p, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK
+          && 0 < tmp_ulong && tmp_ulong <= SIZE_MAX)
+        {
+          line_length = tmp_ulong;
+        }
+      else
+        {
+          error (0, 0,
+             _("ignoring invalid width in environment variable COLUMNS: %s"),
+                 quotearg (p));
+        }
+   }
+
+#ifdef TIOCGWINSZ
+  {
+    struct winsize ws;
+
+    if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) != -1
+        && 0 < ws.ws_col && ws.ws_col == (size_t) ws.ws_col)
+      line_length = ws.ws_col;
+  }
+#endif
+
+  return line_length;
+}
+
 
 int
 main (int argc, char **argv)
@@ -668,7 +723,7 @@ main (int argc, char **argv)
   if (! tabsize)
     tabsize = 8;
   if (! width)
-    width = 130;
+    width = get_default_width ();
 
   {
     /* Maximize first the half line width, and then the gutter width,

-----------------------
-- 
 -----Open up your eyes, open up your mind, open up your code -------   
/ Dr. David Alan Gilbert    |       Running GNU/Linux       | Happy  \ 
\ gro.gilbert @ treblig.org |                               | In Hex /
 \ _________________________|_____ http://www.treblig.org   |_______/




Acknowledgement sent to "Dr. David Alan Gilbert" <dave@HIDDEN>:
New bug report received and forwarded. Copy sent to bug-diffutils@HIDDEN. Full text available.
Report forwarded to bug-diffutils@HIDDEN:
bug#15774; Package diffutils. Full text available.
Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.
Last modified: Fri, 31 Oct 2014 17:00:04 UTC

GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997 nCipher Corporation Ltd, 1994-97 Ian Jackson.