gbranden pushed a commit to branch master
in repository groff.

commit 12c11d3bfa4b81f266125a95360a6b18c7eaf1ad
Author: G. Branden Robinson <[email protected]>
AuthorDate: Tue Apr 21 11:07:39 2026 -0500

    src/roff/troff/input.cpp: Fix Savannah #68260.
    
    * src/roff/troff/input.cpp: Handle brace escape sequences better.  In
      AT&T troff, a brace escape sequence not occurring in a macro
      definition is discarded when read in copy mode--make GNU troff do
      likewise.  When occurring in a macro definition, it _is_ being read in
      copy mode and must be preserved, so retain existing behavior.
      Unfortunately, the datum "we are defining a macro right now" was not
      consistently being passed from `do_define_macro()` to
      `read_character_in_copy_mode()`, so fix that problem too.  Fixing one
      of these without the other produces chaos in the formatter and wrecks
      a build; couple them.
    
      (read_character_in_copy_mode): Return an `ESCAPE_{LEFT,RIGHT}_BRACE`
      encoded token (character code) only if `is_defining_macro`.
    
      (do_define_macro): Supply `true` parameter (`is_defining_macro`) in
      _all_ `read_character_in_copy_mode()` calls.
    
    Fixes <https://savannah.gnu.org/bugs/?68260>.  Problems appear mostly to
    date back to groff's birth: see groff 1.01,[1] "input/troff.cc", lines
    741-746, 3113, and 3119.  Commit 5ba4c4ddb3, 2001-11-16, added another
    instance of `read_character_in_copy_mode()` (then called `get_copy()`)
    being given only one argument.
    
    [1] https://minnie.tuhs.org/cgi-bin/utree.pl?file=Net2/usr/src/usr.bin/\
        groff/troff/input.cc
---
 ChangeLog                | 28 ++++++++++++++++++++++++++++
 src/roff/troff/input.cpp | 14 +++++++++-----
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5dd0f7588..f6aae51f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2026-04-21  G. Branden Robinson <[email protected]>
+
+       * src/roff/troff/input.cpp: Handle brace escape sequences
+       better.  In AT&T troff, a brace escape sequence not occurring in
+       a macro definition is discarded when read in copy mode--make GNU
+       troff do likewise.  When occurring in a macro definition, it
+       _is_ being read in copy mode and must be preserved, so retain
+       existing behavior.  Unfortunately, the datum "we are defining
+       a macro right now" was not consistently being passed from
+       `do_define_macro()` to `read_character_in_copy_mode()`, so fix
+       that problem too.  Fixing one of these without the other
+       produces chaos in the formatter and wrecks a build; couple them.
+       (read_character_in_copy_mode): Return an
+       `ESCAPE_{LEFT,RIGHT}_BRACE` encoded token (character code) only
+       if `is_defining_macro`.
+       (do_define_macro): Supply `true` parameter (`is_defining_macro`)
+       in _all_ `read_character_in_copy_mode()` calls.
+
+       Fixes <https://savannah.gnu.org/bugs/?68260>.  Problems appear
+       mostly to date back to groff's birth: see groff 1.01,[1]
+       "input/troff.cc", lines 741-746, 3113, and 3119.  Commit
+       5ba4c4ddb3, 2001-11-16, added another instance of
+       `read_character_in_copy_mode()` (then called `get_copy()`) being
+       given only one argument.
+
+       [1] https://minnie.tuhs.org/cgi-bin/utree.pl?file=Net2/usr/src/\
+       usr.bin/groff/troff/input.cc
+
 2026-04-20  G. Branden Robinson <[email protected]>
 
        [groff]: Regression-test Savannah #68257.
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index bf256e980..57a49b1f8 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -1344,10 +1344,14 @@ static int read_character_in_copy_mode(node **nd,
       return ESCAPE_CIRCUMFLEX;
     case '{':
       (void) input_stack::get(0 /* nullptr */);
-      return ESCAPE_LEFT_BRACE;
+      if (is_defining_macro)
+       return ESCAPE_LEFT_BRACE;
+      break;
     case '}':
       (void) input_stack::get(0 /* nullptr */);
-      return ESCAPE_RIGHT_BRACE;
+      if (is_defining_macro)
+       return ESCAPE_RIGHT_BRACE;
+      break;
     case '`':
       (void) input_stack::get(0 /* nullptr */);
       return ESCAPE_LEFT_QUOTE;
@@ -5604,12 +5608,12 @@ static void do_define_macro(define_mode mode, 
calling_mode calling,
       // see if it matches term
       int i = 0;
       if (s[0] != '\0') {
-       while (((d = read_character_in_copy_mode(&n)) == ' ')
+       while (((d = read_character_in_copy_mode(&n, true /* is_defining_macro 
*/)) == ' ')
               || ('\t' == d))
          ;
        if (s[0] == d) {
          for (i = 1; s[i] != '\0'; i++) {
-           d = read_character_in_copy_mode(&n);
+           d = read_character_in_copy_mode(&n, true /* is_defining_macro */);
            if (s[i] != d)
              break;
          }
@@ -5617,7 +5621,7 @@ static void do_define_macro(define_mode mode, 
calling_mode calling,
       }
       if (s[i] == '\0'
          && (((i == 2) && want_att_compat)
-             || ((d = read_character_in_copy_mode(&n)) == ' ')
+             || ((d = read_character_in_copy_mode(&n, true /* 
is_defining_macro */)) == ' ')
              || (d == '\n'))) { // we found it
        if (d == '\n')
          tok.make_newline();

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

Reply via email to