From 7e66027c5eaba8a435049fc3067400dc243d5951 Mon Sep 17 00:00:00 2001 From: "G. Branden Robinson" Date: Wed, 1 Apr 2020 03:53:28 +1100 Subject: [PATCH] Support 2-digit \sNN only in compatibility mode. * src/roff/troff/input.cpp: Only scan an additional digit of \sNN in compatibility mode. (Also update an insufficiently general comment; \s(00 works just like \s0.) * doc/groff.texi: * man/groff.7.man: Document the changed behavior. * src/roff/groff/groff.am: * src/roff/groff/tests/use_point_size_escape_with_single_digit_arg.sh: Add regression test. --- doc/groff.texi | 5 +-- man/groff.7.man | 12 +++---- src/roff/groff/groff.am | 3 +- ...point_size_escape_with_single_digit_arg.sh | 36 +++++++++++++++++++ src/roff/troff/input.cpp | 18 ++++++++-- 5 files changed, 63 insertions(+), 11 deletions(-) create mode 100755 src/roff/groff/tests/use_point_size_escape_with_single_digit_arg.sh diff --git a/doc/groff.texi b/doc/groff.texi index 65eea202..78640517 100644 --- a/doc/groff.texi +++ b/doc/groff.texi @@ -10051,8 +10051,9 @@ and the text begins. Any of the following forms are valid: @table @code @item \s@var{n} -Set the point size to @var{n}@tie{}points. @var{n}@tie{}must be either -0 or in the range 4 to@tie{}39. +Set the point size to @var{n}@tie{}points. @var{n}@tie{}must be a +single digit. In compatibility mode only, @var{n}@tie{}may also be a +two-digit value in the range range 10 to@tie{}39. @item \s+@var{n} @itemx \s-@var{n} diff --git a/man/groff.7.man b/man/groff.7.man index e1d6a25a..8af99e55 100644 --- a/man/groff.7.man +++ b/man/groff.7.man @@ -3299,13 +3299,13 @@ The same as .ESC s \[+-]N Set/increase/decrease the point size to/by .I N -scaled points; +scaled points. +. .I N -must be either 0 -(restore previous size) -or, -for historical reasons, -in the range 4\[en]39. +must be a single digit, +except in compatibility mode +(where values from 10\[en]39 are also accepted); +0 restores the previous point size. . Otherwise, same as diff --git a/src/roff/groff/groff.am b/src/roff/groff/groff.am index c56b9562..fae28aa5 100644 --- a/src/roff/groff/groff.am +++ b/src/roff/groff/groff.am @@ -46,7 +46,8 @@ groff_TESTS = \ src/roff/groff/tests/regression_savannah_56555.sh \ src/roff/groff/tests/string_case_xform_errors.sh \ src/roff/groff/tests/string_case_xform_requests.sh \ - src/roff/groff/tests/string_case_xform_unicode_escape.sh + src/roff/groff/tests/string_case_xform_unicode_escape.sh \ + src/roff/groff/tests/use_point_size_escape_with_single_digit_arg.sh TESTS += $(groff_TESTS) groff_XFAIL_TESTS = \ diff --git a/src/roff/groff/tests/use_point_size_escape_with_single_digit_arg.sh b/src/roff/groff/tests/use_point_size_escape_with_single_digit_arg.sh new file mode 100755 index 00000000..4dc90732 --- /dev/null +++ b/src/roff/groff/tests/use_point_size_escape_with_single_digit_arg.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# +# Copyright (C) 2020 Free Software Foundation, Inc. +# +# This file is part of groff. +# +# groff is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# groff is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +groff="${abs_top_builddir:-.}/test-groff" + +# The vertical space is so that the 36-point 'A' won't be truncated by +# the top of the page. That could be confusing and misleading to anyone +# who ever has to troubleshoot this test case. +DOC=".vs 10v +\s36A" + +# Verify that the idiosyncratic behavior of \sN is supported in +# compatibility mode... +echo "testing \s36A in compatiblity mode (36-point 'A')" >&2 +echo "$DOC" | "$groff" -C -Z | grep -qx 's36000' + +# ...and not in regular mode. +echo "testing \s36A in non-compatiblity mode (3-point '6A')" >&2 +echo "$DOC" | "$groff" -Z | grep -qx 's3000' diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp index ba3842b9..e61d0e2c 100644 --- a/src/roff/troff/input.cpp +++ b/src/roff/troff/input.cpp @@ -5091,7 +5091,21 @@ static int read_size(int *x) } else if (csdigit(c)) { val = c - '0'; - if (!inc && c != '0' && c < '4') { + // Note: Very special case! If we have \s followed immediately by a + // digit (not '(', '+', or '-'), and that digit is 1, 2, or 3...read + // another digit! This is because the Graphic Systems C/A/T + // phototypesetter (the original device target for AT&T troff) only + // supported a few discrete point sizes in the range 6..36. + // Kernighan warned of this in the 1992 revision of CSTR #54, and + // more recently, McIlroy referred to it as a "living fossil". This + // DWIM syntax is surprising to the user; it clashes with the syntax + // of several other escapes (\*, \$, \f, \F, \g, \k, \m, \M, \n, \V, + // and \Y). We therefore support it only in compatibility mode. + // + // See: + // https://lists.gnu.org/archive/html/groff/2020-03/msg00054.html + // et seq. + if (compatible_flag && !inc && c != '0' && c < '4') { c = read_size_next_byte(); if (!csdigit(c)) bad = 1; @@ -5123,7 +5137,7 @@ static int read_size(int *x) switch (inc) { case 0: if (val == 0) { - // special case -- \s[0] and \s0 means to revert to previous size + // special case -- point size 0 means "revert to previous size" *x = 0; return 1; } -- 2.20.1