groff-commit
[Top][All Lists]
Advanced

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

[groff] 32/33: [eqn]: Improve unprintable character diagnostics.


From: G. Branden Robinson
Subject: [groff] 32/33: [eqn]: Improve unprintable character diagnostics.
Date: Sun, 16 Oct 2022 15:52:21 -0400 (EDT)

gbranden pushed a commit to branch master
in repository groff.

commit 135aead3da46eb12080c3a673db9e8e5b859ebd9
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
AuthorDate: Sat Oct 15 11:34:34 2022 -0500

    [eqn]: Improve unprintable character diagnostics.
    
    [eqn]: Improve diagnostics involving unprintable characters.
    
    * src/preproc/eqn/main.cpp (input_char_description): New function
      constructs a human-readable string describing characters.
    
      (read_line, inline_equation, main): Call new function and adjust
      diagnostic message wording to accommodate the phrase it returns.
    
    Fixes <https://savannah.gnu.org/bugs/?63218>.
    
    groff 1.22.4:
    
    $ echo | `printf 'eqn -dx\032\n'` >/dev/null
    eqn: bad delimiter ''
    $ printf '\001 x = x + 1\n' | `printf 'eqn -d\001\177\n'` > /dev/null
    eqn:<standard input>:2: fatal error: unterminated '' at line 1, looking for 
''
    $ printf '\001 x = x + 1\n' | `printf 'eqn -N -d\001\177\n'` > /dev/null
    eqn:<standard input>:1: missing ''
    
    groff now:
    
    $ echo | `printf './build/eqn -dx\032\n'` >/dev/null
    ./build/eqn: error: invalid delimiter (character code 26) in '-d' option 
argument
    $ printf '\001 x = x + 1\n' | `printf './build/eqn -d\001\177\n'` > 
/dev/null
    ./build/eqn:<standard input>:2: fatal error: unterminated inline equation; 
started with a leader character, expecting a delete character
    $ printf '\001 x = x + 1\n' | `printf './build/eqn -N -d\001\177\n'` > 
/dev/null
    ./build/eqn:<standard input>:1: error: unterminated inline equation; 
started with a leader character, expecting a delete character
---
 ChangeLog                | 12 ++++++++++++
 src/preproc/eqn/main.cpp | 50 +++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 53 insertions(+), 9 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index bcb0e53d2..97061669f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2022-10-15  G. Branden Robinson <g.branden.robinson@gmail.com>
+
+       [eqn]: Improve diagnostics involving unprintable characters.
+
+       * src/preproc/eqn/main.cpp (input_char_description): New
+       function constructs a human-readable string describing
+       characters.
+       (read_line, inline_equation, main): Call new function and adjust
+       diagnostic message wording to accommodate the phrase it returns.
+
+       Fixes <https://savannah.gnu.org/bugs/?63218>.
+
 2022-10-14  G. Branden Robinson <g.branden.robinson@gmail.com>
 
        [eqn]: Improve diagnostics.
diff --git a/src/preproc/eqn/main.cpp b/src/preproc/eqn/main.cpp
index 95023f5af..536f256a9 100644
--- a/src/preproc/eqn/main.cpp
+++ b/src/preproc/eqn/main.cpp
@@ -46,6 +46,36 @@ int html = 0;
 int xhtml = 0;
 eqnmode_t output_format;
 
+static const char *input_char_description(int c)
+{
+  switch (c) {
+  case '\001':
+    return "a leader character";
+  case '\n':
+    return "a newline character";
+  case '\b':
+    return "a backspace character";
+  case '\t':
+    return "a tab character";
+  case ' ':
+    return "a space character";
+  case '\177':
+    return "a delete character";
+  }
+  size_t bufsz = sizeof "character code " + INT_DIGITS + 1;
+  // repeat expression; no VLAs in ISO C++
+  static char buf[sizeof "character code " + INT_DIGITS + 1];
+  (void) memset(buf, 0, bufsz);
+  if (csprint(c)) {
+    buf[0] = '\'';
+    buf[1] = c;
+    buf[2] = '\'';
+    return buf;
+  }
+  (void) sprintf(buf, "character code %d", c);
+  return buf;
+}
+
 int read_line(FILE *fp, string *p)
 {
   p->clear();
@@ -54,7 +84,7 @@ int read_line(FILE *fp, string *p)
     if (!is_invalid_input_char(c))
       *p += char(c);
     else
-      error("invalid input character code '%1'", c);
+      error("invalid input (%1)", input_char_description(c));
     if (c == '\n')
       break;
   }
@@ -151,8 +181,9 @@ static int inline_equation(FILE *fp, string &linebuf, 
string &str)
   inline_flag = 1;
   for (;;) {
     if (no_newline_in_delim_flag && strchr(start + 1, end_delim) == 0) {
-      error("unterminated inline equation; started with '%1',"
-           " expecting '%2'", start_delim, end_delim);
+      error("unterminated inline equation; started with %1,"
+           " expecting %2", input_char_description(start_delim),
+           input_char_description(end_delim));
       char *nl = strchr(start + 1, '\n');
       if (nl != 0)
        *nl = '\0';
@@ -174,8 +205,9 @@ static int inline_equation(FILE *fp, string &linebuf, 
string &str)
       }
       str += ptr;
       if (!read_line(fp, &linebuf))
-       fatal("unterminated inline equation; started with '%1',"
-             " expecting '%2'", start_delim, end_delim);
+       fatal("unterminated inline equation; started with %1,"
+             " expecting %2", input_char_description(start_delim),
+             input_char_description(end_delim));
       linebuf += '\0';
       ptr = &linebuf[0];
     }
@@ -306,11 +338,11 @@ int main(int argc, char **argv)
       if (optarg[0] == '\0' || optarg[1] == '\0')
        error("'-d' option requires a two-character argument");
       else if (is_invalid_input_char(optarg[0]))
-       error("invalid delimiter '%1' in '-d' option argument",
-             optarg[0]);
+       error("invalid delimiter (%1) in '-d' option argument",
+             input_char_description(optarg[0]));
       else if (is_invalid_input_char(optarg[1]))
-       error("invalid delimiter '%1' in '-d' option argument",
-             optarg[1]);
+       error("invalid delimiter (%1) in '-d' option argument",
+             input_char_description(optarg[1]));
       else {
        start_delim = optarg[0];
        end_delim = optarg[1];



reply via email to

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