* src/roff/troff/input.cpp (do_overstrike, do_bracket)
  (do_name_test, do_expr_test, do_zero_width_output, do_width)
  (do_device_extension, read_drawing_command): Prevent emission of
  confusing warning diagnostic when a newline is used (deprecatedly) as
  a delimiter.

Before:

$ printf '.tl 1\n\\o\nA\n' | ./build/test-groff -z -ww
troff:<standard input>:1: warning: using character '1' as a title request 
delimiter is deprecated [-w delim]
troff:<standard input>:2: warning: using a newline as an escape sequence 
delimiter is deprecated [-w delim]
troff:<standard input>:3: warning: missing closing delimiter in overstrike 
escape sequence; expected a newline, got a newline [-w delim]

After:

$ printf '.tl 1\n\\o\nA\n' | ./build/test-groff -z -ww
troff:<standard input>:1: warning: using character '1' as a title request 
delimiter is deprecated [-w delim]
troff:<standard input>:2: warning: using a newline as an escape sequence 
delimiter is deprecated [-w delim]
---
 ChangeLog                |  8 ++++++++
 src/roff/troff/input.cpp | 40 ++++++++++++++++++++++++++++++++--------
 2 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4ca07b1de..56d007962 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2026-10-25  G. Branden Robinson <[email protected]>
+
+       * src/roff/troff/input.cpp (do_overstrike, do_bracket)
+       (do_name_test, do_expr_test, do_zero_width_output, do_width)
+       (do_device_extension, read_drawing_command): Prevent emission of
+       confusing warning diagnostic when a newline is used
+       {deprecatedly} as a delimiter.
+
 2026-10-25  G. Branden Robinson <[email protected]>
 
        * src/roff/troff/input.cpp (is_char_usable_as_delimiter): Revise
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index 98e39f1ed..eb3c316d6 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -1799,7 +1799,10 @@ node *do_overstrike() // \o
 #endif
   for (;;) {
     tok.next();
-    if (tok.is_newline() || tok.is_eof()) {
+    // TODO: Simplify to the following when `TODO` above is done.
+    // if (tok.is_newline() || tok.is_eof()) {
+    if ((!start_token.is_newline() && tok.is_newline()) || tok.is_eof())
+    {
       // token::description() writes to static, class-wide storage, so
       // we must allocate a copy of it before issuing the next
       // diagnostic.
@@ -1866,7 +1869,10 @@ static node *do_bracket() // \b
   int start_level = input_stack::get_level();
   for (;;) {
     tok.next();
-    if (tok.is_newline() || tok.is_eof()) {
+    // TODO: Simplify to the following when `TODO` above is done.
+    // if (tok.is_newline() || tok.is_eof()) {
+    if ((!start_token.is_newline() && tok.is_newline()) || tok.is_eof())
+    {
       // token::description() writes to static, class-wide storage, so
       // we must allocate a copy of it before issuing the next
       // diagnostic.
@@ -1922,7 +1928,10 @@ static const char *do_name_test() // \A
   bool got_some_char = false;
   for (;;) {
     tok.next();
-    if (tok.is_newline() || tok.is_eof()) {
+    // TODO: Simplify to the following when `TODO` above is done.
+    // if (tok.is_newline() || tok.is_eof()) {
+    if ((!start_token.is_newline() && tok.is_newline()) || tok.is_eof())
+    {
       // token::description() writes to static, class-wide storage, so
       // we must allocate a copy of it before issuing the next
       // diagnostic.
@@ -1978,7 +1987,10 @@ static const char *do_expr_test() // \B
   // There may be garbage after the expression but before the closing
   // delimiter.  Eat it.
   for (;;) {
-    if (tok.is_newline() || tok.is_eof()) {
+    // TODO: Simplify to the following when `TODO` above is done.
+    // if (tok.is_newline() || tok.is_eof()) {
+    if ((!start_token.is_newline() && tok.is_newline()) || tok.is_eof())
+    {
       char *delimdesc = strdup(start_token.description());
       warning(WARN_DELIM, "missing closing delimiter in numeric"
              " expression validation escape sequence; expected %1,"
@@ -2057,7 +2069,10 @@ static node *do_zero_width_output() // \Z
   int start_level = input_stack::get_level();
   for (;;) {
     tok.next();
-    if (tok.is_newline() || tok.is_eof()) {
+    // TODO: Simplify to the following when `TODO` above is done.
+    // if (tok.is_newline() || tok.is_eof()) {
+    if ((!start_token.is_newline() && tok.is_newline()) || tok.is_eof())
+    {
       // token::description() writes to static, class-wide storage, so
       // we must allocate a copy of it before issuing the next
       // diagnostic.
@@ -6696,7 +6711,10 @@ static void do_width() // \w
   curenv = &env;
   for (;;) {
     tok.next();
-    if (tok.is_newline() || tok.is_eof()) {
+    // TODO: Simplify to the following when `TODO` above is done.
+    // if (tok.is_newline() || tok.is_eof()) {
+    if ((!start_token.is_newline() && tok.is_newline()) || tok.is_eof())
+    {
       // token::description() writes to static, class-wide storage, so
       // we must allocate a copy of it before issuing the next
       // diagnostic.
@@ -7021,7 +7039,10 @@ static node *do_device_extension() // \X
     topdiv->begin_page();
   for (;;) {
     tok.next();
-    if (tok.is_newline() || tok.is_eof()) {
+    // TODO: Simplify to the following when `TODO` above is done.
+    // if (tok.is_newline() || tok.is_eof()) {
+    if ((!start_token.is_newline() && tok.is_newline()) || tok.is_eof())
+    {
       // token::description() writes to static, class-wide storage, so
       // we must allocate a copy of it before issuing the next
       // diagnostic.
@@ -10810,7 +10831,10 @@ static node *read_drawing_command() // \D
          maxpoints *= 2;
          delete[] oldpoint;
        }
-       if (tok.is_newline() || tok.is_eof()) {
+       // TODO: Simplify to the following when `TODO` above is done.
+       // if (tok.is_newline() || tok.is_eof()) {
+       if ((!start_token.is_newline() && tok.is_newline())
+           || tok.is_eof()) {
          // token::description() writes to static, class-wide storage,
          // so we must allocate a copy of it before issuing the next
          // diagnostic.
-- 
2.39.5

Attachment: signature.asc
Description: PGP signature

Reply via email to