gbranden pushed a commit to branch master
in repository groff.
commit 1eac1a70d3c6289be57302d476850dcf32bc6953
Author: G. Branden Robinson <[email protected]>
AuthorDate: Sat Mar 28 15:20:56 2026 -0500
[troff]: Unsupport AT&T's bespoke Roman numerals.
...except in AT&T compatibility mode.
* src/roff/troff/reg.cpp (number_value_to_ascii): When not in
compatibility mode, reduce acceptable range of register values when
attempting to format them with Roman numerals to that expressible only
with the numerals "MDCLXVI". (In compatibility mode, retain support
for AT&T troff's novelty of Roman numerals "W" for 5,000 and "Z" for
10,000.) Recast error diagnostic when register value is outside of
the representable range.
* doc/groff.texi.in (Assigning Register Formats):
* NEWS: Document it.
Fixes <https://savannah.gnu.org/bugs/?61999>. Thanks to Dave Kemper for
the report.
ANNOUNCE: Acknowledge Dave.
Illustration:
$ printf '.nr a 3999\n.nr b 4000\n.af a i\n.af b i\n.tm \\na\n.tm \\nb\n' \
| ./build/test-groff
mmmcmxcix
troff:<standard input>:6: error: register value 4000 too large for 'i' or
'I' formats
4000
$ printf '.nr a 3999\n.nr b 4000\n.af a i\n.af b i\n.tm \\na\n.tm \\nb\n' \
| ./build/test-groff -C
mmmcmxcix
mw
---
ANNOUNCE | 1 +
ChangeLog | 19 +++++++++++++++++++
NEWS | 7 +++++--
doc/groff.texi.in | 29 +++++++++++++++++++++++------
src/roff/troff/reg.cpp | 32 ++++++++++++++++++++++----------
5 files changed, 70 insertions(+), 18 deletions(-)
diff --git a/ANNOUNCE b/ANNOUNCE
index 065a3574c..b90660653 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -210,6 +210,7 @@ of this release.
Alex Colomar
Bob Friesenhahn
Bruno Haible
+Dave Kemper
Deri James
Dmytro Bagrii
Morten Bo Johansen
diff --git a/ChangeLog b/ChangeLog
index 28c06a5ff..b70071d3e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2026-03-28 G. Branden Robinson <[email protected]>
+
+ [troff]: Withdraw support for AT&T's exotic Roman numerals
+ except in compatibility mode.
+
+ * src/roff/troff/reg.cpp (number_value_to_ascii): When not in
+ compatibility mode, reduce acceptable range of register values
+ when attempting to format them with Roman numerals to that
+ expressible only with the numerals "MDCLXVI". (In compatibility
+ mode, retain support for AT&T troff's novelty of Roman numerals
+ "W" for 5,000 and "Z" for 10,000.) Recast error diagnostic when
+ register value is outside of the representable range.
+
+ * doc/groff.texi.in (Assigning Register Formats):
+ * NEWS: Document it.
+
+ Fixes <https://savannah.gnu.org/bugs/?61999>. Thanks to Dave
+ Kemper for the report.
+
2026-03-28 G. Branden Robinson <[email protected]>
* src/roff/troff/reg.cpp (number_value_to_ascii): Trivially
diff --git a/NEWS b/NEWS
index 2a5f0183b..100a8b6fe 100644
--- a/NEWS
+++ b/NEWS
@@ -15,8 +15,11 @@ VERSION next
troff
-----
-* GNU troff, the formatter, now issues warnings in the "delim",
- "syntax", and "escape" categories by default.
+* GNU troff, the formatter, now employs the unusual Roman numerals "W"
+ and "Z" of AT&T troff only in compatibility mode.
+
+* The "delim", "syntax", and "escape" categories are enabled by
+ default.
* The `trf` (transparent file throughput) request now discards input
characters that are invalid in GNU troff's output format, meaning all
diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index 376bc0dd7..7b34ed871 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -9285,12 +9285,29 @@ doesn't exist, it is created with a zero value.
@cindex extreme values representable with Roman numerals
@cindex maximum value representable with Roman numerals
@cindex minimum value representable with Roman numerals
-The representable extrema in the @samp{i} and @samp{I} formats
-correspond to Arabic �39,999. GNU @code{troff} uses @samp{w} and
-@samp{z} to represent 5,000 and 10,000 in Roman numerals, respectively,
-following the convention of @acronym{AT&T} @code{troff}---currently, the
-correct glyphs for Roman numerals five thousand (@code{U+2181}) and ten
-thousand (@code{U+2182}) are not used.
+The representable extrema in the
+@samp{i}
+and
+@samp{I}
+formats correspond to Arabic �3,999.@footnote{In compatibility mode,
+GNU
+@command{troff}
+uses
+@samp{w}
+and
+@samp{z}
+to represent 5,000 and 10,000 in Roman numerals,
+respectively,
+following the convention of
+@acronym{AT&T}
+@command{troff},
+and increasing the representable range of register values
+to Arabic �39,999.
+The correct glyphs for Roman numerals five thousand
+(@code{U+2181})
+and ten thousand
+(@code{U+2182})
+are not used.}
@cindex read-only register, changing format
@cindex changing format, and read-only registers
diff --git a/src/roff/troff/reg.cpp b/src/roff/troff/reg.cpp
index 81f5aa53e..587aad1bf 100644
--- a/src/roff/troff/reg.cpp
+++ b/src/roff/troff/reg.cpp
@@ -123,15 +123,25 @@ static const char *number_value_to_ascii(int value, char
format,
case 'I':
{
char *p = buf;
- // troff uses z and w to represent 10000 and 5000 in Roman
- // numerals; I can find no historical basis for this usage
- const char *roman_numerals
- = (format == 'i') ? "zwmdclxvi" : "ZWMDCLXVI";
+ bool is_value_out_of_roman_numeral_range = false;
int n = int(value);
- if (n >= 40000 || n <= -40000) {
- error("magnitude of '%1' too big for i or I format", n);
- return i_to_a(n);
+ // AT&T troff uses z and w to represent 10000 and 5000 in Roman
+ // numerals; jjc could find no historical basis for this usage.
+ if (want_att_compat) {
+ if ((n >= 40000) || (n <= -40000))
+ is_value_out_of_roman_numeral_range = true;
+ }
+ else {
+ if ((n >= 4000) || (n <= -4000))
+ is_value_out_of_roman_numeral_range = true;
+ }
+ if (is_value_out_of_roman_numeral_range) {
+ error("register value %1 is outside of range representable in"
+ " 'i' or 'I' formats", n);
+ return i_to_a(n);
}
+ const char *roman_numerals
+ = (format == 'i') ? "zwmdclxvi" : "ZWMDCLXVI";
if (n == 0) {
*p++ = '0';
*p = '\0';
@@ -141,9 +151,11 @@ static const char *number_value_to_ascii(int value, char
format,
*p++ = '-';
n = -n;
}
- while (n >= 10000) {
- *p++ = roman_numerals[0];
- n -= 10000;
+ if (want_att_compat) {
+ while (n >= 10000) {
+ *p++ = roman_numerals[0];
+ n -= 10000;
+ }
}
for (int i = 1000; i > 0; i /= 10, roman_numerals += 2) {
int m = n/i;
_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit