[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[groff] 20/26: [troff]: Fix Savannah #66434 (spaces in `so` arg).
From: |
G. Branden Robinson |
Subject: |
[groff] 20/26: [troff]: Fix Savannah #66434 (spaces in `so` arg). |
Date: |
Thu, 14 Nov 2024 11:54:12 -0500 (EST) |
gbranden pushed a commit to branch master
in repository groff.
commit f4c19e6e44d8831b0a674eb4865a89ee8f575aed
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
AuthorDate: Tue Nov 12 12:06:08 2024 -0600
[troff]: Fix Savannah #66434 (spaces in `so` arg).
* src/roff/troff/input.cpp (do_source, do_macro_source): Refactor to use
`read_string()` instead of `get_long_name()` to obtain the argument;
this means that the argument consumes the rest of the input line
instead of being treated as a groff identifier. This change permits
spaces in sourced file names.
* doc/groff.texi.in (I/O) <so, soquiet, mso, msoquiet>
(Other Differences):
* man/groff.7.man (Request short reference) <so>:
* man/groff_diff.7.man (New requests) <mso, msoquiet, soquiet>:
(Other differences): Document it.
* src/roff/groff/tests/so-request-accepts-embedded-space-in-arg.sh: Test
it.
* src/roff/groff/groff.am (groff_TESTS): Run test.
* NEWS: Add item.
Fixes <https://savannah.gnu.org/bugs/?66434>.
---
ChangeLog | 22 ++++++++
NEWS | 18 +++---
doc/groff.texi.in | 18 +++---
man/groff.7.man | 5 ++
man/groff_diff.7.man | 13 +++--
src/roff/groff/groff.am | 1 +
.../so-request-accepts-embedded-space-in-arg.sh | 64 ++++++++++++++++++++++
src/roff/troff/input.cpp | 60 ++++++++------------
8 files changed, 147 insertions(+), 54 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c4d0c78da..537ac5c1a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2024-11-12 G. Branden Robinson <g.branden.robinson@gmail.com>
+
+ * src/roff/troff/input.cpp (do_source, do_macro_source):
+ Refactor to use `read_string()` instead of `get_long_name()` to
+ obtain the argument; this means that the argument consumes the
+ rest of the input line instead of being treated as a groff
+ identifier. This change permits spaces in sourced file names.
+
+ * doc/groff.texi.in (I/O) <so, soquiet, mso, msoquiet>
+ (Other Differences):
+ * man/groff.7.man (Request short reference) <so>:
+ * man/groff_diff.7.man (New requests) <mso, msoquiet, soquiet>:
+ (Other differences): Document it.
+
+ * src/roff/groff/tests/\
+ so-request-accepts-embedded-space-in-arg.sh: Test it.
+ * src/roff/groff/groff.am (groff_TESTS): Run test.
+
+ * NEWS: Add item.
+
+ Fixes <https://savannah.gnu.org/bugs/?66434>.
+
2024-11-12 G. Branden Robinson <g.branden.robinson@gmail.com>
[soelim]: Read argument to `so` request in a more GNU troff-ish
diff --git a/NEWS b/NEWS
index ca2bda6ba..e9485954c 100644
--- a/NEWS
+++ b/NEWS
@@ -57,9 +57,12 @@ troff
warning diagnostic in the "range" category.
* GNU troff now strips a leading neutral double quote from the argument
- to the `pi` and `sy` requests, allowing it to contain embedded
+ to the `pi`, `so`, and `sy` requests, allowing it to contain embedded
leading spaces.
+* GNU troff now accepts space characters in the argument to the `mso`,
+ `msoquiet`, `so`, and `soquiet` requests. See "soelim" below.
+
* The "el" warning category has been withdrawn. If enabled (which it
was not by default), the formatter would emit a diagnostic if it
inferred an imbalance between `ie` and `el` requests. Unfortunately
@@ -188,12 +191,13 @@ soelim
------
* soelim no longer requires embedded space characters in `so` arguments
- to be backslash-escaped. (It continues to support that syntax.) If
- the argument to a `so` request must contain leading spaces, any such
- sequence of spaces must now be prefixed with a double quote character
- ("), which the program then discards. These changes are to better
- align this program's parsing rules with those of GNU troff and of
- AT&T troff historically; consider the `ds` and `as` requests.
+ to be backslash-escaped. (It continues to support that syntax, even
+ though neither AT&T nor GNU troff ever has.) If the argument to a
+ `so` request must contain leading spaces, any such sequence of spaces
+ must now be prefixed with a double quote character ("), which the
+ program then discards. These changes are to better align this
+ program's parsing rules with the language of the formatter; consider
+ the `ds` and `as` requests.
Macro packages
--------------
diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index 41f5eaa9e..342357214 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -16245,8 +16245,8 @@ escape sequences.
@command{gtroff} has several requests for including files:
-@DefreqList {so, file}
-@DefreqListEndx {soquiet, file}
+@DefreqList {so, [@code{"}]@Var{file}}
+@DefreqListEndx {soquiet, [@code{"}]@Var{file}}
@cindex including a file (@code{so})
@cindex file, inclusion (@code{so})
Replace the @code{so} request's control line with the contents of the
@@ -16256,6 +16256,9 @@ the directories specified by @option{-I} command-line
option. If
and the request has no further effect. @xref{Warnings}, for
information about the enablement and suppression of warnings.
+GNU @command{troff} strips a leading neutral double quote from the
+argument, allowing embedded leading spaces in @var{contents}.
+
@code{so} can be useful for large documents; e.g., allowing each chapter
of a book to be kept in a separate file. However, files interpolated
with @code{so} are not preprocessed; to overcome this limitation, see
@@ -16296,10 +16299,10 @@ The comment regarding a final newline for the
@code{so} request is valid
for @code{pso} also.
@endDefreq
-@DefreqList {mso, file}
-@DefreqListEndx {msoquiet, file}
+@DefreqList {mso, [@code{"}]@Var{file}}
+@DefreqListEndx {msoquiet, [@code{"}]@Var{file}}
Identical to the @code{so} and @code{soquiet} requests, respectively,
-except that @command{gtroff} searches for the specified @var{file} in
+except that GNU @command{troff} searches for the specified @var{file} in
the same directories as macro files for the @option{-m} command-line
option.
@endDefreq
@@ -17955,10 +17958,11 @@ values of minimum inter-word and additional
inter-sentence space are
each rounded down to the nearest multiple of@tie{}12.
@cindex @code{pi} request, incompatibilities with @acronym{AT&T} @code{troff}
+@cindex @code{so} request, incompatibilities with @acronym{AT&T} @code{troff}
@cindex @code{sy} request, incompatibilities with @acronym{AT&T} @code{troff}
GNU @command{troff} strips a leading neutral double quote from the
-argument to the @code{pi} and @code{sy} requests, allowing it to contain
-embedded leading spaces.
+argument to the @code{pi}, @code{so}, and @code{sy} requests, allowing
+it to contain embedded leading spaces.
@cindex @code{bd} request, incompatibilities with @acronym{AT&T} @code{troff}
@cindex @code{cs} request, incompatibilities with @acronym{AT&T} @code{troff}
diff --git a/man/groff.7.man b/man/groff.7.man
index 80b921ab1..ce738deee 100644
--- a/man/groff.7.man
+++ b/man/groff.7.man
@@ -4361,6 +4361,11 @@ Replace the request's control line with the contents of
.IR file ,
\[lq]sourcing\[rq] it.
.
+A leading neutral double quote is stripped from the argument,
+allowing embedded leading spaces in
+.I file,
+which is read in copy mode and continues to the end of the input line.
+.
.TPx
.REQ .soquiet file
As
diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man
index 2a6049cac..06267d479 100644
--- a/man/groff_diff.7.man
+++ b/man/groff_diff.7.man
@@ -3153,7 +3153,8 @@ word spaces).
.
.
.TP
-.BI .mso\~ file
+.BR .mso\~ [ \[dq] ]\c
+.I file
As
.RB \[lq] so \[rq],
except that
@@ -3176,7 +3177,8 @@ and the request has no other effect.
.
.
.TP
-.BI .msoquiet\~ file
+.BR .msoquiet\~ [ \[dq] ]\c
+.I file
As
.BR mso ,
but no warning is emitted if
@@ -3616,7 +3618,8 @@ the argument list can't extend over more than one line.
.
.
.TP
-.BI .soquiet\~ file
+.BR .soquiet\~ [ \[dq] ]\c
+.I file
As
.RB \[lq] so \[rq],
but no warning is emitted if
@@ -6052,7 +6055,9 @@ inter-sentence space each to the nearest multiple of\~12.
GNU
.I troff \" GNU
strips a leading neutral double quote from the argument to the
-.B pi
+.BR pi ,
+and
+.BR so ,
and
.B sy
requests,
diff --git a/src/roff/groff/groff.am b/src/roff/groff/groff.am
index 3abe3f13d..ee223dc99 100644
--- a/src/roff/groff/groff.am
+++ b/src/roff/groff/groff.am
@@ -88,6 +88,7 @@ groff_TESTS = \
src/roff/groff/tests/regression_savannah_59202.sh \
src/roff/groff/tests/set-stroke-thickness.sh \
src/roff/groff/tests/sizes-request-works.sh \
+ src/roff/groff/tests/so-request-accepts-embedded-space-in-arg.sh \
src/roff/groff/tests/soquiet-request-works.sh \
src/roff/groff/tests/stringdown-and-stringup-requests-work.sh \
src/roff/groff/tests/stringdown-request-rejects-request-names.sh \
diff --git a/src/roff/groff/tests/so-request-accepts-embedded-space-in-arg.sh
b/src/roff/groff/tests/so-request-accepts-embedded-space-in-arg.sh
new file mode 100755
index 000000000..37229527e
--- /dev/null
+++ b/src/roff/groff/tests/so-request-accepts-embedded-space-in-arg.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+#
+# Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
+#
+
+groff="${abs_top_builddir:-.}/test-groff"
+
+fail=
+
+wail () {
+ echo "...FAILED" >&2
+ fail=yes
+}
+
+tmpfile="bar baz.groff"
+
+cleanup () {
+ rm -f "$tmpfile"
+}
+
+# A process handling a fatal signal should:
+# 1. Mask _all_ fatal signals.
+# 2. Perform cleanup operations.
+# 3. Unmask the signal (removing the handler).
+# 4. Signal its own process group with the signal caught so that the
+# the children exit and shell accurately reports how the process
+# died.
+fatals="HUP INT QUIT TERM"
+for s in $fatals
+do
+ trap "trap '' $fatals; cleanup; trap - $fatals; kill -$s -$$" $s
+done
+
+echo bar baz > "$tmpfile"
+
+input='.
+foo
+.so bar baz.groff
+qux
+.'
+
+output=$(echo "$input" | "$groff" -T ascii -U)
+echo "$output"
+echo "$output" | grep -Fqx 'foo bar baz qux' || wail
+
+cleanup
+test -z "$fail"
+
+# vim:set autoindent expandtab shiftwidth=2 tabstop=2 textwidth=72:
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index 5faac261d..7822d5d55 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -6570,23 +6570,17 @@ static void while_continue_request()
void do_source(bool quietly)
{
- symbol nm = get_long_name(true /* required */);
- if (nm.is_null())
- skip_line();
- else {
- while (!tok.is_newline() && !tok.is_eof())
- tok.next();
- errno = 0;
- FILE *fp = include_search_path.open_file_cautious(nm.contents());
- if (fp)
- input_stack::push(new file_iterator(fp, nm.contents()));
- else
- // Suppress diagnostic only if we're operating quietly and it's an
- // expected problem.
- if (!(quietly && (ENOENT == errno)))
- error("cannot open '%1': %2", nm.contents(), strerror(errno));
- tok.next();
- }
+ char *filename = read_string();
+ errno = 0;
+ FILE *fp = include_search_path.open_file_cautious(filename);
+ if (fp != 0 /* nullptr */)
+ input_stack::push(new file_iterator(fp, filename));
+ else
+ // Suppress diagnostic only if we're operating quietly and it's an
+ // expected problem.
+ if (!(quietly && (ENOENT == errno)))
+ error("cannot open '%1': %2", filename, strerror(errno));
+ tok.next();
}
void source_request() // .so
@@ -8740,26 +8734,20 @@ static void process_startup_file(const char *filename)
void do_macro_source(bool quietly)
{
- symbol nm = get_long_name(true /* required */);
- if (nm.is_null())
- skip_line();
- else {
- while (!tok.is_newline() && !tok.is_eof())
- tok.next();
- char *path;
- FILE *fp = mac_path->open_file(nm.contents(), &path);
- if (fp != 0 /* nullptr */) {
- input_stack::push(new file_iterator(fp, symbol(path).contents()));
- free(path);
- }
- else
- // Suppress diagnostic only if we're operating quietly and it's an
- // expected problem.
- if (!quietly && (ENOENT == errno))
- warning(WARN_FILE, "cannot open macro file '%1': %2",
- nm.contents(), strerror(errno));
- tok.next();
+ char *macro_filename = read_string();
+ char *path;
+ FILE *fp = mac_path->open_file(macro_filename, &path);
+ if (fp != 0 /* nullptr */) {
+ input_stack::push(new file_iterator(fp, macro_filename));
+ free(path);
}
+ else
+ // Suppress diagnostic only if we're operating quietly and it's an
+ // expected problem.
+ if (!quietly && (ENOENT == errno))
+ warning(WARN_FILE, "cannot open macro file '%1': %2",
+ macro_filename, strerror(errno));
+ tok.next();
}
void macro_source_request() // .mso
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [groff] 20/26: [troff]: Fix Savannah #66434 (spaces in `so` arg).,
G. Branden Robinson <=