2026-07-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* ChangeLog.124: New file.
	* Makefile.am (EXTRA_DIST): Ship it.

2026-07-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/grog/grog.pl: Update `request` list to include groff
	1.25's new `rhw` request.

2026-07-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/s.tmac (fn@init): Trivially refactor.  Drop now nilpotent
	autoincrement notation from interpolation of `fn*text-num`
	register.

2026-05-18  Deri James  <deri@chuzzlewit.myzen.co.uk>

	* tmac/s.tmac: Fix Savannah #68537, making automatically
	numbered footnotes (`\*[*]` or `\**`) usable in tbl(1) table
	entries.
	(pg@end-text): Remove autoincrement from `fn*text-num` register.
	(@FS): Increment `fn*text-num` only if given no arguments.

	Fixes <https://savannah.gnu.org/bugs/?68527>.  (Problem appears
	to date back to groff's birth.  --GBR)

2026-07-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	[ms]: Regression-test Savannah #68537.

	* tmac/tests/s_automatic-footnote-number-works-in-table.sh: Do
	it.
	* tmac/tmac.am (tmac_TESTS): Run test.

2026-07-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/grog/grog.pl: Add undocumented debugging mode.  New
	global scalar `debugging` of Boolean sense tracks debugging
	state.  Initialize false.
	(debug): New subroutine emits diagnostic message only if
	debugging is enabled.
	(process_arguments): Check for `--debug` command-line option.
	(interpret_line, infer_man_or_ms_package, [main]): Report
	debugging information of interest.

	Feature prompted by surprising diagnosis of Lesk's "Notes on the
	IBM C Compiler." memo as a _me_(7) document instead of the more
	correct _ms_(7).  The misdiagnosis appears to be due to the
	presence of lowercase macro calls, `ip` and `tp`, which happen
	to be defined by _me_(7).  (There are other problems with the
	document, including a fascinating crime against the CSTR #49
	specification of _tbl_ input that no contemporary implementation
	supports, and perhaps only Lesk himself knew about, being that
	program's author.)  See
	<https://www.tuhs.org/pipermail/tuhs/2026-July/034010.html> ff.

2026-07-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (doc/webpage.html): Restore `$(DOC_GNU_EPS)` as
	prerequisite and explain why.

	Fixes <https://savannah.gnu.org/bugs/?68525>.  Problem
	introduced by me in commit 4a4ef28a4e, 2 July.  Thanks to Dave
	Kemper for the report.

2026-07-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/html/pre-html.cpp (main): Make crappy suggestion
	in diagnostic reporting pre-grohtml(1) failure a little less
	crappy.  Prompted by Savannah #68525.

2026-07-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp
	(load_hyphenation_patterns_from_file_request)
	(append_hyphenation_patterns_from_file_request): Before
	returning, call `tok.next()` instead of `skip_line()`.  Annotate
	why: doing so prevents the formatter from ignoring the input
	line after the request.

	Fixes <https://savannah.gnu.org/bugs/?68524>.  Problem
	introduced by me in commit 85c8daa27d, 1 April.  Thanks to Dave
	Kemper for the report.

2026-07-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Add unit tests for `hpf` and `hpfa` requests.

	* src/roff/groff/tests/hpf-request-works.sh:
	* src/roff/groff/tests/hpfa-request-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run tests.

2026-07-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (doc/groff-pdf-features.pdf): Add
	"contrib/sboxes/sboxes.tmac" as prerequisite.

2026-07-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Refactor; shift responsibility for
	positioning the input stream pointer prior to reading the next
	input line to request handlers more consistently.
	(open_file): Stop calling `tok.next()` before returning.
	(open_request, opena_request): Call `tok.next()` before
	returning.
	(read_rest_of_line_as_argument): Annotate future direction.
	(pipe_output, system_request)
	(unsafe_transparent_throughput_file_request): Update
	annotations.

2026-07-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/s.tmac: Relocate initialization of new `cov*got-title`
	register from early occurrence within a `\n[PDFFEAT]` guard to
	an unconditional one within the `cov` "module".  Fixes spurious
	`reg` warning when rendering without `PDFFEAT` in commit
	b6a369d79e, 10 July.

2026-07-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* gnulib: Update to stable/2026-07.

2026-07-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am ($(GROFF_HTML)): Use the official GNU stylesheet
	for our Texinfo manual.

2026-07-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/Groff-PDF-Features.ms: Rename this...
	* doc/groff-pdf-features.ms: ...to this.

	* doc/doc.am: Update `DOCFILES_INST` and `PROCESSEDDOCFILES_PDF`
	macro definitions.
	(doc/Groff-PDF-Features.pdf): Rename this target...
	(doc/groff-pdf-features.pdf): ...to this.  Update prerequisite
	per foregoing rename.  Update recipe likewise.

2026-07-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tmac,troff]: Warn about a deprecated font name only if it isn't
	translated to a non-deprecated name.

	* tmac/ps.tmac: Drop font translations of deprecated names;
	leave it up to the user to do this.

	* src/roff/troff/env.cpp (environment::select_font): Look up the
	font's translated name using "node.cpp"'s
	`get_font_translation()`.  Move check for deprecated font name
	to follow font translation.
	* src/roff/troff/node.cpp (get_font_translation): Drop `static`
	linkage; as noted above, the function needs external visibility
	now.  Annotate planned future reversal of this change.
	* src/roff/troff/node.h: Declare `get_font_translation()`.
	Annotate planned future reversal of this change.

	Fixes <https://savannah.gnu.org/bugs/?68345>.  Thanks to Deri
	James for prompting this (IMO) superior direction for font name
	deprecation to take.

2026-07-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp
	(html_printer::writeHeadMetaStyle): Don't truncate images to the
	newly limited maximum rendering width.  The browser might
	downscale it, making it less legible, but should also keep it
	right-clickable or long-pressable or similar so that our less
	fuzzy pre-rasterized tbl(1) tables (courtesy of pre-grohtml(1))
	can be accessed and read at full size.

2026-07-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp
	(html_printer::writeHeadMetaStyle): Ameliorate horrible UX.
	grohtml(1) has ignored the media width configured by the
	full-service macro package or document forever, but employing a
	CSS 'max-width' of--effectively--infinity, makes for painful
	reading.  Configure the `body` element with a `max-width` of
	`80ch`, which is a little wide but congrues well with the
	default width used by groff man(7) and mdoc(7).  Moreover, these
	packages render nearly all of their content indented, which
	brings the effective line length down to the 65n-75n range
	advised by typography experts.  Employ automatic margins on the
	left and right to center the text on wide browser windows, and a
	`padding` of 1em for ergonomics on "swipey" devices like
	tablets.

2026-07-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (EX, EE): When formatting for HTML, begin and
	end, respectively, a `span` element employing the new
	`code-display` class set up in the document header by
	grohtml(1).

	Fixes <https://savannah.gnu.org/bugs/?68309>.  Thanks to Colin
	Watson and Stephen Gildea for the reports and to them and Ingo
	Schwarze for discussion on the groff list.

2026-07-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp
	(html_printer::writeHeadMetaStyle): Define new class selector
	`.code-display`.  Use monospaced font family and inherit display
	properties from parent block.  Define new descendant selector
	thereof for `p` elements, eliminating vertical margins.
	Initially this is for use by man(7)'s `EX`/`EE` macros, but
	might have applications in other packages.

	Begins fixing <https://savannah.gnu.org/bugs/?68309>.

2026-07-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::next): Perform range check on
	parameter to `\N` escape sequence; throw error diagnostic if it
	fails.

	Fixes <https://savannah.gnu.org/bugs/?68521>.  Problem
	introduced by me in commit b039f8c3d1, 2025-03-29, an attempt to
	improve compatibility with DWB troff.  (But as noted in that
	commit, DWB troff appears not to _exercise_ its freedom to
	employ negative character indices.)

2026-07-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (charinfo::set_number)
	(charinfo::get_number): Make `NDEBUG` execution traces safer:
	clamp negative character indices to zero, avoiding undefined
	formatter behavior.

2026-07-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (charinfo::set_number): Trivially
	refactor.  Rename function parameter from `n` to `idx`, to be
	more expressive and suggest the truth--that it relates to
	indexed characters.

2026-07-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/text.cpp: Fix code style nits.  Rationalize
	header file inclusions.  Arrange C standard library header file
	names in alphabetical order.
	(special_char_box::output): Spell null pointer constant the
	idiomatic C++98 way (`0`) instead of as `NULL`.

2026-07-08  Nguyễn Gia Phong <cnx@loang.net>

	* src/preproc/eqn/text.cpp: Drop dead static data
	{`entity_table`} , its now unused data type declaration {`struct
	map`}.
	(special_to_entity): Drop now unused function.

	Fixes <https://savannah.gnu.org/bugs/?68499>.

2026-07-08  Nguyễn Gia Phong <cnx@loang.net>

	* src/preproc/eqn/text.cpp: Stop mapping special characters to
	named entities when outputting MathML.  Preprocessor-include
	"unicode.h".
	(special_char_box::output): Use libgroff's
	`valid_unicode_code_sequence()` to obtain its Unicode sequence
	representation if it is in groff Unicode special character
	escape sequence syntax.  If not, use `glyph_name_to_unicode()`
	to look up its Unicode representation.

	Continues fixing <https://savannah.gnu.org/bugs/?68499>.

2026-07-08  Nguyễn Gia Phong <cnx@loang.net>

	* src/preproc/eqn/box.cpp
	(half_space_box::output)
	(full_space_box::output)
	(thick_space_box::output)
	(thin_space_box::output):
	* src/preproc/eqn/other.cpp
	(overline_char_box::output)
	(overline_box::output)
	(underline_char_box::output)
	(underline_box::output): Emit numeric character references, not
	named entities, when generating MathML, because GNU eqn supports
	MathML only when producing XHTML.

	Begins fixing <https://savannah.gnu.org/bugs/?68499>.

2026-07-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp (get_html_entity): Emit
	named character entities only for HTML 4, not XHTML, with the
	exception of the handful recognized by XML, already handled
	earlier in this function.

2026-07-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp (get_html_entity): Emit
	`&apos;` for character code 0x27 regardless of `doctype`.  Its
	omission appears to have been a casualty of the IE4 era (Y2K).

2026-07-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp
	(html_printer::writeHeadMetaStyle): Revise XHTML output header
	to modernize it and work with contemporary Firefox and Epiphany.

2026-05-02  Luis Rivera <jlrn@up.edu.mx>

	* tmac/es.tmac: Revise Spanish localization for correctness.

	Fixes <https://savannah.gnu.org/bugs/?68216>.

2026-07-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/s.tmac (TC): Fix code style nit.  De-pessimize by
	handling multiple numerical expression evaluations together with
	the `&` logical "and" operator to connect them.  `.if ... .if`
	is a legitimate pattern, but only necessary when different kinds
	of expressions need to be evaluated, or need to be evaluated
	serially; in *roff the three kinds are numeric expressions,
	output comparison expressions, and the somewhat vaguely named
	"conditional expressions" (`.if d mac`, `.if t`, and so forth).
	This way we avoid a trip through the parser's main loop.

2026-07-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/s.tmac: Trivially refactor.  Rename `gottitle*pdf`
	register to `cov*got-title` to situate it within a documented
	groff ms name space.

2026-07-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/s.tmac (RP): When formatting with PDF features, assign
	the cover page a page number starting with "T-" to avoid
	collision with page 1 of the main matter.  This is a
	quality-of-life improvement when using PDF viewer applications,
	and the sequence "T-1", "T-2", ..., appears to be the convention
	in the PDF world for numbering pages prior to front matter
	numbered with lowercase Roman numerals.

2026-07-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/s.tmac (cov*tl-au-print, ID, par@reset, par@TL, par@AU)
	(par@AI): Cancel temporary indentation before issuing centering
	request, preventing issue of warning in category "style" from
	formatter.

	See <https://savannah.gnu.org/bugs/?68285>.

2026-07-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description):
	* src/roff/troff/node.cpp (make_glyph_node): Adapt new special
	character identifier quoting technique from
	`transparent_translate()`.

2026-07-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (transparent_translate): Improve
	diagnostic message when griping about nonexistent special
	character with a neutral apostrophe in its identifier.

2026-07-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (remove_character_request): Stop
	throwing warning if character already doesn't exist.

2026-07-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Add accessor for `token` class's `nm` member variable.

	* src/roff/troff/token.h (class token): Declare `get_name()`.
	(token::get_name): Define `get_name()`.

2026-07-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (make_glyph_node): Improve diagnostic
	message when griping about nonexistent special character with a
	neutral apostrophe in its identifier.

2026-07-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Revise
	message construction.  When special character syntax `\[foo]` is
	not backed by an existing object, we don't know if a special
	character or character class is meant.  Since the constructed
	description is followed by "is not defined", it's redundant to
	characterize the token as "nonexistent".  Rename `static`
	`const` local object `nonexistent` to
	`special_character_or_class`, and repopulate its contents
	accordingly.

2026-07-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(remove_character): Rename this...
	(remove_character_request): ...to this.
	(init_input_requests): Update wire-uppery of request names to
	handler functions.

2026-07-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (remove_character): Refactor to use
	new `read_any_character()` function.  Drop now unreachable
	diagnostic; `read_any_character()` complains if the token on the
	input stream is not a character.

2026-07-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (set_character_flags_request): Change
	condition of `while` loop from `tok.is_any_character()` to new
	side-effectful `read_any_character()` function.

	Fixes <https://savannah.gnu.org/bugs/?68510>.  Problem
	introduced by me in commit 3f0c81a0a7, 24 May.  Thanks to Dave
	Kemper for the report.

2026-07-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Add unit test for `cflags` request.

	* src/roff/groff/tests/cflags-request-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-07-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (set_character_flags_request):
	Slightly refactor to handle an error case (first argument is not
	an integer) differently so as to return early, dropping
	indentation level of the most complex part of the function.

2026-07-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp (is_valid_term): Recast error
	diagnostic message for clarity in cases like "echo .cflags X |
	groff".

2026-07-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix Savannah #68511, recovering from a botched
	refactor.

	* src/roff/troff/input.cpp (read_any_character): New function
	reads any groff character--ordinary, special, or indexed--from
	the input stream, skipping any spaces.  While a fairly simple
	task, it can be done incorrectly nevertheless.  Multiple request
	handlers can use this.  Start...
	(set_hyphenation_codes): ...here.  Rearrange "do/while" loop to
	"while" loop.  Advance the input stream after reading the
	destination character in a pair.  Failing to do so was the
	defect.  Simplify an error diagnostic message.  Simplify a
	conditional code path.

	Fixes <https://savannah.gnu.org/bugs/?68511>.  Problem
	introduced by me in commit 994fcce775, 24 May.  Thanks to Dave
	Kemper for the report.

2026-07-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Add unit test for `hcode` request.

	* src/roff/groff/tests/hcode-request-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-07-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (zoom_font_request): Refactor.  Call
	`read_font_identifier()` instead of `read_identifier()` to
	gather first argument.  Emit error diagnostic on an attempt to
	apply a zoom factor to a mounting position.  This was already
	prohibited in 1.24.0, but now, thanks to other refactoring, we
	can diagnose it more easily.

2026-07-05  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (suppress_node::suppress_node):
	Initialize `position` with a valid value; while typed `char`, it
	is actually an enumerated type in disguise, and zero (or `\0`)
	is not a valid value.  See
	`src/roff/troff/input.cpp:do_suppress()`.

2026-07-05  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Add unit test for `fzoom` request.

	* src/roff/groff/tests/fzoom-request-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-07-05  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (RE): Rename "local" macro `an-RE-problem` to
	`an*msg`.

2026-07-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp (possible_command::build_argv): Use
	ISO C++98 exceptions to handle heap storage allocation failure.
	Preprocessor-include C++ "<new>" header file.

	Continues the long process of fixing Savannah #68192.

2026-07-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp (possible_command::build_argv): Fix
	code style nits.  Explicitly compare variable of pointer type to
	ISO C++98 null pointer literal, instead of punning it down to a
	Boolean.  Convert type of local variables `len`, `argc` and
	{loop locals} `i` from `int` to `size_t`, since they're used as
	or compared to array indices.  Lift computation of `argc + 1`
	into a new `const` `size_t` variable `argv_len`, for the same
	reason and to prepare for a forthcoming change.

2026-07-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/grn/main.cpp (operand): Exit with status 2, not 8,
	when command-line option argument is missing.
	(interpret): Exit with POSIX `EXIT_FAILURE` status, not 8, when
	reading an unrecognized command keyword.

	* NEWS: Document these changes in behavior.

2026-07-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grn]: Boolify.

	* src/preproc/grn/gprint.h: Delete `TRUE` and `FALSE`
	preprocessor macros.
	* src/preproc/grn/hdb.cpp: Demote external symbols `SUNFILE` and
	`compatibility_flag` from `int` to `bool`.
	(DBRead): Demote local variables `done` and `last` from `int` to
	`bool`.  Assign to `bool` objects using Boolean literals.
	* src/preproc/grn/main.cpp: Demote global symbols `defpoint`,
	`pointscale`, `setdefault`, and `sflag` from `int` to `bool`.
	Initialize `bool` objects using Boolean literals.
	Declare `has_polygon()` as returning `bool`, not `int`.
	(main): Assign to `bool` objects using Boolean literals.
	(has_polygon): Demote return type from `int` to `bool`.

	Continues the long process of fixing Savannah #66672.

2026-07-05  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (texinfo-all): New convenience target builds all
	rendered forms of our Texinfo manual.  Thanks to the new line
	layout diagram, much of groff is now a prerequisite for
	generating it.

2026-07-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am: Move definition of `DOC_LL` macro earlier...
	(mostlyclean_doc): ...and use it here to scrub temporary files
	produced by the later maintainer-mode `$(DOC_LINE_LAYOUT_EPS)`
	target.

2026-07-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (install-info-local): Clean out any existing groff
	Info files in `$(DESTDIR)$(infodir)`, not `$(DESTDIR)/doc`.

	Fixes <https://savannah.gnu.org/bugs/?68498>.  Problem
	introduced by me in commit d79c3f3a4a, 2021-11-11.

2026-07-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[doc,man]: Add line layout diagram.

	* doc/line-layout.roff: New file uses pic(1) to replace ASCII
	art diagram of *roff output line geometry.
	* doc/doc.am: Define new macros `DOC_LINE_LAYOUT_EPS` and
	`DOC_LINE_LAYOUT_PNG` to track names of rendered forms of the
	foregoing pic(1) image.  Clean these files from the build
	directory.  Add them as prerequisites to the `$(GROFF_DVI)` and
	`$(GROFF_PDF)` targets, respectively.  Add the new file and its
	rendered forms to the `EXTRA_DIST` macro to ship them in our
	distribution archive.
	($(GROFF_HTML)): Add `DOC_LINE_LAYOUT_PNG` as prerequisite.
	Copy that file into the directory used by the split-by-node
	version of our Texinfo manual in HTML form, as required for
	makeinfo(1) to generate a non-broken "<img src>" element.
	(maintainer-clean-local): Clean the rendered image files from
	the build directory.
	(install-html-local): Install the rendered image file where the
	monolithic version of our Texinfo manual in HTML form can find
	it.
	(dist-gnueps): Drop apparently unneeded target, and
	`dist-hook`'s use of it as a prerequisite.
	($(DOC_LINE_LAYOUT_EPS)): New target rule renders the new file
	as Encapsulated PostScript file using groff(1), gs(1)
	{Ghostscript}, and sed(1), as documented in grops(1).
	($(DOC_LINE_LAYOUT_PNG)): New target rule renders the new file
	as a Portable Network Graphics file using convert(1)
	{ImageMagick}.
	* doc/groff.texi.in (Line Layout): Inline image.  Retain the
	ASCII art version, but output it only `ifinfo`--rendering to a
	format that doesn't support inline images.
	* man/groff.7.man (Line layout): Inline aforementioned pic(1)
	document with a `so` request, only if in troff mode.  Otherwise,
	use the existing ASCII art version.  So that installed systems
	don't have to manage the installation location of the file...
	* Makefile.am: ...update `.man` suffix rule to depend on
	soelim(1), and unconditionally run all man pages (which are
	generated files already anyway) through soelim(1), literally
	inlining the pic(1) region.  Pass soelim(1) `-I` options so that
	the "line-layout.roff" file should be found whether the build
	takes place inside or outside of the build tree.

	Fixes <https://savannah.gnu.org/bugs/?68407>.  Thanks to Stefan
	Möding for the new diagram!

2026-07-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/eqn.am:
	* src/preproc/pic/pic.am:
	* src/preproc/refer/refer.am: Improve clean behavior, deleting
	YACC/Bison-generated files _only_ from an out-of-source build
	tree.  Because they are shipped in the distribution archive,
	only the "maintainer-clean" target should remove them from the
	source tree.  Add new macros `GROFF_{EQN,PIC,REFER}_YACC_FILES`
	to track these artifacts.  Redefine `MAINTAINERCLEANFILES` in
	terms of these new macros.  Add `mostlyclean-{eqn,pic,refer}`
	targets to perform the cleaning.  Add these new targets as
	dependencies of `mostlyclean-local`.

2026-07-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am: Improve "maintainer-clean" target.
	(maintainer-clean-local): Rewrite recipe to use existing macro
	definitions instead of literals.  Recursively delete
	"$(GROFF_HTML).node", since that, too, is an artifact shipped in
	the distribution archive.

2026-07-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am: Improve "clean" target.
	(mostlyclean_doc): Clean the "doc/gnu.{eps,png}" files and
	generated forms of our Texinfo manual from an out-of-source-tree
	build directory.  Reorganize logic.
	(maintainer-clean-local): Stop cleaning files auxiliary to the
	generated forms of our Texinfo manual.

2026-07-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/groff.texi.in (Output Language Compatibility): On
	supported output formats, inline the "gnu with printing press"
	image as an end mark for this manual's main matter.  Doing so
	demands much build system foolery, in part because different
	output formats demand different image formats.
	* doc/doc.am: Define new macro `DOC_GNU_PNG` storing path to
	relevant image in PNG format.  Override definition of
	`TEXINPUTS` macro so that etex can locate the EPS file when
	generating DVI.  Ship `DOC_GNU_PNG` in our distribution archive.
	(install_doc_gnu_png): New target rule installs `DOC_GNU_PNG`
	file so that installed example files can access it.
	(install_doc_examples): Depend on `DOC_GNU_PNG`.
	(uninstall_doc_examples): Remove "gnu.png" file from example
	directory.
	($(GROFF_DVI)): Add dependency on `DOC_GNU_EPS`, since we're now
	embedding it in our Texinfo manual.
	($(GROFF_PDF)): Add dependency on `DOC_GNU_PNG`, since we're now
	embedding it in our Texinfo manual.
	($(GROFF_HTML)): Override Automake's definition of target with
	one that copies the "gnu.png" file where the HTML versions of
	our Texinfo manual can find it.
	(maintainer-clean-local): Remove "gnu.png" from the build
	directory.
	(install-html-local): Install the "gnu.png" file.
	($(DOC_GNU_PNG)): New target rule generates "gnu.png" from
	"gnu.xpm".

2026-07-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am: Use `GROFF_HTML` macro more aggressively.

2026-07-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (doc/Groff-PDF-Features.pdf): Add `$(DOC_GNU_PNG)`
	and `font/devpdf/stamp` as prerequisites for this target.  Drop
	duplicate `tbl` prerequisite.
	(doc/webpage.html): `$(DOC_GNU_PNG)` should be our prerequisite,
	not `$(DOC_GNU_EPS)`.
	($(GROFF_DVI)): Declare `$(DOC_GNU_EPS)` as prerequisite.
	($(GROFF_PDF)): Declare `$(DOC_GNU_PNG)` as prerequisite.

2026-07-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/txi-en.tex: Delete.
	* doc/doc.am (EXTRA_DIST): Stop shipping that file in our
	distribution archive.

	The macros defined in "doc/texinfo.tex" already handle English
	localization, making this vendored English template file
	redundant.  However, retaining it creates problems when
	overriding the `TEXINPUTS` macro, which a forthcoming change
	requires.  Specifically, the override seems to have altered the
	search path, causing this 13-year-old file to be discovered
	prior to TeX Live's own much more up-to-date version, and
	ultimately causing the Texinfo `@entry` command to fail.

2026-07-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Remove `string::remove_spaces()`.  It no longer has
	any call sites.

	* src/include/stringclass.h (class string): Delete declaration.
	* src/libs/libgroff/string.cpp (string::remove_spaces): Delete.

2026-06-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/main.cpp (strieq, process_options)
	(free_input_entry_format_list, process_format, process_data):
	Define functions as `static`; they do not require external
	linkage.

2026-06-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp (put_string): Make `NDEBUG`-safe.

2026-06-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp (string::clear): Refactor to
	reduce unnecessary memory writes.

2026-06-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp (string::move): Refactor to
	reduce heap manipulation and memory copying.

2026-06-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp (salloc, sfree_and_alloc)
	(string::operator+=(const char *))
	(string::operator+=(const string &)): Fix off-by-one errors,
	maintaining the new invariant that a groff `string` is always
	null-terminated.

2026-07-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::add_node): Fix code style
	nits.  Delete blank line within function definition (JJC style).
	Arrange equality comparisons to avoid inadvertent assignment to
	lvalue (GBR style).

2026-07-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/main.cpp: Refactor to use our own
	string-trimming function instead of the `remove_spaces()` member
	function of groff's bespoke `string` class.
	(trim_spaces): New function updates string parameter to remove
	leading and trailing spaces.
	(process_data): Call new function instead of member function.

2026-07-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Test "nospaces" region option behavior.

	* src/preproc/tbl/tests/nospaces-region-option-works.sh: Add
	test.
	* src/preproc/tbl/tbl.am (tbl_TESTS): Run test.

2026-07-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/main.cpp (process_data): Emit warning when
	ignoring excess table entries instead of doing so silently.

2026-07-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/main.cpp (strieq)
	(process_options)
	(free_input_entry_format_list)
	(process_format)
	(process_data):
	* src/preproc/tbl/table.cpp (init_span_reg)
	(compute_span_width): Define functions as `static`; they
	do not require external linkage.

	Fixes `-Wmissing-declarations` GCC warnings.

2026-07-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Move declarations of
	`dump_node_list_in_reverse()`...
	* src/roff/troff/int.cpp: ...and `dump_node_list()` from here...
	* src/roff/troff/node.h: ...to here.

2026-07-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Move declaration of
	`get_diversion_state()` from here...
	* src/roff/troff/input.h: ...to here.

2026-07-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp (configure_page_offset_request)
	* src/roff/troff/env.cpp (compare_ranges)
	(hyphenation_character_request)
	(do_break_request)
	(input_trap)
	(input_trap_continued)
	(line_tabs_request)
	(sptoa):
	* src/roff/troff/input.cpp (exit_troff)
	(handle_initial_request)
	(do_string_case_transform)
	(get_file_line)
	(do_macro_source)
	(usage):
	* src/roff/troff/node.cpp (node_list_character_type)
	(node_list_vertical_extent): Define functions as `static`; they
	do not require external linkage.

	Fixes `-Wmissing-declarations` GCC warnings.

2026-07-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor to kill off `ESCAPE_NEWLINE`.  There appears
	to be no advantage to encoding escaped newlines in macro
	definitions.  Its purpose cannot be to restore or pretty-print a
	macro definition exactly as it was input, as no mechanism for
	doing so exists, and comments are already discarded upon
	reading.

	* src/roff/troff/input.h: Delete definition of `ESCAPE_NEWLINE`
	constant.
	* src/roff/troff/input.cpp (read_character_in_copy_mode)
	(token::next)
	(string_iterator::fill)
	(do_define_macro): Stop handling constant.

	Fixes <https://savannah.gnu.org/bugs/?66987>.

2026-06-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/pic/object.cpp (graphic_object::add_text): Add new
	local constant `max_text_pieces` to impose limit on size of
	heap-allocated `text_piece` array.

2026-06-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/pic/object.cpp (graphic_object::add_text): Convert
	type of local variables `len` and `i` from `int` to `size_t`,
	since they're used as or compared to array indices.  Refactor
	loop to lift `i` out of it, since it requires a type
	declaration, and you can't do that after a comma in a C++98 for
	loop initialization expression.  Use `i` instead of `len` as the
	index into the `text` array since the value of `len` is now a
	loop invariant--`i` is the index.

2026-06-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/pic/lex.cpp (interpolate_macro_with_args): When
	warning of ignored excess macro arguments, explicitly state that
	they're ignored.

2026-06-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/pic/lex.cpp (interpolate_macro_with_args):
	Boolify.  Demote local variable `ignore` from `int` to `bool`
	and rename it to `is_ignoring_arguments`.  Assign to it using
	Boolean, not integer, literals.

2026-06-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/pic/lex.cpp: Slightly refactor.  Replace
	preprocessor macro `MAX_ARG` with new `static const size_t`
	`pic_macro_maximum_arg_count`.
	(class argument_macro_input)
	(process_body)
	(argument_macro_input::get)
	(argument_macro_input::peek)
	(interpolate_macro_with_args)
	(class copy_thru_input)
	(copy_thru_input::get)
	(copy_thru_input::peek)
	(copy_thru_input::get_line): Lexically replace `MAX_ARG` with
	`pic_macro_maximum_arg_count`.
	(class argument_macro_input, class copy_thru_input): Convert
	type of `argc` member variable from `int` to `size_t`, since
	it's used as an array index.  Update constructor declaration
	accordingly.
	(process_body): Convert type of local variables `j`, `i`, `n`,
	and `k` from `int` to `size_t`, since they're used or compared
	to array indices.
	(argument_macro_input::argument_macro_input)
	(argument_macro_input::~argument_macro_input)
	(argument_macro_input::get)
	(argument_macro_input::peek)
	(copy_thru_input::get)
	(copy_thru_input::peek)
	(get_thru_arg): Convert type of local variable `i` from `int` to
	`size_t`, since it's used as an array index.
	(get_thru_arg): Avoid modular arithmetic wraparound by adjusting
	loop test condition and consequent indices used to index into
	token buffer containing argument that isn't the name of a macro.
	(interpolate_macro_with_args): Convert type of local variable
	`argc` from `int` to `size_t`, since it's compared to an array
	index.

2026-06-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/lex.cpp (interpolate_macro_with_args): When
	warning of ignored excess macro arguments, report how many are
	supported.

2026-06-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/lex.cpp: Slightly refactor.  Replace magic
	constant `9` with new `static const size_t`
	`eqn_macro_maximum_arg_count`.  Retype variables used as array
	indices appropriately.  Retype `const` global `NCONTEXT` from
	`int` to `size_t` and make it `static`.  Retype global
	`context_index` from `int` to `size_t` and make it `static`.
	(class argument_macro_input): Convert type of `argc` member
	variable from `int` to `size_t`, since it's used as an array
	index.  Update constructor declaration accordingly.
	(argument_macro_input::argument_macro_input): Update constructor
	definition accordingly.
	(interpolate_macro_with_args): Use new `size_t` object instead
	of magic constant.  Convert type of `argc` member variable from
	`int` to `size_t`, since it's used as an array index.
	(init_table): Retype local variable `i` from `unsigned int` to
	`size_t`.
	(argument_macro_input::argument_macro_input)
	(show_context): Retype local variables `i` and `j` to `size_t`.
	(argument_macro_input::~argument_macro_input)
	(argument_macro_input::get)
	(argument_macro_input::peek)
	(flush_context): Retype local variable `i` to `size_t`.

2026-06-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/lex.cpp (interpolate_macro_with_args): Fix
	code style nits.  Parenthesize formally complex expressions.
	Arrange equality comparisons to avoid inadvertent assignment to
	lvalue.

2026-06-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/lex.cpp (interpolate_macro_with_args): Declare
	new `bool`, `is_ignoring_arguments`.  Use it within the macro
	argument reading loop to ignore any arguments past the ninth,
	so that they do not populate the `argv` array beyond its bounds.
	Neither AT&T nor GNU eqn has a syntax for interpolating tenth or
	subsequent arguments, nor any `shift` command that would made
	such arguments addressable.  Issue one warning per macro
	expansion with excess arguments.

	Fixes <https://savannah.gnu.org/bugs/?68468>.  Problem appears
	to date back to groff's birth.  Reported apparently by an LLM
	robot in <https://lists.gnu.org/archive/html/bug-groff/2026-06/\
	msg00053.html>.

2026-06-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn]: Regression-test Savannah #68468.

	* src/preproc/eqn/tests/\
	do-not-segv-on-excess-macro-arguments.sh: Do it.
	* src/preproc/eqn/eqn.am (eqn_TESTS): Run test.

2026-06-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn]: Add `lex_warning()` function.

	* src/preproc/eqn/eqn.h: Declare it.
	* src/preproc/eqn/lex.cpp (lex_warning): Define it.

2026-06-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Fix `-Wstringop-truncation`
	warnings.
	(map_special_character_for_device_output): Don't overwrite the
	null terminator in the `character` buffer.
	(init_charset_table): Use memcpy(3) instead of strncpy(3)
	because we're deliberately doing a partial write of a non-string
	`char` (byte) array into a buffer.

2026-06-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp
	(map_special_character_for_device_output): Slightly refactor.
	Drop confusing local variable `unibufsz` (which differs from a
	libgroff symbol only in lettercase) in favor of `UNIBUFSZ + 1`
	expression and (subsequently) `sizeof character`, which can both
	be computed at compile time.

2026-06-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/dictionary.cpp: Preprocessor-include "errarg.h"
	and "error.h" to make visible `fatal()` function.
	(dictionary::lookup): Add overflow check of dictionary capacity.
	GCC's static analyzer was suspicious that it could overflow.
	`capacity` is a `ssize_t`, but C++'s allocator (behind `new`)
	uses `size_t`.  If `capacity` wraps (overflows), emit fatal
	error.

2026-06-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff,troff]: Reallocate fatal error exit responsibilities,
	and communicate them to the compiler.

	* src/include/error.h: Annotate non-returning
	`fatal_with_file_and_line()`, `fatal()`, and
	`fatal_error_exit()` functions with `__noreturn__` attribute to
	ease static analysis.
	* src/libs/libgroff/error.cpp (do_error_with_file_and_line):
	Stop checking `type` and calling `fatal_error_exit()` if it's
	`FATAL`.
	(fatal, fatal_with_file_and_line): Call `fatal_error_exit()`
	from here instead.
	* src/roff/troff/div.h: Annotate non-returning
	`write_any_trailer_and_exit()` function declaration with
	`__noreturn__` attribute to ease static analysis.
	* src/roff/troff/input.cpp (do_error): Stop checking `type` and
	calling `write_any_trailer_and_exit()` if it's `FATAL`.
	(fatal): Call `write_any_trailer_and_exit()` from here instead.

2026-06-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/json_encode.cpp (json_encode_char):
	Explicitly initialize stack-allocated structure.  Fixes
	`-Wmaybe-uninitialized` warning.

2026-06-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/gpl.texi: Add copy of the GNU GPL in Texinfo format.
	* doc/doc.am: Add it to `EXTRA_DIST` so that it ships in our
	distribution archive.
	* doc/groff.texi.in: Document fact of dual-licensing on
	copyright page, inspired by GNU nano's approach.  `@include` the
	new "gpl.texi" file in the "Copying This Manual" appendix.

2026-06-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp: Trivially refactor.
	(sfree_alloc): Rename this...
	(sfree_and_alloc): ...to this.
	(string::operator=(const char*), string::operator=(char) [0])
	(string::move): Update call sites.

2026-06-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp (sfree_alloc): Avoid unnecessary
	memset(3) if the new string's `len` (length) is equal to the
	existing string's capacity (`oldsz`), because it is already
	{invariantly} null-terminated.

2026-06-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp (srealloc): Avoid unnecessary
	memset(3) if the new string's `length` is equal to the old
	string's `sz` (capacity), because it is already (invariantly)
	null-terminated.  Simplify condition for performing memcpy(3) of
	old contents to new: do it only if the old length is not zero.
	Unconditionally memset(3) the memory from the end of the new
	string to the end of string's capacity.

2026-06-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[refer]: Add smoke test.

	* src/preproc/refer/tests/artifacts/little-schemer.bib: Add.
	* src/preproc/refer/tests/smoke-test.sh: Add.
	* src/preproc/refer/refer.am (refer_TESTS): Run test.
	(EXTRA_DIST): Ship new artifact.

2026-06-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp (string::string): Drop redundant
	memset(3) calls; `salloc()` already ensures that the memory to
	which it returns a pointer is cleared.

2026-06-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Disable unused `string` functions.
	* src/include/stringclass.h: "`#if 0`"-out `string` constructor
	taking a `char` parameter and collation operator `friend`
	function declarations.
	* src/libs/libgroff/string.cpp (string::string)
	(operator<, operator<=, operator>, operator>=): "`#if 0`"-out
	corresponding function definitions.

2026-06-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp: Refactor.
	(string::operator=): assert(3) that the `p` parameter (a C
	string) is not a null pointer.  For `NDEBUG` builds, assign it
	an empty string literal in this situation.  Measure `p` with
	strlen(3) and call `sfree_alloc()` instead of `sfree()` on
	member variable `ptr` to size a buffer for it.  assert(3) that
	`sfree_alloc()` returns a non-null pointer.
	(sfree): Delete now-unused function.

2026-06-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp (string::clear): Maintain
	invariant that `ptr` is never a null pointer even in `NDEBUG`
	builds.

2026-06-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp: Manipulate assert(3)ions
	verifying the invariant of `ptr`'s non-nullity to sit closer to
	assignments thereto.  This way the assertions can/should
	reliably fail prior to null pointer dereference.  Also check
	this invariant in more places.
	(string::string, string::operator+=, string::remove_spaces):
	Relocate assertions.
	(string::append, string::set_length, put_string): Add
	assertions.
	(string::clear): Uncomment assertion.  Its comment was
	inaccurate.

2026-06-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp: Document invariant.
	(salloc, sfree_alloc): Always allocate room for a null
	terminator since the groff `string` class's `contents()` member
	function returns a C string.  That interface does not combine
	well with a class design that uses neither memset(3) nor ISO
	C++03 value initialization to fastidiously clean the allocated
	buffers (which, as of recently, we do).  This way we wear
	suspenders _and_ a belt.  As a side effect, we more often
	{re}allocate in chunks of 64 bytes a time, reducing the total
	number of allocations and improving build time by about 5%.

2026-06-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tmac.am: Add "tmac/devtag.tmac" to `TMAC_PACKAGE_MS`
	macro definition, since the package internally uses that
	auxiliary macro file, and any update to it should render an
	ms(7) document out-of-date.

2026-06-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn,pic,refer]: Improve maintainer-clean target.

	* src/preproc/eqn/eqn.am (maintainer-clean-eqn):
	* src/preproc/pic/pic.am (maintainer-clean-pic):
	* src/preproc/refer/refer.am (maintainer-clean-refer): New
	phony target rule scrubs directories housing files generated by
	GNU Bison.  Add each as dependency of `maintainer-clean-local`.

2026-06-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn]: Rearrange Automake material.

	* src/preproc/eqn/eqn.am: Organize build target generation
	before "clean"-stage stuff.

2026-06-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	[pic,refer]: Rearrange Automake material.

	* src/preproc/pic/pic.am:
	* src/preproc/pic/refer.am: Organize consistently with "eqn.am".

2026-06-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* Makefile.am: Fix coverage generation.
	(gen-coverage): Pass `--prefix` and `--ignore-errors` to
	genhtml(1) to kludge around the problem of Bison/YACC-generated
	source files being present in the _build_ tree rather than the
	source tree when doing out-of-tree (`VPATH`) builds.

	Fixes <https://savannah.gnu.org/bugs/?68304>.

2026-06-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* configure.ac: Make build robust against combination of
	maintainer mode, use of GNU Bison, Make's ordering of targets,
	and out-of-tree builds.  Use `AC_CONFIG_COMMANDS` macro to
	ensure that the eqn, pic, and refer directories in the build
	tree that will be populated by Bison (or YACC) exist in the
	event no C++ files from these subdirectories get compiled first.

	Fixes <https://savannah.gnu.org/bugs/?67808>.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (RE): Trivially refactor.  Rename register
	`an-RE-requested-level` to `an*RE-requested-level`.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Trivially refactor.  Rename macro.
	(an-deprecation-warn): Rename this...
	(an*deprecation-warn): ...to this.
	(AT, UC, DT, PD, SB, OP): Update interpolation sites.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grotty]: Slightly refactor.

	* src/devices/grotty/tty.cpp: Use ISO C++98 exceptions to handle
	heap storage allocation failures.  Preprocessor-include C++
	"<new>" header file.
	(tty_font::load_tty_font)
	(tty_printer::make_rgb_string)
	(tty_printer::has_color)
	(tty_printer::add_char)
	(tty_printer::begin_page):
	Catch `std:bad_alloc` exception and `fatal()` out with an
	attempt to describe what we were doing.

	Continues the long process of fixing Savannah #68192.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grops]: Slightly refactor.

	* src/devices/grops/ps.cpp:
	* src/devices/grops/psrm.cpp: Use ISO C++98 exceptions to handle
	heap storage allocation failures.  Preprocessor-include C++
	"<new>" header file.
	* src/devices/grops/ps.cpp:
	(ps_font::load_ps_font, ps_printer::set_subencoding)
	(ps_printer::get_subfont, ps_printer::define_encoding)
	(ps_printer::encode_fonts, ps_printer::set_style):
	* src/devices/grops/psrm.cpp:
	(resource_manager::lookup_resource)
	(resource_manager::lookup_font)
	(resource_manager::document_setup):
	Catch `std:bad_alloc` exception and `fatal()` out with an
	attempt to describe what we were doing.

	* src/devices/grops/psrm.cpp (resource_manager::document_setup):
	Trivially refactor to lift a repeated expression into a local
	variable, `count`.

	Continues the long process of fixing Savannah #68192.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grolj4]: Slightly refactor.

	* src/devices/grolj4/lj4.cpp: Use ISO C++98 exceptions to handle
	heap storage allocation failures.  Preprocessor-include C++
	"<new>" header file.
	(lj4_font::load_lj4_font): Catch `std:bad_alloc` exception and
	`fatal()` out with an attempt to describe what we were doing.

	Continues the long process of fixing Savannah #68192.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grolbp]: Slightly refactor.

	* src/devices/grolbp/lbp.cpp: Use ISO C++98 exceptions to handle
	heap storage allocation failures.  Preprocessor-include C++
	"<new>" header file.
	(lbp_font::load_lbp_font): Catch `std:bad_alloc` exception and
	`fatal()` out with an attempt to describe what we were doing.

	Continues the long process of fixing Savannah #68192.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/html/pushback.cpp: Migrate to ISO C++98 Boolean
	literals.  Drop preprocessor manipulations of `TRUE` and `FALSE`
	macros.
	(pushBackBuffer::pushBackBuffer, pushBackBuffer::getPB)
	(pushBackBuffer::isString): Use ISO C++98 Boolean literals.
	* src/preproc/html/pushback.h (class pushBackBuffer): Demote
	declared return type of `isString()` member function  from `int`
	to `bool`.
	* src/preproc/html/pushback.cpp
	(pushBackBuffer::getPB, pushBackBuffer::isString)
	(isDigit, isWhite, isHexDigit): Demote return type from `int` to
	`bool`.

	Continues the long process of fixing Savannah #66672.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/quotearg.c: Slightly refactor.  Favor C
	standard library symbol `EXIT_FAILURE` over integer literal "1".

	Continues the long process of fixing Savannah #66672.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/quotearg.c: Undefine file-local preprocessor
	macros after we're done with them.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/quotearg.c: Rationalize header file
	inclusions.  Arrange C standard library header file names in
	alphabetical order.  Annotate why they're included.  Drop
	inclusions that seem unnecessary ("<limits.h>" and
	"nonposix.h").

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Boolify "quotearg.c".

	* src/libs/libgroff/quotearg.c: Preprocessor-include
	"<stdbool.h>" header file to ensure visibility of `true` and
	`false` symbols.  Drop preprocessor manipulations of `TRUE` and
	`FALSE` macros.
	(needs_quoting): Migrate Boolean literals from preprocessor
	macros to language objects.  Demote return type from `int` to
	`bool`.

	Continues the long process of fixing Savannah #66672.

2026-06-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Trivially refactor.  Rename `string` class's private
	member function `grow1()` to `embiggen()`.  The former name is
	now potentially misleading because the internal function
	`srealloc()` now doubles a `string` object's capacity (`sz`)
	when exceeded.

	* src/include/stringclass.h (class string): Rename declaration.
	(string::operator+=): Update call site.
	* src/libs/libgroff/string.cpp (string::grow1): Rename this...
	(string:embiggen): ...to this.

2026-06-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp: Continue refactoring to
	implement new invariant: any existing `string` object is backed
	by "clean" storage.
	(string::move): Rewrite.  Use `sfree_alloc()`, which also backs
	`operator=()`, on destination string to perform replacement
	allocation.  Use memcpy(3) to copy contents from source string
	to destination.  Use member function `clear()` on source string.
	Add assert(3)ion enforcing new invariant.

2026-06-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp (string::operator=)
	(string::grow1, string::clear): Add assert(3)ion enforcing new
	invariant.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp (sfree_alloc, srealloc): Be more
	fasitidious with heap memory; when "shortening" the length of an
	existing `string`, zero out the memory from the new length to
	the capacity (which is not reduced).

2026-06-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp: Continue refactoring to
	implement new invariant: any existing `string` object is backed
	by "clean" storage.
	(sfree_alloc, srealloc): Simplify special-case handling of
	replacement string having zero length.  Deal with it as
	`salloc()` now does, using `initial_string_buffer_size` as the
	`amount` in that case.

2026-06-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp: Increase initial buffer size
	backing `string` objects from 8 to 64, and stop allocating
	double the requested length on initial or replacement
	allocations.  An initial buffer size of 64 appears to balance
	build time against minimization of reallocations.
	(salloc, sfree_alloc): Allocate only `len` `char` elements, not
	`len * 2`, unless `len` equals zero.
	(sfree_alloc): Drop now-tautologous assert(3)ion.

2026-06-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp: Continue refactoring to
	implement new invariant: any existing `string` object is backed
	by "clean" storage.
	(sfree): After deleting old storage, allocate "clean"
	replacement new storage of `initial_string_buffer_size`, just as
	`salloc()` does when given a zero second argument.  Also delete
	unused second function parameter.
	(string::~string): Stop calling `sfree()` (since it reallocates
	the backing storage) in favor of direct deletion, thus
	maintaining the invariant--it occurs only when the entire object
	is being destroyed.
	(string::operator=, string::move): Update to call `sfree()`with
	its new, simpler signature.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Use a more appropriate return type for
	`string::find()`: `ssize_t` instead of `size_t`, since the
	function can return `-1`.

	* src/include/stringclass.h:
	* src/libs/libgroff/string.cpp: Preprocessor-include C
	"<sys/types.h>" header file to ensure visibility of POSIX.1-2001
	type `ssize_t`.
	* src/include/stringclass.h: Update function declaration.
	* src/libs/libgroff/string.cpp (string::find): Update function
	definition.

	* src/preproc/tbl/table.cpp: Preprocessor-include C
	"<sys/types.h>" header file.
	(table::add_entry): Retype `len` local variable from `size_t` to
	`ssize_t` to pacify `-Wsign-compare` GCC warning.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/stringclass.h:
	* src/libs/libgroff/string.cpp: Preprocessor-include C
	"<stddef.h>" header file to ensure visibility of ISO C99 type
	`size_t`.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/soelim/soelim.cpp (usage, set_location, do_so):
	Define function as `static`; external linkage is not required.

	Fixes `-Wmissing-declarations` GCC warning.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/refer/command.cpp (get_word):
	* src/preproc/refer/ref.cpp (sortify_words)
	(sortify_word)
	(sortify_other)
	(sortify_title)
	(sortify_name)
	(sortify_date)
	(sortify_label)
	(reverse_names)
	(join_fields)
	(capitalize_field)
	(is_terminated):
	* src/preproc/refer/refer.cpp (rcompare): Define function as
	`static`; external linkage is not required.

	Fixes `-Wmissing-declarations` GCC warning.

2026-06-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/refer/command.cpp (input_item::input_item):
	Populate member variable `buffer` with copy initialization.  We
	shouldn't use `string::move()` because the string contents might
	not be heap-allocated in the first place.  Problem found the
	hard way with refactoring of groff's `string` class.

2026-06-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	[refer]: Migrate to strdup(3).

	* src/preproc/refer/command.cpp:
	* src/preproc/refer/token.cpp: Preprocessor-include C
	"<string.h>" header file.
	* src/preproc/refer/command.cpp (input_item::input_item):
	* src/preproc/refer/token.cpp (init_ascii, init_letter)
	(init_two_char_letter, init_strings): Migrate from libgroff's
	`strsave()` to POSIX's strdup(3).

	Continues the long process of fixing Savannah #66672.

2026-06-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/refer/command.cpp (input_item::~input_item): The
	storage backing the `filename` pointer is allocated (via
	`strsave()`) by malloc(3), not `new`, so free it with free(3),
	not `delete[]`.

2026-06-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/tests/\
	do-not-segv-when-backslash-R-in-text-block.sh: Revise test to
	stop using the presence of a "core" file as a failure oracle.
	Instead, pattern-match tbl(1)'s output for the `TE` macro call
	that gets issed only after the formerly buggy table processing
	completes successfully.

	Fixes <https://savannah.gnu.org/bugs/?68204>.

2026-06-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/tests/\
	do-not-segv-on-invalid-vertical-span-entry.sh: Revise test to
	stop using the presence of a "core" file as a failure oracle.
	Instead, pattern-match tbl(1)'s output for the `TE` macro call
	that gets issed only after the formerly buggy table processing
	completes successfully.

	Continues fixing <https://savannah.gnu.org/bugs/?68204>.

2026-06-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/pic/tests/\
	do-not-crash-when-reading-macro-arguments.sh: Revise test to
	stop using the presence of a "core" file as a failure oracle.
	Instead, pattern-match pic(1)'s output for the `PE` *roff macro
	call that gets issed only after the formerly buggy macro
	processing completes successfully.

	Begins fixing <https://savannah.gnu.org/bugs/?68204>.

2026-06-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/count-macro-arguments-correctly.sh: Add
	test verifying that macro arguments are counted correctly even
	in the presence of right-brace escape sequences.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-06-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (decode_macro_call_arguments): Handle
	right-brace escape sequences in macro arguments consistently
	with past groffs, and Solaris 10, DWB 3.3, and Heirloom Doctools
	troffs (but not _quite_ like Plan 9 troff, whose macro argument
	handling differs from all the others).

	Fixes <https://savannah.gnu.org/bugs/?68430>.  Problem
	introduced by me in commit ebf943aa66, 2026-04-20.

	Also completes fixing <https://savannah.gnu.org/bugs/?42675>.

2026-06-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #68430.

	* src/roff/groff/tests/\
	handle-right-brace-escape-as-macro-argument.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-06-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (assign_control_character_request)
	(assign_no_break_control_character_request): Fix (further)
	blunders in assert(3) usage.  Spurious assertion failures
	occurred when user attempted to set a control character to one
	that is already in use as the other control character, or the
	escape character.

	Fixes <https://savannah.gnu.org/bugs/?68420>.  Problem
	introduced by me in commit 20feac542d, 2025-11-23.  Thanks to
	Martin Simmons for the report.

2026-06-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #68420.

	* src/roff/groff/tests/c2-request-does-not-fail-assertion.sh:
	* src/roff/groff/tests/cc-request-does-not-fail-assertion.sh:
	Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run tests.

2026-06-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grohtml]: Migrate to ISO C++98 Boolean literals.

	* src/devices/grohtml/html-table.cpp:
	* src/devices/grohtml/html-text.cpp:
	* src/devices/grohtml/output.cpp:
	* src/devices/grohtml/post-html.cpp: Kill preprocessor-based
	definitions of `TRUE` and `FALSE` macros.  Replace macros `TRUE`
	and `FALSE` with language literals `true` and `false`,
	respectively.

	Continues the long process of fixing Savannah #66672.

2026-06-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grohtml]: Be more fastidious with heap-allocated memory.

	* src/devices/grohtml/post-html.cpp: Use ISO C++98 exceptions to
	handle heap storage allocation failures.  Preprocessor-include
	C++ "<new>" header file.  Declare and initialize variables
	outside of `try`/`catch` blocks.  Initialize such variables with
	null pointers where appropriate.
	(files::add_new_file)
	(text_glob::text_glob_html)
	(text_glob::text_glob_special)
	(text_glob::text_glob_line)
	(text_glob::text_glob_auto_image)
	(text_glob::text_glob_tag)
	(list:add)
	(list:insert)
	(page::page)
	(page::add)
	(page::add_tag)
	(page::add_line)
	(html_font::load_html_font)
	(assert_state::add)
	(generate_img_src)
	(html_printer::write_header)
	(html_printer::lookahead_for_tables)
	(html_printer::flush_page)
	(html_printer::draw)
	(html_printer::html_printer)
	(html_printer::begin_page)
	(get_str)
	(main): Do it.

	Continues the long process of fixing Savannah #68192.

2026-06-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp: Fix memory leak.
	Preprocessor-include C++ "<stack>" header file.
	(class char_buffer): Add new private member variable `strings`
	of type `std::stack<char *>`, to keep track of the strdup(3)ped
	pointers that our `add_string()` member functions return.
	(char_buffer::char_buffer): Initialize `strings`.
	(char_buffer::~char_buffer): Pop `strings` stack, free(3)ing
	strdup(3)ped pointers until empty.
	(char_buffer::add_string): strdup(3) the `char *` argument and
	push it onto the `strings` stack before returning.

2026-06-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp: Refactor.  New `static`
	`const` variable of type `size_t`, `char_buffer_block_size`,
	does what's written on the tin.
	(struct char_block): Drop; it has been used exclusively by the
	file-local `char_buffer` class.
	(class char_buffer): Replace `head` and `tail` private member
	variables--pointers to `char_block`s, with an STL vector of
	`char` called `vec`.
	(char_buffer::char_buffer): Drop initializers of `head` and
	`tail`.  Populate body with call of `std::vector<char>`
	constructor.
	(char_buffer::~char_buffer): Empty destructor body; being an STL
	container, we expect `vec` to dispose of its own backing storage
	when it goes out of scope (when its parent object, a
	`char_buffer`, is destroyed).
	(char_buffer::add_string): Rewrite to idiomatically populate
	`vec`, resizing it by `char_buffer_block_size` as needed.  Stop
	returning a pointer into the data backing the STL vector, as
	its `resize()` operation might alter its memory addresses, as
	realloc(3) can.  Return a strdup(3)-ed copy of the string
	instead.

	Continues the long process of fixing Savannah #66672.

2026-06-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp: Improve type-correctness.
	`html` is an object of type `simple_output` which contains a
	`word_list`, which contains a list of `word`s, each of which
	stores its contents in a `char *`, _not_ objects of groff's
	`string` class.
	(html_printer::write_html_anchor)
	(html_printer::write_xhtml_anchor)
	(html_printer::write_header): Populate `html` object with
	`contents()` of `header.header_buffer` object.
	(html_printer::do_heading): Catenate `header.header_buffer` with
	`g->text_string`, not a groff `string` constructed therefrom.

2026-06-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp (page::add_encode): Add null
	terminator to `html_string` groff `string`.  Its contents are
	shortly to become a C string.  Null-terminating it prevents
	trailing garbage from populating a `char_buffer`.

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grohtml]: Fix code style nit.

	* src/devices/grohtml/post-html.cpp
	(char_block::~char_block)
	(text_glob::~text_glob)
	(text_glob::remember_table)
	(element_list::~element_list)
	(list::sub_move_right)
	(replace_negate_str)
	(replace_str)
	(html_printer::lookahead_for_tables)
	(html_printer::draw): Simplify.  Don't wrap `delete` operations
	with null pointer checks.

	It is not necessary to make conditional the deletion (or array
	deletion) of a null pointer.  "If the _delete-expression_ calls
	the implementation deallocation function (3.7.3.2), and if the
	operand of the delete expression is not the null pointer
	constant, the deallocation function will deallocate the storage
	referenced by the pointer thus rendering the pointer invalid"
	{ISO/IEC 14882-1998, §5.3.5, paragraph 4}.  Or as Stroustrup
	puts it, "Applying _delete_ to zero has no effect." (_The C++
	Programming Language, Special Edition_, p. 128).

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp: Handle `NDEBUG` builds
	better.
	(text_glob::get_arg)
	(list::is_less)
	(page::add_and_encode)
	(header_desc::write_headings)
	(assert_state:add)
	(assert_state:compare)
	(assert_state:close)
	(replace_negate_str)
	(assert_state:set)
	(assert_state:build)
	(assert_state:check_value)
	(html_printer::is_bold)
	(html_printer::make_bold)
	(html_printer::emit_raw)
	(html_printer::handle_tag_within_title)
	(html_printer::do_center)
	(exists)
	(html_printer::do_auto_image)
	(html_printer::do_heading)
	(html_printer::do_linelength)
	(html_printer::do_pageoffset)
	(html_printer::do_indentation)
	(html_printer::do_tempindent)
	(html_printer::do_verticalspacing)
	(html_printer::do_pointsize)
	(html_printer::do_fill)
	(html_printer::do_head)
	(html_printer::do_space)
	(html_printer::do_tab_ts)
	(html_printer::do_tab)
	(html_printer::do_col)
	(html_printer::troff_tag)
	(html_printer::do_math)
	(html_printer::calc_po_in)
	(html_printer::determine_space)
	(html_printer::end_font)
	(html_printer::start_font)
	(html_printer::do_font)
	(html_printer::start_subscript)
	(html_printer::start_superscript)
	(html_printer::end_subscript)
	(html_printer::end_superscript)
	(html_printer::do_end_para)
	(html_printer::emit_html)
	(html_printer::set_line_thickness)
	(html_printer::draw)
	(html_printer::sbuf_continuation)
	(html_printer::overstrike)
	(html_printer::set_char)
	(html_printer::set_numbered_char)
	(html_printer::set_char_and_width)
	(html_printer::emit_link)
	(get_str)
	(make_val)
	(html_printer::special)
	(html_printer::devtag)
	(main): After (almost) every assert(3)ion, add appropriate
	{usually complementary} tests and return early from functions
	when invariants are not maintained.
	(html_printer::add_table_end) [DEBUG_TABLES]: Replace
	assert(3)ion with fatal error, since we know we're doing highly
	targeted debugging.
	(html_printer::do_file_components): Avoid null pointer
	dereference of `current_paragraph` if `NDEBUG` defined; simply
	guard the dereference and otherwise proceed normally since this
	function is responsible for writing out a lot of high-level
	HTML structure, and failing to mark an invalid/nonexistent
	paragraph as "done" seems relatively harmless.

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp (html_printer::do_job_name):
	Add paranoia.  Add assert(3)ion that our (C string) argument is
	not a null pointer.  For `NDEBUG` builds, return early if it is.

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp (generate_img_src): Add
	paranoia.  Ensure we don't dereference a null `filename`
	pointer.  (Strictly, the `static` function `exists()` handles
	that case for us, but my idea of design-by-contract permits
	sanity checks on both ends of a call.  This choice also gives us
	flexibility to replace or change `exists()`, possibly with a
	standard library function call.)

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp: Fix code style nit.
	(main): Return using exit(3), not `return`.

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grohtml]: Be more fastidious with heap-allocated memory.

	* src/devices/grohtml/output.cpp: Use ISO C++98 exceptions to
	handle heap storage allocation failures.  Preprocessor-include
	C++ "<new>" header file.
	(word::word): Slightly refactor.  Introduce new local variable
	`amount` to track the count of `char`s we wish to allocate, so
	that we can use it both in a `new` allocation and in the fatal
	diagnostic thrown if that allocation fails.
	(word::word):
	(word_list::add_word): Catch `std::bad_alloc` exception and
	`fatal()` out with an attempt to describe what we were doing.

	Continues the long process of fixing Savannah #68192.

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grohtml]: Fix code style nit.

	* src/devices/grohtml/output.cpp (word::word)
	(word_list::word_list)
	(word_list::add_list): Do it.  Use idiomatic C++98 null pointer
	literal instead of C's `NULL`.

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grohtml]: Be more fastidious with heap-allocated memory.

	* src/devices/grohtml/html-table.cpp: Use ISO C++98 exceptions
	to handle heap storage allocation failures.  Preprocessor-
	include C++ "<new>" header file and project-local "errarg.h" and
	"error.h" header files.
	(tabs::init): Slightly refactor.  Introduce new local variable
	`newtab` (a pointer to `tab_position`, lifting 2 identical
	attempted memory allocations out of both branches of an if/else.
	(tabs::init):
	(html_table::html_table):
	(html_table::insert_column):
	(html_indent::html_indent): Catch `std::bad_alloc` exception and
	`fatal()` out with an attempt to describe what we were doing.

	Continues the long process of fixing Savannah #68192.

2026-06-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp
	(html_printer::determine_header_level): Fix code style nit.
	Isolate loop variable within `for` loop scope.

2026-06-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp (string::remove_spaces): Fix code
	style nit.  Parenthesize formally complex expression.

2026-06-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp: Back all strings with clean
	storage.  And ensure that all `string`s are backed by storage
	such that the capacity `sz` is always nonzero, and the
	`contents()` member function never returns a null pointer.  Add
	assert(3)ions to enforce these invariants.  New `static` `const`
	variable `initial_string_buffer_size` does what it says,
	reserving a minimum backing allocation even for empty strings.
	(salloc): Discard zero-length code, except insofar as a
	zero-length allocation request gets `initial_string_buffer_size`
	`char` array elements.
	(string::string): Discard now tautologously true `if` tests.
	Drop early return from constructor taking only a `char *`
	argument, so that we can assert(3) a postcondition invariant.

2026-06-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	Refactor groff's bespoke `string` class to use `size_t` instead
	of `int` to track array sizes and indices.

	* src/include/stringclass.h: Update declarations and `inline`
	function definitions.
	* src/libs/libgroff/string.cpp: Update definitions and local
	variables.  Drop now tautologically true assert(3)ions.
	(string::remove_spaces): This function searches for spaces
	backward from the end of the string contents.  Alter loop
	invariant from a non-negative array index (now impossible) to
	one that is less than the array length.  Discard now-unreachable
	logic branch.

	* src/preproc/eqn/lex.cpp (add_quoted_context):
	* src/preproc/preconv/preconv.cpp (get_tag_lines):
	* src/preproc/refer/label.ypp (format_serial)
	(alternative_expr::evaluate)
	(substitute_expr::evaluate)
	(int_set::set)
	(int_set::get):
	* src/preproc/refer/ref.cpp (reference::canonicalize_authors):
	* src/preproc/tbl/table.cpp (table::add_entry): Retype variables
	populated by or compared to applicable `string` member functions
	from `int` to `size_t`.

2026-06-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp: Drop unnecessary prototypes of
	functions that lack external linkage (they're `static`) and do
	not require forward declarations.

2026-06-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Boolify groff's `string` class.

	* src/include/stringclass.h:
	* src/libs/libgroff/string.cpp: Demote return values of
	`operator==()`, `operator!=()`, `empty()`, `operator<=()`,
	`operator<()`, `operator>=()`, and `operator>()` from `int` to
	`bool`.

2026-06-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp: Use ISO C++98 exceptions to
	handle heap storage allocation failures.  Preprocessor-include
	C++ "<new>" header file.  Preprocessor-include "error.h" and its
	prerequisite "errarg.h" to make visible the `fatal()` symbol.
	(salloc, sfree_alloc, srealloc, string::remove_spaces): Catch
	`std:bad_alloc` exception and `fatal()` out with an attempt to
	describe what we were doing.

	Continues the long process of fixing Savannah #68192.

2026-06-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp (salloc, sfree_alloc, srealloc)
	(string::string, string::clear, string::remove_spaces): Zero out
	memory allocations from the heap, and when user requests erasure
	of `string` contents.

2026-06-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp: Fix code style nits.
	Parenthesize formally complex expressions.  Arrange equality
	comparisons to avoid inadvertent lvalue assignment (exception:
	in overloads of comparison operators, retain "risky" arrangement
	to keep structural parallels and contrasts clear).

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/html-table.cpp (tabs::tabs)
	(tabs::delete_list)
	(tabs::compatible)
	(tabs::init)
	(tabs::find_tab)
	(tabs::get_tab_pos)
	(tabs::get_tab_align)
	(tabs::dump_tabs)
	(html_table::html_table)
	(html_table::remove_cols)
	(html_table::set_linelength)
	(html_table::get_effective_linelength)
	(html_table::emit_table_header)
	(html_table::get_right)
	(html_table::emit_colspan)
	(html_table::emit_td)
	(html_table::emit_col)
	(html_table::finish_row)
	(html_table::emit_new_row)
	(html_table::add_column)
	(html_table::get_column)
	(html_table::insert_column)
	(html_table::modify_column)
	(html_table::find_column)
	(html_table::no_columns)
	(html_table::is_gap)
	(html_table::no_gaps)
	(html_table::dump_table): Fix code style nit.  Use idiomatic
	C++98 null pointer literal instead of C's `NULL`.

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	[pic]: Rationalize header file inclusions.  Move some into
	"object.h" or "pic.h" where not doing so introduces cycles.

	* src/preproc/pic/output.h: Preprocessor-include "text.h".
	* src/preproc/pic/lex.cpp:
	* src/preproc/pic/main.cpp:
	* src/preproc/pic/object.cpp:
	* src/preproc/pic/output.cpp:
	* src/preproc/pic/pic.h:
	* src/preproc/pic/pic.ypp:
	* src/preproc/pic/tex.cpp:
	* src/preproc/pic/troff.cpp: Arrange inclusions of "libgroff"
	header files before pic-specific ones.  Within such inclusions,
	sort header file names in alphabetical order, where the header
	file dependency graph permits.  Annotate exceptions.
	* src/preproc/pic/main.cpp: Preprocessor-include "<limits.h>" to
	ensure visiblity of `CHAR_MAX` symbol.
	* src/preproc/pic/pic.h: Declare `extern` symbols from "lex.cpp"
	here, not in "pic.ypp".

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	[pic]: Fix code style nit.

	* src/preproc/pic/lex.cpp (process_body)
	(interpolate_macro_with_args, lookup_keyword)
	(get_token_after_dot, get_token, get_delimited, do_define)
	(do_undef, get_thru_arg):
	* src/preproc/pic/main.cpp (do_picture, usage):
	* src/preproc/pic/object.cpp (draw_arrow):
	* src/preproc/pic/troff.cpp (strsame): Define functions as
	`static`; external linkage is not required.

	Fixes `-Wmissing-declarations` GCC warning.

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/pic/lex.cpp: Fix code style nit.  Add `extern`
	declarations of `yylex()` and `yyerror()` since--as I understand
	it--there is still no standard header file that prototypes them.

	Fixes `-Wmissing-declarations` GCC warning.

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grn]: Give command a proper header file for external symbols.

	* src/preproc/grn/hdb.cpp:
	* src/preproc/grn/hpoint.cpp:
	* src/preproc/grn/main.cpp: Move `extern` declarations of
	symbols from here...
	* src/preproc/grn/grn.h: ...to this new file.
	* src/preproc/grn/hdb.cpp:
	* src/preproc/grn/hgraph.cpp:
	* src/preproc/grn/hpoint.cpp:
	* src/preproc/grn/main.cpp: Preprocessor-include new file.
	* src/preproc/grn/grn.am: Add new file to `grn_SOURCES` macro
	definition.

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/grn/main.cpp: Rationalize header file inclusions.
	Arrange inclusions of "libgroff" header files before grn-
	specific one.  Within such inclusions, sort header file names in
	alphabetical order (where the header file dependency graph
	permits).

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grn]: Rearrange code.

	* src/preproc/grn/main.cpp (operand): Relocate definition to
	precede function housing its only call site (`main()`).  Define
	functions as `static`; external linkage is not required.
	(main): Drop now unnecessary function-local declaration of
	`operand()`.
	* src/preproc/grn/hdb.cpp (DBCreateElt):
	* src/preproc/grn/hgraph.cpp (line, change):
	* src/preproc/grn/main.cpp (usage, add_file, initpic): Define
	functions as `static`; external linkage is not required.

	Fixes `-Wmissing-declarations` GCC warning.

2026-05-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn]: Fix code style nit.

	* src/preproc/eqn/main.cpp (do_file, usage):
	* src/preproc/eqn/lex.cpp (flush_context, show_context)
	(add_context, add_quoted_context, get_delimited_text)
	(interpolate_macro_with_args, get_token, do_include)
	(ignore_definition, do_definition, do_undef, do_gsize, do_gfont)
	(do_gifont, do_grfont, do_gbfont, do_space, do_ifdef, do_delim)
	(do_chartype, do_set, do_reset):
	* src/preproc/eqn/text.cpp (special_to_entity): Define functions
	as `static`; external linkage is not required.
	* src/preproc/eqn/lex.cpp: Add `extern` declarations of
	`yylex()` and `yyerror()` since--as I understand it--there is
	still no standard header file that prototypes them.

	Fixes `-Wmissing-declarations` GCC warning.

2026-05-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libbib/common.cpp: Preprocessor-include "index.h" to
	make visible prototype of `hash()`.

	Fixes `-Wmissing-declarations` GCC warning.

2026-05-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Trivially refactor.  Rename string `an-pageref`
	to `an*pageref`.
	(PT, an*abbreviate-page-identifier, an-footer)
	([initialization]): Update definition and interpolation sites.

2026-05-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (LE): Throw warning when macro called with no
	lists open.

2026-05-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Trivially refactor.
	(an-warn): Rename this...
	(an*warn): ...to this.
	(an*abbreviate-inner-footer, SH, SS, TP, MT, ME, UR, UE, LS)
	(TE): Update call sites.

2026-05-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (suppress_node::tprint): Migrate from
	libgroff's `strsave()` to POSIX's strdup(3).

	Continues the long process of fixing Savannah #66672.

2026-05-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp (top_level_diversion::remove_trap)
	(top_level_diversion::remove_trap_at)
	(top_level_diversion::change_trap)
	(top_level_diversion::print_traps): Fix code style nit.
	Explicitly compare variables of pointer type to null pointer
	literal instead of letting them pun down to Booleans.

2026-05-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp (top_level_diversion::add_trap)
	(top_level_diversion::remove_trap)
	(macro_diversion::set_diversion_trap): Add assert(3)ions and
	{if `#define NDEBUG`} early returns if the `symbol` argument
	`is_null()`.

2026-05-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp (when_request, diversion_trap_request):
	Enforce space requirement between first and second arguments to
	`wh` and `dt` requests.

	* doc/groff.texi.in (Other Differences):
	* man/groff_diff.7.man (Other differences):
	* NEWS: Document this behavioral difference from AT&T troffs.

	Fixes <https://savannah.gnu.org/bugs/?68357>.  Problem appears
	to date back to groff's birth.

2026-05-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #68357.

	* src/roff/groff/tests/\
	error-no-space-between-dt-or-wh-arguments.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-05-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test `wh` and `ch` requests.

	* src/roff/groff/tests/wh-and-ch-requests-work.sh: Do it.
	* src/roff/groff/groff.am: Run test.

2026-05-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (has_arg): Revise semantics.
	Function now returns `false` if the current token is anything
	but a space.

2026-05-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp (set_page_number_request): Refactor--
	trivially now but not so in the near future.  Stop calling
	`has_arg()` redundantly.  A forthcoming change will alter the
	semantics of `has_arg()` to return true only if an _argument_
	lies ahead in the input stream, and a space must occur before
	any _argument_.  `has_arg()`, when not "peeking", advances the
	input stream cursor, and this function has already called it (to
	throw a diagnostic if the argument is omitted), so the cursor is
	already at the argument's first character.  The argument is at
	{or under} the formatter's feet, and does not "lie ahead".
	Manual inspection suggests that other request handlers are
	already careful not to call `has_arg()` except (1) upon
	receiving control from the request-handler dispatcher (via a
	function pointer); or (2) after calling a function that itself
	advances the input stream cursor, like `read_identifier()`.

2026-05-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tfmtodit]: Be more fastidious with heap-allocated memory.

	* src/utils/tfmtodit/tfmtodit.cpp: Use ISO C++98 exceptions to
	handle heap storage allocation failures.  Preprocessor-include
	C++ "<new>" header file.
	(tfm::load): Catch `std:bad_alloc` exception and `fatal()` out
	with an attempt to describe what we were doing.

	Continues the long process of fixing Savannah #68192.

2026-05-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tfmtodit]: Be more fastidious with heap-allocated memory.

	* src/utils/tfmtodit/tfmtodit.cpp (struct char_list): Declare
	destructor.
	(char_list::~char_list): Define destructor free(3)ing memory
	allocated by strdup(3) in constructor.
	(main): Handle failure of strdup(3) as a fatal error.  free(3)
	the storage it allocates when done with it.

	Continues the long process of fixing Savannah #68192.

2026-05-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/tfmtodit/tfmtodit.cpp (char_list::char_list, main):
	Migrate from libgroff's `strsave()` to POSIX's strdup(3).

	Continues the long process of fixing Savannah #66672.

2026-05-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/tfmtodit/tfmtodit.cpp (main): Use ISO C standard
	constant `M_PI` instead of our own `PI`.

	Continues the long process of fixing Savannah #66672.

2026-05-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/tfmtodit/tfmtodit.cpp (read2, read4, read_map):
	Fix code style nit.  Define functions as `static`; external
	linkage is not required.

2026-05-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/tfmtodit/tfmtodit.cpp (usage): Relocate function
	definition to obviate need for forward declaration.

2026-05-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/tfmtodit/tfmtodit.cpp (tfm::load, gf::load)
	(read_map): Characterize files being read as "invalid", not
	"bad".

2026-05-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/tfmtodit/tfmtodit.cpp: Boolify.
	(class tfm): Demote member function declaration return types
	for `load()`, `contains()`, `get_param()`, and `get_lig()` from
	`int` to `bool`.
	(class kern_iterator): Demote member function declaration return
	type for `next()` from `int` to `bool`.
	(class gf): Demote member function declaration return types
	for `skip()` and `load()` from `int` to `bool`.
	(kern_iterator::next)
	(tfm::get_lig)
	(tfm::contains)
	(tfm::get_param)
	(tfm::load)
	(gf::load)
	(gf::skip): Update definitions.  Return Boolean, not integer,
	literals.
	(read_map): Demote return type from `int` to `bool`.
	(tfm::load): Declare local variable closer to point of use.
	(main): Demote local variable `special_flag` from `int` to
	`bool` and rename it to `is_font_special`.  Assign to it using
	Boolean, not integer, literals.

2026-05-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/tfmtodit/tfmtodit.cpp (tfm::load, gf::load)
	(read_map, main): Revise diagnostic messages to more closely
	match terminology from our documentation and model language from
	elsewhere in the source tree.

	Continues the long process of fixing Savannah #66519.

2026-05-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/tfmtodit/tfmtodit.cpp (tfm:load): Fix code style
	nits.  Parenthesize formally complex expressions.  Explicitly
	compare variables of pointer type to null pointer literal
	instead of letting them pun down to Booleans.  Arrange equality
	comparisons to avoid inadvertent lvalue assignment.
	(main): Consistently use exit(3) to return from `main()` instead
	of `return`.  Simplify an `error()`+`return` combination to a
	`fatal()` call.

2026-05-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/tfmtodit/tfmtodit.cpp (kern_iterator::next)
	(tfm::get_lig)
	(tfm::get_italic)
	(tfm::load)
	(gf::load)
	(main): Fix code style nits.  Parenthesize formally complex
	expressions.

2026-05-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grodvi]: Slightly refactor.

	* src/devices/grodvi/dvi.cpp: Use ISO C++98 exceptions to handle
	heap storage allocation failures.  Preprocessor-include C++
	"<new>" header file.
	(dvi_font::load_dvi_font): Catch `std:bad_alloc` exception and
	`fatal()` out with an attempt to describe what we were doing.

	Continues the long process of fixing Savannah #68192.

2026-05-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Extend argument printer for diagnostic messages to
	handle object of type `unsigned long int`, so that we can report
	`sizeof` values messages, perhaps among other purposes.

	* src/include/errarg.h (class errarg): Extend `type` enumeration
	type to support `UNSIGNED_LONG_INTEGER` constant.  Add member
	`l` of type `unsigned long int` to anonymous union.  Declare
	constructor taking argument of `unsigned long int` type.
	* src/libs/libgroff/errarg.cpp (errarg:errargs): Define new
	constructor taking argument of `unsigned long int` type.
	(errarg::print): Handle case of `UNSIGNED_LONG_INTEGER`,
	delegating printing to fprintf(3).

2026-05-25  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Handle URI encoded characters (%nn) correctly.

	* src/devices/gropdf/gropdf.pl (LoadPDF): A `%` is used to
	introduce a comment in a PDF, but it may also be used to hex
	encode a character in a URI of an external link.  Page 620 of
	the PDF 1.7 standard has a NOTE about this.  Fix it.

2026-05-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	When building outside of the source tree and with the configure
	script's dependency tracking disabled, work harder to ensure
	that the parent directories of build artifacts exist before
	attempting to populate them.

	* font/devpdf/devpdf.am (font/devpdf/SS):
	* src/libs/libgroff/libgroff.am (src/libs/libgroff/version.cpp):
	Do it.

	Fixes <https://savannah.gnu.org/bugs/?68372>.  Thanks to Ross
	Burton for the report.

2026-05-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp
	(add_hyphenation_exception_words_request): Refactor.  Convert
	`while` loop to `do-while` loop.  (1) We already know at first
	loop entry that the condition is true and (2) structuring it
	this way makes more sense given a planned revision to
	`has_arg()` to tighten up its semantics.

2026-05-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (set_hyphenation_codes):
	Refactor in preparation for firming-up of the semantics and
	logic of request arguments to constitute space-separated lexical
	tokens, as our documentation defines "argument".  Call
	`token::skip_spaces()` when "pumping" the input stream and
	govern the input-reading loop using `token::is_newline()` and
	`token::is_eof()` instead of `has_arg()`.

2026-05-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (set_character_flags_request):
	Refactor; use `token::is_any_character()` instead of `has_arg()`
	as loop control, in preparation for firming-up of the semantics
	and logic of request arguments to constitute space-separated
	lexical tokens, as our documentation defines "argument".

2026-05-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (set_hyphenation_codes): Throw error
	if either the "source" or "destination" operand of a hyphenation
	code assignment pair it not a character token.

2026-05-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp
	(define_font_specific_character_request): Check for presence of
	arguments after the first before handing off processing of the
	remainder of the input line to `define_character()`.  Resolves
	assertion failure thrown by the latter function.

	Fixes <https://savannah.gnu.org/bugs/?68395>.  Problem
	introduced by me in commit f87b107497, 20 November.

2026-05-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #68395.

	* src/roff/groff/tests/\
	do-not-crash-on-missing-fschar-argument.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-05-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp
	(escape_off_request)
	(save_escape_char_request)
	(restore_escape_char_request)
	(assign_control_character_request)
	(assign_no_break_control_character_request)
	(backtrace_request)
	(exit_request)
	(return_macro_request)
	(do_request)
	(flush_pending_lines) [WIDOW_CONTROL]
	(print_macro_request)
	(read_from_terminal_request)
	(ignore)
	(remove_macro)
	(rename_macro)
	(alias_macro)
	(substring_request)
	(length_request)
	(unformat_macro)
	(line_file)
	(source_request)
	(source_quietly_request)
	(pipe_source_request)
	(ps_bbox_request)
	(tag)
	(taga)
	(warnscale_request)
	(spreadwarn_request)
	(translate)
	(translate_no_transparent)
	(translate_input)
	(hyphenation_patterns_file_code)
	(abort_request)
	(pipe_output)
	(system_request)
	(vjustify) [COLUMN]
	(macro_source_request)
	(macro_source_quietly_request)
	(configure_desired_warnings_request): Fix code style nits;
	declare as `static`; external linkage is not required.

2026-05-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp
	(stringdown_request)
	(stringup_request): Fix code style nits; declare as `static`;
	external linkage is not required.

2026-05-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor and fix code
	style nits.
	(next_file)
	(shift)
	(compatible): Rename these...
	(next_file_request)
	(shift_request)
	(configure_att_compatibility_mode_request): ...to these, and
	declare them as `static`; external linkage is not required.
	(init_input_requests): Update wire-uppery of request names to
	handler functions.

2026-05-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Fix code style nits.
	(do_register_assignment, do_string_assignment): Explicitly
	compare variable of pointer type to null pointer literal instead
	of letting it pun down to a Boolean.

2026-05-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp: Refactor to rationalize and
	parallelize vertical position trap request handlers.
	(when_request): Check for presence of arguments; if none, throw
	warning in category "missing".
	(diversion_trap_request): Clear any existing diversion trap if
	given a valid vertical position argument but no second argument,
	analogously to `ch` request.

2026-05-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.h (class diversion): Declare new pure
	virtual member function `print_diversion_trap()` returning
	`void`.
	(class macro_diversion)
	(class top_level_diversion): Declare member function
	`print_diversion_trap()`.
	* src/roff/troff/div.cpp
	(macro_diversion::print_diversion_trap): New member function
	reports properties of a diversion trap if one exists.
	(top_level_diversion::print_diversion_trap): New member function
	throws assert(3)ion if called.  Internal logic should ensure
	that such a call is impossible.
	(print_traps_request): Call the `print_traps()` member function
	of `topdiv` (as before) only if it is the current diversion.
	Otherwise, the current diversion is a macro diversion, so call
	its `print_diversion_trap()` member function.

	* doc/groff.texi.in (Diversion Traps, Debugging):
	* man/groff.7.man (Request short reference):
	* man/groff_diff.7.man (New requests): Document it.

	* src/roff/groff/tests/pwh-request-works.sh: Unit-test request.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

	Fixes <https://savannah.gnu.org/bugs/?68358>.

2026-05-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (char_list::get): De-optimize read
	access at the end of a `char_list`, because the pointer
	arithmetic used can access heap storage beyond the end of the
	underlying `char_block` used to house the list.

	Fixes <https://savannah.gnu.org/bugs/?68340>.  Resolves ASAN
	runtime error when formatting the groff_mdoc(7) man page in
	troff mode.  Thanks to Bjarni Ingi Gislason for the report.

2026-05-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor and fix code
	style nit.
	(eoi_macro)
	(blank_line_macro)
	(leading_spaces_macro): Rename these...
	(configure_end_of_input_macro_request)
	(configure_blank_line_macro_request)
	(configure_leading_spaces_macro_request): ...to these.
	(configure_end_of_input_macro_request)
	(configure_blank_line_macro_request)
	(configure_leading_spaces_macro_request): Declare as `static`;
	external linkage is not required.
	(init_input_requests): Update wire-uppery of request names to
	handler functions.

2026-05-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Implement `LS`/`LE` indentation management.

	* tmac/an.tmac (TP, IP, HP): If macro called in a list context
	{the "list depth" is greater than zero}, and an indentation for
	the current list depth is defined, set the prevailing indent to
	that indentation.  {We still, and subsequently, override the
	prevailing indent with the indentation argument to these macros,
	if present.}

	* tmac/groff_man.7.man.in (List enclosure macros): Document it.

	* tmac/tests/an_LS-and-LE-work.sh: Unit-test effect of list
	indentation on `HP` macro behavior.  Update test expecations of
	`TP` behavior now that indentation is inherited.  Apply a
	tab-to-space-translating tr(1) command on the test output,
	fearing inconsistencies among Unices in how nl(1) prefixes the
	lines it filters.

	Continues fixing <https://savannah.gnu.org/bugs/?68335>.

2026-05-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grotty/tty.cpp: Preprocessor-include
	"<string.h>" header file, since strcmp(3) and strncmp(3) are
	used (the former only in `#if 0`-ed code).

2026-05-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/html-text.cpp: Preprocessor-include
	"<string.h>" header file, since strcmp(3) and strlen(3) are
	used.
	* src/devices/grohtml/post-html.cpp: Preprocessor-include
	"<strings.h>" header file, since strcasecmp(3) is used.

2026-05-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/preconv/preconv.cpp: Preprocessor-include
	"<strings.h>" header file, since strcasecmp(3) is used.

2026-05-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/post-html.cpp
	(html_printer::write_navigation): Fix code style nit.
	Parenthesize formally complex expressions.

2026-05-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/an_MR-works.sh: Validate behavior of macro when
	given only one argument.

	Prompted by GitHub user avih in
	<https://github.com/gwsw/less/pull/770>.

2026-05-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/an_MR-works.sh: Future-proof test against more
	spaceful "grout" (still within CSTR #54/#97 specifications).

	See <https://savannah.gnu.org/bugs/?63544>.

2026-05-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[hpftodit]: Give command a proper header file for external
	symbol.

	* src/utils/hpftodit/hpftodit.cpp: Move `extern` declaration of
	symbol defined in "hpuni.cpp" from here...
	* src/utils/hpftodit/hpftodit.h: ...to this new file.
	* src/utils/hpftodit/hpftodit.cpp:
	* src/utils/hpftodit/hpuni.cpp: Preprocessor-include new file.
	* src/utils/hpftodit/hpftodit.am: Add new file to
	`hpftodit_SOURCES` macro definition.

2026-05-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Give command a proper header file for external symbols.

	* src/roff/groff/pipeline.c: Move `extern` declarations of
	symbols defined in "groff.cpp" from here...
	* src/roff/groff/groff.h: ...to this new file.
	* src/roff/groff/groff.cpp:
	* src/roff/groff/pipeline.c: Preprocessor-include new file.
	* src/roff/groff/groff.cpp: Wrap this inclusion in `extern "C"`
	brace scope to indicate need for C-compatible calling
	conventions.
	* src/roff/groff/groff.am: Add new file to `groff_SOURCES` macro
	definition.

	Fixes `-Wmissing-declarations` GCC warning.

2026-05-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/html/pre-html.cpp (html_system, make_string)
	(min, max, addArg, addRegDef, print_args):
	* src/preproc/html/pushback.cpp (localexit):
	Declare `static`; external linkage is not required.  Fixes
	`-Wmissing-declarations` GCC warning.

2026-05-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/html-text.cpp: Slightly refactor.  Use
	ISO C++98 exceptions to handle heap storage allocation failures.
	Align code style a bit more with groff conventions.
	Preprocessor-include C++ "<new>" header file.
	(html_text::push_para, html_text::do_para): Catch
	`std:bad_alloc` exceptions and `fatal()` out with an attempt to
	describe what we were doing.

	Continues the long process of fixing Savannah #68192.

2026-05-11  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[ms]: Add PDF support.

	* tmac/s.tmac: Depend on register `PDFFEAT` set to 1 to add
	features.  Allowed only with `-T pdf`.  Alias new `XR`/`XM`
	macros to LP (to prevent use before ms initialises).
	(XR/@XR): New macro implements internal hyperlinks.
	(XM/@XM): New macro 'marks' destination for internal links.
	(RP): Name 'title' page, used to relocate TOC in .TC.
	(cov*ab-init): Turn on XR/XM.
	(cov*print): Extract title and author for PDF metadata.
	(@SH, @NH): New second parameter names bookmark; XR can link to
	it.  Set up box diversion to collect bookmark text.
	(@NH-end): Diversion trap springs when NH/SH has collected one
	line of _output_.
	(XA): Start hotlink text (in TOC).
	(XE): Stop marking hotlink.
	(TC): If .RP seen, move TOC to page after 'title'.

	* doc/ms.ms.in: Call RP so that the TOC moves after the cover.
	Name sections throughout to support hyperlinking.  Change man
	page references to hyperlinks.
	(Abstract): Mention PDF features.
	(Introduction): Enable PDF features with PDFFEAT register.
	(Document Structure): Change references to hotlinks.
	(Tables of Contents): Explain how to move TOC.
	(Headings) <NH, SH>: Document new 'name' parameter.
	(Using PDF features with ms): New.

	* tmac/groff_ms.7.man:
	* doc/groff.texi.in: Sync with the foregoing.

	* doc/Groff-PDF-Features.ms: New file documents PDF features in
	pdf.tmac and macro packages mom, "man", mdoc, ms (and their
	absence in "me" and mm).

	* doc/doc.am: Build the new file above and switch ms.ms and
	pic.ms to generate PDFs with `PDFFEAT` enabled.

	* NEWS: Announce changes to groff ms(7) and acknowledge
	antecedent work in spdf.tmac (now externally maintained).

	Fixes <https://savannah.gnu.org/bugs/?68299>.

2026-05-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Rename test scripts to accommodate case-insensitive
	file systems.

	* src/roff/groff/tests/backslash-l-works.sh:
	* src/roff/groff/tests/backslash-L-works.sh: Rename these...
	* src/roff/groff/tests/backslash-lowercase-l-works.sh:
	* src/roff/groff/tests/backslash-uppercase-L-works.sh: ...to
	these.

	* src/roff/groff/groff.am (groff_TESTS): Reflect rename.

	Fixes <https://savannah.gnu.org/bugs/?68327>.  Thanks to
	John Gardner for the report.  Problem introduced by me in commit
	58adafa251, 22 April.

2026-05-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/grog/grog.pl: Account for new `LS` and `LE` man(7)
	macros.
	(interpret_line): Drop `LE` from list of mm(7)-exclusive macros.
	Drop `LS` from list of mom(7)-exclusive macros.

	See <https://savannah.gnu.org/bugs/?68335>.

2026-05-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Unit-test new `LS` and `LE` macros.

	* tmac/tests/an_LS-and-LE-work.sh: Do it.
	* tmac/tmac.am (tmac_TESTS): Run test.

2026-05-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Begin implementing new `LS` and `LE` macros.

	* tmac/an.tmac (LS): New interface macro starts (opens) a list
	enclosure.
	(LE): New interface macro ends (closes) a list enclosure.
	(an*list-close-all): New macro recursively closes all lists.
	(an*end-document, SH, SS): Call `an*list-close-all`.
	(an*break-paragraph): Recognize argument to permit override of
	inter-paragraph spacing application by checking list context for
	"compactness".
	(TP, IP, HP): Call `an*break-paragraph` with an argument,
	thereby checking for override of inter-paragraph spacing
	application.

	* tmac/groff_man.7.man.in (Description): Document it.  Add new
	macro names to initial table thereof.
	(List enclosure macros): New subsection specifies them.

	Begins fixing <https://savannah.gnu.org/bugs/?68335>.

2026-05-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/xditview/xditview.am: Fix race when running
	"install" Make target with concurrency.  This Automake file was
	duplicatively claiming responsibility for installing the
	"tty.tmac" and "tty-char.tmac" files, which are properly within
	_grotty_'s demense exclusively.  Drop definitions of
	`GXDITVIEWTMACFILES`, `gxditviewtmacdir`, and
	`dist_gxditviewtmac_DATA` macros.
	(uninstall_xditview): Drop now superfluous rmdir(1) from recipe.

	Fixes <https://savannah.gnu.org/bugs/?68336>.  Thanks to
	Santiago Vila for the report and analysis.  Problem introduced
	by me in commit 8910c63b6d, 2024-12-10.

2026-05-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/html-text.cpp: Fix code style nits.
	(html_text::html_text)
	(html_text::dump_stack_element)
	(html_text::dump_stack)
	(html_text::end_tag)
	(html_text::start_tag)
	(html_text::flush_text)
	(html_text::is_present)
	(html_text::uses_indent)
	(html_text::do_push)
	(html_text::push_para)
	(html_text::do_pre)
	(html_text::shutdown)
	(html_text::check_emit_text)
	(html_text::do_para)
	(html_text::remove_indent)
	(html_text::remove_def)
	(html_text::remove_break)
	(html_text::remove_para_align)
	(html_text::get_alignment): Use idiomatic C++98 null pointer
	literal.
	(html_text::dump_stack_element)
	(html_text::end_tag)
	(html_text::start_tag)
	(html_text::do_push)
	(html_text::shutdown)
	(html_text::do_para)
	(html_text::remove_def)
	(html_text::remove_break): Arrange equality comparisons to avoid
	inadvertent lvalue assignment.
	(html_text::do_para)
	(html_text::remove_para_align)
	(html_text::get_alignment): Parenthesize formally complex
	expressions.

2026-05-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (IP): Slightly refactor.  Call
	`an*break-paragraph` only if there are no arguments.  If
	arguments are present, we call `TP`, which already calls the
	aforementioned internal macro.  This way we avoid calling it
	duplicatively.  Right now there's no visible effect, but there
	is with forthcoming work to implement new `LS` and `LE` macros.

2026-05-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/grog/grog.pl (interpret_line): Recognize `pwh`
	instead of `ptr` as a GNU troff request name.  That request-
	renaming was a late-breaking change in the 1.24.0 release cycle.

	Continues fixing <https://savannah.gnu.org/bugs/?67880>.

2026-05-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/doc.tmac: Recognize that using the "X100-12" or "X75-12"
	output devices necessarily implies an `S` register default of
	"12", not "10", just as groff man(7) has done for a long time.

	Fixes <https://savannah.gnu.org/bugs/?68334>.  Problem dates
	back to introduction of mdoc(7) support for `S` register in
	commit b57a732836, 2001-03-24.

2026-05-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Define empty "bookmark handlers" for X100,
	X100-12, X75, and X75-12 devices.  Continues commit d1a148f95c,
	2024-01-27.

	Fixes <https://savannah.gnu.org/bugs/?68333>.

2026-05-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/xditview/device.c: Fix damage from code style nit
	picking, which rendered gxditview(1) ineffective.  Repair sense
	of comparisons to null pointers, and apply parentheses where
	overlooked.  Problem introduced by me in commit 111bf3255b, 8
	May.

2026-05-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (an*reset-section-parameters)
	(an-write-paragraph-tag, P, TP, IP, HP, RS, RE): Trivially
	refactor; rename registers.
	- an-inset-level           -> an*inset-level
	- an-margin                -> an*margin
	- an-saved-margin!1 (etc.) -> an*saved-margin!1 (etc.)
	- an-prevailing-indent     -> an*prevailing-indent
	- an-saved-prevailing-indent!1 (etc.)
	  -> an*saved-prevailing-indent!1 (etc.)

2026-05-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Make `-I` stop implying `-g` and `-s`.

	To date, specifying `-I` has been the only way (employing only
	groff(1) as a pipeline manager, a usage we strongly encourage)
	to get an `-M` option of the same meaning to grn.

	However, we didn't know, simply from the user's specification of
	`-I`, that they meant to pass a `-M` option to grn.  Maybe they
	meant it for soelim(1).  Maybe they don't need preprocessors at
	all.

	With grn(1) now accepting `-I`, groff(1) no longer needs to
	synthesize `-g` and `-s` to cover these bases.  If the user
	demands the grn(1) and soelim(1) preprocessors, they can specify
	their options, consistently with other groff preprocessors
	supported by a command-line option.

	* src/roff/groff/groff.cpp (main) <I>: Do it.

	* doc/doc.am (doc/webpage.html, doc/webpage.ps): Drop
	now-unnecessary dependencies on "grn" and "soelim".

	* src/roff/groff/groff.1.man (groff-specific options) <I>:
	* NEWS: Document it.

	Fixes <https://savannah.gnu.org/bugs/?68277>.

2026-05-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grn]: Rename `-M` option to `-I`, better paralleling troff(1).
	Inclusions are not the same things as macro file resources.

	* src/preproc/grn/main.cpp (main): Accept `-I`, `-L` (the
	original Berkeley name for this option), and `-M` (groff grn
	prior to this point) synonymously.
	* src/roff/groff/groff.cpp (main): Pass `-I` options as-is to
	grn.  Stop doing so for `-M` arguments.
	* doc/doc.am (doc/grnexmpl.ps): Pass groff option `-I` instead
	of `-M`.

	* src/preproc/grn/grn.1.man (Synopsis, Options):
	* NEWS: Document it.

	Fixes <https://savannah.gnu.org/bugs/?68276>.

2026-05-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (temporary_indent_request): If given no
	arguments, cancel any temporary indentation existing in the
	environment.

	Fixes <https://savannah.gnu.org/bugs/?68286>.

2026-05-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Trivially refactor.
	(temporary_indent): Rename this...
	(temporary_indent_request): ...to this.  Also declare it
	`static`, as `friend` access via the `environment` class is now
	gone and so external linkage is unnecessary.
	(init_env_requests): Update wire-uppery of request name to
	handler function.

2026-05-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor.  Separate engine logic from parsing logic
	with respect to an environment's temporary indentation.

	* src/roff/troff/env.h: Stop globally declaring
	`temporary_indent()`.
	(class environment): Declare new member functions returning
	`void`: `set_temporary_indent()` and
	`cancel_temporary_indent()`.  Drop declaration of `friend`
	functions `temporary_indent()` and
	`cancel_temporary_indentation()`.
	* src/roff/troff/env.cpp (environment::set_temporary_indent)
	(environment::cancel_temporary_indent): New functions mutate
	object of `environment` class.
	(set_temporary_indentation): New function updates the
	environment through a mutator member function, much like the
	existing `cancel_temporary_indentation()` does.
	(temporary_indent): Use accessor member functions of
	`environment` class to get at object properties.  Call
	`set_temporary_indentation()` instead of open-coding its
	operations.

	Continues the long process of fixing Savannah #68240.

2026-05-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (temporary_indent): Slightly refactor.
	Rename `temp` local variable to `amount` for clarity.  Shift
	output line breaking logic earlier, separating it from
	argument handling.  Drop redundant `skip_line()` call when
	handling no-argument case.  Move declaration of `is_valid` local
	variable within its narrower applicable brace scope.

2026-05-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Rename `.zoom` register to `.fzoom`.

	* src/roff/troff/env.cpp (init_env_requests): Do it.
	* tmac/troffrc: Configure alias for backward compatibility.

	* doc/groff.texi.in (Selecting Fonts):
	* man/groff.7.man (Read-only registers):
	* man/groff_diff.7.man (New register):
	* NEWS: Document change.

	Fixes <https://savannah.gnu.org/bugs/?68288>.

2026-05-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	Relocate "pdfmom" in source tree.

	* src/devices/gropdf/pdfmom.1.man:
	* src/devices/gropdf/pdfmom.pl: Rename these...
	* src/utils/pdfmom/pdfmom.1.man:
	* src/utils/pdfmom/pdfmom.pl: ...to these.

	* src/devices/gropdf/gropdf.am: Move pdfmom-related stuff from
	here...
	* src/utils/pdfmom/pdfmom.am: ...into this new file.

	* Makefile.am: Include new Automake script.
	* doc/doc.am (GROFF_MAN_PAGES1): Update man page location.

	* MANIFEST: Update.

	Fixes <https://savannah.gnu.org/bugs/?68294>.

2026-05-05  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Fix code style nits.
	(decode_macro_call_arguments)
	(decode_escape_sequence_arguments)
	(read_from_terminal_request)
	(do_define_string)
	(define_character)
	(do_define_macro)
	(length_request)
	(read_size)
	(skip_branch)
	(is_conditional_expression_true)
	(while_request)
	(psbb_locator::get_line)
	(tag)
	(taga): Arrange equality comparisons to avoid inadvertent lvalue
	assignment.  Parenthesize formally complex expressions.  For
	clarity, compare characters (even if of `int` type for <stdio.h>
	reasons) to null character literal instead of numeric zero.
	(is_conditional_expression_true): More consistently cast
	character literals to `int` in comparisons.

2026-05-05  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp
	(read_character_in_escape_sequence_parameter): Fix code style
	nits.  Arrange equality comparisons to avoid inadvertent lvalue
	assignment.  Return explicitly constructed `char` object from
	an `int` value rather than relying upon "the default
	conversions" of C and C++.

2026-05-05  G. Branden Robinson <g.branden.robinson@gmail.com>

	Correct some highly outdated Microsoft DOS/Windows port stuff.

	* arch/mingw/groffer.cmd:
	* arch/mingw/roff2dvi.cmd:
	* arch/mingw/roff2html.cmd:
	* arch/mingw/roff2pdf.cmd:
	* arch/mingw/roff2ps.cmd:
	* arch/mingw/roff2text.cmd:
	* arch/mingw/roff2x.cmd: Delete these remnants of "groffer",
	dropped from the groff distribution in commit 1d2df80a93,
	2020-04-22.
	* arch/mingw/mingw.am: Update `WINSCRIPTS` macro to no longer
	specify them.
	* arch/djgpp/README: Update.

2026-05-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/xditview/device.c: Fix code style nits.  Spell
	null pointer literal the idiomatic (pre-ISO C23) C way (`NULL`)
	instead of as `0`.  Explicitly compare variables of pointer type
	to null pointer literal instead of letting them pun down to
	Booleans.  Arrange equality comparisons to avoid inadvertent
	lvalue assignment.  Explicitly compare variables of type `int`
	{that store error codes, for example} to integer literals
	instead of letting them pun down to Booleans.  Parenthesize
	formally complex expressions.

2026-05-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/xditview/Dvi.c:
	* src/devices/xditview/device.c:
	* src/devices/xditview/font.c: Arrange inclusions of C standard
	library header files before X11 ones.  Within such inclusions,
	sort header file names in alphabetical order.

2026-05-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grotty/tty.cpp (tty_font::handle_x_command): Fix
	code style nit.  Parenthesize formally complex expressions.

2026-05-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/ps.cpp
	(ps_font::handle_unknown_font_command)
	(ps_font::handle_unknown_desc_command)
	(ps_printer::ps_printer)
	(ps_printer::set_char)
	(ps_printer::draw)
	(ps_printer::end_page)
	(ps_printer::~ps_printer)
	(ps_printer::special)
	(ps_printer::do_exec)
	(ps_printer::do_file)
	(ps_printer::do_def)
	(ps_printer::do_mdef)
	(ps_printer::do_import)
	(ps_printer::do_invis)
	(main): Revise diagnostic messages to more closely match
	terminology from our documentation and model language from
	elsewhere in the source tree.

	Continues the long process of fixing Savannah #66519.

2026-05-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/ps.cpp: Fix code style nits.
	(ps_output::special)
	(ps_font::handle_unknown_font_command)
	(ps_font::handle_unknown_desc_command)
	(ps_printer::ps_printer)
	(ps_printer::set_char)
	(ps_printer::define_encoding)
	(ps_printer::encode_fonts)
	(ps_printer::set_style)
	(ps_printer::flush_sbuf)
	(ps_printer::do_import): Arrange equality comparisons to avoid
	inadvertent lvalue assignment.
	(style::operator==)
	(ps_printer::ps_printer)
	(ps_printer::set_char)
	(ps_printer::define_encoding)
	(ps_printer::flush_sbuf)
	(ps_printer::do_import)
	(main): Parenthesize formally complex expression.
	(ps_printer::ps_printer): Compare variable of floating-point
	type to a floating point, not integer, literal.
	(ps_printer::set_subencoding): Compare variable of unsigned
	integer type to unsigned, not signed, integer literal.

2026-05-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/ps.cpp (ps_printer::flush_sbuf): Demote
	local variable `space_flag` from `int` to `bool`.  Assign to it
	using Boolean, not integer, literals.  Explicitly construct
	integer from its Boolean value when summing it with other values
	to compute an array index.

2026-05-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grops]: Boolify and rename class member variable.

	* src/devices/grops/ps.h (class ps_output): `need_space` of type
	`int` becomes `is_space_needed` of type `bool`.
	* src/devices/grops/ps.cpp (ps_output::ps_output): Update
	constructor's initializer list.
	(ps_output::end_line):
	(ps_output::special):
	(ps_output::simple_comment):
	(ps_output::end_comment):
	(ps_output::put_delimiter):
	(ps_output::put_string):
	(ps_output::put_number):
	(ps_output::put_fix_number):
	(ps_output::put_float):
	(ps_output::put_symbol):
	(ps_output::put_color):
	(ps_output::put_literal_symbol): Update.

	(ps_output::put_fix_number):
	(ps_output::put_float):
	(ps_output::put_symbol):
	(ps_output::put_color):
	(ps_output::put_literal_symbol): Explicitly construct integer
	from its Boolean value when summing it with `col` and `end` to
	decide whether to put a newline on the output.

2026-05-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Unit-test
	asciification of (left and regular) italic correction nodes.

2026-05-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Test sample
	input not just with "ps" output device, but "utf8" as well.
	Exclude two checks when producing output for the latter; one
	because it's an as yet unimplemented feature, and the other
	because the feature (ligature rendering) is unsupported in nroff
	mode.  This is to catch more cases like Savannah #68303.

2026-05-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (left_italic_corrected_node::asciify):
	Revise assert(3)ion: it's okay for this type of container node's
	contents (`nodes`) to be empty if we're in nroff mode.

	Fixes <https://savannah.gnu.org/bugs/?68303>.  Problem
	introduced by me in commit d445aee94e, 10 September, as part of
	the redesign of the "asciify" feature.  Thanks to Deri James for
	catching the problem and root-cause analyzing it.

2026-05-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (process_input_stack): Add null
	pointer check when processing a horizontal motion token.  An
	experimental code change in my working copy while exploring
	Savannah #68303 caused a SEGV in a place I didn't expect.  While
	that change is likely erroneous, it appears to have revealed an
	implicit invariant.  Make the invariant explicit, as above, and
	add an assert(3)ion for it as well.

2026-04-29  Dave Kemper <saint.snit@gmail.com>

	* doc/groff.texi.in (Ligatures and Kerning):
	* man/groff.7.man (Request short reference):
	* man/groff_diff.7.man (New requests): Clarify behavior of `tkf`
	request.

2026-04-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Alter extension macro testing technique.  What we had
	wasn't working when copy-and-pasted into man pages formatted
	with non-groff-compatible formatters.  Now people copying these
	macros can preserve or discard the lines with brace escape
	sequences surrounding the macro definitions, or not, and things
	should work either way.

	* tmac/an.tmac: Initialize `mG` register to zero.
	* tmac/an-ext.tmac: Invert sense of test when defining macros
	that also have definitions in "tmac/an.tmac".
	* tmac/tests/an-ext_MR-works.sh: Assign `mG` value of "1" when
	testing the "an-ext.tmac" file's implementations of macros.

2026-04-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an-ext.tmac: Relocate material.  Group all the macro
	definitions that don't conditionalize their definitions on the
	value of the `mG` register before those that do.

2026-04-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix Savannah #68285.

	* src/roff/troff/env.cpp (temporary_indent): When invalidly
	given no argument, the `ti` request was failing to correctly
	skip the remainder of the input line.  Drop two instances of
	logic that "manually" pump the input stream by calling
	`tok.next()`.  The second is better replaced by `skip_line()`,
	and the first made redundant thereby.  Nearly all request
	handlers call that function to consume the remainder of the
	input line once they've handled all the arguments they expect.

	Fixes <https://savannah.gnu.org/bugs/?68285>.  Problem
	introduced by me in commit ca8c376830, 2024-11-09.  I altered
	request handlers for four requests in that commit: `pn`, `ti`,
	`rchar`, and `hpfcode`, but fortunately made this mistake only
	with `ti`.

2026-04-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #68285.

	* src/roff/groff/tests/ti-request-works.sh: Do it.

2026-04-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test `ti` request.

	* src/roff/groff/tests/ti-request-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/groff.texi.in: Explicitly call out read-only registers as
	such.  Most already were; gather up the stragglers: `.O`,
	`.cdp`, `.cht`, `.csk`, `.int`, `.n`, `.nm`, `.nn`, and `.w`.
	(Built-in Registers): Accordingly annotate the table of such
	registers whose values are fixed at formatter start-up.

	Fixes <https://savannah.gnu.org/bugs/?68287>.  Thanks to Dave
	Kemper for the report.

2026-04-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/reg.cpp: Slightly refactor.  Tweak and make
	consistent the buffer-scribbling technique when formatting
	register properties.  Never hit the stack for this purpose; use
	only one file-global static buffer, `scratchpad`.  Shrink size
	of said buffer to only what we require: `INT_DIGITS` decimal
	places plus a leading sign.  As long as `INT_DIGITS` remains
	{generously} sized for 64-bit `int`s--though I'm not familiar
	with a port of groff to an I(LP)64 host--doing so buys back over
	100 bytes of BSS.  If this technique seems old-fashioned, it
	is--but GNU troff is single-threaded and none of the functions
	using this buffer participate in cycles in the program's call
	graph (i.e., they're not reëntrant).
	(number_value_to_ascii, number_format_to_ascii, dump_register):
	Zero out the buffer with memset(3) before using it, for
	paranoia's sake.
	(number_format_to_ascii): Use the `scratchpad` buffer instead of
	a different, local `static` buffer of 24 bytes.
	(dump_register): Use `scratchpad` instead of automatic (stack)
	storage as buffer for autoincrement value.  Declare `n` variable
	closer to use.

2026-04-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(read_increment_and_escape_sequence_parameter): Rename this...
	(read_crement_and_escape_sequence_parameter): ...to this.
	(read_character_in_copy_mode, token::next): Update call sites.

2026-04-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp: Trivially refactor.  Rename
	`incr_number_result` enumeration type to `crement`.  Annotate
	it.  Rename `get_incr_number()` to `read_crement()`.  We're
	pretty close to exclusive use of function names starting with
	"read_" for input stream reading operations; that is,
	interpretation of *roff language.  This change moves us closer
	to that goal.
	(get_incr_number): Rename this...
	(read_crement): ...to this.  Update its return type.
	(read_vunits, read_hunits, read_measurement_crement)
	(read_integer_crement): Update call sites.

2026-04-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp: Slightly refactor.  Convince any
	compiler that we're not falling off the end of functions
	returning `bool` (or `incr_number_result`).  End function bodies
	with an unconditional `return`.
	(read_vunits, read_hunits, read_measurement, read_integer)
	(get_incr_number): Do it.

2026-04-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Stop reporting number format for read-only registers.

	* src/roff/troff/reg.h (class reg, class general_reg): Define
	new public member function `has_format()` returning `bool`.
	* src/roff/troff/reg.cpp (reg::has_format): Return `false`.
	(general_reg::has_format): Return `true`.
	(dump_register): Report register format only if register's
	`has_format()` member function returns `true`.

2026-04-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (init_input_requests): Make `.O`
	read-only register actually read-only.

	Fixes <https://savannah.gnu.org/bugs/?68284>.  Problem appears
	to date back to feature addition in commit bc34881980,
	2007-09-19.

2026-04-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[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 <g.branden.robinson@gmail.com>

	* tmac/an.tmac (SH, SS, TP): Throw warning if macro called while
	an input trap is pending (for example, `.TP` followed
	immediately by `.SH`).  This input is not specified or
	countenanced by any man(7) documentation I know of, mandoc(1)'s
	"-T lint" warns about it, and it produces unpredictable output
	across implementations.  (Given the foregoing example, Plan 9
	troff truncates the input at that point.)  Seen in the wild in
	fvwm-config(1).

	Fixes <https://savannah.gnu.org/bugs/?68279>.

2026-04-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::newline): Reset contents
	of read-only `.itm` register (introduced in groff 1.24.0) to
	null after an input trap has sprung, so that it doesn't
	interpolate a stale and/or misleading value.

	Fixes <https://savannah.gnu.org/bugs/?68278>.  Continues commit
	1fce75f6ba, 2024-02-11.

2026-04-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/\
	roman-format-register-interpolation-works.sh: Fix missing
	parentheses in AT&T troff register interpolation syntax.  Make
	final two test cases capable of actually failing.

	Continues commit 5050eecc10, 16 April.

2026-04-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test `\l` and `\L` escape sequences.

	* src/roff/groff/tests/backslash-L-works.sh:
	* src/roff/groff/tests/backslash-l-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run tests.

2026-04-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `get_flags()` global
	function to `recompute_character_flags()`.  In addition to being
	more clear and explicit, it avoids a collision with the
	`charinfo` class's own `get_flags()` member function.

	* src/roff/troff/input.cpp (get_flags): Rename this...
	(recompute_character_flags): ...to this.
	* src/roff/troff/charinfo.h: Update `extern` declaration
	"importing" the symbol.
	(charinfo::overlaps_horizontally)
	(charinfo::overlaps_vertically)
	(charinfo::allows_break_before)
	(charinfo::allows_break_after)
	(charinfo::ends_sentence)
	(charinfo::is_transparent_to_end_of_sentence)
	(charinfo::ignores_surrounding_hyphenation_codes)
	(charinfo::prohibits_break_before)
	(charinfo::prohibits_break_after)
	(charinfo::is_interword_space): Update call sites.  Drop now-
	unneeded namespace access operator.

2026-04-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Drop dead/unreachable nested character class code.

	* src/roff/troff/charinfo.h (class charinfo): Drop
	`nested_classes` member variable.  Drop declaration of
	overloaded `add_to_class()` member function taking a pointer to
	a `charinfo` as argument.
	(charinfo::add_to_class): Drop definition per above.
	(charinfo::is_class): Simplify test to eliminate dereference of
	now-vanished `nested_classes` member variable.
	* src/roff/troff/input.cpp (define_class_request): Generalize
	condition under which warning diagnostics about inability to
	nest character classes are thrown.  Drop branches unreached in a
	"make check" build that required the aforementioned member
	function signature.
	(charinfo::contains, charinfo::dump): Drop iterators of nested
	classes `#if 0`-ed out in groff 1.24.0 release.

2022-04-17  Dave Kemper <saint.snit@gmail.com>

	* tmac/pspic.tmac: Allow `PSPIC` macro to place image at bottom
	of page.  From groff 1.01 through 1.04, the macro did not invoke
	a break, explicitly or implicitly; thus the vertical space
	`.ne`eded for the image was incremented by 1v to account for a
	possible partially collected output line.  The "ChangeLog.old"
	file shows that James Clark added a break to this macro in a
	1992-03-16 change (the Git history for this era is too coarse to
	show this change alone; it first shows up in commit a48ab7b6d,
	containing all changes between groff 1.04 and groff 1.05).
	However, the 1v increment was (presumably) inadvertently left in
	place, preventing an image that would exactly fit at the bottom
	of a page from being placed there.  This adjustment has been
	unnecessary for over 34 years, so get rid of it.

	[Fixes <https://savannah.gnu.org/bugs/?50770>.  Per the
	foregoing, problem dates back to groff 1.05, March 1992.  Thanks
	to Dave and Deri for sorting this out! --GBR]

2026-04-24  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[pdfmom]: Don't try to pass commands to pdfroff (-Tps) if
	pdfroff is not installed.

	* src/devices/gropdf/pdfmom.pl: Check if pdfroff is available
	before using it. (Withdrawn from groff since 1.24.0)

	See: <https://savannah.gnu.org/bugs/?68207>

2026-04-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_error): Report warning category
	governing diagnostic message even if the type of diagnostic is
	not `WARNING` but `OUTPUT_WARNING`.

	Continues commit 0220f00c3c, 18 March.

2026-04-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Throw warning in category "style" when nilpotent brace
	escape sequences are encountered.

	* src/roff/troff/input.cpp (read_character_in_copy_mode): Do it.

	* doc/groff.texi.in (Conditional Blocks, Warnings):
	* man/groff.7.man (Conditional blocks):
	* src/roff/troff/troff.1.man (Warnings): Document new warning
	circumstance.

2026-04-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Handle brace escape sequences
	better.  In AT&T troff, a brace escape sequence not occurring in
	a macro definition is discarded when read in copy mode--make GNU
	troff do likewise.  When occurring in a macro definition, it
	_is_ being read in copy mode and must be preserved, so retain
	existing behavior.  Unfortunately, the datum "we are defining
	a macro right now" was not consistently being passed from
	`do_define_macro()` to `read_character_in_copy_mode()`, so fix
	that problem too.  Fixing one of these without the other
	produces chaos in the formatter and wrecks a build; couple them.
	(read_character_in_copy_mode): Return an
	`ESCAPE_{LEFT,RIGHT}_BRACE` encoded token (character code) only
	if `is_defining_macro`.
	(do_define_macro): Supply `true` parameter (`is_defining_macro`)
	in _all_ `read_character_in_copy_mode()` calls.

	Fixes <https://savannah.gnu.org/bugs/?68260>.  Problems appear
	mostly to date back to groff's birth: see groff 1.01,[1]
	"input/troff.cc", lines 741-746, 3113, and 3119.  Commit
	5ba4c4ddb3, 2001-11-16, added another instance of
	`read_character_in_copy_mode()` (then called `get_copy()`) being
	given only one argument.

	[1] https://minnie.tuhs.org/cgi-bin/utree.pl?file=Net2/usr/src/\
	usr.bin/groff/troff/input.cc

2026-04-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #68257.

	* src/roff/groff/tests/\
	backslash-right-brace-ends-string-definition.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/token.h (token::is_terminator): Add
	`TOKEN_RIGHT_BRACE` to the set of tokens that can terminate a
	sequence of nonterminal symbols (such as the character sequence
	producing a *roff identifier, transparent throughput argument,
	contents of a string definition, or other string-like request
	argument like file names or system commands).

	Fixes <https://savannah.gnu.org/bugs/?68257>.

2026-04-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename
	`read_character_in_copy_mode()` function parameter from
	`is_defining` to `is_defining_macro` in declaration.
	(read_character_in_copy_mode): Update definition.
	(read_character_in_escape_sequence_parameter):
	(do_define_macro): Update call sites.

2026-04-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Test conditional block nesting.

	* src/roff/groff/tests/nested-conditional-blocks-work.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/token.h (class token): Add new member function,
	`is_terminator()` returning `bool`.  The idea is to make
	handlers of formatter instructions more consistent by having one
	source of truth regarding whether, in the parlance of parser
	theory, the token on the input stream terminates a "nonterminal
	symbol" (like an identifier or numeric expression, which can
	comprise multiple "terminal" or "primitive" tokens).  Right now,
	GNU troff pretty consistently regards newline and EOF tokens as
	terminating a sequence of such nonterminals.  It's less
	consistent regarding whether a right brace escape sequence does,
	causing inconsistency in its handling of numeric expressions as
	arguments to `nr` requests on the one hand and "contents"
	arguments to `ds` requests on the other, and divergence between
	AT&T and GNU troff parsers.  See Savannah #68257.
	(token::is_terminator): Define it `inline`.  Equivalent to
	`tok.is_newline() && tok.is_eof()`.

	* src/roff/troff/div.cpp (begin_page_request)
	(space_request)
	(need_vertical_space_request)
	(save_vertical_space_request)
	(output_saved_vertical_space_request)
	(flush_request):
	* src/roff/troff/env.cpp (fill)
	(no_fill)
	(center)
	(right_justify)
	(indent)
	(temporary_indent)
	(number_lines)
	(do_break_request):
	* src/roff/troff/input.cpp (diagnose_missing_identifier)
	(diagnose_invalid_identifier)
	(flush_pending_lines)
	(decode_macro_call_arguments)
	(remove_character)
	(do_define_macro)
	(read_title_parts)
	(ps_bbox_request)
	(do_translate)
	(hyphenation_patterns_file_code)
	(define_class_request)
	(read_drawing_command):
	* src/roff/troff/node.cpp
	(remove_font_specific_character_request): Migrate input handlers
	to call `token::is_terminator()` rather than evaluating the
	Boolean expression `tok.is_newline() && tok.is_eof()`.

2026-04-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/dt-request-works.sh: Add test case: a
	diversion trap is removed when `dt` is called with one argument.
	If that argument is a valid numeric expression (albeit a
	meaningless one), the diversion's trap is removed.

2026-04-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Slightly refactor.  Demote return
	types of `font_info` class's member functions returning Boolean
	values from `int` to `bool`.
	(class font_info): Update declarations.
	(font_info::contains)
	(font_info::is_special)
	(font_info::is_style)
	(font_info::is_named): Update definitions.

2026-04-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (read_font_identifier): Rewrite to fix
	Savannah #68252, an assertion failure I introduced in commit
	8b83fd3dd8, 2 November, in "src/roff/troff/input.cpp:token::
	is_usable_as_delimiter()".

	Time to fire up the development mailing list critical homunculus
	and have a Socratic dialogue with it.

	"Rewrite"?  Why hit such a small thing with such a big hammer?
	Why not just fix my stupid mistake of adding an assertion?  {A}
	I couldn't--wouldn't--just rip the assertion out, because it's
	in a hot-path function where much sanity checking takes place.
	{B} This code implicates one of the more challenging parts of
	the *roff language grammar: (almost) anywhere you can read a
	font identifier like `B`, `TR`, or `MARIGOLD`, it's also valid
	to read a font mounting position, a nonnegative integer.  In
	*roff, nonnegative integers also happen to be valid identifier
	names!  You can have a register named `55` or a string/macro/
	diversion named `10` {hello, eqn(1)}.  {C} This function is
	called only by uncommonly used request handlers, those for `uf`,
	`fschar`, `rfschar`, `special`, `fspecial`, `fzoom`, `bd`, and
	`tkf`.  {It's a rare groff user who can say with confidence what
	_all_ of those requests do.}  "But wait," you say, "isn't this
	same kind of font lookup done wildly commonly, like with every
	`ft` request or `\f` escape sequence?  {D} Yes!  So there's good
	news and bad news, and they're the same news.  There is logic to
	do exactly that--to disambiguate and resolve font mounting
	positions and identifiers behind that request and that escape
	sequence.  It lives, duplicatively, in another function in a
	different source file.  {E} "But wait," you say, "why was this
	function, a supporting function for request handlers that read
	only space-delimited arguments, calling `token::
	is_usable_as_delimiter()`?"  Good question!  I don't know, but
	it's been doing that, modulus the renamings for which I fear I
	am becoming notorious, at least since groff 1.22.3 in November
	2014.  Within the request handlers, we aren't in a delimited
	input context at all--as the GNU troff code base uses that
	term--so it's a mystery.

	`token::is_usable_as_delimiter()` used to be known as
	`token::delimiter()`.  I invite the reader to compare and
	contrast the following.

	https://cgit.git.savannah.gnu.org/cgit/groff.git/tree/src/roff/\
	troff/node.cpp?h=1.22.3#n6163

	https://cgit.git.savannah.gnu.org/cgit/groff.git/tree/troff/\
	node.c?h=1.02#n4373

	Why not just have `read_font_identifier()` call `select_font()`
	over in "env.cpp"?  Side effects.  As with many GNU troff
	functions, parsing logic is entangled with engine logic; see
	Savannah #68240.  So instead I copy the lexical analysis bits of
	`select_font()` into this function, replacing most of it.  How
	can I be confident this will work well?  Apart from a build
	proceeding successfully and passing our test suite (now with 340
	automated tests), the `select_font()` logic is a hotter code
	path and, I suspect, always has been.  After my last push
	earlier this week, I gathered coverage statistics from a full
	build with tests.  `read_font_identifier() was hit 12,023 times.
	That seems like a lot, right?

	`select_font()` was hit 254,489 times.  If you can't
	successfully change fonts in GNU troff, a lot more people (and
	test scripts of ours) will notice than can observe malfunctions
	of the `uf`, `fschar`, `rfschar`, `special`, `fspecial`,
	`fzoom`, `bd`, or `tkf` requests.  (And, in fact, `bd` _doesn't_
	work well.  See Savannah #68256.)  So if I have to violate DRY,
	I'm cribbing the battle-hardened code.  Moreover there's no
	reason at all, on any principle, to be checking for delimiters
	in this input context, as noted above.

	Fixes <https://savannah.gnu.org/bugs/?68252>.  The root cause of
	the problem depends on what you consider the defect to be.  As
	noted above, the assertion came in with commit 8b83fd3dd8, 2
	November, affecting groff 1.24.0.  But the code path
	_containing_ the assertion should never have been taken in the
	first place by the request handlers for `bd` et al.--yet it has
	been, ever since groff's birth.  Until now.

2026-04-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (read_font_identifier): Trivially
	refactor.  Rename local variable `n` to `mp` to prepare for
	subsequent, larger change.

2026-04-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (select_font): Fix code style nit.
	Parenthesize formally complex expression.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/env.h: Declare `init_size_list()` here,
	corresponding to its definition in "env.cpp", and along with
	other "size_list"-related stuff...
	* src/roff/troff/node.h: ...instead of here.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h: Drop declaration of unused symbol
	`read_desc()`.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Trivially refactor.
	(read_special_fonts): Rename this...
	(read_special_font_identifiers): ...to this.
	(set_font_specific_special_fonts_request)
	(set_special_fonts_request): Update call sites.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(read_request): Rename this...
	(read_from_terminal_request): ...to this.  It's a *roff
	input-reading function, but an oddball and highly specific one.
	Make its name less apparently general.
	(init_input_requests): Update wire-uppery of request name to
	handler function.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(read_escape_sequence_parameter)
	(read_long_escape_sequence_parameters): Rename function
	parameter `mode`, a heavily overloaded term in *roff
	parlance--like "transparent" and "special"--to `arity`.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(read_char_in_copy_mode): Rename this...
	(read_character_in_copy_mode): ...to this.

	(read_character_in_escape_sequence_parameter)
	(has_arg)
	(process_input_stack)
	(decode_macro_call_arguments)
	(decode_escape_sequence_arguments)
	(read_request)
	(do_define_string)
	(define_character)
	(do_define_macro)
	(length_request)
	(do_non_interpreted)
	(device_request)
	(output_request)
	(tag)
	(taga)
	(terminal_write)
	(do_write_request)
	(abort_request)
	(read_rest_of_line_as_argument): Update call sites.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (abort_request): Fix code style nit.
	Drop extraneous parentheses; no formally complex operation is
	occurring here, in the sense I use the term.  Only one dyadic
	operator is involved in the `for` loop's updating expression.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(read_char_in_escape_sequence_parameter): Rename this...
	(read_character_in_escape_sequence_parameter): ...to this.
	(read_two_character_escape_sequence_parameter)
	(read_long_escape_sequence_parameters)
	(read_escape_sequence_parameter): Update call sites.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(read_two_char_escape_parameter): Rename this...
	(read_two_character_escape_sequence_parameter): ...to this.
	(read_escape_sequence_parameter)
	(read_increment_and_escape_sequence_parameter)
	(token::next): Update call sites.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(read_long_escape_parameters): Rename this...
	(read_long_escape_sequence_parameters): ...to this.
	(read_escape_sequence_parameter)
	(read_increment_and_escape_sequence_parameter)
	(token::next)
	(device_request): Update call sites.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(read_increment_and_escape_parameter): Rename this...
	(read_increment_and_escape_sequence_parameter): ...to this.
	(read_char_in_copy_mode)
	(token::next): Update call sites.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(read_escape_parameter): Rename this...
	(read_escape_sequence_parameter): ...to this.
	(read_increment_and_escape_parameter)
	(read_char_in_copy_mode)
	(token::next): Update call sites.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename
	constant in `escape_sequence_parameter_cardinality` enumeration
	from `ALLOW_EMPTY` to `ARGUMENTS_OPTIONAL`.
	(read_long_escape_parameters)
	(token::next): Update dereference sites.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename
	constant in `escape_sequence_parameter_cardinality` enumeration
	from `WITH_ARGS` to `ARGUMENTS_MANDATORY`.
	(read_long_escape_parameters)
	(read_char_in_copy_mode)
	(token::next)
	(device_request): Update dereference sites.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename
	constant in `escape_sequence_parameter_cardinality` enumeration
	from `NO_ARGS` to `ARGUMENTS_FORBIDDEN`.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename
	`read_mode` enumeration type to `escape_parameter_cardinality`.
	(read_escape_parameter, read_long_escape_parameters): Update
	function declarations and definitions accordingly.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Trivially refactor.  Rename
	`hyphen_trie` class's member function `read_patterns_file()` to
	`interpret_patterns_file()`.  We're pretty close to exclusive
	use of function names starting with "read_" for input stream
	reading operations; that is, interpretation of *roff language.
	This change moves us closer to that goal.
	(class hyphen_trie): Update declaration.
	(hyphen_trie::read_patterns_file): Rename this...
	(hyphen_trie::interpret_patterns_file): ...to this.
	(read_hyphenation_patterns_from_file): Update call site.

2026-04-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (read_hyphenation_patterns_from_file):
	Trivially refactor.  Rename function parameter `append` to
	`appending`.  (Elsewhere, we have member functions named
	`append()` that have side effects.)

2026-04-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/dot-nm-register-works.sh: Repair test
	script so it can fail again.  Problem introduced by me in commit
	7aaeddf570, 14 April.

2026-04-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp
	(remove_hyphenation_exception_words_request): Implement argument
	processing; each is normalized (hyphens are removed), looked up
	in the current hyphenation language's exception word dictionary,
	and deleted thence if present.

	* src/roff/groff/tests/rhw-request-works.sh: Test functionality.

	* doc/groff.texi.in (Manipulating Hyphenation):
	* man/groff.7.man (Request short reference):
	* man/groff_diff.7.man (New requests):
	* NEWS: Document it.

	Fixes <https://savannah.gnu.org/bugs/?64478>.

2026-04-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test `pnr` request.

	* src/roff/groff/tests/pnr-request-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test support for alphabetic register formats.

	* src/roff/groff/tests/\
	alpha-format-register-interpolation-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test support for Roman numeral register formats.

	* src/roff/groff/tests/\
	roman-format-register-interpolation-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

	See <https://savannah.gnu.org/bugs/?61999>.

2026-04-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test `sv` and `os` requests.

	* src/roff/groff/tests/sv-and-os-requests-work.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp (set_page_number_request): Drop logic
	testing existence of `ps4html` register.  That can easily be
	handled by macro programming.

2026-04-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp: Trivially refactor.  Rename request
	handler functions.
	(need_space)
	(page_number)
	(save_vertical_space)
	(output_saved_vertical_space): Rename these...
	(need_vertical_space_request)
	(set_page_number_request)
	(save_vertical_space_request)
	(output_saved_vertical_space_request): ...to these.
	(init_div_requests): Update wire-uppery of request names to
	handler functions.

2026-04-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp (diversion_trap_request): Ignore
	request if arguments are present but nonsensical: either the
	first is not a valid vertical position expression, or it's
	present and valid but no second argument is present.

	* src/roff/groff/tests/\
	error-dt-request-given-bogus-arguments.sh: Test it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

	* doc/groff.texi.in (Other Differences):
	* man/groff_diff.7.man (Other differences):
	* NEWS: Document this behavioral difference from AT&T troffs.

	Fixes <https://savannah.gnu.org/bugs/?68246>.

2026-04-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp (diversion_trap_request): Throw warning
	in category "missing" if a `dist` argument is specified but the
	then-mandatory `name` argument is omitted.

2026-04-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp: Trivially refactor.  Rename request
	handler functions.
	(diversion_trap)
	(change_trap)
	(print_traps)
	(mark)
	(vertical_position_traps): Rename these...
	(diversion_trap_request)
	(change_trap_request)
	(print_traps_request)
	(mark_request)
	(configure_vertical_position_traps_request): ...to these.
	(init_div_requests): Update wire-uppery of request names to
	handler functions.

2026-04-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Improve `dt` request unit test.

	* src/roff/groff/tests/dt-request-works.sh: Verify that
	diversion trap removal works.

2026-04-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (suppress_node::tprint): Refactor code
	populating "grohtml-info" output to access the contents of
	built-in registers `.F` and `.c` directly via their
	`get_string()` member functions instead of this file's
	`get_string()` function, which syntactically sugars that
	procedure.
	(get_string): Delete now-unused function.

2026-04-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (suppress_node::tprint): Refactor code
	populating "grohtml-info" output to access the contents of
	`psbb` request-populated registers `op{min,max}{x,y}` directly
	via their member functions instead of this file's
	`get_register()` function, which syntactically sugars that
	procedure.
	(get_register): Delete now-unused function.

2026-04-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (suppress_node::tprint): Refactor code
	populating "grohtml-info" output to access the formatter's page
	offset and line length parameters directly, instead of going
	through the register dictionary.  Because we're adding them,
	check that addition for overflow; preprocessor-include
	"<stdckdint.h>" accordingly.

	We can consequently drop some now-unused code.

	* src/roff/troff/div.cpp (class page_offset_reg): Drop
	`get_value()` declaration.
	(page_offset_reg::get_value): Delete.

2026-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp: Drop unused code introduced in initial
	commit 351da0dcd, 1991-06-02.  Since the `.p` register is
	interpolated only by its `get_string()` member function and
	never `get_value()` (and nothing internal to the formatter
	attempts to get at it by that means, since accessing the datum
	via `curdiv->get_page_length()` is more straightforward), we can
	drop the latter.

	(class page_length_reg): Drop `get_value()` declaration.
	(page_length_reg::get_value): Delete.

2026-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp: Drop unused code introduced in initial
	commit 351da0dcd, 1991-06-02.  Since the `.d` register is
	interpolated only by its `get_string()` member function and
	never `get_value()` (and nothing internal to the formatter
	attempts to get at it by that means, since accessing the datum
	via `curdiv->get_vertical_position()` is more straightforward),
	we can drop the latter.

	(class vertical_position_reg): Drop `get_value()` declaration.
	(vertical_position_reg::get_value): Delete.

2026-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp: Drop unused code introduced in initial
	commit 351da0dcd, 1991-06-02.  Since the `.h` register is
	interpolated only by its `get_string()` member function and
	never `get_value()` (and nothing internal to the formatter
	attempts to get at it by that means, since accessing the datum
	via `curdiv->get_high_water_mark()` is more straightforward),
	we can drop the latter.

	(class high_water_mark_reg): Drop `get_value()` declaration.
	(high_water_mark_reg::get_value): Delete.

2026-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp: Drop unused code introduced in initial
	commit 351da0dcd, 1991-06-02.  Since the `.t` register is
	interpolated only by its `get_string()` member function and
	never `get_value()` (and nothing internal to the formatter
	attempts to get at it by that means, since accessing the datum
	via `curdiv->distance_to_next_trap()` is more straightforward),
	we can drop the latter.

	(class distance_to_next_trap_reg): Drop `get_value()`
	declaration.
	(distance_to_next_trap_reg::get_value): Delete.

2026-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp: Drop unused code introduced in commit
	0216fc85d3, 2001-05-05.  Since the (now-named) `.ns` register is
	interpolated only by its `get_string()` member function and
	never `get_value()` (and nothing internal to the formatter
	attempts to get at it by that means, since accessing the datum
	via `curdiv->is_in_no_space_mode` is more straightforward), we
	can drop the latter.

	(class no_space_mode_reg): Drop `get_value()` declaration.
	(no_space_mode_reg::get_value): Delete.

2026-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test `.ns` register.

	* src/roff/groff/tests/dot-ns-register-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test `ns` request.

	* src/roff/groff/tests/ns-request-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test `dt` request.

	* src/roff/groff/tests/dt-request-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test `aln` and `als` requests.

	* src/roff/groff/tests/aln-request-works.sh:
	* src/roff/groff/tests/als-request-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run tests.

2026-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Slightly refactor.  Migrate GNU troff's `dictionary`
	class to use `ssize_t` for measurement of its capacity and
	occupancy (and for integer variables iterating through it on
	that basis).

	* src/roff/troff/dictionary.h (class dictionary_iterator):
	Migrate member variable `i` from `int` to `ssize_t`.
	(class dictionary): Migrate member variables `capacity` and
	`occupancy` from `int` to `ssize_t`.
	(class dictionary, class object_dictionary): Migrate
	constructors to take an argument of `ssize_t` instead of `int`
	type.
	* src/roff/troff/dictionary.cpp: Preprocessor-include
	"<sys/types.h"> header defining `ssize_t` type.

	* bootstrap.conf: Add "ssize_t" to `gnulib_modules`, since
	neither ISO C99 nor ISO C++98 guarantee its existence.  (It's a
	POSIX 2001 feature).

2026-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/dictionary.h (class dictionary): Rename member
	variables.
	- size -> capacity
	- used -> occupancy
	* src/roff/troff/dictionary.cpp (dictionary::dictionary)
	(dictionary::lookup)
	(dictionary::remove)
	(dictionary_iterator::dictionary_iterator): Update dereference
	sites.

2026-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/dictionary.cpp: Fix code style nits.
	(is_good_size)
	(dictionary::lookup)
	(dictionary::remove): Parenthesize formally complex expressions.
	(dictionary::lookup):
	(object_dictionary::lookup): Favor C++ `static_cast<>` operator
	over omnipotent C-style cast.
	(object_dictionary::define)
	(object_dictionary::rename)
	(object_dictionary::remove): Explicitly compare value of pointer
	type to null pointer literal instead of letting it pun down to a
	Boolean.

2026-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/dictionary.h (class dictionary): Drop
	declaration of unimplemented member function `rehash()`.

2026-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Drop some code introduced in
	commit dc3c168c3b, 2004-10-10.  Per lcov(1) it's never used, and
	deleting it does not adversely affect "make check".  It appears
	that the `is_diversion()` member function that callers actually
	use comes from the `macro` and `string_iterator` classes in
	"input.cpp".

	* src/roff/troff/div.h (class diversion): Drop `is_diversion()`
	declaration.
	(macro_diversion::is_diversion)
	(top_level_diversion::is_diversion): Drop definitions.

2026-04-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	Ditch our local (outdated) copy of gnulib's "localcharset"
	module.  Our build brings it in already via the dependencies of
	gnulib's "hypot" module.

	* src/include/localcharset.h:
	* src/libs/libgroff/localcharset.c: Delete.

	* src/libs/libgroff/libgroff.am (libgroff_a_SOURCES): Drop
	"src/libs/libgroff/localcharset.c" from macro definition.
	(EXTRA_DIST): Stop shipping "src/libs/libgroff/config.charset",
	"src/libs/libgroff/ref-add.sin", and
	"src/libs/libgroff/ref-del.sin" in our distribution archive.
	(CLEANFILES): Drop "config.charset", "ref-add.sin", and
	"ref-del.sin" from macro definition.
	(LIBGROFF_PACKAGE): Delete macro definition.
	(all, charset.alias, ref-add.sed, ref-del.sed)
	(install-data-local, install_charset_data)
	(uninstall-local, uninstall_charset_data): Delete targets.

	* m4/localcharset.m4: Delete.
	* acinclude.m4: Drop inclusion of "m4/localcharset.m4".

	Continues the long process of fixing Savannah #66518.

2026-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Trivially refactor.
	(class hyphen_trie): Demote type of `read_patterns_file()`
	member function's second argument from `int` to `bool`.
	(hyphen_trie::read_patterns_file): Likewise, and rename it from
	`append` to `appending`.

2026-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (has_arg): Trivially refactor.
	Rename argument from `want_peek` to `peeking`.

2026-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (make_composite_node)
	(make_glyph_node): Fix code style nit.  Parenthesize formally
	complex expressions.

2026-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Trivially refactor.  Rename class
	to better align with terminology used in our documentation.
	(class next_available_font_position_reg): Rename this...
	(class next_available_font_mounting_position_reg): ...to this.
	(init_node_requests): Update wire-uppery of built-in register
	interpolator to its name in the formatter.

2026-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Trivially refactor.  Rename objects
	to better align with terminology used in our documentation.
	(class troff_output_file): Rename:
	- font_position -> font_mounting_position
	- nfont_positions -> mounting_position_count
	(troff_output_file::set_font)
	(troff_output_file::really_begin_page)
	(troff_output_file::really_copy_file)
	(troff_output_file::~troff_output_file)
	(troff_output_file::troff_output_file): Update dereference
	sites.

2026-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename functions to better align
	with terminology used in our documentation.

	* src/roff/troff/node.h: Rename declaration of `symbol_fontno()`
	to `mounting_position_of_font()`, since it has nothing to do
	with a "symbol font" (like "S") as discussed by user-facing
	documentation.
	* src/roff/troff/node.cpp (symbol_fontno): Rename this...
	(mounting_position_of_font): ...to this.
	* src/roff/troff/env.cpp (environment::set_font):
	* src/roff/troff/node.cpp (is_abstract_style)
	(font_family::resolve, read_font_identifier): Update call sites.

	* src/roff/troff/node.h: Rename declaration of
	`next_available_font_position()` to
	`next_available_font_mounting_position()`.  Yes, it's a
	mouthful, but the term "position" can apply to many things: the
	drawing position, an index into an array, and so forth.
	* src/roff/troff/node.cpp (next_available_font_position): Rename
	this...
	(next_available_font_mounting_position): ...to this.
	* src/roff/troff/env.cpp (environment::set_font):
	* src/roff/troff/node.cpp
	(assign_font_and_file_name_to_mounting_position)
	(font_family::resolve, read_font_identifier, zoom_font_request)
	(next_available_font_position_reg): Update call sites.

	* src/roff/troff/node.h: Rename declaration of
	`mount_font()` to `mount_font_at_position()`.  Also resequence
	arguments to follow the order implied by the English words in
	the function name.  (Compare fprintf(3) and contrast fputs(3).)
	* src/roff/troff/node.cpp (mount_font): Rename this...
	(mount_font_at_position): ...to this.  Resequence arguments.
	* src/roff/troff/env.cpp (environment::set_font):
	* src/roff/troff/input.cpp (main):
	* src/roff/troff/node.cpp (mount_font_at_position_request)
	(read_font_identifier, zoom_font_request): Update call sites.

	* src/roff/troff/node.cpp
	(associate_style_with_font_position_request): Rename this...
	(assign_style_to_font_mounting_position_request): ...to this.
	(init_node_requests): Update wire-uppery of request handler to
	its name in the formatter.

	* src/roff/troff/node.h: Rename declaration of
	`get_underline_fontno()` to
	`get_selected_underline_font_mounting_position()`.
	* src/roff/troff/env.cpp (get_underline_fontno): Rename this...
	(get_selected_underline_font_mounting_position): ...to this.
	* src/roff/troff/env.cpp (environment::set_font)
	(configure_underlining): Update call sites.

	* src/roff/troff/node.h (class font_family): Rename declaration
	of `invalidate_fontno()` to
	`invalidate_selected_font_mounting_position()`.
	* src/roff/troff/node.cpp (font_family::invalidate_fontno):
	Rename this...
	(font_family::invalidate_selected_font_mounting_position): ...to
	this.
	* src/roff/troff/node.cpp
	(assign_font_and_file_name_to_mounting_position)
	(mount_style): Update call sites.

	* src/roff/troff/env.h (class environment): Rename declaration
	of `set_font()` to `select_font()`.
	* src/roff/troff/env.cpp (environment::set_font): Rename
	these overloaded names...
	(environment::select_font): ...to these.
	(select_font): Update call site.

	* src/roff/troff/node.cpp (class troff_output_file): Rename
	declaration of `set_font()` to `select_font()`.
	(troff_output_file::set_font): Rename this...
	(troff_output_file::select_font): ...to this.
	(troff_output_file::start_device_extension)
	(troff_output_file::put_char_width): Update call sites.

2026-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Refactor.  Take one of
	`assign_font_and_file_name_to_mounting_position()`'s jobs away
	from it, awarding it instead to the only call site that wanted
	that job done.
	(assign_font_and_file_name_to_mounting_position): Drop
	`check_only` parameter and dependent logic, and...
	(is_font_available): ...open-code that logic here instead.

2026-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Trivially refactor.  Rename library's `concat()`
	function to `catenate()`.

	* src/include/symbol.h: Rename in declaration.
	* src/libs/libgroff/symbol.cpp (concat): Rename this...
	(catenate): ...to this.
	* src/roff/troff/node.cpp (get_font_name, is_abstract_style)
	(font_family::resolve): Update call sites.

2026-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/font.cpp (font::load_font, font::load):
	Trivially refactor.  Rename `load_header_only` parameter to
	`validate_only` for clarity.

2026-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Trivially refactor.  Relocate
	`is_abstract_style()` function definition to precede its call
	site.

2026-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (is_abstract_style): Fix code style
	nits.  Return Boolean instead of integer literal from this
	function returning `bool`.  Parenthesize formally complex
	expression.

2026-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `is_font_name()` to
	`is_font_available()`.

	* src/roff/troff/node.h: Update declaration.
	* src/roff/troff/node.cpp (is_font_name): Rename this...
	(is_font_available): ...to this.
	* src/roff/troff/input.cpp (is_conditional_expression_true):
	Update call site.

2026-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Trivially refactor.  Rename
	`mount_font_no_translate()` to
	`assign_font_and_file_name_to_mounting_position()` and update
	ordering of parameters to match the function name.
	(mount_font_at_position_request): Rename this...
	(assign_font_and_file_name_to_mounting_position): ...to this,
	and resequence arguments.
	(mount_font, is_font_name, font_family::resolve): Update
	call sites.

2026-04-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/preconv/preconv.cpp (conversion_latin1)
	(conversion_utf8, conversion_cp1047, conversion_iconv, get_BOM)
	(get_tag_lines, is_comment_line, get_variable_value_pair)
	(check_coding_tag, detect_file_encoding, do_file, usage):
	Declare `static`; external linkage is not required.  Fixes
	`-Wmissing-declarations` GCC warning.

2026-04-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/font.cpp (font::load): If we're not "loading
	header only" (that is, not attempting to actually mount a font,
	but merely checking its availability or validity, as with `.if F
	ZCMI`), issue an error diagnostic disclosing the problem and the
	system's reason the file couldn't be opened.

2026-04-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libdriver/printer.cpp (printer::load_font): Validate
	function arguments.  Add assert(3)ion that the string
	representing the font description to load isn't a null pointer.
	If a function argument is invalid, return early in `NDEBUG`
	builds.

2026-04-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libdriver/printer.cpp: Favor idiomatic C++ over C
	preprocessor hacks.
	(check_for_output_error)
	[!(_MSC_VER || _WIN32 && !__CYGWIN && !__UWIN)]: Define as a
	`static inline` function, not a preprocessor macro.

2026-04-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: The `phw` request now accepts arguments.  Each is
	interpreted as a possible hyphenation word, ignoring hyphens in
	the input, looked up in the hyphenation exception list for the
	hyphenation language, and if found, is reported with its
	hyphenation points.  Only hyphenation exceptions defined by the
	`hw` request are reported.

	* src/roff/troff/env.cpp (print_hyphenation_exceptions_request):
	Implement it.

	* src/roff/groff/tests/phw-request-works.sh: Test it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

	* doc/groff.texi.in (Debugging):
	* man/groff.7.man (Request short reference):
	* man/groff_diff.7.man (New requests):
	* NEWS: Document it.

	Fixes <https://savannah.gnu.org/bugs/?68205>.

2026-04-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (print_hyphenation_exceptions):
	Slightly refactor.  Declare `const` symbol `bufsz` computed at
	compile time as `static`.  Explicitly clear the stack memory
	allocated to `wordbuf` array.

2026-04-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (read_hyphenation_exception_word):
	Generalize.  Support being called with null pointers to store
	the breakpoint count and positions, so that a request that isn't
	interested in them need not reserve storage for them.
	Consequently, default these function parameters to null
	pointers.  Dereference and populate the breakpoint count and
	positions only if these data are wanted.  Add assert(3)ion that
	either both pointers are null or neither one is.

2026-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Refactor.  Lift logic for parsing a
	hyphenation exception word request argument into its own
	function, so that other requests can use it.
	(read_hyphenation_exception_word): Implement it.
	(add_hyphenation_exception_words_request): Call new function
	from here.

2026-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp
	(add_hyphenation_exception_words_request): Slightly refactor.
	Declare `const` symbols computed at compile time as `static`.

2026-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp
	(add_hyphenation_exception_words_request): Trivially refactor.
	Rename local variables.
	- buflen       -> wordbuflen
	- buf          -> wordbuf
	- posbuflen    -> bpbuflen
	- pos          -> bpbuf
	- npos         -> bp_count
	- newposbuflen -> newbpbuflen

2026-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp
	(add_hyphenation_exception_words_request): Slightly refactor.
	Revise loop style.

2026-04-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grotty/tty.cpp: Fix code style nit.  Favor C++
	`static_cast<>` operator over omnipotent C-style cast.

2026-04-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grotty/tty.cpp: Fix code style nit.  Arrange
	equality comparisons to avoid inadvertent lvalue assignment.

2026-04-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grotty/tty.cpp: Fix code style nit.  Correctly
	type-annotate zero literals in comparisons.

2026-04-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grotty/tty.cpp: Fix code style nit.  Parenthesize
	formally complex expressions.

2026-04-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/symbol.cpp (symbol::json_length): Strengthen
	assertion, since we don't permit use of C0 controls in
	identifiers; see Savannah #67734.  Use preprocessor to disable
	unused code.
	(symbol::json_extract): Add assertion, since we don't permit
	empty identifiers.  Use preprocessor to disable unused code.

2026-04-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Test unusual characters in identifiers, improving
	coverage of src/libs/libgroff/symbol.cpp:symbol::json_extract().

	* src/roff/groff/tests/coverage-symbol-cpp.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Validate error path in
	src/libs/libgroff/symbol.cpp:symbol::symbol.

	* src/roff/groff/tests/error-overflow-symbol-table.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Slightly refactor.  Lift `wordbuflen`
	and `bpbuflen` into file-global scope...
	(add_hyphenation_exception_words_request): ...from here, because
	we're going to need them in another function.

2026-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp
	(remove_hyphenation_exception_words_request): Free the heap
	storage backing a hyphenation exception word when removing
	one--specifically, this is its list of hyphenation break points
	expressed as integers representing character positions in the
	word, allocated by `add_hyphenation_exception_words_request()`.
	Fastidiously assign null pointer literal to `word` local
	addressing that memory afterwards.

2026-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Rationalize header file inclusions,
	adding "<stdlib.h>" and "<string.h>".

2026-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/symbol.h: Preprocessor-include "<string.h>" header
	file to access strchr(3).
	(class symbol): Declare new member function `contains()`
	indicating whether the `char` argument appears in the symbol's
	name.
	(symbol::contains): Implement it `inline`, wrapping strchr(3).

2026-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/symbol.h (class symbol): Comment formal argument
	names in function declarations as a compromise with the
	Stroustrup-style C++ used in most of groff.

2026-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp
	(add_hyphenation_exception_words_request): Catch
	`std::bad_alloc` exceptions from `new` operator.  Throw a fatal
	error indicating how much memory we couldn't allocate.

	Continues the long process of fixing Savannah #68192.

2026-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp
	(add_hyphenation_exception_words_request): Refactor and add
	warning diagnostic.  Elevate scope of `c` local variable and
	rename it to `hc` since it stores the hyphenation code of the
	character under examination in the hyphenation exception word
	argument.  Gather that hyphenation code earlier, and mark the
	word as invalid if the hyphenation code is zero--exception: the
	character '-' is also valid, since it marks a hyphenation point.
	Consequently, we now throw a warning in category "char" on
	attempted hyphenation exception words like "non*sense" and
	"0123456789".  (You can still make these eligible for
	hyphenation breaking by using the `hcode` request to assign
	hyphenation codes to non-letters.)  Drop later conditional loop
	break if the hyphenation code is zero since that now cannot be
	the case--we now don't enter the containing branch in the first
	place.  Replace a test of the index into the hyphenation
	exception word being greater than zero with an assert(3)ion of
	the same inside the branch, as it's now an invariant that a
	valid hyphenation exception word contains a nonzero count of
	characters bearing hyphenation codes.

	* doc/groff.texi.in (Warnings):
	* src/roff/troff/troff.1.man (Warnings): Document new warning
	circumstance.

2026-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp
	(add_hyphenation_exception_words_request): Slightly refactor.
	memset(3) stack-allocated character arrays `buf` and `pos` with
	null terminators/zeroes as a paranoid hedge.  Drop later
	null-termination of `buf` as redundant.

2026-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp
	(add_hyphenation_exception_words_request): Fix code style nits.
	Assign unsigned literal to array element of type `unsigned
	char`.  Explicitly compare value of pointer type to null pointer
	literal instead of letting it pun down to a Boolean.
	Parenthesize formally complex expressions.

2026-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/symbol.cpp (symbol::symbol): Fix code style
	nits.  Use explicit `const_cast` C++ operator instead of C-style
	cast.  Parenthesize formally complex expressions.

2026-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/symbol.cpp (symbol::symbol): Improve fatal
	diagnostic message; when construction of a larger symbol table
	is impossible, describe the failure better and report the
	exceeded table capacity.

2026-04-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Trivially refactor.

	* src/include/symbol.h (class symbol): Rename `table_used`
	member variable, which could suggest a Boolean value, to
	`table_occupancy`.
	* src/libs/libgroff/symbol.cpp: Update dereference sites.

2026-04-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.h (class diversion, class macro_diversion):
	Use Boolean, not numeric, literals as default values for
	function arguments of type `bool`.

2026-04-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Use `UCHAR_MAX` from ISO C99's
	standard library instead of the literal `256` to configure the
	`WORD_MAX` constant.  Preprocessor-include "<limits.h>" header
	file to access `UCHAR_MAX`.  Declare `WORD_MAX` as `static`;
	external linkage is not required.

2026-04-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp (read_measurement_crement)
	(read_integer_crement): Trivially refactor for semantic clarity.
	Rename the last argument from `prev_value` to `operand`.
	Nothing in the implementation of these functions imparts a
	"previous value" meaning to that argument; that matter is
	context-dependent.

2026-04-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor for semantic clarity.  We had two
	pairs of functions where the pair members differed by signature
	but not by name, and which moreover did somewhat different
	things, interpreting different expression types.  Rename them to
	more obviously distinguish their purposes.  ("crement" is a
	nonce usage I devised to generalize "{in,de}crement".)

	* src/roff/troff/token.h: Rename functions in declarations.
	- read_measurement() -> read_measurement_crement()
	- read_integer()     -> read_integer_crement()
	* src/roff/troff/number.cpp (read_measurement): Rename this...
	(read_measurement_crement): ...to this.
	(read_integer): Rename this...
	(read_integer_crement): ...to this.
	* src/roff/troff/div.cpp (begin_page, page_number):
	* src/roff/troff/env.cpp (number_lines): Migrate callers of
	two-argument `read_integer()` to `read_integer_crement()`.
	* src/roff/troff/env.cpp (point_size):
	* src/roff/troff/input.cpp (read_delimited_measurement)
	(do_register):
	* src/roff/troff/reg.cpp (define_register_request)
	(inline_define_register): Migrate callers of three-argument
	`read_measurement()` to `read_measurement_crement()`.

2026-04-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp:
	* src/roff/troff/token.h: Comment formal argument names in
	function declarations as a compromise with the Stroustrup-style
	C++ used in most of groff.

2026-04-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Work on Savannah #67735.

	Improve type discipline with respect to internal character
	representation.

	* src/roff/troff/env.cpp (embolden_font_request)
	(configure_track_kerning_request)
	(constantly_space_font_request):
	* src/roff/troff/reg.cpp (inline_define_register): Improve type
	discipline with respect to groff's internal character
	representation.  Call `read_measurement()` with explicitly
	constructed literal argument of type `unsigned char` for
	conceptual clarity.  "groff characters" are, for now, unsigned
	bytes.

	Continues the long process of fixing Savannah #67735.

2026-04-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor for semantic clarity.  The parameter
	named `required` used by many functions was employed for two
	slightly different purposes.  In some instances, it indicated
	whether emission of a diagnostic message was desired in the
	event a token expected on the input stream (or similar) was
	absent.  In others, it encoded whether the presence of such a
	token was _optional_, in which case both its presence and
	absence were valid.  The latter tends to be the case when a
	token is present but might or might not have associated
	`charinfo` data.  Detangle these issues by renaming `required`
	arguments to `want_diagnostic` and `is_mandatory` as
	appropriate.

	* src/roff/troff/token.h: Rename `required` argument in
	declarations.

	* src/roff/troff/input.cpp (diagnose_missing_identifier):
	(token::get_charinfo): Rename `required` argument to
	`is_mandatory` in definitions.
	(read_identifier, read_long_identifier)
	(read_input_until_terminator): Rename `required` argument to
	`want_diagnostic` in definitions.

	* src/roff/troff/column.cpp (column_justify) [COLUMN]:
	* src/roff/troff/div.cpp (change_trap):
	* src/roff/troff/env.cpp (do_input_trap)
	(add_hyphenation_exception_words_request):
	* src/roff/troff/input.cpp (read_rgb, read_cmy, read_cmyk)
	(read_gray, do_overstrike, do_bracket, token::next)
	(token::description, read_input_until_terminator)
	(do_define_string, define_character, print_character_request)
	(remove_character, do_define_macro, read_line_rule_expression)
	(do_register, encode_special_character_for_device_output)
	(device_request, device_macro_request)
	(is_conditional_expression_true, ps_bbox_request, open_file)
	(do_write_request, stream_write_macro_request, do_translate)
	(set_character_flags_request, define_class_request)
	(vjustify) [COLUMN]:
	* src/roff/troff/node.cpp (translate_font_request)
	(mount_font_at_position_request)
	(associate_style_with_font_position_request)
	(read_font_identifier, remove_font_specific_character_request)
	* src/roff/troff/reg.cpp (inline_define_register): Update
	annotations at call sites and in declarations.

2026-04-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[build]: Drop no longer needed check for `struct exception`.  It
	was used only by the now-deleted "src/libs/libgroff/matherr.c".

	* m4/groff.m4 (GROFF_STRUCT_EXCEPTION): Delete.
	* configure.ac: Drop interpolation of `GROFF_STRUCT_EXCEPTION`.
	* Makefile.am: Stop advertising availability of
	`HAVE_STRUCT_EXCEPTION` preprocessor symbol.

2026-04-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Drop "matherr.c" file, declaring (under the
	preprocessor conditions `HAVE_STRUCT_EXCEPTION` and `TLOSS`)
	`matherr()` and `struct exception`.  The former is K&R-style,
	thus prohibited in ISO C23, and can (should) cause build
	failures with compilers configured for that version of the C
	language.  Autoconf 2.73, released last month, tries harder to
	arrange builds to use C23 by default.  Also we straight up don't
	_need_ this declaration (anymore); nothing in groff calls
	`matherr()`.  It dates back to the Clark days, when there was no
	gnulib for groff to use (or maybe it didn't support C++ projects
	at the time).  Whatever gnulib needs, it transitively closures
	for us, so we no longer need to and can throw this 30-year old
	stuff of ours away.

	* src/libs/libgroff/matherr.c: Delete.
	* src/libs/libgroff/libgroff.am (libgroff_a_SOURCES): Drop
	aforementioned file from macro definition.

	Fixes <https://savannah.gnu.org/bugs/?68220>.  Thanks to Alexis
	Hildebrandt for the report.  Also continues the long process of
	fixing Savannah #66518.

2026-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (space_size): Clarify warning
	diagnostics in category "range".

2026-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp (is_valid_term): Compare local
	`scaling_unit` and return value of `token::char()` to literals
	of type `unsigned char` instead of signed literals for
	conceptual clarity.  "groff characters" are, for now, unsigned
	bytes.

	Continues the long process of fixing Savannah #67735.

2026-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp: Refactor.  Migrate
	`valid_scaling_units` global constant from type array-of-`char`
	to a groff `string`.
	(is_valid_term): Employ `contains()` function of
	`valid_scaling_units`'s new type instead of the standard C
	library's strchr(3).

	Continues the long process of fixing Savannah #67735.

2026-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Add `contains()` member function to `string` class.

	* src/include/stringclass.h (class string): Declare it,
	returning `bool`.
	* src/libs/libgroff/string.cpp (string::contains): Define it.

2026-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Improve type discipline with respect to internal
	character representation.

	* src/roff/troff/env.cpp (point_size): Call `read_measurement()`
	with explicitly constructed literal argument of type `unsigned
	char` for conceptual clarity.  "groff characters" are, for now,
	unsigned bytes.
	* src/roff/troff/number.cpp (is_valid_term): Demote local
	variable `si` from `int` to `unsigned char`.

	Continues the long process of fixing Savannah #67735.

2026-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment_copy, environment_switch):
	Declare as `static`; external linkage is not required.

2026-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (fill, no_fill): Declare as `static`;
	external linkage is not required.

2026-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor.  Separate engine logic from parsing logic
	with respect to an environment's filling enablement.

	* src/roff/troff/env.h: Stop globally declaring `fill()` and
	`no_fill()`.
	(class environment): Declare new member function returning
	`void`: `configure_filling()`.  Drop declaration of `friend`
	functions `fill()` and `no_fill()`.
	* src/roff/troff/env.cpp (environment::configure_filling): New
	function mutates object of `environment` class.
	(fill, no_fill): Replace manipulation of `environment` object's
	private member variable with calls of the foregoing new public
	member function.

2026-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/env.h (get_fill): Rename this declaration...
	(get_filling): ...to this.
	* src/roff/troff/env.cpp (environment::get_fill): Rename this
	definition...
	(environment::get_filling): ...to this.
	(init_env_requests): Update wire-uppery to `.u` register.
	* src/roff/troff/input.cpp (diverted_space_node::need_reread):
	Update call site.

2026-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test `fi` and `nf` requests.

	* src/roff/groff/tests/fi-and-nf-requests-work.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (family_change, point_size)
	(space_size): Declare as `static`; external linkage is not
	required.

2026-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor.  Separate engine logic from input parsing
	logic with respect to an environment's "line tabs" enablement (a
	GNU troff feature altering how tab stop positions are computed).

	* src/roff/troff/env.h: Stop globally declaring
	`line_tabs_request()`.
	(class environment): Declare new member function returning
	`void`: `configure_line_tabs()`.  Drop declaration of `friend`
	function `line_tabs_request()`.
	* src/roff/troff/env.cpp (environment::configure_line_tabs): New
	function mutates object of `environment` class.
	(line_tabs_request): Replace manipulation of `environment`
	object's private member variable with call of the foregoing new
	public member function.

2026-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test `linetabs` request.

	* src/roff/groff/tests/linetabs-request-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor.  Separate engine logic from input parsing
	logic with respect to configuration of an environment's
	inter-word and supplemental inter-sentence space sizes.

	* src/roff/troff/env.h: Stop globally declaring `space_size()`.
	(class environment): Declare new member functions returning
	`void`: `set_interword_space_size()`,
	`reset_supplemental_intersentence_space_size()`, and
	`set_supplemental_intersentence_space_size()`.  (The latter two
	differ because callers of the former require no knowledge of the
	default supplemental inter-sentence space size.)  Drop
	declaration of `friend` function `space_size()`.
	* src/roff/troff/env.cpp (environment::set_interword_space_size)
	(environment::reset_supplemental_intersentence_space_size)
	(environment::set_supplemental_intersentence_space_size): New
	functions mutate object of `environment` class.
	(space_size): Replace manipulation of `environment` object's
	private member variables with calls of public member functions.

2026-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test `ss` request.

	* src/roff/groff/tests/ss-request-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/box.cpp (get_param): Add strictly unnecessary
	`return 0` statement with lint-style `NOTREACHED` comment to
	quieten `-Wreturn-type` warning on GCC 9.5.0, which apparently
	doesn't do deep enough control-flow analysis to figure that out
	for itself.

2026-04-03  Johannes Altmanninger <aclopte@gmail.com>

	* src/preproc/eqn/neqn.sh:
	* src/roff/nroff/nroff.sh: Use a subshell instead of the user's
	login shell `$SHELL` to evaluate features of the running shell.
	The login shell need not be a POSIX shell script interpreter; it
	could be tcsh(1), rc(1), fish(1), or something exotic.
	* src/roff/nroff/nroff.sh: Update fatal error diagnostic
	accordingly.

	Fixes <https://savannah.gnu.org/bugs/?68212>.  [Problem
	introduced by me in commit c34c6cc58c, 2024-12-07. --GBR]

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp (xstrdup):
	* src/roff/groff/pipeline.c (sbasename): Tweak wording of error
	diagnostics; favor "cannot" over "unable to".

	Continues the long process of fixing Savannah #66519.

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man,mdoc]: Apply new `rhw` request, clearing the user-defined
	hyphenation exception word list with every new man(7) or mdoc(7)
	document.

	* tmac/an.tmac (TH):
	* tmac/doc-old.tmac (Dd):
	* tmac/mdoc/doc-common (Dd): Do it.

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Implement `rhw` request removing
	user-defined hyphenation exception words.
	(remove_hyphenation_exception_words_request): New function
	empties the current language's hyphenation exception word
	dictionary of all entries populated by the input.  (We retain
	those supplied by files like "tmac/hyphenex.{cs,en,pl}".)
	(init_hyphenation_pattern_requests): Wire up `rhw` request name
	to `remove_hyphenation_exception_words_request()`.

	* src/roff/groff/tests/rhw-request-works.sh: Test it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

	* doc/groff.texi.in (Manipulating Hyphenation):
	* man/groff.7.man (Request short reference):
	* man/groff_diff.7.man (New requests):
	* NEWS: Document it.

	Begins fixing <https://savannah.gnu.org/bugs/?64478>.

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/dictionary.cpp (dictionary_iterator::get):
	Accept a null pointer as second argument, to handle situation
	where the caller is interested only in the dictionary's keys.
	Dereference the pointer only if that argument is not null.
	{There was no check for this previously; were I not making this
	change, I'd be assert(3)ing that instead.}

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Promote `process_input_stack()`'s
	local `can_accept_control_character` from local to global.
	(interpolate_macro_or_invoke_request): Drop early `return` when
	no invokable request or callable macro exists on control line.
	Add assert(3)ion at end of function to enforce invariant: once
	we've processed a control line, either
	`can_accept_control_character` must be true or the token pending
	on the input stream must represent the end of input.

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(do_define_macro): Rename `reading_beginning_of_input_line`
	local to `can_terminate_definition_with_dot`.
	(transparent_throughput_file_request): Rename
	`reading_beginning_of_input_line` local to
	`is_at_beginning_of_input_line`.

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_define_macro)
	(transparent_throughput_file_request): Fix code style nits.
	Arrange equality comparisons to avoid inadvertent lvalue
	assignment.  Parenthesize formally complex expressions.

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (process_input_stack): Slightly
	refactor.  Align element type of templated STL `stack` container
	with the local variable representing its top: demote from `int`
	to `bool`.  Rename the stack object from `trap_bol_stack` to
	`trap_accepting_control_character_stack` and the (effective) top
	from `reading_beginning_of_input_line` to
	`can_accept_control_character`.

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Slightly refactor.  Resequence
	prototypes and forward declarations.

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Slightly refactor.  Retype
	`default_buffer_size` from `int` to more idiomatic `size_t`.

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(interpolate_macro): Rename this...
	(interpolate_macro_or_invoke_request): ...to this.
	(do_request, process_input_stack, do_define_macro): Update call
	sites.

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (decode_escape_sequence_arguments):
	Revise wording of warning diagnostic.

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename global
	`while_depth` to `while_loop_depth`.
	(while_request, while_break_flag, while_continue_request):
	Update dereference sites.

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (make_glyph_node): Revise wording of
	warning diagnostic.

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (embolden_font_request): Throw warning
	in category "style" if request arguments are ambiguous.  This
	could arguably be made an error since the ambiguity is inherent;
	it shows up in Kernighan troff (see CSTR #54, 1992 revision).
	But let's try a style warning first.  See Savannah #62776.

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (translate_font)
	(mount_font_at_position)
	(associate_style_with_font_position)
	(select_underline_font)
	(define_font_specific_character)
	(remove_font_specific_character)
	(set_font_specific_special_fonts)
	(set_special_fonts)
	(zoom_font)
	(embolden_font)
	(configure_track_kerning)
	(constantly_space_font)
	(set_ligature_mode)
	(set_kerning_mode): Rename these...
	(translate_font_request)
	(mount_font_at_position_request)
	(associate_style_with_font_position_request)
	(select_underline_font_request)
	(define_font_specific_character_request)
	(remove_font_specific_character_request)
	(set_font_specific_special_fonts_request)
	(set_special_fonts_request)
	(zoom_font_request)
	(embolden_font_request)
	(configure_track_kerning_request)
	(constantly_space_font_request)
	(set_ligature_mode_request)
	(set_kerning_mode_request): ...to these, following a developing
	convention of naming request handlers to end with "_request".

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp
	(print_font_mounting_position_request): Declare as `static`
	since it does not require external linkage.

2026-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/reg.cpp (number_value_to_ascii): When
	diagnosing a value beyond representatable Roman numeral range,
	disclose the specific format demanded.  Also tighten message
	wording.

2026-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Slightly refactor.  Make request
	handler functions more consistent such that calling
	`skip_line()` is the last thing they do before returning.  The
	goal is to build confidence that request handlers reliably leave
	the input stream in a well-defined state.  Doing so would
	prevent several bugs I introduced (and resolved, with help from
	fellow developers) in the groff 1.23.0 development cycle, but
	also cases like Savannah #68064, which lurked insidiously for
	about 35 years.
	(read_hyphenation_patterns_from_file): Stop calling `tok.next()`
	before returning.
	(load_hyphenation_patterns_from_file_request)
	(append_hyphenation_patterns_from_file_request): Call
	`skip_line()` before returning.

2026-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (print_environment_request): Declare as
	`static` since it does not require external linkage.

2026-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Trivially refactor.
	(print_hyphenation_exceptions)
	(load_hyphenation_patterns_from_file)
	(append_hyphenation_patterns_from_file): Rename these...
	(print_hyphenation_exceptions_request)
	(load_hyphenation_patterns_from_file_request)
	(append_hyphenation_patterns_from_file_request): ...to these,
	following a developing convention of naming request handlers to
	end with "_request".

2026-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Rationalize header inclusions.  Use
	preprocessor to include <assert.h> header, which declares the
	`assert()` macro used in this file.

2026-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/dictionary.h (object_dictionary_iterator::get):
	Use explicit `reinterpret_cast` C++ operator instead of C-style
	cast.  Annotate why we use this footgun.

2026-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (print_hyphenation_exceptions): Skip
	the remainder of the input line if no hyphenation language is
	configured.

	Fixes <https://savannah.gnu.org/bugs/?68203>.  Problem
	introduced by me in commit e05fb6b377, 2024-11-07 (itself a fix
	for a SEGV under the same circumstance).

2026-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #68203.

	* src/roff/groff/tests/\
	phw-request-skips-line-if-no-hyph-lang.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp
	(add_hyphenation_exception_words_request): Continue interpreting
	any arguments subsequent to an invalid one.  Doing so is more
	consistent with AT&T troff (tested: DWB 3.3, Plan 9 from User
	Space, Heirloom Doctools, Solaris).  Demote diagnostic emitted
	in this circumstance from an error to a warning in category
	"char".

	Fixes <https://savannah.gnu.org/bugs/?68202>.  Problem appears
	to date back to groff's birth.

2026-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #68202.

	* src/roff/groff/tests/\
	hw-request-skips-only-invalid-arguments.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp
	(add_hyphenation_exception_words_request): Stop throwing
	assert(3)ion if an argument contains a non-character.  The
	assertion is invalidated by plausible user input like:
	  `.hw baz\%qux`
	and similar.

	Begins fixing <https://savannah.gnu.org/bugs/?68202>.  Problem
	introduced by me in commit effd6835dc, 19 November.

2026-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Trivially refactor.

	* tmac/an.tmac (TH, AT, UC, PT, BT)
	(an*abbreviate-page-identifier, an*abbreviate-inner-footer):
	Rename `an-extra[123]` strings to `an*extra[123]`.

2026-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Trivially refactor.

	* tmac/an.tmac (an-style-warn): Rename this...
	(an*style-warn): ...to this.
	(an-deprecation-warn, an-blank-line-trap, an-leading-space-trap)
	(TH, BI, BR, IB, IR, RB, RI, RE, OP, EX, EE, MR): Update call
	sites.

2026-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (BI, BR, IB, IR, RB, RI): Trivially refactor;
	rename `an-result` (a temporary string into which these macros'
	arguments are catenated with font style changes and italic
	corrections as appropriate) to `an*result`.

2026-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Trivially refactor; rename `an-msg` (a temporary
	string into which a diagnostic message is constructed) to
	`an*msg`.

2026-03-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Ensure that the register
	`an-remap-I-style-in-headings` is always defined.  Fixes `reg`
	warning when user employs `HF` string to configure an unusual
	heading font (one that isn't bold, or isn't a member of a
	family).

2026-03-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/relocate.cpp (set_current_prefix): Move call
	of `msw2posixpath()` from an all-configurations path through the
	function to an `#ifdef _WIN32`-only one.
	(msw2posixpath) [_WIN32]: Since this function is now called only
	if `_WIN32` is defined, shift an `#endif` to also define it only
	under that circumstance.

2026-03-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/lf.h: Drop argument names from function
	declarations, better aligning code style with groff's
	Stroustrup-ish conventions.

2026-03-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Improve #include discipline.

	To illuminate inter-module dependencies, get header files out of
	the business of `#include`-ing other header files, in favor of
	putting preprocessor inclusions only in translation units (C/C++
	source files).  Annotate dependencies.

	* src/include/lf.h: Move preprocessor inclusion of
	"stringclass.h" from here...
	* src/libs/libgroff/change_lf.cpp: ...to here.
	* src/libs/libgroff/lf.cpp: Drop unnecessary inclusion of
	"lib.h".

2026-03-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Improve #include discipline.

	* src/include/lib.h: Declare `gen_tempname()` here...
	* src/libs/libgroff/mksdir.cpp: ...instead of here (as an
	`extern`).
	* src/libs/libgroff/tmpname.cpp: Resequence order of header file
	inclusions.

2026-03-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/strsave.cpp: Fix code style nits.  Arrange
	equality comparisons to avoid inadvertent lvalue assignment.
	Favor C++ `static_cast<>` operator over omnipotent C-style
	cast, except to explicitly discard unused return value of
	function.

2026-03-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/strsave.cpp: Improve header file
	inclusion discipline.  Use preprocessor to include "lib.h"
	header, which declares the `strsave()` function defined here.

2026-03-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/prime.cpp: Improve header file inclusion
	discipline.  Use preprocessor to include "lib.h" header, which
	declares the `ceil_prime()` function defined here.  Also
	unabbreviate data type of argument and return value; I prefer
	`unsigned int` to `unsigned`.  (It's surprising that Thompson
	and Ritchie overcame their inclination to extreme abbreviation
	here; not only are "signed" and "unsigned" intelligible English
	words, but it proved to be a bad idea to make their syntax
	closely resemble what eventually became ANSI C89's type
	qualifiers `const`--notably an abbreviation again--and
	`volatile`.  It took ISO C99 to bring us `uintN_t` and `intN_t`
	types, at which point Ritchie, at least, appears to have given
	up on staying current with the language, never preparing with
	Kernighan a third edition of their _The C Programming Language_
	before his death in 2011.  I find it a fun diversion to consider
	how many problems of the C language can be sufficiently
	explained by a tacit but intense resentment of strong typing.)

2026-03-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/mksdir.cpp: Improve header file
	inclusion discipline.  Use preprocessor to include "lib.h"
	header, which declares the `mkdsir()` function defined here.

2026-03-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/relocate.cpp (msw2posixpath): Declare as
	`static` since it does not require external linkage.

2026-03-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/relocate.cpp (searchpathext): Declare as
	`static` since it does not require external linkage.  Doing so
	reveals that the function is not used at all except on Windows
	systems, so bracket with preprocessor `#ifdef`/`#endif`,
	avoiding `-Wunused-function` warning from GCC on GNU/Linux.

2026-03-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/pipeline.c: Check for memory allocation
	failure, and emit a fatal error diagnostic if it occurs.
	Unfortunately I was unable to test this code, as it's only
	reachable on non-POSIX systems (via `is_system_shell()` and
	`system_shell_dash_c()`; see "src/include/nonposix.h").

	Continues the long process of fixing Savannah #68192.

2026-03-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (main): Fix spaces missing from
	recently recast error diagnostic messages.

2026-03-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (parse_output_page_list, main):
	Revise and parallelize wording of error diagnostics relating to
	invalid command-line option arguments.

2026-03-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (in_output_page_list, main):
	Explicitly compare values of pointer type to null pointer
	literals instead of letting them pun down to Booleans.

2022-02-05  Dave Kemper <saint.snit@gmail.com>

	* doc/groff.texi.in (Assigning Register Formats): Clarify
	guidance from Unicode regarding Roman numerals.

	Fixes <https://savannah.gnu.org/bugs/?61998>.

2026-03-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[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 <g.branden.robinson@gmail.com>

	* src/roff/troff/reg.cpp (number_value_to_ascii): Trivially
	refactor.  Rename cryptic local `s` to `roman_numerals`.  Also
	parenthesize formally complex expression.

2026-03-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::set_font): Invert
	returned Boolean value when this function is activated on a
	font-change operation that lies on the unformatted portion of an
	input line interrupted/continued with `\c`.  Returning "true"
	was inconsistent with other environment mutator functions in
	this file, including the signature of this member function
	taking an integer (rather than a `symbol`) argument.
	Eventually, we should make these functions unreachable in such
	circumstances.  See Savannah #67812.

2026-03-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Rename `WARN_INVALID` enumeration constant to
	`WARN_DUMMY`.  The latter is more descriptive of its purpose.

	* src/roff/troff/troff.h (enum warning_category):
	* src/roff/troff/input.cpp (debug, error, fatal): Do it.

2026-03-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libdriver]: Rename `do_file()` to
	`interpret_troff_output_file()`.  There are several `do_file()`
	functions in the groff code base; each does something different.

	* src/include/driver.h: Update declaration.
	* src/libs/libdriver/input.cpp (do_file): Rename this...
	(interpret_troff_output_file): ...to this.
	* src/devices/grodvi/dvi.cpp (main):
	* src/devices/grohtml/post-html.cpp (main):
	* src/devices/grolbp/lbp.cpp (main):
	* src/devices/grolj4/lj4.cpp (main):
	* src/devices/grops/ps.cpp (main):
	* src/devices/grotty/tty.cpp (main): Update call sites.

2026-03-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	Rationalize header file inclusions.  To illuminate inter-module
	dependencies, get header files out of the business of
	`#include`-ing other header files, in favor of putting
	preprocessor inclusions only in translation units (C/C++ source
	files).  Annotate dependencies.

	* src/devices/grodvi/dvi.cpp:
	* src/devices/grodvi/dvi.cpp:
	* src/devices/grohtml/html-table.cpp:
	* src/devices/grohtml/html-text.cpp:
	* src/devices/grohtml/html-text.h:
	* src/devices/grohtml/post-html.cpp:
	* src/devices/grolbp/lbp.cpp:
	* src/devices/grolj4/lj4.cpp:
	* src/devices/grops/ps.cpp:
	* src/devices/grotty/tty.cpp:
	* src/include/color.h:
	* src/include/driver.h:
	* src/include/printer.h:
	* src/libs/libdriver/input.cpp:
	* src/libs/libdriver/printer.cpp:
	* src/libs/libgroff/color.cpp:
	* src/roff/troff/dictionary.cpp:
	* src/roff/troff/div.cpp:
	* src/roff/troff/env.cpp:
	* src/roff/troff/input.cpp:
	* src/roff/troff/mtsm.cpp:
	* src/roff/troff/mtsm.h:
	* src/roff/troff/node.cpp:
	* src/roff/troff/number.cpp:
	* src/roff/troff/reg.cpp:
	* src/roff/troff/troff.h: Do it.

2026-03-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/html-table.cpp: Arrange inclusions of
	libgroff header files before application-specific ones.

2026-03-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grohtml/html-table.cpp: Improve header file
	inclusion discipline.  Drop unnecessary preprocessor
	inclusions of standard <stdio.h> and local (but nonexistent)
	"ctype.h" header files.

2026-03-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grodvi,grolbp,grops]: Improve header file inclusion discipline.

	* src/devices/grodvi/dvi.cpp:
	* src/devices/grolbp/lbp.cpp:
	* src/devices/grops/ps.cpp: Drop unnecessary preprocessor
	inclusions of "paper.h" header file.

2026-03-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/driver.h: Drop preprocessor inclusion of
	"geometry.h" from here, and add it where it's needed...
	* src/devices/grodvi/dvi.cpp:
	* src/devices/grolj4/lj4.cpp:
	* src/devices/grops/ps.cpp:
	* src/libs/libgroff/geometry.cpp: ...here.

2026-03-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/error.cpp: Drop `extern` declaration of
	`fatal_error_exit()`, now declared properly in "error.h".
	* src/libs/libgroff/fatal.cpp: Use preprocessor to include
	"errarg.h" and "error.h" header files.

2026-03-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/change_lf.cpp (change_filename):
	Parenthesize formally complex expressions.

2026-03-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/htmlhint.h: Drop redundant keyword `extern` from
	`html_begin_suppress()` and `html_end_suppress()` function
	declarations.
	* src/libs/libgroff/htmlhint.cpp: Use preprocessor to include
	"htmlhint.h" header file.

	Fixes `-Wmissing-declarations` warning.

2026-03-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/lf.h: Declare `change_filename()` and
	`change_lineno()` properly here...
	* src/libs/libgroff/lf.cpp: ...instead of here, with `extern`.
	* src/libs/libgroff/change_lf.cpp: Use preprocessor to include
	"lib.h" header file, also obviating the need for an `extern`
	declaration of `strsave()`, declared by the same header file.

	Fixes `-Wmissing-declarations` warning.

2026-03-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Boolify and rename static class member variable.

	* src/include/cmap.h (class cmap_init): `initialised` of type
	`int` becomes `is_initialised` of type `bool`.
	* src/libs/libgroff/cmap.cpp: Assign to it with Boolean, not
	integer, literals.

2026-03-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/error.h: Declare `fatal_error_exit()` here...
	* src/libs/libgroff/error.cpp: ...instead of here.

2026-03-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/ps.cpp (is_ascii): Fix code style nit.
	Produce return value with value construction syntax instead of a
	C-style type cast.

2026-03-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/ps.cpp (is_ascii): Boolify.

2026-03-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/ps.cpp (radians): Fix code style nit.
	Parenthesize formally complex expression.

2026-03-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grodvi,post-grohtml,grops]: Improve declarations.

	* src/devices/grodvi/dvi.cpp (scale):
	* src/devices/grohtml/post-html.cpp (stop, replace_negate_str)
	(replace_str):
	* src/devices/grops/ps.cpp (degrees, radians, is_ascii):
	* src/devices/grops/psrm.cpp (read_one_of)
	(skip_possible_newline): Declare functions as `static` since
	they do not require external linkage.

2026-03-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grolbp/lbp.cpp: Rearrange and annotate header file
	inclusions, placing module-specific header files last, after
	those of libraries.

2026-03-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix `-Wformat-truncation` warnings.

	* src/roff/troff/input.cpp (charinfo::dump):
	* src/roff/troff/node.cpp (glyph_node::asciify): When preparing
	to format the hexadecimal representation of a Unicode code
	point with `get_unicode_code()`, prepare a buffer of sufficient
	size to store a 32-bit unsigned integer, as that's what
	snprintf(3)'s `%X` conversion produces.  It doesn't know that
	Unicode is only a 20.1-bit code.  Even if it did, our use of
	`int` to store the value fails to communicate that constraint to
	snprintf(3).

	Even the use of `int` is a bit slippery of us, since it's a
	signed type with a 31-bit significand.  But libgroff's
	`glyph_to_unicode()`, which `get_unicode_code()` calls, uses
	"-1" to signal an error in-band.

2026-03-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* configure.ac: Stop interpolating `GROFF_CXX_CHECK` macro.
	* m4/groff.m4 (GROFF_CXX_CHECK): Delete macro definition. It
	dates back at least to groff 1.10 (1995).  ISO standardized C++
	in 1998; it no longer seems necessary in 2026 to check that a
	purported C++ compiler validly compiles a `main()` that simply
	returns `0`, nor that it correctly arranges for constructors and
	destructors of statically allocated objects to run.  A C++
	compiler failing to meet these criteria is not fit for purpose;
	working alternatives are universally available.

2026-03-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (char_list::set, char_list::get):
	Fix code style nit.  Parenthesize formally complex expressions.

2026-03-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (class char_list): Rename member
	variable `len` to `length`.
	(char_list::char_list, char_list::get_length, char_list::append)
	(char_list::set, char_list::get): Update dereference sites.

2026-03-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/request.h (class macro): Rename member variable
	`len` to `length`.
	* src/roff/troff/input.cpp (macro::macro, macro::operator=)
	(macro::append, macro::get_length, macro::chop)
	(macro::print_size, macro::json_dump)
	(string_iterator::string_iterator)
	(operator==): Update dereference sites.

2026-03-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Rename some member functions.

	* src/roff/troff/request.h (class macro):
	* src/roff/troff/input.cpp (class char_list, class node_list):
	Rename `length()` member function to `get_length()`, like other
	accessors in GNU troff.
	(char_list::length)
	(node_list::length)
	(macro::length): Rename these...
	(char_list::get_length)
	(node_list::get_length)
	(macro::get_length): ...to these.
	(macro:append, macro_header::json_dump_macro)
	(do_string_case_transform, substring_request): Update call
	sites.
	(do_string_case_transform): Drop unnecessary name space
	qualification.

2026-03-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (substring_request): Ignore request
	if both the "start" and "end" indices are out of range.
	* src/roff/troff/request.h (class macro): Drop declaration of
	`friend` function `substring_request()`.

	* doc/groff.texi.in (Strings) <substring>:
	* man/groff_diff.7.man (New requests) <substring>: Document it.

	* src/roff/groff/tests/\
	substring-request-on-invalid-range-is-no-op.sh: Test new
	behavior.

2026-03-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (substring_request): Slightly
	refactor.  Use `macro` object's public member function
	`length()` to obtain its length rather than its private member
	variable `len`.

2026-03-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (substring_request): Slightly
	refactor.  Introduce new local variable `len` to store value of
	`len` `macro` object being operated on, in case the compiler
	isn't smart enough to cache a repeated member variable access
	itself.

2026-03-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (substring_request): Slightly
	refactor.  When iterating through a `macro` object's contents,
	use its stored length to decide when to stop instead of relying
	on the `string_iterator` accessing each element to return an
	`EOF` character.  This change prepares for a future where GNU
	troff's internal character type might not encode `EOF` (at least
	not in the same way that the C standard I/O library does).  This
	change also weakens the resemblance of file and string
	iterators, but that seems acceptable to me, because string and
	macro contents have already undergone input processing.  In the
	future, this will mean decoding of UTF-8 sequences and possible
	NFD decomposition to one or more `char32_t` (or similar)
	objects.

2026-03-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (substring_request): Recast warning
	diagnostics when request argument(s) out of range.

2026-03-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (substring_request): Trivially
	refactor.  Rename local variable `real_length` to
	`operable_length`.  Annotate its meaning.

2026-03-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Drop dead code.
	(class node_list): Undeclare `extract()` member function.
	(node_list::extract): Drop unused  member function definition.

2026-03-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test no-op behavior of `substring` request when
	one of its index arguments is both negative and out-of-range.

	* src/roff/groff/tests/\
	substring-request-on-invalid-range-is-no-op.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-03-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (substring_request): Revise wording
	of error diagnostic.  The use of the term "extract" could be
	taken to mean that the original string was left intact, which is
	not the case; if the operation proceeds, it edits the string/
	macro/diversion's contents in place.

2026-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (abort_request): Slightly refactor.
	Avail ourselves of the `has_arg()` function; don't mess with any
	of the input character processing rigmarole if there is no such
	input to process.  Also flush the standard error stream only if
	we have written to it.  If someone feels that this should
	happen anyway "just in case" some other part of GNU troff
	neglects to do so, then an even better place for that insurance
	policy is `write_any_trailer_and_exit()`--it lies on _all_
	controlled paths out of the program.

2026-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/ab-request-works.sh: Conform better to
	modern groff test conventions.

2026-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	Skip more tests on buggy Solaris.

	* src/roff/groff/tests/ab-request-works.sh:
	* src/roff/groff/tests/handle-special-input-code-points.sh:
	* tmac/tests/an-ext_MR-works.sh:
	* tmac/tests/an_MR-works.sh:
	* tmac/tests/an_font-remapping-does-not-affect-titles.sh: Skip
	test if the shell in "/usr/xpg4/bin" mis-implements the `unset`
	shell built-in command.

2026-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (abort_request): Trivially refactor;
	for clarity, apply DeMorgan's Law so that the `if` statement
	guarding entry to a `for` loop matches the expression tested
	within it.

2026-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Improve type discipline with respect
	to groff's internal character representation.
	(macro::append): Append to macro contents using explicitly
	unsigned character (integer) literal rather than a signed one,
	for conceptual clarity.  "groff characters" are, for now,
	unsigned bytes.
	(macro_header::copy, string_iterator::fill, substring_request):
	Compare character read from an groff string iterator to unsigned
	character {integer} literal.

	Continues the long process of fixing Savannah #67735.

2026-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (composite_glyph_name)
	(do_define_string): Explicitly compare values of pointer type to
	null pointer literals instead of letting them pun down to
	Booleans.

2026-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (string_iterator::fill)
	(decode_macro_call_arguments, decode_escape_sequence_arguments)
	(do_define_string, do_define_macro, do_string_case_transform)
	(substring_request, do_non_interpreted, abort_request):
	Parenthesize formally complex expressions.

2026-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_char_in_copy_mode)
	(token::next, process_input_stack, macro_header::copy)
	(string_iterator::fill, decode_macro_call_arguments)
	(decode_escape_sequence_arguments, do_define_string)
	(interpolate_positional_parameter, do_define_macro)
	(do_string_case_transform, substring_request, asciify_request)
	(unformat_macro, non_interpreted_node::interpret)
	(do_non_interpreted, skip_branch, while_request)
	(stream_write_macro_request, abort_request,
	transparent_throughput_file_request, do_error): Arrange equality
	comparisons to avoid inadvertent lvalue assignment.

2026-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor.  Make the "guts" of the `chop_macro()`
	function a member function of class `macro`.

	* src/roff/troff/request.h (class macro): Declare member
	function `chop()`, taking no argument and returning `void`.
	Drop declaration of `friend` function `chop_macro()`.
	* src/roff/troff/input.cpp: Drop forward declaration of
	`chop_macro()`.
	(macro::chop): Member function takes responsibility for updating
	a `macro` object, reducing internally stored length of its
	contents if possible.  (Exception: token values used internally
	to manage the state of compatibility mode do not contribute to
	the length count.)
	(chop_macro): Rename this...
	(chop_request): ...to this, following a developing convention of
	naming request handlers to end with "_request".  Declare it
	`static`.  Replace lengthy `else` branch with a call of the
	resolved macro's `chop()` member function.
	(init_input_requests): Update wire-uppery of "chop" request
	name.

2026-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (chop_macro): Arrange equality
	comparisons to avoid inadvertent lvalue assignment.

2026-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (chop_macro): Drop error diagnostic
	that was thrown only in the event of an internal logic error.
	An assert(3)ion now handles that, and in an `NDEBUG` build the
	formatter can safely proceed.

2026-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (chop_macro): Add assert(3)ion to
	verify an invariant in the logic.  Instrumenting this test
	during a full groff build reveals that it's reached 670 times.

2026-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (chop_macro): Boolify and rename
	local variable.  `have_restore` becomes `contains_mode_tokens`.
	Assign to it with Boolean, not integer, literals.

2026-03-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp
	(transparent_throughput_file_request): Disallow all
	grout-invalid characters in "safer" transparent file throughput
	{implemented by the `trf` request}, including all C0 control
	code points except the line feed (Unix newline), and all C1
	controls and Latin-1 extension code points.  Revise warning
	diagnostic message.

	* doc/groff.texi.in (Host System Service Access, Warnings):
	* man/groff.7.man (Request short reference):
	* man/groff_diff.7.man (New requests):
	* src/roff/troff/troff.1.man (Warnings):
	* NEWS: Document it.

	Fixes <https://savannah.gnu.org/bugs/?66547>.

2026-03-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grotty/tty.cpp (tty_printer::end_page): Further
	simplify new dynamic memory management strategy to avoid memory
	leaks.  Always `delete[]` (free) the `lines` array at the end of
	a page, regardless of the value of `nlines`.  Comparing the
	latter's value to `default_lines_per_page` was a naïve
	technique.  First, reducing the page length _below_ the default
	would also cause a reallocation, so it needs to be freed.
	Second, if the input document resized the page multiple times,
	with the final value being equal to `default_lines_per_page`, we
	would similarly wrongly skip the `delete[]`.  Since
	`begin_page()` _always_ allocates storage with `new` and
	`add_char()` _always_ reallocates it with `new` (and deletes the
	old one) in the event of a resize, we can (and should) _always_
	delete the storage allocated to `lines` at the end of a page.

2026-03-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/tests/neqn-smoke-test.sh: Configure
	`GROFF_BIN_PATH` so that the build tree's "neqn" is more likely
	to locate the "eqn" that is also in the build tree.

2026-03-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn]: Add test of neqn's wrapping of eqn; their versions should
	match.

	* src/preproc/eqn/tests/neqn-finds-matching-eqn.sh: Add test.
	* src/preproc/eqn/eqn.am (eqn_TESTS): Run test.

2026-03-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: When issuing warning diagnostic messages, report the
	warning category governing its emission.  Idea ripped off from
	GCC, which has been doing similarly for many years.

	* src/roff/troff/troff.h (enum warning_category): Add a
	`WARN_INVALID` enumeration constant with value zero, since we're
	extending the signatures of diagnostic functions to pass the
	warning category as a parameter.  Doing so has no meaning for
	non-warning diagnostics, but `do_error()` handles _all_
	diagnostic messages, and so it must be prepared for this extra
	data.  This being C++98, we also don't have option types.

	* src/roff/troff/input.cpp (lookup_warning_by_bitset): New
	function looks up a bitset in the `warning_map` array and
	returns a pointer to a constant string naming the corresponding
	warning category.
	(do_error): Expect new parameter of type `warning_category`.
	If the diagnostic is of type `WARNING`, look up the new
	parameter with `lookup_warning_by_bitset` and report it in the
	message to the user.
	(debug, warning, output_warning, error, fatal): Update to pass
	`do_error()` either the given warning category, or
	`WARN_INVALID` if the diagnostic is not a warning.

	* NEWS: Document this.

2026-03-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/troff.h (enum warning_type): Rename this...
	(enum warning_category): ...to this, for consistency with groff
	documentation and because the enumeration constants aren't
	distinct "types" in the C++ sense.
	* src/roff/troff/input.cpp (warning, output_warning): Update
	users of the enumeration type.  Any given diagnostic warning
	corresponds to only one warning category.

2026-03-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(struct warning_category): Rename this...
	(struct warning_selection): ...to this.  This data structure
	creates a mapping between C strings and a bit vector.  The
	strings "all" and "w" aren't warning categories, but convenient
	shorthands for selection of multiple warning categories.

2026-03-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename global
	array `warning_table` to `warning_map`, for greater precision.
	(lookup_warning): Update dereference site.  Also rename this...
	(lookup_warning_by_name): ...to this.
	(enable_warning, disable_warning): Update call sites of
	foregoing.
	(struct warning_category): Rename member variable `set` to
	`bitset`, for clarity.

2026-03-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grotty]: Revise dynamic memory allocation strategy.  The
	`tty_printer` class maintains a member variable `lines`, a
	pointer to a pointer to type `tty_glyph`, which it uses as a
	reference to a dynamically allocated rectangular array of
	character cells.  The size of this array is not fixed; `pl`
	requests in an input document can grow or shrink the page
	length.  The strategy it has used to date to handle a
	non-default page length proved to perform badly with the new
	approach to continuous rendering used by groff's man(7) and
	mdoc(7) packages in version 1.24.0.  If the initial allocation
	of 66 lines (rows) of character cells was insufficient because
	the input extended the page length, it grew the allocation (and
	performed a memcpy(3) of its existing contents) by only as much
	as required to accommodate the current vertical drawing
	position, plus one line.  For a famously lengthy man page like
	bash(1), this meant many repeated trips through
	new/memcpy()/delete sequences, giving the language runtime
	allocator a lot of work to do.  In an extreme case {formatting
	64 catenated copies of bash(1)}, this led to long runtimes with
	two-thirds of program time spent in the kernel.

	The new strategy is to double the allocation size every time it
	is exceeded, but also to free any resized allocation at the end
	of every page.  When continuously rendering, there will only
	ever be one page anyway, but this tactic is more considerate for
	the {admittedly niche} case of paginated documents that vary the
	page length frequently--which is the approach that groff 1.23.0
	and earlier took to continuous rendering, and that other macro
	packages or documents might still.  (tbl(1) users should beware
	of the sort of problem observed in Savannah #65189.)  This
	change reduces grotty(1)'s wall-clock time for the
	aforementioned 64 copies of bash(1) from 92.1 seconds to 3.5,
	and the proportion of process time spent in the system from
	63.3% to 6.38%.

	* src/devices/grotty/tty.cpp: Define new global constant
	integer, `default_lines_per_page`, obviating a local literal in
	the `tty_printer` constructor.
	(class tty_printer): Drop empty body from `begin_page()`
	declaration.
	(tty_printer::tty_printer): Replace open-coded initial
	allocation of storage backing `lines` member variable with call
	to `begin_page()`.
	(tty_printer::~tty_printer): Stop freeing the storage backing
	`lines` here.  Instead...
	(tty_printer::end_page): ...do it here, if its size grew beyond
	the default initial allocation.
	(tty_printer::add_char): Apply the new reallocation strategy.
	Use memset(3) to zero out the new storage before memcpy(3)-ing
	the previous contents into (part of) it, eliminating a `for`
	loop that manually zeroed out the pointers after the copied
	storage.  While arguably wasteful to write some memory twice,
	the runtime can easily optimize `memset()`, as, for instance,
	glibc does.[1]  Measurement shows that any reduced efficiency
	here is lost in the noise of the vast improvement arising from
	the allocation size-doubling approach.
	(tty_printer::begin_page): Implement.  Initially allocate
	`default_lines_per_page` rows of `tty_glyph` pointers.  Use
	memset(3) here, too, to zero them out.

	[1] https://sourceware.org/git/?p=glibc.git;a=commit;\
	h=46b5e98ef6f1

	Fixes <https://savannah.gnu.org/bugs/?68145>.  Thanks to Dmytro
	Bagrii for the report, to Morten Bo Johansen for help
	reproducing the problem, and to Deri James for a shrewd pointer
	in the right direction.

2026-03-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (struct warning_category): Add
	{further} `const` qualification to type and its members.  This
	structure is immutable for the lifetime of the program.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* bootstrap.conf (gnulib_modules): Drop `putenv`.

	Fixes <https://savannah.gnu.org/bugs/?68024>.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp: Refactor: migrate from putenv(3) to
	setenv(3) (4/4).
	(xputenv): Drop no-longer-used function.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp: Refactor: migrate from putenv(3) to
	setenv(3) (3/4).  Drop global pointer variable `groff_bin_path`.
	(main): Stop initially populating `newpath` local variable with
	"PATH=" in favor of straightforward call to `xsetenv()` with
	`PATH` string literal and contents of `newpath` groff string as
	arguments.  Because, unlike putenv(3), setenv(3) makes its own
	copies of its C string operands, we no longer need to reserve
	statically allocated storage for them to keep them from going
	out of scope.
	(xexit): Stop free(3)ing abandoned variable `groff_bin_path`.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp: Refactor: migrate from putenv(3) to
	setenv(3) (2/4).  Drop global pointer variable `saved_path`.
	(main): Drop local string `g` containing shell-like
	environment variable assignment in favor of straightforward call
	to `xsetenv()` with `GROFF_PATH__` string literal and existing
	`path` (populated by `getenv("PATH")`) as arguments.  Because,
	unlike putenv(3), setenv(3) makes its own copies of its C string
	operands, we no longer need to reserve statically allocated
	storage for them to keep them from going out of scope.
	(xexit): Stop free(3)ing abandoned variable `saved_path`.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp: Refactor: migrate from putenv(3) to
	setenv(3) (1/4).  Drop global pointer variable
	`groff_font_path`.
	(xsetenv): New function wraps setenv(3) as `xputenv()` does
	putenv(3).
	(main): Replace local string `e` containing shell-like
	environment variable assignment with string `value` containing
	only the value to be assigned.  Call `xsetenv()` with
	`GROFF_FONT_PATH` string literal and `value` as arguments.
	Because, unlike putenv(3), setenv(3) makes its own copies of its
	C string operands, we no longer need to reserve statically
	allocated storage for them to keep them from going out of scope.
	(xexit): Stop free(3)ing abandoned variable `groff_font_path`.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	Refactor: migrate from putenv(3) to setenv(3).

	* src/devices/grops/ps.cpp (main):
	* src/devices/grops/psrm.cpp (resource_manager::output_prolog):
	* src/roff/troff/input.cpp (main): Do it.

	Begins fixing <https://savannah.gnu.org/bugs/?68024>.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp (main): Slightly refactor.  Rename
	local variable `f` to `newpath` to make its purpose clearer.
	Reduce number of string operations.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/xditview/device.c (find_file): Initialize local
	pointer variables with explicit null pointer constant.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	Trivially refactor.  Compare C/C++ objects of `char` type to
	character literals instead of punning them down to Booleans.

	* src/devices/xditview/device.c (find_file):
	* src/libs/libgroff/device.cpp (device_init):
	* src/libs/libgroff/searchpath.cpp (search_path::search_path):
	* src/roff/groff/groff.cpp (main):
	* src/roff/troff/input.cpp (interpolate_environment_variable):
	Do it.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	Trivially refactor.  Compare return value of getenv(3) to
	explicit null pointer constants appropriate for C or C++ instead
	punning that return value down to a Boolean.

	* src/devices/grops/psrm.cpp (resource_manager::output_prolog):
	* src/devices/grotty/tty.cpp (main):
	* src/devices/xditview/device.c (find_file):
	* src/libs/libgroff/curtime.cpp (current_time):
	* src/libs/libgroff/device.cpp (device_init):
	* src/libs/libgroff/relocate.cpp (set_current_prefix):
	* src/libs/libgroff/searchpath.cpp (search_path::search_path):
	* src/preproc/html/pre-html.cpp (scanArguments):
	* src/preproc/refer/refer.cpp (possibly_load_default_database):
	* src/roff/groff/groff.cpp (main):
	* src/utils/lkbib/lkbib.cpp (main): Do it.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/psrm.cpp (resource_manager::output_prolog):
	Handle getenv(3) failure.  Having just written successfully to
	the process environment (else we `fatal()`ed out), assert(3)
	that reading back the same environment variable with getenv(3)
	returned a non-null pointer.  If it didn't and `NDEBUG` is
	defined, `fatal()` out in this case too.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/xditview/device.c: Slightly refactor.  Convert
	C/C++ preprocessor macro `FONTPATH_ENV_VAR` to global `const`
	object named `FONT_ENV_VAR`, for consistency with identical
	usage in "src/libs/libgroff/fontfile.cpp".
	(find_file): Update getenv(3) call to use the new symbol name.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* m4/groff.m4 (GROFF_USE_GROFF_ALLOCATOR): Update help string to
	mark `--enable-groff-allocator` configuration option as
	deprecated.
	(GROFF_ALLOCATOR_NOTICE): New macro warns user of option's
	planned withdrawal if they have selected it.
	* configure.ac: Interpolate `GROFF_ALLOCATOR_NOTICE` macro.

	* NEWS: Document this.

	Fixes <https://savannah.gnu.org/bugs/?67936>.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* configure.ac: Stop reporting use of libgroff's custom memory
	allocator in configuration summary.

	Begins fixing <https://savannah.gnu.org/bugs/?67936>.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/xditview/xditview.c (main): Avoid invalid memory
	access by checking that `argc` is greater than 1 before trying
	to access `argv[1]`.

	Fixes <https://savannah.gnu.org/bugs/?68152>.

2026-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/reg.cpp (rename_register_request): Fix typo in
	warning diagnostic message.

2026-03-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (is_conditional_expression_true):
	Keep track of how many leading `!` complementation operators
	appear in a conditional expression.  If multiple occur and the
	formatter is in AT&T compatibility mode, warn in category
	"syntax" that the construction is not portable to AT&T troffs.

	* doc/groff.texi.in (Other Differences):
	* man/groff_diff.7.man (Other differences): Document this
	syntactical difference.

2026-03-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/html/pushback.cpp (pushBackBuffer::readInt):
	Eliminate initialized-and-written-to-but-never-read local
	variable `c`.

	Thanks to Bjarni Ingi Gislason for the report in <https://\
	lists.gnu.org/archive/html/groff/2026-03/msg00072.html>.

2026-03-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Throw warning in category "style" if
	{a} centering or right-alignment is configured while a temporary
	indentation is in effect; or {b} a temporary indentation request
	is issued while centering or right-alignment are in effect.
	(cancel_temporary_indentation): New function--which I suspect
	should be a member function of class `environment`, but that
	would be confusingly inconsistent with existing practice--sets
	the temporary indentation amount to zero and sets the property
	of having a temporary indent off.  (Those are not the same
	thing.  Temporary indentation _overrides_ ordinary indentation,
	so a temporary indent of zero is often sensible.)  Also tell the
	mysterious MTSM machine that temporary indentation is off.
	(center): Throw the aforementioned warning from this `ce`
	request handler.
	(right_justify): Throw the aforementioned warning from this `rj`
	request handler.
	(temporary_indent): Throw the aforementioned warning from this
	`ti` request handler.
	* src/roff/troff/env.h (class environment): Declare new non-OO
	`cancel_temporary_indentation()` function as a friend.
	{Eighties-style.  <finger guns>}

	* doc/groff.texi.in (Warnings):
	* src/roff/troff/troff.1.man (Warnings): Document it.

	Fixes <https://savannah.gnu.org/bugs/?64275>.  See
	<https://lists.gnu.org/archive/html/groff/2023-05/msg00079.html>
	for illustration of the ill-defined composition of these
	features and (brief) discussion.

2026-03-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::space): Throw warning in
	category "style" if the end of a sentence is detected before the
	end of a text line.

	* doc/groff.texi.in (Warnings):
	* src/roff/troff/troff.1.man (Warnings): Document it.

	Fixes <https://savannah.gnu.org/bugs/?68151>.  Thanks to Alex
	Colomar for the original feature request.

2026-03-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (struct warning_category): Add new
	warning category, "style" (with symbol `WARN_STYLE`).  Suppress
	its enablement from the `-wall` command-line option shorthand,
	as categories "di", "mac", and "reg" are.  I expect much noise
	from historical documents in forthcoming applications of this
	category, and AT&T troff syntax is too loosely specified to
	support some of the ideas I have in mind.

	* doc/groff.texi.in (Warnings):
	* src/roff/troff/troff.1.man (Warnings):
	* NEWS: Document it.

	Fixes <https://savannah.gnu.org/bugs/?62776>.

2026-03-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_request): Boolify and rename
	some local variables.  `reading_from_terminal` becomes
	`is_reading_from_terminal`.  `nl` becomes `saw_newline`.  Assign
	to `is_reading_from_terminal`, `had_prompt`, and `saw_newline`
	with Boolean, not integer, literals.  Use idiomatic test
	expressions.

2026-03-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (word_space_node::need_reread)
	(hmotion_node::need_reread): Assign to `bool`-typed `unformat`
	member variable with Boolean, not integer, literals.  Continues
	commit 8ab4aa8bec, 2024-08-14.

2026-03-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Boolify and rename `global_diverted_space`.

	* src/roff/troff/input.cpp: Demote global variable
	`global_diverted_space` from `int` to `bool` and rename it to
	`have_global_diverted_space`.  Annotate it as used only by the
	MTSM feature, which I hope some day either to better understand,
	or to remove.
	* src/roff/troff/env.cpp: Update an `extern` declaration.
	* src/roff/troff/input.cpp (diverted_space_node::need_reread):
	* src/roff/troff/env.cpp (environment::do_break): Update sites
	of use.

2026-03-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/pfbtops/pfbtops.am (nodist_EXTRA_pfbtops_SOURCES):
	Drop "trick" macro definition 'to force the use of C++
	compiler[.]  See the Automake manual, "Libtool Convenience
	Libraries"'.  However, groff doesn't use Libtool.  The
	nonexistent dummy file declared here impedes the use of
	Automake's "tags" target.  After this change, "pfbtops"'s
	linkage is unchanged per ldd(1), the smoke test still passes,
	and the program appears to still operate fine on the file
	"build/font/devpdf/symbolsl.pfb"...on amd64 GNU/Linux with a GNU
	toolchain.

2026-03-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Implement `.ul` register for orthogonal completeness
	with respect to the `.ce`, `.rj`, and `.it` registers.

	* src/roff/troff/env.h (class environment): Declare new accessor
	member function `get_underlined_line_count()`.
	* src/roff/troff/env.cpp
	(environment::get_underlined_line_count): Define it.
	(init_env_requests): Wire up `.ul` register name to
	`get_underlined_line_count()`.

	* src/roff/groff/tests/dot-ul-register-works.sh: Test it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

	* doc/groff.texi.in (Artificial Fonts):
	* man/groff.7.man (Read-only registers):
	* man/groff_diff.7.man (New registers):
	* NEWS: Document it.

	Fixes <https://savannah.gnu.org/bugs/?68130>.

2026-03-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix Savannah #68137.

	* src/roff/troff/number.cpp (is_valid_expression): When
	interpreting a parenthesized sub-expression within a numeric
	expression while in AT&T compatibility mode, throw a warning in
	category "syntax" if encountering a space in the input, advising
	of non-portability to that family of formatters.  GNU troff
	continues to interpret the expression as it always has.

	Fixes <https://savannah.gnu.org/bugs/?68137>.

2026-03-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Make `want_att_compat` global.  This is a prerequisite
	to fixing Savannah #68137.
	
	* src/roff/troff/input.cpp: Drop its `static` storage class.
	* src/roff/troff/token.h: Declare it with `extern` storage
	class.

2026-01-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Refer to C0
	control characters (that are valid as GNU troff input) and Basic
	Latin DEL (all unprintable) by their decimal code points, not by
	writing them out literally.

	Noted while working on Savannah #67978.

2026-01-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix Savannah #64300.

	* src/roff/troff/div.cpp (space_request): If the `sp` request is
	invoked with the no-break control character (that is, "'sp")
	when the drawing position is off the page (as when the formatter
	starts up), ignore the request and throw an error diagnostic.
	This is inconsistent with AT&T troffs (including Heirloom
	Doctools) and neatroff, but precisely consistent with all other
	requests that have different semantics when invoked with the
	no-break control character.  When invoked thus, none of `br`,
	`brp`, `ce`, `cf`, `fi`, `fl`, `in`, `nf`, or `rj` move the
	drawing position onto the page.

	* tmac/doc-old.tmac (Sh): If the formatter claims groff
	compatibility, simply emit a `br` request to start the (next)
	document instead of invoking `sp` with the no-break control
	character.

	* doc/groff.texi (Manipulating Spacing): Document that invoking
	`'sp` in the top-level diversion when the vertical drawing
	position is negative is an error.

	* doc/groff.texi (Other Differences):
	* man/groff_diff.7.man: (Other differences): Document difference
	between AT&T and GNU troffs.  (AT&T troff's behavior looks buggy
	to me...)

	Fixes <https://savannah.gnu.org/bugs/?64300>.  Thanks to Dave
	Kemper for the discussion.

2026-03-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Add `WARN_ESCAPE` to default warning
	"mask".  (It's not a mask, just a vector--or a set.)

	* doc/groff.texi (Warnings):
	* src/roff/troff/troff.1.man (Warnings):
	* NEWS: Document it.

	Fixes <https://savannah.gnu.org/bugs/?67783>.

2026-03-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Add `WARN_SYNTAX` to default warning
	"mask".  (It's not a mask, just a vector--or a set.)

	* doc/groff.texi (Warnings):
	* src/roff/troff/troff.1.man (Warnings):
	* NEWS: Document it.

	Begins fixing <https://savannah.gnu.org/bugs/?67783>.

2026-03-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Add `WARN_DELIM` to default warning
	"mask".  (It's not a mask, just a vector--or a set.)

	* doc/groff.texi (Warnings):
	* src/roff/troff/troff.1.man (Warnings):
	* NEWS: Document it.

	Continues the long process of fixing Savannah #66009.

2026-03-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_device_extension): Emit error
	diagnostic instead of accessing invalid memory if an attempt is
	made to output a device extension command while the currently
	selected font is invalid.  In the future we might not need the
	current font to be valid to format a device extension node, but
	for now we do because it "dirties", and therefore has to
	subsequently restore, several bits of font-related state.  We
	might be able to make this unnecessary with a parameterized
	extension to the `fl` request.  See Savannah #66187.

	Fixes <https://savannah.gnu.org/bugs/?67978>.  Thanks to Bruno
	Haible for the report.

2026-03-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/\
	do-not-crash-on-mismatched-diversion-request.sh: Revise and
	expand test.  Stop checking for core dump file, as this is not
	necessarily reliable.  Instead seed test input with formattable
	words that we expect to be present or not, depending on whether
	and where the formatter exits abnormally.  Check that closing a
	`box` diversion with `di` is not a fatal error, and that closing
	a `di` diversion with `box` _is_ fatal.

	Thanks to Bob Friesenhahn and Zack Weinberg for the suggestion
	to not rely on core dump files as failure oracles.

2026-03-05  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #67978.

	* src/roff/groff/tests/\
	do-not-crash-on-backslash-X-if-font-invalid.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2026-03-05  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Add internal mechanism for distinguishing validity of
	font mounting positions as _values_ from their usability to
	format output.  A font mounting position is an integer with a
	limited range.  The font information associated with that
	{otherwise valid} position can nevertheless not be usable for
	formatting output.  While the formatter attempts to prevent
	input documents from contorting themselves into this situation,
	it also affords a means of egress from valid state.  See the
	`sty` (counter-)example in groff's Texinfo manual <https://\
	www.gnu.org/software/groff/manual/groff.html.node/
	Font-Families.html>.

	Add new function taking an integer mounting position and
	returning a Boolean.

	* src/roff/troff/node.h: Declare it.
	* src/roff/troff/node.cpp (is_valid_font): Define it.

2026-03-05  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor resolution of currently selected font (which
	can be an abstract style, or even invalid) to a font mounting
	position.
	* src/roff/troff/node.h: Declare function
	`resolve_current_font_to_mounting_position()`; we'll need access
	to it from "input.cpp" in a forthcoming change.
	* src/roff/troff/node.cpp (env_resolve_font): Drop `static`
	storage class and `inline`.  "[T]he ... otherwise perfectly
	logical combination of external linkage and inlining is banned
	to make life simpler for compiler writers[.]" (_The C++
	Programming Language, Special Edition_, Stroustrup, 1997, p.
	199)  And rename this...
	(resolve_current_font_to_mounting_position): ...to this.
	Annotate purpose.
	(device_extension_node::device_extension_node)
	(make_composite_node)
	(make_glyph_node)
	(env_space_width)
	(env_sentence_space_width)
	(env_half_narrow_space_width)
	(env_narrow_space_width): Update call sites.

2026-03-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Boolify
	`psbb_locator::skip_to_trailer()`.  Its lone call site tests
	only for a positive return value and discards it.
	(class psbb_locator): Demote return type from `int` to `bool` in
	declaration.
	(psbb_locator::psbb_locator): Simplify test of return value.
	(psbb_locator::skip_to_trailer): Demote return type from `int`
	to `bool` in definition.  Return Boolean rather than integer
	literals or the otherwise unused `status` local value.

2026-03-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Make warning diagnostic functions return `void`.
	Change return type of `warning()` and `output_warning()`
	functions from `int` to `void`.  I would have boolified them,
	but nothing ever checks their return values.

	* src/roff/troff/troff.h: Update declarations.
	* src/roff/troff/input.cpp (warning, output_warning): Update
	definitions.  Simplify function bodies.

2026-03-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Rename several warning-relatd data
	for clarity.  Rename preprocessor macro `DEFAULT_WARNING_MASK`
	to `DEFAULT_WARNING_CATEGORY_SET`.  Rename file-scoped variable
	`warning_mask` to `desired_warnings` (it's a _set_ type, not a
	"mask", which is more specific).
	(enable_warning):
	(disable_warning):
	(warning):
	(output_warning): Update site of dereference.
	(init_input_requests) <.warn>: Update wire-uppery.

	(do_expr_test): Rename local variable `saved_warning_mask` to
	`saved_desired_warnings`.
	(enable_warning, disable_warning): Rename local variable `mask`
	to `category`.

	(set_warning_mask_request): Rename this...
	(configure_desired_warnings_request): ...to this.
	(init_input_requests) <warn>: Update wire-uppery.

	(struct warning_category): Rename `mask` member to `set`.
	(lookup_warning): Track rename of structure member.

2026-03-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_expr_test)
	(string_iterator::fill): Fix code style nit: assign to variable
	of unsigned integral type with explicitly unsigned integer
	literal.

2026-03-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Fix typoed variable name; rename
	`is_output_supressed` to `is_output_suppressed`.
	(glyph_node::asciify):
	(kern_pair_node::asciify):
	(dbreak_node::asciify):
	(ligrature_node::asciify):
	(break_char_node::asciify):
	(italic_corrected_node::asciify):
	(left_italic_corrected_node::asciify):
	(space_char_hmotion_node::asciify):
	(word_space_node::asciify):
	(unbreakable_space_node::asciify):
	(suppress_node::asciify):
	(zero_width_node::asciify):
	(composite_node::asciify): Update sites of dereference.

	Fixes <https://savannah.gnu.org/bugs/?68071>.

2026-03-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	* Makefile.am (.version, dist-hook): Use `AM_V_GEN` macro in
	production of targets, to make them less garish in builds
	without `V=1` specified as a make(1) argument.



________________________________________________________________________

##### License

Copyright 2026 G. Branden Robinson

Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.


##### Editor settings
Local Variables:
fill-column: 72
mode: change-log
version-control: never
End:
vim:set autoindent textwidth=72:
