gbranden pushed a commit to branch master in repository groff. commit aac609bb1f39bdd5b59bb9d4298f4dcc38a8ea54 Author: G. Branden Robinson <g.branden.robin...@gmail.com> 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 <g.branden.robin...@gmail.com> + + * 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 <g.branden.robin...@gmail.com> * 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 groff-commit@gnu.org https://lists.gnu.org/mailman/listinfo/groff-commit