bison-patches
[Top][All Lists]
Advanced

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

[PATCH 11/11] diagnostics: get the screen width from the terminal


From: Akim Demaille
Subject: [PATCH 11/11] diagnostics: get the screen width from the terminal
Date: Sat, 21 Sep 2019 12:00:04 +0200

* bootstrap.conf: We need winsz-ioctl and winsz-termios.
* src/location.c (columns): Use winsize to get the number of
columns.
Code taken from the GNU Coreutils.
* src/location.h, src/location.c (caret_init): New.
* src/complain.c (complain_init): Call it.
* tests/bison.in: Export COLUMNS so that users of tests/bison can
enjoy proper line truncation.
---
 bootstrap.conf |  2 ++
 m4/.gitignore  |  2 ++
 src/complain.c |  2 ++
 src/location.c | 50 ++++++++++++++++++++++++++++++++++++++++----------
 src/location.h |  3 +++
 tests/bison.in |  5 +++++
 6 files changed, 54 insertions(+), 10 deletions(-)

diff --git a/bootstrap.conf b/bootstrap.conf
index 756d798d..8d121f00 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -45,6 +45,8 @@ gnulib_modules='
   unistd unistd-safer unlink unlocked-io
   update-copyright unsetenv verify
   warnings
+  winsz-ioctl
+  winsz-termios
   xalloc
   xalloc-die
   xconcat-filename
diff --git a/m4/.gitignore b/m4/.gitignore
index 286437d0..b816141e 100644
--- a/m4/.gitignore
+++ b/m4/.gitignore
@@ -201,3 +201,5 @@
 /xalloc.m4
 /xsize.m4
 /xstrndup.m4
+/jm-winsz1.m4
+/jm-winsz2.m4
diff --git a/src/complain.c b/src/complain.c
index 75c53192..65a34671 100644
--- a/src/complain.c
+++ b/src/complain.c
@@ -308,6 +308,8 @@ complain_init_color (void)
 void
 complain_init (void)
 {
+  caret_init ();
+
   warnings warnings_default =
     Wconflicts_sr | Wconflicts_rr | Wdeprecated | Wother;
 
diff --git a/src/location.c b/src/location.c
index a7824557..bb2592f9 100644
--- a/src/location.c
+++ b/src/location.c
@@ -25,7 +25,14 @@
 #include <mbswidth.h>
 #include <quotearg.h>
 #include <stdio.h>    /* fileno */
+#include <sys/ioctl.h>
 #include <sys/stat.h> /* fstat */
+#include <termios.h>
+
+#ifdef WINSIZE_IN_PTEM
+# include <sys/stream.h>
+# include <sys/ptem.h>
+#endif
 
 #include "complain.h"
 #include "getargs.h"
@@ -39,7 +46,13 @@ min_int (int a, int b)
   return a < b ? a : b;
 }
 
-/* The terminal width.  */
+static int
+max_int (int a, int b)
+{
+  return a >= b ? a : b;
+}
+
+/* The terminal width.  Not less than 40.  */
 static int
 columns (void)
 {
@@ -50,9 +63,21 @@ columns (void)
       unsigned long ul = strtoul (cp, NULL, 10);
       res = ul < INT_MAX ? ul : INT_MAX;
     }
-  return res;
+  else
+    {
+#ifdef TIOCGWINSZ
+      struct winsize ws;
+      if (ioctl (STDERR_FILENO, TIOCGWINSZ, &ws) != -1
+          && 0 < ws.ws_col && ws.ws_col == (size_t) ws.ws_col)
+        res = ws.ws_col;
+#endif
+    }
+  return max_int (res, 40);
 }
 
+/* Available screen width.  */
+static int screen_width = 80;
+
 /* If BUF is null, add BUFSIZE (which in this case must be less than
    INT_MAX) to COLUMN; otherwise, add mbsnwidth (BUF, BUFSIZE, 0) to
    COLUMN.  If an overflow occurs, return INT_MAX.  */
@@ -235,6 +260,11 @@ caret_set_file (const char *file)
   return caret_info.file;
 }
 
+void caret_init (void)
+{
+  screen_width = columns ();
+}
+
 void
 caret_free (void)
 {
@@ -308,10 +338,17 @@ location_caret (location loc, const char *style, FILE 
*out)
       boundary_compute (&caret_info.pos, mb_ptr (c), mb_len (c));
     }
   int line_len = caret_info.pos.column;
+  /* Go back to the beginning of line.  */
+  fseek (caret_info.file, caret_info.offset, SEEK_SET);
+  /* Reset mbf's internal state.
+     FIXME: should be done in mbfile.  */
+  caret_info.mbfile.eof_seen = 0;
+  caret_info.pos.column = 1;
+
 
   /* Available width.  Eight chars are consumed by the left-margin of
      the quoting lines.  */
-  int width = columns () - 8;
+  int width = screen_width - 8;
   int skip = 0;
   if (width < line_len)
     {
@@ -327,13 +364,6 @@ location_caret (location loc, const char *style, FILE *out)
   if (width < line_len - skip)
     width -= 3;
 
-  /* Go back to the beginning of line.  */
-  fseek (caret_info.file, caret_info.offset, SEEK_SET);
-  /* Reset mbf's internal state.
-     FIXME: should be done in mbfile.  */
-  caret_info.mbfile.eof_seen = 0;
-  caret_info.pos.column = 1;
-
   /* Read the actual line.  Don't update the offset, so that we keep a pointer
      to the start of the line.  */
   {
diff --git a/src/location.h b/src/location.h
index 5926b069..64e80266 100644
--- a/src/location.h
+++ b/src/location.h
@@ -114,6 +114,9 @@ void location_compute (location *loc,
    Warning: uses quotearg's slot 3. */
 unsigned location_print (location loc, FILE *out);
 
+/* Prepare the use of location_caret.  */
+void caret_init (void);
+
 /* Free any allocated resources and close any open file handles that are
    left-over by the usage of location_caret.  */
 void caret_free (void);
diff --git a/tests/bison.in b/tests/bison.in
index 9de13e42..ef623a66 100644
--- a/tests/bison.in
+++ b/tests/bison.in
@@ -34,6 +34,11 @@ if test -t 2; then
     shift
 fi
 
+# We redirect stderr, which breaks the computation of the terminal
+# screen width.  So export COLUMNS to Bison, hoping for the shell to
+# have defined it.
+: ${COLUMNS=132}
+export COLUMNS
 $PREBISON "$abs_top_builddir/src/bison" ${1+"$@"} 2>"$stderr"
 status=$?
 
-- 
2.23.0




reply via email to

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