From 67bff62e315f7589145cf2a361151bb23293a55d Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sat, 21 Sep 2019 08:28:56 +0200 Subject: [PATCH] diagnostics: get the screen width from the terminal * 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 d452172b..45f05270 100644 --- a/m4/.gitignore +++ b/m4/.gitignore @@ -202,3 +202,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 #include #include /* fileno */ +#include #include /* fstat */ +#include + +#ifdef WINSIZE_IN_PTEM +# include +# include +#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=$?