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