gbranden pushed a commit to branch master
in repository groff.
commit aac609bb1f39bdd5b59bb9d4298f4dcc38a8ea54
Author: G. Branden Robinson <[email protected]>
AuthorDate: Sat Jun 7 00:15:20 2025 -0500
[troff]: Loosen choke on prohibited delimiters.
* src/roff/troff/input.cpp (is_char_usable_as_delimiter): Loosen the
choke on prohibited delimiters. To eliminate syntactic ambiguity in
conditional expressions, we need only reject characters that can
_begin_ numeric expressions; those in the set '/*%<>=&:)' cannot, so
permit them as delimiters once more.
(do_overstrike, do_bracket, do_name_test, do_zero_width_output)
(read_size, do_register, do_width, do_device_extension)
(read_drawing_command): Clarify warning diagnostic accordingly.
* doc/groff.texi.in (Compatibility Mode):
* man/groff_diff.7.man (Compatibility mode): Update.
The careful reader will note that the foregoing means that `)` is a
valid (non-ambiguous) delimiter, but `(` is not.
Also clarify comments contemplating timeline of future directions.
---
ChangeLog | 14 +++++
doc/groff.texi.in | 2 +-
man/groff_diff.7.man | 2 +-
src/roff/groff/tests/check-delimiter-validity.sh | 4 +-
src/roff/troff/input.cpp | 70 ++++++++++++------------
5 files changed, 53 insertions(+), 39 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 5a45d07a6..7a82a37d3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2025-06-06 G. Branden Robinson <[email protected]>
+
+ * src/roff/troff/input.cpp (is_char_usable_as_delimiter): Loosen
+ the choke on prohibited delimiters. To eliminate syntactic
+ ambiguity in conditional expressions, we need only reject
+ characters that can _begin_ numeric expressions; those in the
+ set '/*%<>=&:)' cannot, so permit them as delimiters once more.
+ (do_overstrike, do_bracket, do_name_test, do_zero_width_output)
+ (read_size, do_register, do_width, do_device_extension)
+ (read_drawing_command): Clarify warning diagnostic accordingly.
+
+ * doc/groff.texi.in (Compatibility Mode):
+ * man/groff_diff.7.man (Compatibility mode): Update.
+
2025-06-06 G. Branden Robinson <[email protected]>
* tmac/an-ext.tmac (SY): The single-argument form of `SY` need
diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index c97aa8998..5ba59d2b1 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -18929,7 +18929,7 @@ accepts several characters as delimiters that it
ordinarily rejects,
because they are meaningful in numeric expressions and therefore
potentially ambiguous to the document maintainer.
The set of additional delimiters comprises
-@samp{0123456789+-/*%<>=&:().|}.
+@samp{0123456789+-(.|}.
@cindex input level in delimited arguments
@cindex interpolation depth in delimited arguments
diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man
index 0a31f7ce8..0e857c0bb 100644
--- a/man/groff_diff.7.man
+++ b/man/groff_diff.7.man
@@ -6103,7 +6103,7 @@ because they are meaningful in numeric expressions and
therefore
potentially ambiguous to the document maintainer.
.
The set of additional delimiters comprises
-.RB \[lq] 0123456789+\-/*%<>=&:().| \[rq].
+.RB \[lq] 0123456789+\-(.| \[rq].
.
.
.\" ====================================================================
diff --git a/src/roff/groff/tests/check-delimiter-validity.sh
b/src/roff/groff/tests/check-delimiter-validity.sh
index c2e107182..ad4aefbe1 100755
--- a/src/roff/groff/tests/check-delimiter-validity.sh
+++ b/src/roff/groff/tests/check-delimiter-validity.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (C) 2024 Free Software Foundation, Inc.
+# Copyright (C) 2024-2025 Free Software Foundation, Inc.
#
# This file is part of groff.
#
@@ -38,7 +38,7 @@ do
echo "$output" | grep -Fqx ___ || wail
done
-for c in 0 1 2 3 4 5 6 7 8 9 + - / '*' % '<' '>' = '&' : '(' ')' . '|'
+for c in 0 1 2 3 4 5 6 7 8 9 + - '(' . '|'
do
echo "checking invalidity of '$c' as delimiter in normal mode" \
>&2
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index 7fd5f6f4d..9d08a8c28 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -1610,9 +1610,9 @@ node *do_overstrike() // \o
start_token.next();
if (!start_token.is_usable_as_delimiter())
warning(WARN_DELIM, "interpreting %1 as an escape sequence"
- " delimiter; it is ambiguous because it is also meaningful"
- " in a numeric expression", start_token.description());
- // TODO: groff 1.25?
+ " delimiter; it is ambiguous because it can also begin a"
+ " numeric expression", start_token.description());
+ // TODO: groff 1.24.0 release + 2 years?
#if 0
if (!start_token.is_usable_as_delimiter(true /* report error */)) {
delete osnode;
@@ -1662,9 +1662,9 @@ static node *do_bracket() // \b
start_token.next();
if (!start_token.is_usable_as_delimiter())
warning(WARN_DELIM, "interpreting %1 as an escape sequence"
- " delimiter; it is ambiguous because it is also meaningful"
- " in a numeric expression", start_token.description());
- // TODO: groff 1.25?
+ " delimiter; it is ambiguous because it can also begin a"
+ " numeric expression", start_token.description());
+ // TODO: groff 1.24.0 release + 2 years?
#if 0
if (!start_token.is_usable_as_delimiter(true /* report error */)) {
delete bracketnode;
@@ -1704,9 +1704,9 @@ static const char *do_name_test() // \A
start_token.next();
if (!start_token.is_usable_as_delimiter())
warning(WARN_DELIM, "interpreting %1 as an escape sequence"
- " delimiter; it is ambiguous because it is also meaningful"
- " in a numeric expression", start_token.description());
- // TODO: groff 1.25?
+ " delimiter; it is ambiguous because it can also begin a"
+ " numeric expression", start_token.description());
+ // TODO: groff 1.24.0 release + 2 years?
#if 0
if (!start_token.is_usable_as_delimiter(true /* report error */))
return 0 /* nullptr */;
@@ -1821,9 +1821,9 @@ static node *do_zero_width_output() // \Z
start_token.next();
if (!start_token.is_usable_as_delimiter())
warning(WARN_DELIM, "interpreting %1 as an escape sequence"
- " delimiter; it is ambiguous because it is also meaningful"
- " in a numeric expression", start_token.description());
- // TODO: groff 1.25?
+ " delimiter; it is ambiguous because it can also begin a"
+ " numeric expression", start_token.description());
+ // TODO: groff 1.24.0 release + 2 years?
#if 0
if (!start_token.is_usable_as_delimiter(true /* report error */)) {
delete rev;
@@ -2605,16 +2605,16 @@ static bool is_char_usable_as_delimiter(int c)
switch (c) {
case '+':
case '-':
- case '/':
- case '*':
- case '%':
- case '<':
- case '>':
- case '=':
- case '&':
- case ':':
+ // case '/':
+ // case '*':
+ // case '%':
+ // case '<':
+ // case '>':
+ // case '=':
+ // case '&':
+ // case ':':
case '(':
- case ')':
+ // case ')':
case '.':
case '|':
return false;
@@ -5724,9 +5724,9 @@ static bool read_size(int *x)
}
else if (!tok.is_usable_as_delimiter())
warning(WARN_DELIM, "interpreting %1 as an escape sequence"
- " delimiter; it is ambiguous because it is also meaningful"
- " in a numeric expression", tok.description());
- // TODO: groff 1.25?
+ " delimiter; it is ambiguous because it can also begin a"
+ " numeric expression", tok.description());
+ // TODO: groff 1.24.0 release + 2 years?
#if 0
else if (!tok.is_usable_as_delimiter(true /* report error */))
return false;
@@ -5863,9 +5863,9 @@ static void do_register() // \R
start_token.next();
if (!start_token.is_usable_as_delimiter())
warning(WARN_DELIM, "interpreting %1 as an escape sequence"
- " delimiter; it is ambiguous because it is also meaningful"
- " in a numeric expression", start_token.description());
- // TODO: groff 1.25?
+ " delimiter; it is ambiguous because it can also begin a"
+ " numeric expression", start_token.description());
+ // TODO: groff 1.24.0 release + 2 years?
#if 0
if (!start_token.is_usable_as_delimiter(true /* report error */)) {
return;
@@ -5905,7 +5905,7 @@ static void do_width() // \w
warning(WARN_DELIM, "interpreting %1 as an escape sequence"
" delimiter; it is ambiguous because it is also meaningful"
" in a numeric expression", start_token.description());
- // TODO: groff 1.25?
+ // TODO: groff 1.24.0 release + 2 years?
#if 0
if (!start_token.is_usable_as_delimiter(true /* report error */))
return;
@@ -6198,9 +6198,9 @@ static node *do_device_extension() // \X
start_token.next();
if (!start_token.is_usable_as_delimiter())
warning(WARN_DELIM, "interpreting %1 as an escape sequence"
- " delimiter; it is ambiguous because it is also meaningful"
- " in a numeric expression", start_token.description());
- // TODO: groff 1.25?
+ " delimiter; it is ambiguous because it can also begin a"
+ " numeric expression", start_token.description());
+ // TODO: groff 1.24.0 release + 2 years?
#if 0
if (!start_token.is_usable_as_delimiter(true /* report error */))
return 0 /* nullptr */;
@@ -9365,7 +9365,7 @@ int main(int argc, char **argv)
if (want_unsafe_requests)
mac_path = ¯o_path;
set_string(".T", device);
- // TODO: Kill this off in groff 1.25. See env.cpp.
+ // TODO: Kill this off in groff 1.24.0 release + 2 years. See env.cpp.
if ((strcmp("pdf", device) == 0) || strcmp("ps", device) == 0)
is_device_ps_or_pdf = true;
init_charset_table();
@@ -9727,9 +9727,9 @@ static node *read_drawing_command()
start_token.next();
if (!start_token.is_usable_as_delimiter())
warning(WARN_DELIM, "interpreting %1 as an escape sequence"
- " delimiter; it is ambiguous because it is also meaningful"
- " in a numeric expression", start_token.description());
- // TODO: groff 1.25?
+ " delimiter; it is ambiguous because it can also begin a"
+ " numeric expression", start_token.description());
+ // TODO: groff 1.24.0 release + 2 years?
#if 0
if (!start_token.is_usable_as_delimiter(true /* report error */))
return 0 /* nullptr */;
_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit