gbranden pushed a commit to branch master
in repository groff.
commit 008837b618203b8c0d303ade101a11cca807678c
Author: G. Branden Robinson <[email protected]>
AuthorDate: Mon Apr 27 09:25:43 2026 -0500
[libgroff,troff]: Refactor font load diagnostics.
Decouple diagnosis of file I/O error from font description file content
validation.
* src/include/font.h (class font): Update declaration of `load_font()`
public member function to insert new `bool`-valued argument defaulting
`true`. It governs whether an error diagnostic is issued if a font
description file can't be opened. Update declaration of `load`
protected member function with a new `bool`-valued first argument
defaulting true, for the same purpose, since the former function wraps
the latter.
* src/libs/libgroff/font.cpp (font::load_font): Update definition and
pass new argument to `load()` member function of object.
(font::load): Condition `error()` diagnostic on `want_diagnostic`
argument, not `validate_only`.
* src/roff/troff/node.cpp
(assign_font_and_file_name_to_mounting_position): Update
`font::load_font()` call to pass `!in_nroff_mode` as the value of the
former's `want_diagnostic` parameter. Annotate why.
(is_font_available): Pass `font::load_font()` a `false`
`want_diagnostic` parameter.
Continues commit 48ab338d25, 12 April.
Illustration:
Before (but only in Git post-groff 1.24.1):
$ echo '\fBfoo\fZbar\fPbaz' | nroff | cat -s
troff:<standard input>:1: error: cannot open font description file 'Z': No
such file or directory
troff:<standard input>:1: warning: cannot select font 'Z' [-w font]
foobarbaz
$ echo '\fBfoo\fZbar\fPbaz' | nroff -W font | cat -s
troff:<standard input>:1: error: cannot open font description file 'Z': No
such file or directory
foobarbaz
After:
$ echo '\fBfoo\fZbar\fPbaz' | ./build/test-groff -T ascii | cat -s
troff:<standard input>:1: warning: cannot select font 'Z' [-w font]
foobarbaz
$ echo '\fBfoo\fZbar\fPbaz' | ./build/test-groff -W font -T ascii | cat -s
foobarbaz
---
ChangeLog | 26 ++++++++++++++++++++++++++
src/include/font.h | 25 ++++++++++++++-----------
src/libs/libgroff/font.cpp | 9 +++++----
src/roff/troff/node.cpp | 28 +++++++++++++++++++++++++---
4 files changed, 70 insertions(+), 18 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index b538d715a..3dff01384 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2026-04-27 G. Branden Robinson <[email protected]>
+
+ [libgroff]: Decouple diagnosis of file I/O error from font
+ description file content validation.
+
+ * src/include/font.h (class font): Update declaration of
+ `load_font()` public member function to insert new `bool`-valued
+ argument defaulting `true`. It governs whether an error
+ diagnostic is issued if a font description file can't be opened.
+ Update declaration of `load` protected member function with a
+ new `bool`-valued first argument defaulting true, for the same
+ purpose, since the former function wraps the latter.
+ * src/libs/libgroff/font.cpp (font::load_font): Update
+ definition and pass new argument to `load()` member function of
+ object.
+ (font::load): Condition `error()` diagnostic on
+ `want_diagnostic` argument, not `validate_only`.
+ * src/roff/troff/node.cpp
+ (assign_font_and_file_name_to_mounting_position): Update
+ `font::load_font()` call to pass `!in_nroff_mode` as the value
+ of the former's `want_diagnostic` parameter. Annotate why.
+ (is_font_available): Pass `font::load_font()` a `false`
+ `want_diagnostic` parameter.
+
+ Continues commit 48ab338d25, 12 April.
+
2026-04-24 G. Branden Robinson <[email protected]>
* tmac/an.tmac (SH, SS, TP): Throw warning if macro called while
diff --git a/src/include/font.h b/src/include/font.h
index 275aa9e67..85bae6719 100644
--- a/src/include/font.h
+++ b/src/include/font.h
@@ -206,13 +206,15 @@ public:
// of the paper format and arg3 and arg4 with
// its length and width, respectively. Return
// whether paper size was successfully set.
- static font *load_font(const char *, bool = false); // Load the font
- // description file with the given name (arg1)
- // and return a pointer to a 'font' object. If
- // arg2 is true, only the part of the font
- // description file before the 'charset' and
- // 'kernpairs' sections is checked for validity.
- // Return null pointer in case of failure.
+ static font *load_font(const char *, bool = true, bool = false);
+ // Load the font description file with the given
+ // name (arg1) and return a pointer to a 'font'
+ // object. If arg2 is true, failure to open it
+ // produces an error diagnostic. If arg3 is
+ // true, only the part of the font description
+ // file before the 'charset' and 'kernpairs'
+ // sections is checked for validity. Return
+ // null pointer in case of failure.
static void command_line_font_dir(const char *); // Prepend given
// path (arg1) to the list of directories in which
// to look up fonts.
@@ -345,10 +347,11 @@ private:
protected:
// Load the font description file with the name in member variable
- // `name` into this object. If arg1 is true, only the part of the
- // font description file before the 'charset' and 'kernpairs' sections
- // is loaded. Return success/failure status of load.
- bool load(bool = false);
+ // `name` into this object. If arg1 is true, failure to open it
+ // produces an error diagnostic. If arg2 is true, the part of
+ // the font description file before the 'charset' and 'kernpairs'
+ // sections is loaded. Return success/failure status of load.
+ bool load(bool = true, bool = false);
};
// Local Variables:
diff --git a/src/libs/libgroff/font.cpp b/src/libs/libgroff/font.cpp
index 3ac6878d6..362abf527 100644
--- a/src/libs/libgroff/font.cpp
+++ b/src/libs/libgroff/font.cpp
@@ -818,10 +818,11 @@ void font::copy_entry(glyph *new_glyph, glyph *old_glyph)
ch_index[new_index] = ch_index[old_index];
}
-font *font::load_font(const char *fn, bool validate_only)
+font *font::load_font(const char *fn, bool want_diagnostic,
+ bool validate_only)
{
font *f = new font(fn);
- if (!f->load(validate_only)) {
+ if (!f->load(want_diagnostic, validate_only)) {
delete f;
return 0 /* nullptr */;
}
@@ -895,12 +896,12 @@ again:
return false;
}
-bool font::load(bool validate_only)
+bool font::load(bool want_diagnostic, bool validate_only)
{
char *path;
FILE *fp = open_file(filename, &path);
if (0 /* nullptr */ == fp) {
- if (!validate_only)
+ if (want_diagnostic)
error("cannot open font description file '%1': %2", filename,
strerror(errno));
return false;
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 9f6d72393..ca124d072 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -1,5 +1,5 @@
/* Copyright 1989-2010 Free Software Foundation, Inc.
- 2021-2025 G. Branden Robinson
+ 2021-2026 G. Branden Robinson
Written by James Clark ([email protected])
@@ -6677,7 +6677,28 @@ static bool
assign_font_and_file_name_to_mounting_position(
font *fm = 0 /* nullptr */;
void *p = font_dictionary.lookup(filename);
if (0 /* nullptr */ == p) {
- fm = font::load_font(filename.contents());
+ // XXX: Most nroff mode users are readers of man pages, and man
+ // pages have a tendency to spray-and-pray with respect to font
+ // selections. There's a long tradition of employing `\fC` and
+ // `\f(CW` escape sequences even when (on a terminal device) they
+ // can't possibly do anything.[*] The unpredictable resulting value
+ // of the previous font selection (see "Other differences" in
+ // groff_diff(7) or our Texinfo manual) does not seem to deter
+ // this practice. Some day, if enough man pages wean themselves
+ // from this carelessness, we can drop the second argument.
+ //
+ // [*] One _could_ copy the terminal device's `B` font's description
+ // file (AT&T: "driving table") to a file named "C" or "CW" (or,
+ // for smooth interoperation with groff in troff mode, "CR"),
+ // and if one avoided setting bold adjacently to it, one could
+ // get a meaningful change of typeface. As far as I know, no
+ // one has ever bothered to try. Perhaps the typing of
+ // inscrutable runes with no evident effect is a comfort to the
+ // hacker saddled with the hateful task of writing
+ // documentation. See <https://lists.gnu.org/archive/html/
+ // groff/2026-04/msg00039.html>. --GBR
+ fm = font::load_font(filename.contents(),
+ !in_nroff_mode /* want_diagnostic */);
if (0 /* nullptr */ == fm) {
(void) font_dictionary.lookup(filename, &nonexistent_font);
return false;
@@ -6751,7 +6772,8 @@ bool is_font_available(symbol fam, symbol name)
void *p = font_dictionary.lookup(name);
if (0 /* nullptr */ == p) {
// The font is not already mounted; could it be?
- fm = font::load_font(name.contents(), true /* validate_only */);
+ fm = font::load_font(name.contents(), false /* want_diagnostic */,
+ true /* validate_only */);
return (fm != 0 /* nullptr */);
}
else if (&nonexistent_font == p)
_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit