gbranden pushed a commit to branch master
in repository groff.

commit 852d2209bd892a71be36fec55efb7dac28109a22
Author: G. Branden Robinson <[email protected]>
AuthorDate: Sat Aug 17 18:32:51 2024 -0500

    [troff]: Fix Savannah #63202 (2/3).
    
    * src/roff/troff/input.cpp (do_overstrike, do_bracket, do_name_test):
      (do_zero_width, do_width, do_device_control): When throwing a warning
      diagnostic about a mismatched escape sequence delimiter (in an escape
      sequence that accepts a newline as a delimiter(!)), say what what we
      were expecting and what we got instead.
    
    $ printf '\\o\nabc' | build/test-groff -a -ww
    troff: warning: missing closing delimiter in overstrike escape sequence; 
expected a newline, got end of input
    <beginning of page>
    
    $ printf '\\b\nabc' | build/test-groff -a -ww
    troff: warning: missing closing delimiter in bracket-building escape 
sequence; expected a newline, got end of input
    <beginning of page>
    
    $ printf '\\A\nabc' | build/test-groff -a -ww
    troff: warning: missing closing delimiter in identifier validation escape 
sequence; expected a newline, got end of input
    <beginning of page>
    1
    
    $ printf '\\Z\nabc' | build/test-groff -a -ww
    troff: warning: missing closing delimiter in zero-width escape sequence; 
expected a newline, got end of input
    <beginning of page>
    
    $ printf '\\w\nabc' | build/test-groff -a -ww
    troff: warning: missing closing delimiter in width computation escape 
sequence (got end of input)
    <beginning of page>
    13880
    $ printf '\\X\nabc' | build/test-groff -a -ww
    troff: warning: missing closing delimiter in device control escape sequence 
(got end of input)
    <beginning of page>
    
    We don't see output from most of the cases above because the
    "approximate output" option `-a` doesn't do anything to render
    overstrike, bracket, zero-width output, or device control nodes.  The
    "abc" characters are visible in device-independent output `-Z` and of
    course, e.g., PostScript.
---
 ChangeLog                |  5 +++--
 src/roff/troff/input.cpp | 51 +++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index aa7e29766..db721ffad 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,8 +4,9 @@
        escape sequence delimiter, say what what we were expecting and
        what we got instead.
 
-       * src/roff/troff/input.cpp (read_delimited_number, get_line_arg)
-       (do_register):
+       * src/roff/troff/input.cpp (do_overstrike, do_bracket)
+       (do_name_test, do_zero_width, do_width, do_device_control)
+       (read_delimited_number, get_line_arg, do_register):
        * src/roff/troff/reg.cpp (inline_define_register [0]): Do it.
 
        Fixes <https://savannah.gnu.org/bugs/?63202>.
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index 1cb5650c7..b8dc125aa 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -1577,8 +1577,14 @@ node *do_overstrike()
       break;
     }
     if (tok.is_eof()) {
+      // token::description() writes to static, class-wide storage, so
+      // we must allocate a copy of it before issuing the next
+      // diagnostic.
+      char *delimdesc = strdup(start_token.description());
       warning(WARN_DELIM, "missing closing delimiter in overstrike"
-            " escape sequence (got %1)", tok.description());
+             " escape sequence; expected %1, got %2", delimdesc,
+             tok.description());
+      free(delimdesc);
       // Synthesize an input line ending.
       input_stack::push(make_temp_iterator("\n"));
       break;
@@ -1618,9 +1624,14 @@ static node *do_bracket()
       break;
     }
     if (tok.is_eof()) {
+      // token::description() writes to static, class-wide storage, so
+      // we must allocate a copy of it before issuing the next
+      // diagnostic.
+      char *delimdesc = strdup(start_token.description());
       warning(WARN_DELIM, "missing closing delimiter in"
-             " bracket-building escape sequence (got %1)",
-             tok.description());
+             " bracket-building escape sequence; expected %1, got"
+             " %2", delimdesc, tok.description());
+      free(delimdesc);
       // Synthesize an input line ending.
       input_stack::push(make_temp_iterator("\n"));
       break;
@@ -1648,9 +1659,14 @@ static int do_name_test()
   for (;;) {
     tok.next();
     if (tok.is_eof()) {
+      // token::description() writes to static, class-wide storage, so
+      // we must allocate a copy of it before issuing the next
+      // diagnostic.
+      char *delimdesc = strdup(start_token.description());
       warning(WARN_DELIM, "missing closing delimiter in identifier"
-             " validation escape sequence (got %1)",
-             tok.description());
+             " validation escape sequence; expected %1, got %2",
+             delimdesc, tok.description());
+      free(delimdesc);
       // Synthesize an input line ending.
       input_stack::push(make_temp_iterator("\n"));
       break;
@@ -1746,8 +1762,14 @@ static node *do_zero_width()
   for (;;) {
     tok.next();
     if (tok.is_eof()) {
+      // token::description() writes to static, class-wide storage, so
+      // we must allocate a copy of it before issuing the next
+      // diagnostic.
+      char *delimdesc = strdup(start_token.description());
       warning(WARN_DELIM, "missing closing delimiter in zero-width"
-             " escape sequence (got %1)", tok.description());
+             " escape sequence; expected %1, got %2", delimdesc,
+             tok.description());
+      free(delimdesc);
       // Synthesize an input line ending.
       input_stack::push(make_temp_iterator("\n"));
       break;
@@ -5482,9 +5504,14 @@ static void do_width()
   for (;;) {
     tok.next();
     if (tok.is_eof()) {
+      // token::description() writes to static, class-wide storage, so
+      // we must allocate a copy of it before issuing the next
+      // diagnostic.
+      char *delimdesc = strdup(start_token.description());
       warning(WARN_DELIM, "missing closing delimiter in width"
-             " computation escape sequence (got %1)",
-             tok.description());
+             "computation escape sequence; expected %1, got %2",
+             delimdesc, tok.description());
+      free(delimdesc);
       // Synthesize an input line ending.
       input_stack::push(make_temp_iterator("\n"));
       break;
@@ -5703,8 +5730,14 @@ static node *do_device_control() // \X
       break;
     }
     if (tok.is_eof()) {
+      // token::description() writes to static, class-wide storage, so
+      // we must allocate a copy of it before issuing the next
+      // diagnostic.
+      char *delimdesc = strdup(start_token.description());
       warning(WARN_DELIM, "missing closing delimiter in device control"
-             " escape sequence (got %1)", tok.description());
+             " escape sequence; expected %1, got %2", delimdesc,
+             tok.description());
+      free(delimdesc);
       // Synthesize an input line ending.
       input_stack::push(make_temp_iterator("\n"));
       break;

_______________________________________________
Groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit

Reply via email to