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

	[gropdf]: Regression-test Savannah #67927.

	* tmac/tests/pdf_pdfhref-W-without-link-text-works.sh: New file.
	* src/devices/gropdf/gropdf.am (gropdf_TESTS): Run test.

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

	* src/roff/groff/tests/lj4-device-smoke-test.sh: Pass `-P
	-pletter` arguments to groff, to compel output driver to use
	U.S. letter paper format.  Fixes test failure in environments
	where this paper format is not the default.

	Fixes <https://savannah.gnu.org/bugs/?67927>.  Thanks to Bjarni
	Ingi Gislason for the report and Deri James for the analysis and
	solution.

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

	* doc/groff.texi.in:
	- Stop attempting to manually recapitulate the topology of the
	  Info node tree with arguments after the first to `@node`
	  commands; doing so is no longer required by recent versions of
	  Texinfo--thanks to Alexis Hildebrandt for bringing this to my
	  attention and providing a proof-of-concept patch--but the
	  normative topology of the directed tree is radically
	  unintuitive to me, leading me to make many errors.  It _seems_
	  like Info's idea of the node traversal strategy preferred by
	  humans is breadth-first in one direction ("Next") and
	  _depth_-first in the other ("Prev").
	- Fix erroneous menu entries.  This finishes cleaning up
	  warnings about the document's node topology from recent
	  Texinfo.

	Fixes Savannah #67838.

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

	Crib gnulib's coverage generation from its "maint.mk" file.
	This way developers can run "make coverage" to produce a code
	coverage report.  Requires "lcov" package.

	* Makefile.am: Define macros `COVERAGE_CCOPTS` and
	`COVERAGE_OUT`.
	(init-coverage, build-coverage, gen-coverage, coverage): Define
	new (phony) target rules.

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

	* src/devices/gropdf/gropdf.pl (.pdf*href): For external
	hotspot links (.pdfhref W  [-D URI] [-P prefix-text] \
	[-A affixed-text] [--] [hotlink text]), if no 'hotlink text'
	is specified but an URI is given, use it as the text
	rather than 'Unknown'.

	Fixes <https://savannah.gnu.org/bugs/?67916>. Thanks to
	Branden Robinson for the suggested improvement.

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

	* src/devices/gropdf/gropdf.1.man (Macros) <pdfbookmark>
	<pdfnote, pdhref>: Document macros.

	Fixes <https://savannah.gnu.org/bugs/?66453>.  Thanks to Deri
	James for supplying an overview of features in Savannah #67665.

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

	* src/devices/gropdf/gropdf.1.man (Usage): Drop references to
	Keith Marshall's "pdfmark" macro package; it is now maintained
	separately from groff, and some of the claims had become stale.

	Fixes <https://savannah.gnu.org/bugs/?67911>.  Thanks to Bjarni
	Ingi Gislason for the report.

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

	[pic]: Improve fix for Savannah #67899.

	* src/preproc/pic/lex.cpp (interpolate_macro_with_args): Shift
	more logic inside the `!ignore` conditional; this way we
	correctly handle the case of a non-empty 33rd macro argument.
	We were no longer smashing the stack with a list of pointers of
	user-controlled length, but we were permitting the stack memory
	at a location one past the end of the `argv` array to be
	written to.

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

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

	* src/roff/groff/groff.cpp (main): Bump ending year of copyright
	notice to 2026 to reflect (presumably) copyrightable changes in
	the source tree as a whole since December 31.  See "Updating
	Copyright Notices" in our "HACKING" file.

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

	[troff]: Rename `ptr` request to `pwh`.

	* src/roff/troff/div.cpp (init_div_requests): Do it.
	* tmac/troffrc (ptr): Define macro advising user to migrate.
	Invoke `pwh`.

	* doc/groff.texi.in (Page Location Traps, The Implicit Page
	Trap, Debugging):
	* man/groff.7.man (Request short reference, Page location traps,
	Debugging):
	* man/groff_diff.7.man (New requests, Debugging): Update
	documentation.

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

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

	[pic]: Fix Savannah #67899.

	* src/preproc/pic/lex.cpp (interpolate_macro_with_args): Shift
	test of argument count so that it is performed for empty
	arguments as well as populated ones.  The misplacement of the
	test made it possible to defeat that test by supplying an empty
	32nd argument to a macro, consequently overrunning stack storage
	allocated for this function's local `argv` array.

	Fixes <https://savannah.gnu.org/bugs/?67899>.  Thanks to John de
	Armas for the report and a reproducer, based on the
	"jumperblock" example from our "doc/pic.ms" file.  Problem
	appears to date back to groff's birth.

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

	[pic]: Regression-test Savannah #67899.

	* src/preproc/pic/tests/\
	do-not-crash-when-reading-macro-arguments.sh: New file.
	* src/preproc/pic/pic.am (pic_TESTS): Run test.

2025-12-21  Alexis Hildebrandt <afh@surryhill.net>

	* tmac/trans.tmac [PH]: Expose mm package's `Captc` string to
	translation.
	* tmac/cs.tmac:
	* tmac/de.tmac:
	* tmac/es.tmac:
	* tmac/fr.tmac:
	* tmac/it.tmac:
	* tmac/ru.tmac:
	* tmac/sv.tmac: Update string name and lexicographic sort.

	Begins fixing Savannah #67830.

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

	* src/roff/groff/groff.am (EXTRA_DIST): Ship
	"small-gnu-head.png" test artifact in distribution archive.

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

	* src/roff/groff/tests/using-diversion-as-character-works.sh:
	Fail hard (with status 99) if our test artifact isn't present.
	Continues commit 3f783091f0, 19 December 2024.

2026-01-02  Helmut Grohne <helmut@subdivi.de>

	* src/libs/libgroff/libgroff.am (install_charset_data): Don't
	ship a "charset.alias" file if it's empty or contains nothing
	but comments.  Such files, a common product of certain gnulib
	internals, aggrieve a Debian packaging assistance tool.

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

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

	* tmac/groff_mdoc.7.man (Other possible pitfalls): Advise
	composers of mdoc(7) documents to use `\-` for copy-and-pastable
	hyphen-minus characters.

	Fixes <https://savannah.gnu.org/bugs/?67881>.  Thanks to Bjarni
	Ingi Gislason for pointing out incorrect usage in sudo(8).

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

	* src/roff/groff/tests/\
	double-do-request-does-not-raise-assertion.sh: Rename this...
	* src/roff/groff/tests/\
	double-do-request-does-not-fail-assertion.sh: ...to this.
	* src/roff/groff/groff.am (groff_TESTS): Track rename.

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

	* gnulib: Refresh stable/2025-07 branch.  We need some
	recent fixes that have landed there.  See
	<https://lists.gnu.org/archive/html/bug-gnulib/2025-12/msg00158.html>
	and
	<https://lists.gnu.org/archive/html/bug-gnulib/2026-01/msg00000.html>.

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

	* src/preproc/preconv/preconv.cpp (conversion_iconv): Use
	`const_cast<>` to cast away `const`, not `static_cast<>`.  Fixes
	build on Solaris 11/sparc64/GCC 5.5.  Problem introduced by me
	in commit 1740c22b4a, 11 July.  Thanks to Bruno Haible for the
	clue.

2025-12-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp (do_divert): Shift checks resulting in
	error diagnostics, including a fatal one, later in the logic.
	It's not a problem to close a diversion of mismatched "boxing"
	{see Savannah #67139} when the diversion stack is empty.  We can
	simply emit a warning as groff 1.23.0 and earlier did.
	Continues commit 251115ed5a, 19 May.

2025-12-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Work on Savannah #67735.

	* src/roff/troff/node.h (struct node):
	* src/roff/troff/node.cpp (class break_char_node)
	(node::get_break_code): Demote type of hyphenation codes from
	`int` to `unsigned char`, since the range of the latter is as
	much as has ever been stored in them anyway.  (This was
	discovered the hard way in Savannah #66919.)  Retype
	`break_code` and `prev_break_code` private member variables and
	`get_break_code()` public member function accordingly.

2025-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Improve type-correctness (slightly).

	* src/roff/troff/number.cpp: Define globals `hresolution`,
	`vresolution`, and `units_per_inch` as having `units` type
	rather than `int`.  This is merely _documentary_
	type-correctness, however, as `units` isn't strongly typed, but
	only a slovenly `typedef` alias of `int`.
	* src/roff/troff/troff.h: Align declarations with foregoing
	definitions.

2025-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Fix code style nits.
	(font_info::set_bold)
	(troff_output_file::fill_color): Parenthesize formally complex
	expressions.
	(tfont::tfont)
	(real_output_file::~real_output_file)
	(zero_width_node::tprint)
	(translate_font): Explicitly compare value of pointer type to
	null pointer literal instead of letting it pun down to a
	Boolean.
	(translate_font)
	(configure_track_kerning)
	(constantly_space_font): Drop unnecessary parentheses from
	expression.

2025-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/div.h: Rename declaration `cleanup_and_exit()`
	to `write_any_trailer_and_exit()`.  Comment formal argument
	name as a compromise with the Stroustrup-style C++ used in most
	of groff.
	* src/roff/troff/div.cpp (cleanup_and_exit): Rename this...
	(write_any_trailer_and_exit): ...to this.
	* src/roff/troff/div.cpp (top_level_diversion::begin_page):
	* src/roff/troff/input.cpp (exit_troff, abort_request, do_error)
	(fatal_with_file_and_line): Migrate call sites.

2025-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(do_terminal)
	(terminal)
	(terminal1)
	(terminal_continue): Rename these...
	(terminal_write)
	(terminal_message_request)
	(terminal_message1_request)
	(terminal_message_continuation_request): ...to these.
	(init_input_requests): Update wire-uppery.

2025-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor for clarity.  "asciify" is one of
	the code base's more overloaded terms.  Rename one application
	of it.

	* src/roff/troff/token.h: Rename `asciify()` and relocate its
	declaration from here...
	* src/roff/troff/input.h: ...to here, as
	`encode_for_stream_output()`.

	* src/roff/troff/input.cpp (asciify): Rename this definition...
	(encode_for_stream_output): ...to this.

	* src/roff/troff/div.cpp
	(top_level_diversion::transparent_output):
	* src/roff/troff/input.cpp:
	(device_extension_node::tprint)
	(input_char_description)
	(do_terminal)
	(do_write_request)
	(stream_write_macro_request)
	(abort_request): Update call sites.

2025-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(write_request)
	(write_request_continue)
	(write_macro_request): Rename these...
	(stream_write_request)
	(stream_write_continuation_request):
	(stream_write_macro_request): ...to these.
	(init_input_requests): Update wire-uppery.

2025-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_terminal): Fix code style nits.
	Parenthesize formally complex expressions.  Arrange equality
	comparisons to avoid inadvertent lvalue assignment.

2025-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Fix code style nits.
	(do_terminal, terminal, terminal1, terminal_continue)
	(do_write_request, write_request, write_request_continue)
	(write_macro_request): Mark functions `static` since they do not
	require external linkage.
	(do_terminal): Demote argument types from `int` to `bool`.
	Rename them from `newline` and `string_like` to
	`do_append_newline` and `interpret_leading_spaces`.
	(terminal, terminal1, terminal_continue): Update call sites to
	use Boolean rather than integer literals.
	(do_write_request): Demote argument type from `int` to `bool`.
	Rename it from `newline` to `do_append_newline`.
	(write_request, write_request_continue): Update call sites to
	use Boolean rather than integer literals.

2025-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (process_macro_package_argument):
	Clarify fatal diagnostic message.

2025-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Slightly refactor.

	* src/roff/troff/env.h: Rename `want_break` global Boolean,
	relocating its declaration from here...
	* src/roff/troff/input.h: ...to here, as
	`was_invoked_with_regular_control_character`.  Yes, it's a
	mouthful, but it is the task of the request handlers, which are
	input processing functions, to interpret *roff's two distinct
	control characters, giving them one of them break suppression
	semantics.
	* src/roff/troff/div.cpp (begin_page, space_request)
	(flush_request):
	* src/roff/troff/env.cpp (fill, no_fill, center, right_justify)
	(indent, temporary_indent)
	(break_without_forced_adjustment_request)
	(break_with_forced_adjustment_request):
	* src/roff/troff/input.cpp (process_input_stack)
	(macro_iterator::macro_iterator)
	(unsafe_transparent_throughput_file_request)
	(transparent_throughput_file_request): Update dereference sites.
	* src/roff/troff/input.cpp: Update definition.
	* src/roff/troff/div.cpp: Include local "input.h" header file to
	get at the symbol's relocated declaration.

2025-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Refactor.  Further separate input
	processing logic from engine logic.
	(environment::do_break): Rename argument from `want_adjustment`
	to `want_forced_adjustment` for clarity.
	(break_output_line): Stop checking value of `want_break` global
	here, as that's determined by the input control character used
	to invoke the request, a front-end rather than an engine concern
	{albeit brearing an engine-oriented name}.  However, removing
	that conditional leaves this function as a one-liner with two
	call sites differing only by a Boolean literal argument, so drop
	the function altogether, instead open-coding it...
	(break_without_adjustment, break_without_adjustment): ...here.

2025-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test `br` and `brp` requests.

	* src/roff/groff/tests/br-and-brp-requests-work.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2025-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Trivially refactor.
	(break_output_line): Rename argument from `want_adjustment` to
	`want_forced_adjustment` for clarity.
	(break_without_adjustment): Rename this request handler...
	(break_without_forced_adjustment_request): ...to this.
	(break_with_adjustment): Rename this request handler...
	(break_with_forced_adjustment_request): ...to this.
	(init_env_requests): Update wire-uppery.

2025-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Refactor.  More cleanly separate input
	processing logic from engine logic.
	(do_break_request): Rename this...
	(break_output_line): ...to this.  Mark it `static` since it does
	not require external linkage.  Drop its manipulation of the
	input stream via the global `tok` object...
	(break_without_adjustment, break_without_adjustment): ...in
	favor of simply calling `skip_line()` from these handlers for
	the `br` and `brp` requests, which take no arguments.

2025-12-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Add new Boolean-valued parameter to
	`read_input_until_terminator()`, `want_identifier`, defaulting
	to false, so that we can distinguish callers that want a GNU
	troff identifier from those gathering some other kind of input.
	This is so that can we can reject (all) C0 control and Latin-1
	Supplement characters in identifiers.  (C1 controls are already
	rejected on input.)  The prohibition against C0 controls is to
	make the language less tolerant of unreadable input, and the
	latter is to enable us to pivot to reading UTF-8-encoded input
	in a future release.
	(read_input_until_terminator): Update declaration to add new
	parameter with default value.  Update definition to reject, with
	error diagnostic, character codes less than 32 and greater than
	159.  Add assertion that the putative identifier character is
	not a space (character code 32); these have never been valid in
	*roff identifiers.  This function's callers must ensure that the
	terminator precedes any space in the input.

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

2025-12-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_delimited_measurement): Make
	function definition agree with declaration; return object of
	type `units` rather than `int`.  (They're type-aliased with
	`typedef`, but scrupulous type correctness is more conceptually
	coherent and forecloses an avenue of future error.)

2025-12-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_input_until_terminator):
	Slightly refactor.  Introduce `const`-qualified local variable
	to defeat inadvertent lvalue assignment.

2025-12-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_input_until_terminator):
	Trivially refactor.  Split assignment-within-comparison into its
	own statement.  Arrange equality comparisons to (prepare to)
	avoid inadvertent lvalue assignment.

2025-12-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_define_string, define_string)
	(define_nocomp_string, append_string, append_nocomp_macro)
	(do_define_macro, define_macro, define_nocomp_string)
	(define_indirect_macro, define_indirect_nocomp_macro)
	(append_macro, append_nocomp_macro, append_indirect_macro)
	(append_indirect_nocomp_macro): Fix code style nit.  Mark
	functions `static` since they do not require external linkage.

2025-12-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_define_macro): Work on Savannah
	#67735.  Assign `char`-valued literals to temporary `int`
	storing value we got from `read_char_in_copy_mode()` (which
	calls `input_iterator::fill()`, which in turn calls getc(3)),
	since it is destined to become an input character--if we don't
	have to handle EOF.  Since we must, drop C-style type casts to
	`unsigned char` while still scanning input.  Absence of a
	premature EOF established, use `static_cast` operator to demote
	this `int` to `unsigned char` before appending it to a macro.

2025-12-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_define_macro): Improve
	diagnostic.  Communicate error to the user by _describing what
	happened_, rather than just throwing a noun phrase at them.

2025-12-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_define_macro): Slightly refactor.
	Parallelize wording of error diagnostic when encountering EOF
	inside `ig`nored input, pull it into a local `static const`
	character array, and pass that to our diagnostic functions.

2025-12-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(read_char_in_copy_mode, do_define_macro): Parenthesize formally
	complex expressions.

2025-12-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename
	`get_copy()` to `read_char_in_copy_mode()`, because this
	function advances the input stream pointer and because it
	changes the formatter's lexing and parsing rules from the
	default to "copy mode", a fundamental *roff concept since J. F.
	Ossanna transformed roff(1) into the macro language nroff(1)
	with the introduction of macro definitions circa 1972.
	(get_copy): Rename this...
	(read_char_in_copy_mode): ...to this (decl and defn).
	(read_char_in_copy_mode): Rename Boolean-valued argument
	`handle_escape_E` to `handle_escaped_E`, to appease the ruthless
	grammarian in my head.
	(read_char_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)
	(do_terminal)
	(do_write_request)
	(abort_request)
	(read_rest_of_line_as_argument): Update call sites.

2025-12-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp (get_number_rigidly): Delete.  It no
	longer has a caller; that has migrated to `read_measurement(...,
	..., true)`.  Continues commit 6dcbaa0a7a, 19 December.

2025-12-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (glyph_node::add_self): Initialize
	local pointer variable `nn` to `0`.  Before returning,
	`assert(3)` that it is no longer a null pointer.

2025-12-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::is_usable_as_delimiter)
	(token::description): Double the size of the stack-allocated
	buffer we use to populate diagnostic messages about characters
	being unsuitable for use as delimiter, or unsuitable for use at
	all, respectively.  I'm thrilled about neither potentially
	truncating identifiers nor about grabbing a potentially
	unbounded amount of space from the stack, nor about leaking
	memory on the heap--there's no good place to free this memory
	because we return a `char` pointer to our caller.  Risking
	truncation seems the best of a bad set of choices.

2025-12-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Improve
	diagnostic when describing a nonexistent special character or
	class by reporting its identifier, at least up to the point
	where the size of our buffer truncates it.  (How do you get a
	"nonexistent special character or class" that nevertheless has
	an identifier?  It's part of the input syntax.  What you do is
	attempt to interpolate a special character [or class--an invalid
	operation anyway, but stay with me] in a context where character
	interpolation makes no sense, as in a numeric expression.)

2025-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/preconv/preconv.cpp (do_file): Say "non-portable"
	instead of "unportable" in diagnostic message.  Prompted by a
	similar change to the tzdata project by Paul Eggert.

2025-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/groff.texi.in (Delimiters):
	* man/groff.7.man (Delimiters): Clarify that an invalid escape
	sequence is valid as a delimiter if the character after the
	escape character would be valid as one.

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

2025-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/groff.texi.in (Delimiters):
	* man/groff.7.man (Delimiters): Clarify what makes an escape
	sequence ineligible for use as a delimiter--not its
	parameterization, but its own use of delimiters.  Relatedly,
	document the clever hack (dirty trick?) GNU eqn and tbl use to
	surround arbitrary user input with delimiters that are nigh upon
	guaranteed not to collide with that input.

	Fixes <https://savannah.gnu.org/bugs/?67372>.  I hope.

2025-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Split `TOKEN_SPECIAL_CHAR` token type into two, leaving
	the existing one for `\(` and `\[` escape sequences, and
	creating a new `TOKEN_DELIMITED_SPECIAL_CHAR` for the delimited
	`\C` escape sequence.

	* src/roff/troff/token.h (class token): Add new
	`TOKEN_DELIMITED_SPECIAL_CHAR` enumeration constant.
	(token::is_special_character, token::is_any_character): Return
	`true` for both new and old token types.
	* src/roff/troff/input.cpp (token::next) <C>: Tokenize `C`
	escape sequence as `TOKEN_DELIMITED_SPECIAL_CHAR`.
	(token::is_usable_as_delimiter): Reject
	`TOKEN_DELIMITED_SPECIAL_CHAR` as a delimiter.
	(token::operator==, token::description, process_input_stack)
	(token::get_charinfo, token::add_to_zero_width_node_list)
	(token::process): Treat new token type the same as the old one.

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

2025-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/check-delimiter-validity.sh: Add
	regression test for Savannah #67842.

2025-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Drop
	`assert()`-ion that is reachable with invalid input.

2025-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/div.cpp (page_offset, page_length): Rename
	these...
	(configure_page_offset_request, configure_page_length_request):
	...to these.
	(init_div_requests): Update wire-uppery.

2025-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor.  Move page offset access from language
	parser logic into "engine" logic.

	* src/roff/troff/div.h: Drop unnecessary declaration of
	`page_offset()` returning `void`.  This concealed a latent
	symbol visibility problem.
	(class top_level_diversion): Declare new member function
	`get_previous_page_offset()`, giving it a simple inline
	definition akin to the existing `get_page_offset()`.
	* src/roff/troff/div.cpp (page_offset): Make request handler
	use accessor member functions instead of retrieving the
	diversion's properties directly.

2025-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor.  Move page offset updates from language
	parser logic into "engine" logic.

	* src/roff/troff/div.h (class top_level_diversion): Declare new
	member function `set_page_offset()`.
	(top_level_diversion::set_page_offset): Define it, and make it
	responsible for updating both `page_offset` and
	`prev_page_offset` private member variables.
	* src/roff/troff/div.cpp (page_offset): Make request handler
	call this new mutator member function instead of manipulating
	the diversion's properties directly.

2025-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grohtml,grotty]: Fix Savannah #67843.

	* tmac/html-end.tmac:
	* tmac/tty.tmac: Set the page offset to zero _twice_, to better
	simulate AT&T nroff behavior.  (Do it for the "html" device too;
	it better resembles an nroff-mode device than a troff-mode one.)

2025-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Regression-test Savannah #67843.

	* src/roff/groff/tests/po-request-works: New file.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2025-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor.  Split `TOKEN_HORIZONTAL_MOTION` token type
	into two, leaving the existing one for `\0`, `\^`, and `\|`
	escape sequences, and creating a new
	`TOKEN_DELIMITED_HORIZONTAL_MOTION` for the parameterized `\h`
	escape sequence.

	* src/roff/troff/token.h (class token): Add new
	`TOKEN_DELIMITED_HORIZONTAL_MOTION` enumeration constant.
	(token::is_horizontal_motion): Return `true` for both new and
	old token types.
	* src/roff/troff/input.cpp (token::next) <h>: Tokenize `h`
	escape sequence as `TOKEN_DELIMITED_HORIZONTAL_MOTION`.
	(token::is_usable_as_delimiter): Reject
	`TOKEN_DELIMITED_HORIZONTAL_MOTION` instead of
	`TOKEN_HORIZONTAL_MOTION` as a delimiter.
	(token::next <z>, process_input_stack)
	(token::add_to_zero_width_node_list, token::process): Treat new
	token type the same as the old one.
	(token::description): Describe new token type distinctly.

	* src/roff/groff/tests/check-delimiter-validity.sh: Delete check
	for invalidity of `\0`, `\^`, and `\|` as delimiters--they're
	valid again now.

	* doc/groff.texi.in (Delimiters):
	* man/groff.7.man (Delimiters): Re-document `\0`, `\^`, and `\|`
	as valid delimiters.

2025-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/token.h (class token): Trivially refactor.
	Sort enumeration constants lexicographically by their symbol
	names.  It seems that they once were thus sorted (except for
	`TOKEN_EOF`), but my renaming activities have effaced that.
	Restore that ordering, but stop treating `TOKEN_EOF` specially.
	Its magnitude is never compared to anything (and shouldn't be).

2025-12-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/pdf-device-smoke-test.sh: New file.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2025-12-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/lj4-device-smoke-test.sh: New file.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2025-12-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/lbp-device-smoke-test.sh: New file.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2025-12-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/safer-mode-works.sh: Fix newly added test
	to actually test what it means to test.  Continues commit
	49cbc926cf, 15 December.

2025-12-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/check-delimiter-validity.sh: Check
	unparameterized and invalid escape sequences for usability as
	escape sequence delimiters.  See Savannah #67375.

2025-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_title_parts): Throw deprecation
	warning in category "delim" if the delimiter is invalid and
	we're not in compatibility mode.  This is a training wheel to
	get people off of ambiguous delimiters.  See Savannah #66009.

2025-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/check-delimiter-validity.sh: Improve
	tests.  Clarify progress messages to distinguish escape
	sequence, title request, and output comparison contexts.  Test
	two characters ('@', '_') that weren't tested before because I
	ran out of steam.  Test delimiters used with title requests and
	output comparisons even when not in compatibility mode.  Also
	cosmetically sort big lists to vertically align punctuation
	characters that aren't significant in numeric expressions,
	pairing them up by low-order bits of their ISO 646 code points.

2025-12-07  Alejandro Colomar <alx@kernel.org>

	* src/libs/libgroff/uniglyph.cpp:
	* src/preproc/eqn/delim.cpp:
	* src/preproc/eqn/text.cpp:
	* src/preproc/pic/lex.cpp:
	* src/preproc/refer/command.cpp:
	* src/preproc/refer/ref.cpp:
	* src/utils/hpftodit/hpuni.cpp:
	* src/utils/tfmtodit/tfmtodit.cpp: Include "stdcountof.h" header
	file.

	* src/preproc/eqn/delim.cpp: Initialize global constant
	`DELIM_TABLE_SIZE` using `countof()` instead of `sizeof` and
	division.

	* src/libs/libgroff/uniglyph.cpp
	(unicode_to_glyph_init::unicode_decompose_init):
	* src/preproc/eqn/text.cpp (special_to_entity):
	* src/preproc/pic/lex.cpp (lookup_keyword):
	* src/preproc/refer/command.cpp (execute_command):
	* src/preproc/refer/ref.cpp (find_month):
	* src/utils/hpftodit/hpuni.cpp
	(hp_msl_to_unicode_init::hp_msl_to_unicode_init):
	* src/utils/tfmtodit/tfmtodit.cpp (main): Use `countof()`
	instead of `sizeof` and division.

	countof() is [expected to be --GBR] standard (ISO C2y).

	Continues the long process of fixing Savannah #66518.

2025-12-07  Alejandro Colomar <alx@kernel.org>

	* src/utils/hpftodit/hpftodit.cpp: Include "stdcountof.h" header
	file.  Drop `SIZEOF()` function-like preprocessor macro.
	(output_ligatures): Use `countof()` instead of `SIZEOF()`.

	countof() is [expected to be --GBR] standard (ISO C2y).

	Continues the long process of fixing Savannah #66518.

2025-12-07  Alejandro Colomar <alx@kernel.org>

	* src/devices/grolbp/lbp.cpp:
	* src/devices/grolj4/lj4.cpp:
	* src/devices/grops/ps.cpp:
	* src/devices/grops/psrm.cpp:
	* src/libs/libgroff/font.cpp:
	* src/libs/libgroff/glyphuni.cpp:
	* src/libs/libgroff/make-uniuni:
	* src/libs/libgroff/uniuni.cpp:
	* src/preproc/eqn/box.cpp:
	* src/preproc/eqn/lex.cpp:
	* src/preproc/pic/pic.ypp:
	* src/preproc/preconv/preconv.cpp:
	* src/roff/troff/input.cpp:
	* src/utils/addftinfo/addftinfo.cpp: Include "stdcountof.h"
	header file.

	* src/devices/grolbp/lbp.cpp (set_papersize):
	* src/devices/grolj4/lj4.cpp
	(lj4_font::handle_unknown_font_command, lookup_paper_size):
	* src/devices/grops/ps.cpp (ps_printer::special):
	* src/devices/grops/psrm.cpp (resource_manager::process_file):
	* src/libs/libgroff/font.cpp (font::load_desc):
	* src/libs/libgroff/glyphuni.cpp
	(glyph_to_unicode_init::glyph_to_unicode_init):
	* src/libs/libgroff/make-uniuni
	(unicode_decompose_init::unicode_decompose_init):
	* src/libs/libgroff/uniuni.cpp
	(unicode_decompose_init::unicode_decompose_init):
	* src/preproc/eqn/box.cpp (set_param, reset_param, get_param)
	(init_param_table, free_param_table):
	* src/preproc/eqn/lex.cpp (init_table):
	* src/preproc/pic/pic.ypp (define_variable, reset, reset_all):
	* src/preproc/preconv/preconv.cpp (get_BOM):
	* src/roff/troff/input.cpp (lookup_warning):
	* src/utils/addftinfo/addftinfo.cpp (main, usage): Use countof()
	instead of [groff's template function --GBR] array_length().

	* src/devices/grops/psrm.cpp: Initialize constant globals with
	`countof()` instead of `array_length()`.

	countof() is [expected to be --GBR] standard (ISO C2y).

	Continues the long process of fixing Savannah #66518.

2025-12-07  Alejandro Colomar <alx@kernel.org>

	* bootstrap.conf (gnulib_modules): Add stdcountof-h.

	Continues the long process of fixing Savannah #66518.

2025-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `get_long_name()` to
	`read_long_identifier()`, because it's used for more than just
	reading "names" (request, macro, string, or diversion
	identifiers), but also identifiers of environments, colors,
	registers, typefaces (fonts, famililies, and styles), and file
	names.  (The last occurs only in `ps_bbox_request()` and might
	be inapposite; GNU troff now handles file names with spaces in
	them, and that might not work because the `psbb` request is not
	parsing its arguments appropriately.)
	* src/roff/troff/token.h: Rename in declaration.
	* src/roff/troff/input.cpp (get_long_name): Rename this...
	(read_long_identifier): ...to this.
	* src/roff/troff/column.cpp (column_justify) [COLUMN]:
	* src/roff/troff/env.cpp (environment_copy, environment_switch):
	* src/roff/troff/input.cpp (define_color, read_identifier)
	(do_register, is_conditional_expression_true, ps_bbox_request)
	(vjustify) [COLUMN]:
	* src/roff/troff/node.cpp (mount_font_at_position): Update call
	sites.

2025-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/token.h: Relocate declaration of "input.cpp"
	function `has_arg()` to sit alongside others for the same file,
	and mark it `extern`.  Arrange nearby declarations to match the
	order of their definition in "input.cpp", in case any deep
	meaning is thereby revealed (perhaps not).

2025-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor for conceptual clarity.  In *roff,
	spaces and horizontal motions are distinct kinds of thing.
	Spaces are potentially breakable, discardable (at the distal
	ends of text lines), and adjustable.  Horizontal motions are
	none of these.

	* src/roff/troff/token.h (class token): Rename enumeration
	constant from `TOKEN_HORIZONTAL_SPACE` to
	`TOKEN_HORIZONTAL_MOTION`.  Rename member function declaration
	from `is_horizontal_space()` to `is_horizontal_motion()`.
	(token::is_horizontal_space): Rename this...
	(token::is_horizontal_motion): ...to this.
	* src/roff/troff/input.cpp (do_overstrike): Update lone call
	site of `is_horizontal_space()`.
	* src/roff/troff/token.h (token::is_horizontal_motion):
	* src/roff/troff/input.cpp (token::next): Update sites of
	comparisons to `TOKEN_HORIZONTAL_SPACE`.

2025-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/token.h (class token): Rename member function
	{declared} from `is_white_space()` to
	`is_horizontal_whitespace()`.  Whitespace isn't "white" in the
	chromatic sense (cf. "red" or "black") but in an abstract one;
	further, this member function does not test for form feeds or
	any other conceivable "vertical whitespace".
	(token::is_white_space): Rename {definition} from this...
	(token::is_horizontal_whitespace): ...to this.
	* src/roff/troff/input.cpp (process_input_stack): Update lone
	call site.  (So why have `is_horizontal_whitespace()` in the
	`token` class at all?)

2025-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h: Drop duplicate incomplete type
	declaration.
	* src/roff/troff/token.h: Drop unneeded incomplete type
	declaration.

2025-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/token.h (token::ch): Compare member variable
	`c` to literal of `unsigned char` type, not a character literal
	of undefined signedness.

	Continues the long process of fixing Savannah #67735.

2025-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::next, token::get_charinfo)
	(is_conditional_expression_true):
	* src/roff/troff/token.h (token::is_newline, token::is_space)
	(token::is_stretchable_space, token::is_unstretchable_space)
	(token::is_horizontal_space, token::is_special_character)
	(token::nspaces, token::is_white_space, token::is_transparent)
	(token::is_page_ejector, token::ch, token::is_any_character)
	(token::is_indexed_character, token::is_node, token::is_eof)
	(token::is_dummy, token::is_transparent_dummy)
	(token::is_left_brace, token::is_right_brace, token::is_tab)
	(token::is_leader, token::is_backspace)
	(token::is_hyphen_indicator, token::is_zero_width_break): Fix
	code style nits.  Parenthesize formally complex expressions.
	Arrange equality comparisons to avoid inadvertent lvalue
	assignment.

2025-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor to use the force--C++ default argument force.
	Merge function `get_number_rigidly()` into `read_measurement(),
	which differed by one line out of a dozen, by extending the
	latter's signature with a default argument `is_mandatory` of
	type `bool`.  This coincidentally made GCC's overload resolver
	more sensitive to arguments of ambiguous integral type, so take
	this opportunity to stop punning between character literals and
	`unsigned char`, in favor of the explicitness we'll need anyway
	for GNU troff's planned wider fundamental character type.

	* src/roff/troff/token.h: Drop declaration of
	`get_number_rigidly()`.  Update declaration of
	`read_measurement()` with `bool`-valued 3rd argument defaulting
	`false`.
	* src/roff/troff/input.cpp (read_color_channel_value)
	(do_expr_test, read_size, do_register)
	(is_conditional_expression_true, evaluate_expression):
	* src/roff/troff/reg.cpp (define_register_request):
	Explicitly construct literal of `unsigned char` type as argument
	to `read_measurement()`.
	* src/roff/troff/input.cpp (do_expr_test): Migrate only call
	site of `get_number_rigidly()` to `read_measurement()` with an
	explicit `true` 3rd argument.
	* src/roff/troff/number.cpp (get_number_rigidly): Delete.
	(read_measurement): Accept third argument, `is_mandatory`, of
	type `bool`.  Pass it to `is_valid_expression()`, which is
	already prepared for same.

	Continues the long process of fixing Savannah #67735.

2025-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp: Fix code style nits.  Replace
	preprocessor macro `SCALING_UNITS` with `static const char`
	array `valid_scaling_units`.
	(is_valid_term): Use the array instead of the string literal
	macro as the haystack in strchr(3) call; explicitly construct a
	`char`-typed needle from an `int`-typed argument.
	(is_valid_term, scale): Parenthesize formally complex
	expressions.
	(scale): Split one `&&`-using assert(3)ion into two.  Construct
	temporary `unsigned int` objects using the syntax C++ seems to
	support for this.  Return object of type `units` rather than
	`int`.  (They're type-aliased with `typedef`, but scrupulous
	type correctness is more conceptually coherent and forecloses an
	avenue of future error.)
	(is_valid_expression, is_valid_term): Prepare (I think) all
	comparisons of C++ character literals to the input read by our
	numeric expression parser for groff's planned wider fundamental
	character type.  Construct `int`s from character literals, and
	annotate their need to be constructed as that future type.

	Continues the long process of fixing Savannah #67735.

2025-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/hvunits.h (get_vunits, get_hunits): Rename (in
	declarations) these...
	(read_vunits, read_hunits): ...to these, because they advance
	the input stream pointer.
	* src/roff/troff/number.cpp (get_vunits, get_hunits): Rename (in
	definitions) these...
	(read_vunits, read_hunits): ...to these.  Update literals in
	assertions.
	* src/roff/troff/column.cpp (column_justify) [COLUMN]:
	* src/roff/troff/div.cpp (page_offset, when_request)
	(space_request, need_space, save_vertical_space, diversion_trap)
	(change_trap, return_request):
	* src/roff/troff/env.cpp (line_length, title_length)
	(vertical_spacing, post_vertical_spacing, indent)
	(temporary_indent, margin_character, hyphenation_space_request)
	(hyphenation_margin_request, configure_tab_stops_request):
	Update call sites.

2025-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp: Drop unnecessary header file
	inclusion.

2025-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Further conceal broken nested class feature.

	* src/roff/troff/charinfo.h (class charinfo): Annotate
	nonfunctional member variable.
	* src/roff/troff/input.cpp (define_class_request)
	(charinfo::get_number, charinfo::contains): Drop word "cyclic"
	from warning diagnostics in category "syntax"; we don't
	implemented nested classes _at all_; lack of support is not
	limited to cyclic ones.
	(charinfo::contains): `#if 0`-disable code that searches
	`nested_classes` member variable for matching `charinfo`
	objects.

	Fixes <https://savannah.gnu.org/bugs/?67770>.  Continues commit
	d330127900, 6 December.

2025-12-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* font/devpdf/devpdf.am: Fix "BuildFoundries" failure if the URW
	fonts can't be found in its built-in search path.  If the macro
	`HAVE_URW_FONTS` is defined, define new macro
	`buildfoundries_extra_arg` so as to construct a `--dirURW=`
	argument; otherwise, make `buildfoundries_extra_arg` empty.
	(font/devpdf/download): Interpolate `buildfoundries_extra_arg`
	macro when running "BuildFoundries" command.

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

2025-12-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Size the buffer
	housing the node description more scrupulously, avoiding
	potential string truncation.

	Fixes problem introduced by me in commit 1fb72c15e6, 3 December.

2025-12-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/xtotroff/xtotroff.c (main): Fix thinko in fprintf(3)
	call; that's not one of groff's diagnostic functions, so we must
	use `%s` in its format string, not `%1`.

	Fixes problem introduced by me in commit 4b7a0fe5ab, 6 December.

2025-12-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	Recognize materials licensed under LGPLv3.

	* LGPLv3: New file, retrieved from gnu.org on this date.
	* LICENSES: Discuss materials distributed under LGPLv3.  State
	where to find texts of FDL and LGPLv3 licenses.  (It's not a big
	mystery.)
	* MANIFEST: Document presence of "LGPLv3" file.
	* Makefile.am (EXTRA_DIST): Ship "LGPLv3" file.
	* src/include/relocate.h:
	* src/libs/libgroff/relocate.cpp: Cosmetically reindent and
	reflow copyright and license notices.  Reflect renaming of LGPL
	from "Library" to "Lesser" General Public License.

2025-12-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	Retire our hypot(3) replacement in favor of gnulib's.  Werner
	Lemberg borrowed ours from glibc in 2005 to work around a
	problem with its Interix implementation.  Interix has been dead
	a long time.  We still want a replacement, though, as gnulib
	documents hypot(3) as broken on mingw and MSVC 2014.  We
	certainly wish to keep working on the former.

	* bootstrap.conf: Add "hypot" to "gnulib_modules".
	* src/include/lib.h: Drop declaration of `groff_hypot()`.
	* src/libs/libgroff/hypot.cpp: Delete.
	* src/libs/libgroff/libgroff.am (libgroff_a_SOURCES): Drop
	foregoing file.
	* src/preproc/grn/hgraph.cpp (len, HGArc, picurve)
	(Parameterize):
	* src/preproc/pic/object.cpp (hypot): Migrate `groff_hypot()`
	calls to `hypot()`.

	Continues the long process of fixing Savannah #66518.

2025-12-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/ps.tmac: Delete internal macros after we're done using
	them.  They are not documented and therefore not supported for
	use by documents.  They consequently should not litter the macro
	name space after formatter startup.

2025-12-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/safer-mode-works.sh: Unit-test "locking"
	of safer mode after `-S` option is specified.

2025-12-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp (main): Initialize `want_unsafe_mode`
	to `false`, not `true`.  When flipping the semantics of this
	variable name in commit 3a1b01474d (to make it easier to
	implement "locking" `-S` option behavior), I neglected to flip
	its default value.

	Fixes <https://savannah.gnu.org/bugs/?67815>.  Thanks to Dave
	Kemper for the report and root-cause analysis.  Problem
	introduced by me in commit 3a1b01474d, 7 October.

2025-12-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #67815.

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

2025-12-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (interpolate_rg): Rename this...
	(interpolate_positional_parameter): ...to this.
	(get_copy, token::next): Update call sites.

2025-12-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (get_color_element): Rename this...
	(read_color_channel_value): ...to this.
	(read_rgb, read_cmy, read_cmyk, read_gray): Update call sites.

2025-12-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (get_char_for_escape_parameter):
	Rename this...
	(read_char_in_escape_sequence_parameter): ...to this.
	(read_long_escape_parameters, read_escape_parameter)
	(read_increment_and_escape_parameter): Update call sites.

2025-12-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (get_line_arg): Rename this...
	(read_line_rule_expression): ...to this.  Update forward
	declaration.
	(token:next): Update call site.

2025-12-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::is_usable_as_delimiter):
	Explicitly clear stack-allocated buffer before otherwise writing
	to it, for paranoia's sake.

2025-12-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Fix code style nits.
	(get_color_element): Favor value constructor over C-style type
	cast.
	(read_rgb, read_cmy, read_cmyk, read_gray)
	(interpolate_string_with_args): Arrange equality comparisons to
	avoid inadvertent lvalue assignment.
	(token::next, interpolate_string, interpolate_string_with_args)
	(chop_macro, do_string_case_transform, substring_request)
	(unformat_macro, write_macro_request): Explicitly compare value
	of pointer type to null pointer literal instead of letting it
	pun down to a Boolean.

2025-12-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Fix code style nits.
	(file_iterator::fill, file_iterator::peek): Stop pointlessly
	constructing a new `int` from an existing one.
	(file_iterator::fill): Arrange equality comparisons to avoid
	inadvertent lvalue assignment.

2025-12-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (assign_control_character): Rename
	this...
	(assign_control_character_request): ...to this.
	(assign_no_break_control_character): Rename this...
	(assign_no_break_control_character_request): ...to this.
	(init_input_requests): Update wire-uppery of request names to
	their handlers.

2025-12-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Add new `const` globals
	`default_control_char` and `default_no_break_control_char`.
	(assign_control_character): Use `default_control_char` instead of
	a `.` character literal.
	(assign_no_break_control_character): Use
	`default_no_break_control_char` instead of a `'` character
	literal.

2025-12-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (assign_escape_character): Rename
	this...
	(assign_escape_character_request): ...to this.
	(escape_off): Rename this...
	(escape_off_request): ...to this.
	(save_escape_char): Rename this...
	(save_escape_char_request): ...to this.
	(restore_escape_char): Rename this...
	(restore_escape_char_request): ...to this.
	(init_input_requests): Update wire-uppery of request names to
	their handlers.

2025-12-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Add new `const` global
	`default_escape_char`.  Initialize `escape_char` using it.
	(assign_escape_character): Use `default_escape_char` instead of
	a `\\` character literal.

2025-12-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (process_input_stack): Emit warning
	in category "syntax", and otherwise ignore, horizontal space
	tokens (including `\h`, `\0`, `\|`, and `\^) after `\c` on an
	input line.

2025-12-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::next): Reject `\s` escape
	sequence after `\c` on an input line.  Throw warning in category
	"syntax" and don't interpret it at all.

2025-12-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::set_font): Move warning
	thrown (and recast it, and change its category from "font" to
	"syntax") when font selection attempted on the ignored part of
	an input line interrupted/continued with `\c` from here...
	* src/roff/troff/input.cpp (token::next): ...to here.

	* doc/groff.texi.in (Warnings):
	* man/groff_diff.7.man (Warnings): Simplify description of
	warning category "font" accordingly.

2025-12-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp
	(override_available_type_sizes_request): Fix code style nits.
	Arrange equality comparisons to avoid inadvertent lvalue
	assignment.  Parenthesize formally complex expressions.

2025-12-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::possibly_break_line): Fix
	code style nits.  Parenthesize formally complex expressions.
	Arrange equality comparisons to avoid inadvertent lvalue
	assignment.

2025-12-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp
	(non_interpreted_char_node::non_interpreted_char_node): Fix code
	style nit.  Migrate input character handling constructor to deal
	in the type `unsigned char` rather than `char`.  Use explicitly
	unsigned literal in comparison.

	Continues the long process of fixing Savannah #67735.

2025-12-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (process_input_stack): Fix code style
	nit.  Eliminate unnecessary brace scopes that introduce no new
	local variables in switch `case`s.

2025-12-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::set_size): Fix code style
	nit.  Arrange equality comparison to avoid inadvertent lvalue
	assignment.

2025-12-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* README.git: Delete file not distributed in archives.
	* bootstrap.conf (checkout_only_file): Identify "FOR-RELEASE"
	instead of "README.git" as the indicator of a Git checkout.

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

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

	* src/utils/grog/grog.pl: Improve heuristics for distinguishing
	mm(7) documents from those for other packages.
	(interpret_line): Recognize `APP`, `APPSK`, `AF`, `AS`,
	`COVEND`, `INITI`, `IND`, `INDP`, `INITR`, `SETR`, `GETHN`,
	`GETPN`, `ISODATE`, `MULB`, `MULN`, and `MULE` as unique to mm.
	(infer_man_or_ms_package): Stop recognizing `RP`, `TL`, `AU`,
	`ND`, `AE`, `B1`, `B2`, `DS`, `DE`, `1C`, `2C`, and `MC` as
	unique to ms, since mm also defines them.  Stop recognizing `P`
	and `EX` as unique to man, since mm also defines them.
	* src/utils/grog/tests/smoke-test.sh: Add most mm examples as
	test cases.  A couple are deeply ambiguous, like "B1B2", which
	is so limited that it is valid (and renders sensibly) with
	either the mm(7) _or_ ms(7) packages, and "story.mm" which uses
	only macro names that are shared variously among man(7), mm(7),
	mom(7), and ms(7).

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

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

	* src/utils/xtotroff/xtotroff.c (MapFont): Make fatal error
	diagnostic on memory allocation failure disclose how many bytes
	we attempted to grab from the heap.  This way the user can
	better distinguish system starvation scenarios from attempted
	denial-of-service attacks (or worse).  (Admittedly, few people
	ever run xtotroff at all, let alone in scenarios where a busy
	system is so pinned that `malloc(PATH_MAX)` is likely to fail.
	But I feel that since we have this information, we should
	disclose it.)

2025-12-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/groff.texi.in (Other Differences):
	* man/groff_diff.7.man (Other differences): Document difference
	in timing of output flushes between AT&T and GNU troffs.

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

2025-12-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_input_until_terminator): Fix
	apparent memory leak.  The heap-allocated memory we allocate to
	back the local `buf` was not being freed on an error path out of
	the function.

2025-12-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename
	`do_get_long_name()` to `read_input_until_terminator()` because
	{A} that's more descriptive of its function, and {B} it's used
	for more than just reading "long names" (GNU troff-style
	identifiers); in fact 4 out of its 5 call sites read things that
	aren't identifiers.
	(do_get_long_name): Rename declaration and definition from
	this...
	(read_input_until_terminator): ...to this.
	(read_rgb, read_cmy, read_cmyk, read_gray, do_get_long_name):
	Update call sites.

2025-12-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Migrate more input character reading
	functions to deal in the type `unsigned char` rather than
	`char`.
	(do_get_long_name): Update declaration.
	(read_rgb, read_cmy, read_cmyk, read_gray, do_get_long_name):
	Update definitions.
	(get_long_name): Update `do_get_long_name()` call site to use
	literal of `unsigned char` rathern than `char` type.
	(do_get_long_name): Change type of local variable `buf` from
	`char` to `unsigned char`, since it is directly populated by
	reads of bytes from the input stream.  This function converts
	said input into an object of the groff class `symbol` and
	returns it, but `symbol` has no constructor accepting a pointer
	to `const unsigned char`.  Consequently, once we have
	successfuly populated `buf`, create a new buffer `chbuf`, a
	heap-allocated array of `char` type.  Free this array after
	constructing a `symbol` on the stack.  (If all this seems like
	rigmarole, consider that it's going to be necessary anyway when
	we read bytes from the input stream, confirm that they're valid
	UTF-8 sequences, apply Normalization Form D decomposition, and
	then store them as one or more 32-bit code points in GNU troff's
	planned future internal character data type.  See Savannah
	#40720.)
	(read_drawing_command_color_arguments): Change type of `end`
	local variable from `int` to `unsigned char`, since that is what
	the `read_{rgb,cmy,cmyk,gray}()` functions now expect as
	arguments.

	Continues the long process of fixing Savannah #67735.

2025-12-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_identifier): Fix code style
	nit.  Populate array of type `char` with char-valued, not
	integer-valued, literal.

2025-12-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_rgb, read_cmy, read_cmyk)
	(read_gray): Fix code style nit.  Call `do_get_long_name()`,
	which takes a `bool` as its first parameter, using Boolean, not
	integer, literals.

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

	* src/roff/troff/input.cpp (read_delimited_identifier): Update
	diagnostic wording to reflect function's generality, making its
	issue in the case of, say, `\C\h'1m'foobar\h'1m'` more truthful.

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

	* src/roff/troff/input.cpp: Trivially refactor.  Rename
	`read_delimited_name()` to `read_delimited_identifier()`.  This
	function isn't actually used for "names" (identifiers of macros,
	strings, and diversions), but, at present, only for special
	character or class identifiers.  But its operation is
	sufficiently general to handle any GNU troff identifier.
	(read_delimited_name): Rename declaration and definition from
	this...
	(read_delimited_identifier): ...to this.
	(token::next): Update call site.

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

	* tmac/ja.tmac:
	* tmac/zh.tmac: Correct apparently mistaken character flags for
	`[CJKpostpunct]` class from "266" to "256".  A typo introduced
	two spurious flags (2 and 8).

	Fixes <https://savannah.gnu.org/bugs/?67757>.  Problem appears
	to date back to commit 1cb8dd7bde, 13 December 2010.  Thanks to
	Colin Watson for suggesting a regression test procedure.

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

	* src/roff/troff/input.cpp (charinfo::dump): Use preprocessor to
	disable reporting of nested class information.  The feature
	doesn't work.

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

	* src/roff/troff/input.cpp (charinfo::dump): Use more
	user-intelligible language when dumping character classes; refer
	to "code points" instead of "ranges", since the notation is
	conventional (e.g., "U+002C U+003A" or "U+4E00-U+9FFF").

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

	* src/roff/troff/reg.cpp (dump_register): Fix assertion failure.
	Some string-valued registers, like `.z` and the new `.itm`, can
	be empty.

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

	* src/roff/troff/input.cpp (print_stream_request): Tweak JSON
	output, following model in "node.cpp"'s
	`dump_node_list_in_reverse()` (but using `errprint()` instead of
	fputc(3)).  Fixes extra spaces in list notation.

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

	* src/utils/xtotroff/xtotroff.c (MapFont, main): Tweak wording
	of error diagnostics; favor "cannot" over "unable to" or
	"can't".  Also quote name of environment variable.

	Continues fixing Savannah #66519.

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

	* src/utils/xtotroff/xtotroff.c: Fix code style nit.
	(CanonicalizeFontName, FontNamesAmbiguous, MapFont, main):
	Explicitly cast unused return values of printf(3)-family
	functions to `void`.

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

	* src/utils/pfbtops/pfbtops.c: Refactor.
	(error): Drop exit(3) call so that we can use this function for
	nonfatal errors or fatal ones that need to exit with a status
	other than `EXIT_FAILURE` (as with usage errors).
	(die): New function wraps `error()` and exit(3)s.
	(get_text, get_binary, main): Migrate callers from `error()` to
	`die()`.
	(error, usage): Explicitly cast unused return value of
	fprintf(3) to `void`.
	(main): Employ new strategies for construction of error
	diagnostics reporting unrecognized options.

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

	Handle unrecognized long option arguments better.

	* 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):
	* src/preproc/eqn/main.cpp (main):
	* src/preproc/grn/main.cpp (main):
	* src/preproc/html/pre-html.cpp (main):
	* src/preproc/pic/main.cpp (main):
	* src/preproc/preconv/main.cpp (main):
	* src/preproc/soelim/main.cpp (main):
	* src/preproc/tbl/main.cpp (main):
	* src/roff/groff/groff.cpp (main):
	* src/roff/troff/input.cpp (main):
	* src/utils/hpftodit/hpftodit.cpp (main):
	* src/utils/indxbib/indxbib.cpp (main):
	* src/utils/lkbib/lkbib.cpp (main):
	* src/utils/lookbib/lookbib.cpp (main):
	* src/utils/pfbtops/pfbtops.c (main):
	* src/utils/tfmtodit/tfmtodit.cpp (main):
	* src/utils/xtotroff/xtotroff.c (main): When given an
	unrecognized long option, report what it was.

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

	* src/roff/troff/input.cpp (token::description): Improve
	descriptiveness of C string returned when preprocessor symbol
	`NDEBUG` is defined and we're called upon to describe a
	nonexistent special character or class.

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

	* src/roff/troff/input.cpp (print_character_request): Don't try
	to describe a special character (or class) that doesn't exist;
	say nothing, just as we do with `.pnr nonexistent` and `.pm
	nonexistent`.

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

	* src/roff/troff/input.cpp (token::description): Don't create a
	special character in the course of trying to describe it.

	Fixes blunder I introduced in commit fcf3505a09, 19 November.

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

	* src/roff/troff/input.cpp (define_class_request): Add assertion
	and, if preprocessor `NDEBUG` symbol is defined, guard against
	null pointer derefrence.

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

	* src/roff/troff/input.cpp (define_class_request): Add assertion
	to check (what I believe to be) an invariant.

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

	* src/roff/troff/input.cpp (define_class_request): Stop warning
	on trailing space after arguments to `class` request.  Populate
	local variable `child1` (which helps us keep track of range
	expressions) only if the current token is a kind of character.

	Fixes <https://savannah.gnu.org/bugs/?67771>.  Problem appears
	to date back to commit 1cb8dd7bde, 13 December 2010.

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

	[groff]: Regression-test Savannah #67771.

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

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

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

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

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

	* src/roff/troff/input.cpp (print_character_request): Fix
	blunder in lexical analysis.  We were skipping over spaces
	_prior_ to arguments, but not _after_ them, just before we hit
	the end of the line, and issuing a spurious error diagnostic.
	Fix it by moving the condition that terminates the input reading
	loop, making it formally infinite (but with a conditional
	`break` in the middle--we'll read a newline or EOF eventually).

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

	[groff]: Add unit test for new `pchar` request.

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

2025-12-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Describe character (classes) better.  Character classes
	have one more property beyond their name, and lists of ranges
	and nested classes: a set of character flags that the formatter
	bitwise "or"s with any character members of the class
	{recursively}.  However, the computation of flags applicable to
	a character has been done lazily almost from the time the
	character class feature was first implemented, presumably to
	keep a `cflags` request on a highly populated character class
	from taking a lot of time.  Improve the output of `pchar`
	accordingly.  When reporting properties of a character class,
	report the flags associated with it.  When reporting properties
	of a character, if it is a member of any class, compute its
	"effective" character flags and report them in distinction to
	its "inherent" character flags if they differ.  Then, revert the
	lazy computation of the effective character flags so that the
	`pchar` request has no visible effect on formatter state; we
	want this property for debugging documents, avoiding Heisenbugs.

	* roff/troff/charinfo.h (class charinfo): Declare new
	`describe_flags()` member function returning `void`.
	* src/roff/troff/input.cpp (charinfo::describe_flags): Refactor
	the tedious flags-to-English logic from `charinfo::dump_flags()`
	into this new member function, since we might need to perform
	this translation more than once when dumping a character's
	properties.
	(charinfo::describe_flags): Strip out flags-to-English
	translation as above.  For a character per se (not a class),
	report assigned character flags thereto as "inherent".  Then
	save them, do the lazy computation that normally occurs when
	formatting a character, report the combination as the "effective
	flags" if they differ, and restore the saved flags.
	(charinfo::dump): Call `dump_flags()` on character classes.

	Fixes <https://savannah.gnu.org/bugs/?67711>.  Thanks to Dave
	Kemper for prompting me to better understand this aspect of GNU
	troff's design.

2025-12-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor.  Bust character flag dumping (a report to the
	standard error stream) into its own member function of the
	`charinfo` class because (A) it's about 50 lines of code and (B)
	we're about to need another call site, and there's no way
	repeating 50 lines of code is a good idea.

	* src/roff/troff/charinfo.h (class charinfo): Declare new
	`dump_flags()` member function returning `void`.
	* src/roff/troff/input.cpp (charinfo::dump_flags): Implement it,
	moving code to here...
	(charinfo::dump): ...from here, instead calling the new
	function.

2025-12-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Describe a
	`TOKEN_NODE` explicitly as a "token", because it still is one.

2025-12-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Return the node
	token description using the correct buffer.

2025-12-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Hedge against
	programmer carelessness.  If someone creates a node type without
	a human-readable descripion, pre-populate the buffer describing
	it with a revealing description that is less frustrating than
	nothing at all.

2025-12-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/xditview/xditview.am
	(src/devices/xditview/GXditview-ad.h): Add `$(MKDIR_P)` to
	target rule to ensure the parent directory exists.  This problem
	is hard to observe because it shows up only when our `configure`
	script is run with the `--disable-dependency-tracking` option
	and, apparently, stochastically with highly parallelized builds.
	{A "stock" build never encounters it because with
	"dependency tracking", Automake generates make(1) files that
	create ".deps" files in the build tree, and a prerequisite to
	doing so is to create the parents of the directories housing
	them, a convenience that this target rule snuck through.}

	Fixes <https://savannah.gnu.org/bugs/?67754> and
	<https://bugs.debian.org/1121570>.  Problem dates back at least
	to commit 62a22cb540, 22 August 2014 (but which did not appear
	in the "master" branch until 27 January of the next year), when
	groff's build system adopted Automake.  Thanks to Helmut Grohne
	for the report and Colin Watson for assistance reproducing it.

2025-12-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (charinfo::get_flags): Fix
	inadvertent regression caused by fumbled refactoring, wherein I
	inexplicably mistook a Boolean-valued return type for an
	`int`-valued one.  (`contains()` sounds Boolean to me now, in
	the cold light of day.)

	Fixes <https://savannah.gnu.org/bugs/?67570>.  Thanks to Dave
	Kemper for the report.  Problem introduced by me in commit
	77d8f728d, 4 September.

2025-12-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #67570.

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

2025-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp (is_valid_expression_start):
	Slightly refactor.  Call `tok.skip_spaces()` instead of
	open-coding exactly what it does.

2025-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/column.cpp [COLUMN] (column_justify)
	(column_start, column_output, column_trim, column_reset)
	(no_vjustify, restore_vjustify):
	* src/roff/troff/div.cpp (divert, divert_append, box)
	(box_append, page_length, when_request, begin_page, no_space)
	(restore_spacing, space_request, need_space, page_number)
	(save_vertical_space, output_saved_vertical_space)
	(diversion_trap, change_trap, print_traps, mark, return_request)
	(vertical_position_traps): Mark functions `static` since they do
	not require external linkage.

2025-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.h: Drop unnecessary declaration of
	`begin_page()`.

2025-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename function
	`read_delimited_number()` to `read_delimited_measurement()` to
	reinforce the fact that it reads a measurement (which is, in
	turn, a numeric expression potentially including operators).
	(read_delimited_number): Rename (overloaded) declarations and
	definitions from these...
	(read_delimited_measurement): ...to these.
	(token::next): Update call sites.

2025-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp (is_valid_expression)
	(is_valid_term): Fix code style nits.  Parenthesize formally
	complex expressions.  Arrange equality comparisons to avoid
	inadvertent lvalue assignment.

2025-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp (is_valid_term): Adjust wording of
	warnings in "syntax" category.

2025-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (warnscale_request): Fix code style
	nit.  Favor value constructors over C-style type casts.  Arrange
	equality comparisons to avoid inadvertent lvalue assignment.

2025-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (warnscale_request): In warning
	diagnostic in category "syntax", accurately describe the
	argument to the request even if it is something bizarre, instead
	of presenting the user with an empty pair of quotation marks.

	Fixes <https://savannah.gnu.org/bugs/?67747>.  Problem dates
	back to intoduction of `warnscale` request in commit 9993a881c1,
	5 May 2002.

2025-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (warnscale_request): Actually reset
	the computed `warn_scale` to `units_per_inch` when recovering
	from an invalid argument and telling the user we're reverting to
	inches.

	Fixes <https://savannah.gnu.org/bugs/?67748>.  Problem dates
	back to intoduction of `warnscale` request in commit 9993a881c1,
	5 May 2002.

2025-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Explicitly construct the global
	constant `TAB_REPEAT_CHAR` as type `unsigned char`, because it
	is destined for comparison to input characters, instead of
	inheriting the type `char` from its literal initializer.

	Continues the long process of fixing Savannah #67735.

2025-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix regression in syntax warning diagnostics introduced
	in recent days' commits.  Now that we're scrupulous about the
	data type of an input character to GNU troff, our diagnostic
	apparatus takes us at our word when we pass it unsigned chars,
	and it formats them as decimal integers instead of characters.
	Use value constructors to pass C++ `char`s where appropriate.

	* src/roff/troff/input.cpp (is_conditional_expression_true):
	* src/roff/troff/number.cpp (is_valid_term): Do it.

2025-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_size): Clarify diagnostic when
	an `\s` escape sequence that is bracketed or delimited (a GNU
	extension) contains an invalid numeric expression.  Describe
	what we were expecting and what we got instead.

	Fixes <https://savannah.gnu.org/bugs/?67746>.  Problem
	observable since groff 1.22.3 and appears to date back to
	groff's birth.

2025-11-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Perform more careful comparisons of the `unsigned char`
	values the formatter reads from input (or a token sequence) by
	promoting either the token or a character literal to which it is
	compared to `int` to (A) explicitly avoid issues with the
	implementation-defined signedness of unqualified `char`, and (B)
	lay foundation for future migration of GNU troff's internal
	character type to a custom, wider type.

	* src/roff/troff/div.cpp (return_request):
	* src/roff/troff/reg.cpp (assign_register_format_request):
	* src/roff/troff/env.cpp (configure_tab_stops_request):
	* src/roff/troff/number.cpp (get_incr_number)
	(is_valid_expression, is_valid_term):
	* src/roff/troff/input.cpp (get_line_arg)
	(read_size)
	(is_conditional_expression_true):
	Construct integer from character literal.
	* src/roff/troff/env.cpp (adjust):
	* src/roff/troff/reg.cpp (assign_register_format_request):
	* src/roff/troff/number.cpp (is_valid_term):
	* src/roff/troff/input.cpp (is_conditional_expression_true):
	* src/roff/troff/input.cpp (is_conditional_expression_true)
	(read_drawing_command):
	Store return value of `tok.ch()` in local variable of `int`, not
	`char`, type.
	* src/roff/troff/env.cpp: Retype global `TAB_REPEAT_CHAR` from
	{`const`} `char` to `unsigned char`.
	* src/roff/troff/input.cpp (read_size): Use local variables to
	avoid repeated member function calls.  (Presumably a smart
	optimizer would do the equivalent on its own, but this change
	also makes a lengthy compound conditional expression shorter.)

	Begins a long long process of fixing Savannah #67735.

2025-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_size): Fix code style nit;
	compare integer-valued variable to integer literal instead of
	letting it pun down to a Boolean.

2025-11-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_get_long_name, read_size):
	* src/roff/troff/reg.cpp (assign_register_format_request): Fix
	code style nit; parenthesize formally complex expressions.

2025-11-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_name_test, return_macro_request):
	Fix code style nits.  Rather than letting an input character pun
	down to a Boolean value, compare it to an appropriate constant
	literal.

2025-11-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_identifier, do_get_long_name)
	(get_delimited_name): Fix code style nits.  Compare input
	character values to constant literals of appropriate type and
	signedness--they should be `unsigned char`s, since the formatter
	reads its input as bytes.

2025-11-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `token` class's member
	function `is_character()` to `is_any_character()` to try and get
	across the idea that it's true for _any_ sort of character:
	ordinary {`A`}, special {`\[em]`, `\C'em'`}, or indexed
	{`\N'45'`}.

	* src/roff/troff/token.h (class token): Update declaration.
	(token::is_any_character): Update (inline) definition.
	* src/roff/troff/input.cpp (print_character_request)
	(remove_character):
	* src/roff/troff/node.cpp (embolden_font): Update call sites.

2025-11-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/reg.cpp (dump_register): Add assertion.

2025-11-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/reg.cpp (define_register_request)
	(assign_register_format_request, remove_register_request)
	(alias_register_request, rename_register_request)
	(print_register_request): Mark functions `static` since they do
	not require external linkage.

2025-11-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (are_comparands_equal): Fix code
	style nit; parenthesize formally complex expression.

2025-11-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_request): Adjust wording of
	warning diagnostic to better describe what the `do` request
	actually does.

2025-11-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_overstrike, do_bracket)
	(token::next): Convert some recent assertions to error
	diagnostics, since inputs to provoke them are not impossible.
	I found these by attempting to format GNU troff's own ELF
	executable as a document (the laziest possible fuzz testing).

2025-11-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Add description
	of the "empty" token type to which the global `tok` is
	initialized.  This comes up in a corner case of parser state,
	because sometimes we have to read multiple characters to decide
	what kind of token the very first one in the input stream is.
	Consider a delimited escape sequence whose wheels fall off
	because it's invalidly delimited.

2025-11-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_delimited_number)
	(read_delimited_name): Refactor.  Make logic more parallel.
	Make both functions check explicitly for EOF where the starting
	delimiter should be (and throw error if it's encountered).  Make
	both call `is_usable_as_delimiter()` member function of
	`start_token` object.  Parallelize wording of warning
	diagnostics in "delim" category.

2025-11-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/check-delimiter-validity.sh: Add unit
	test for foregoing change to delimiters accepted when reading a
	delimited name.

2025-11-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_delimited_name): Stop accepting
	horizontal motion tokens as escape sequence delimiters.  This is
	to prohibit use of the delimited `\h` escape sequence as a
	delimiter, but because of GNU troff's internal design, also
	prohibits the parameterless `\0`, `\^`, and `\|` delimiters.

	* doc/groff.texi.in (Delimiters):
	* man/groff.7.man (Delimiters): De-document support for these
	delimiters.

	* NEWS: Report change.

	Fixes <https://savannah.gnu.org/bugs/?67744>.  The problem of
	acceptance of `\h` as an escape sequence delimiter appears to
	date back to groff's birth.  (`get_delim_name()` didn't check
	for any token types except EOF and newline.)

2025-11-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/check-delimiter-validity.sh:
	Regression-test Savannah #67744.

2025-11-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Add assertion;
	every token type should have a human-readable description.  In
	the event that's not the case and `NDEBUG` is defined, describe
	the anomalous token as "an undescribed token" rather than "a
	magic token", to make it clearer that the problem results from
	developer oversight.

2025-11-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/token.h: Add new inline member function
	`is_node()` to aid input parser diagnostics.

2025-11-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename
	`get_delimited_name()` to `read_delimited_name()` because it
	does not retrieve a property; it advances the input stream
	pointer.  Update declaration and definition.
	(token::next): Update call site.

2025-11-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::is_usable_as_delimiter): Use
	new node token description member function.

2025-11-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor new token description logic into its own
	function, since there is a second place it can be used.

	* src/roff/troff/token.h (class token): Declare new
	`describe_node()` member function.
	* src/roff/troff/input.cpp (token::description): Move the logic
	from here...
	(token::describe_node): ...to this new member function.
	(token::description): Call the new member function.

2025-11-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp
	(read_drawing_command)
	(do_device_extension)
	(do_register)
	(do_zero_width_output)
	(do_name_test)
	(do_bracket)
	(do_overstrike)
	(do_width)
	(read_size):
	Revise text of warnings in category "delim" thrown when an
	inauspicious delimiter is selected outside of compatibility
	mode.

2025-11-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (assign_control_character)
	(assign_no_break_control_character): Fix blunders in `assert()`
	usage.  I'm trying to make groff safe for builds using `NDEBUG`.
	That can't be achieved if we wrap substantive function calls (or
	expressions with side effects) with `assert()`.

	Continues commit e09bc6c083, 7 May 2023 (but not merged onto the
	master branch until after the groff 1.23.0 release).

2025-11-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (assign_control_character)
	(assign_no_break_control_character): Improve diagnostics when
	user fumbles control character selections.

2025-11-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (assign_escape_character): Improve
	diagnostic when user fumbles escape character selection.

2025-11-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::add_node): Add assertion.
	This function should never be given a null pointer argument.

2025-11-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::make_tag): When not
	formatting HTML, return a new transparent dummy node instead of
	a null pointer.  When this function was implemented in
	2001-2004, the decision to return a null pointer violated an
	{undocumented, possibly uncontemplated} invariant that
	`environment::add_node()` was never passed a null pointer.  By
	returning an actual object, we can restore that invariant.

2025-11-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Fix code style nits.
	(environment::make_tab_node): Parenthesize formally complex
	expression.
	(environment::make_tab_node, environment::advance_to_tab_stop):
	Explicitly compare value of pointer type to null pointer literal
	instead of letting it pun down to a Boolean.  Revise logic for
	less cleverness (gratuitous use of ternary operator on pointer).

2025-11-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Trivially refactor.
	(add_hyphenation_exceptions): Rename this...
	(add_hyphenation_exception_words_request): ...to this.
	(init_hyphenation_pattern_requests): Update wiry-uppery.

2025-11-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_translate): Fix copy-and-paste
	braino in assertion message.

2025-11-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (remove_font_specific_character):
	Recover from invalid input more robustly.  If we encounter an
	invalid character token in the `rfschar` argument list (one that
	has a null pointer to its `charinfo`), and the build used
	`NDEBUG` to suppress assertions, skip the character and process
	the next token (if any) instead of ignoring the rest of the
	input line.  Also proceed to the next token if the font-specific
	character to be removed already doesn't exist as such.
	`rfschar` now better aligns with what `cflags` and `rchar` do.

2025-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (define_character, get_line_arg)
	(do_translate):
	* src/roff/troff/node.cpp (remove_font_specific_character): Add
	assertions.
	* src/roff/troff/input.cpp (do_overstrike, do_bracket)
	(token::description)
	(encode_special_character_for_device_output)
	(set_character_flags_request): Invert sense of test and add
	assertion.
	(token::next): Add assertions to `\z` escape sequence handler.
	(token:description): Split conditional to accommodate assertion.
	(encode_special_character_for_device_output): Lift assignment
	out of conditional branch since a null pointer check now guards
	it from execution with an early `return`.  Add assertion for
	impossible situation of a special character already being
	defined with a null groff `symbol` as its identifier.  For
	`NDEBUG` builds, return early should that eventuate, as we can't
	usefully call `map_special_character_for_device_output()` with a
	null pointer argument.

2025-11-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_title_parts): Slightly
	refactor.  Lift return value of repeated `tok.get_charinfo()`
	function call into a local variable, `ci`.

2025-11-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Report the node
	type of node tokens when describing them.

2025-11-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Give node types' self-reported type information
	human-readable names.  That is, use English noun phrases for
	them instead of C++ identifiers.

	* src/roff/troff/column.cpp (vjustify_node::type) [COLUMN]:
	* src/roff/troff/input.cpp (non_interpreted_char_node)
	(token_node, non_interpreted_node):
	* src/roff/troff/node.cpp (hyphen_inhibitor_node)
	(device_extension_node, suppress_node, tag_node, draw_node)
	(extra_size_node, vertical_size_node, hmotion_node)
	(space_char_hmotion_node, vmotion_node, hline_node, vline_node)
	(dummy_node, transparent_dummy_node, zero_width_node)
	(italic_corrected_node, left_italic_corrected_node)
	(overstrike_node, bracket_node, composite_node, glyph_node)
	(ligature_node, kern_pair_node, dbreak_node, break_char_node)
	(line_start_node, space_node, word_space_node)
	(unbreakable_space_node, diverted_space_node)
	(diverted_copy_file_node): Do it.

2025-11-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (remove_font_specific_character): Add
	null pointer check on `charinfo` object returned by
	`get_charinfo()` on token (a character to be removed as a
	font-specific fallback, which need not already exist).  If null,
	break from the loop just as is already done when the lookup on
	the same character as a font-specific character takes place.
	{Font-specific fallback characters are implemented sneakily by
	injecting spaces into their identifiers, making them otherwise
	invalid.  Where `A`, `\[em]` or `\N'45'` are non-font-specific
	characters (be they fallbacks or not), `TR \[em]` is a fallback
	for `\[em]` specific to the font named `TR`.}

2025-11-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (print_character_request): Slightly
	refactor; delay gathering of the current token's `charinfo`
	until we absolutely need it.

2025-11-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp
	(encode_special_character_for_device_output): Simplify logic.
	Both branches in this function were doing the same thing, except
	for a null pointer check.  Add another null pointer check since,
	in theory, `charinfo::get_symbol()` can return one.  Continues
	commit c4259eb20a, 14 September 2024.

2025-11-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (print_character_request)
	(remove_character): Simplify logic.  `token::description()`
	describes indexed characters adequately.

2025-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (add_hyphenation_exceptions): Fix code
	style nit; parenthesize formally complex expressions.  Also
	break lengthy chain of short-circuit operators across multiple
	lines, using indentation to illuminate (lack of) nesting.

2025-11-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Slightly refactor.  Make the global function
	`check_missing_character()` a member function of the `token`
	class since it operates only on token objects and can be more
	economically expressed that way.  Rename it.

	* src/roff/troff/token.h: Drop `extern` declaration of global
	`check_missing_character()`.
	(class token): Declare new member function.
	* src/roff/troff/input.cpp (check_missing_character): Relocate
	from here...
	(token::diagnose_non_character): ...to here, renaming.
	* src/roff/troff/env.cpp (margin_character):
	* src/roff/troff/input.cpp (read_character): Update call sites.

2025-11-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (define_character)
	(check_missing_character): Revise wording of error diagnostics
	to mention indexed characters alongside ordinary and special
	ones.

2025-11-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_title_parts): Avoid null
	pointer dereference.

2025-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (add_hyphenation_exceptions): Revise
	wording of diagnostic messages, better paralleling language in
	our documentation.

2025-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (add_hyphenation_exceptions): Drop
	`error()` call prior to `assert()`.  It's okay if, when built
	with the preprocessor `NDEBUG` symbol defined, we silently
	discard the remainder of the input line and resume reading the
	next.  Should feel familiar to users of AT&T troff.  (Also, this
	makes a forthcoming change easier.)

2025-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (margin_character): Trivially refactor.
	Invert test and resequence logic to handle the argumentless form
	of the `mc` request first.  This is to facilitate a forthcoming
	change.

2025-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (encode_character_for_device_output):
	Avoid null pointer dereference.

2025-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (get_line_arg): Add assertion.

2025-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/token.h (token::nspaces): Fix code style nit.
	Replace C-style type cast with value construction.

2025-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `skip()` member function of
	`token` class to `skip_spaces()` so that it is obvious at all of
	its (many) call sites what, exactly, it's doing with the input
	stream.

	* src/roff/troff/token.h (class token): Rename declaration.
	* src/roff/troff/input.cpp (token::skip): Rename definition from
	this...
	(token::skip_spaces): ...to this.
	* src/roff/troff/div.cpp (do_divert):
	* src/roff/troff/env.cpp (margin_character, environment_copy):
	* src/roff/troff/input.cpp (has_arg, read_identifier)
	(do_get_long_name, define_character, print_character_request)
	(do_register, nop_request, is_conditional_expression_true)
	(do_translate, set_hyphenation_codes)
	(hyphenation_patterns_file_code, define_class_request)
	(read_character, read_drawing_command):
	* src/roff/troff/node.cpp (read_font_identifier):
	* src/roff/troff/number.cpp (is_valid_expression)
	(is_valid_term):
	* src/roff/troff/reg.cpp (assign_register_format_request):
	Update call sites.

2025-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (margin_character):
	* src/roff/troff/input.cpp (has_arg, get_long_name)
	(print_character_request, do_register, nop_request)
	(is_conditional_expression_true, read_character): Slightly
	refactor.  Call `tok.skip()` instead of open-coding exactly what
	it does.

2025-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Slightly
	refactor.  Use different technique (with `static` `const`
	character literals) to construct computed string describing a
	special character or character class token.  See
	`assign_escape_character()` for a similar pattern.

2025-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `get_char()` member
	function of `token` class to `get_charinfo()` to clearly
	communicate the data type to which it returns a pointer.

	* src/roff/troff/token.h (class token): Rename declaration.
	* src/roff/troff/input.cpp (token::get_char): Rename definition
	from this...
	(token::get_charinfo): ...to this.
	* src/roff/troff/env.cpp (margin_character)
	(add_hyphenation_exceptions):
	* src/roff/troff/input.cpp (do_overstrike, do_bracket)
	(token::next, token::description, define_character)
	(print_character_request, remove_character, get_line_arg)
	(read_title_parts, encode_special_character_for_device_output)
	(is_conditional_expression_true, do_translate)
	(set_character_flags_request, set_hyphenation_codes)
	(define_class_request, read_character):
	* src/roff/troff/node.cpp (remove_font_specific_character):
	Update call sites.

2025-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `get_charinfo()` global
	function to `lookup_charinfo()` because (a) this parallels the
	naming of other functions that look up (and potentially create)
	entries in dictionaries (cf. `lookup_{color,family,request,
	warning}()`), and (b) this function is not an accessor
	{"getter"} for a property of a class object.

	* src/roff/troff/charinfo.h (get_charinfo): Rename declaration
	from this...
	(lookup_charinfo): ...to this.
	* src/roff/troff/input.cpp (get_charinfo): Rename definition
	from this...
	(lookup_charinfo): ...to this.
	* src/roff/troff/input.cpp (token::next, define_character)
	(init_charset_table, define_class_request, token::get_char)
	(token::add_to_zero_width_node_list, token::process)
	(name_to_glyph):
	* src/roff/troff/node.cpp (font_info::get_narrow_space_width)
	(font_info::get_half_narrow_space_width)
	(tfont::get_lig, make_glyph_node)
	(remove_font_specific_character, soft_hyphen_character_request)
	(init_node_requests): Update call sites.

2025-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (define_class_request): Stop adding
	the second end point of a character code range (to a character
	class) duplicatively as a singleton, preventing redundant
	population of the range.

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

2025-11-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (define_class_request): Eliminate
	extraneous diagnostic message.  We already throw a more
	contextually specific one subsequently.

2025-11-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::get_char): Recognize
	existence of indexed characters in diagnostic messages.

2025-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/groff.texi.in (Manipulating Hyphenation):
	* man/groff.7.man (Request short reference): Fix error that
	crept into groff 1.23.0 documentation; hyphenation exception
	words have no association with formatter environments (though
	that is a contemplated change; see Savannah #66387).

	Fixes <https://savannah.gnu.org/bugs/?66803>.  Thanks to Dave
	Kemper for the report.  Problem introduced by me in commit
	493a01c02d4, 28 June 2020.

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

	* src/devices/gropdf/gropdf.pl (Warn): Set exit status to 1, not
	2, if the scalar `warnexit` (set by the `-W` command-line
	option) is truthy.
	(usage): Exit with status 2, not 1, on usage errors.
	* src/devices/gropdf/gropdf.1.man (Options, Exit status): Update
	documentation accordingly.

	Fixes <https://savannah.gnu.org/bugs/?67612>.  Thanks to Dave
	Kemper for the report and to him and Deri for the code review.

2025-11-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Slightly refactor.
	(assign_escape_character, interpolate_arg): Mark variables
	pointing to C string literals as `static` and `const`.
	(assign_escape_character): Mark variable that selects between
	one of the aforementioned static literals a pointer to `const`.

2025-11-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (get_line_arg): Trivially refactor.
	Rename function argument whose type is a pointer to a `charinfo`
	object from `cp` to `cip` for (slightly more) clarity.  `ci` is
	almost universally used in the code base for `charinfo` objects.

2025-11-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_suppress): Improve diagnostic
	message when input malformed; the one we had wasn't clear in the
	easily anticipated scenario where the user assumes that `\O` is
	a delimited escape sequence (it isn't) and selects "'" as the
	"delimiter".

2025-11-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (add_hyphenation_exceptions):
	Instrument seemingly impossible scenario.

2025-11-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (margin_character): Fix code style
	nit; explicitly compare value of pointer type to null pointer
	literal instead of letting it pun down to a Boolean.

2025-11-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (hyphenation_patterns_file_code): Fix
	code style nit; parenthesize formally complex expressions.

2025-11-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (line_spacing): Clarify diagnostic
	message.

2025-11-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `get_integer()` to
	`read_integer()` because it does more than retrieve a property;
	it advances the input stream pointer.

	* src/roff/troff/token.h (get_integer): Rename this
	declaration...
	(read_integer): ...to this.
	* src/roff/troff/number.cpp (get_integer): Rename this
	definition...
	(read_integer): ...to this.  Also update assertion text.

	* src/roff/troff/div.cpp (begin_page, page_number)
	(return_request):
	* src/roff/troff/env.cpp (window_control_request) [0]
	(space_size, no_fill, center, right_justify)
	(post_vertical_spacing, temporary_indent, number_lines)
	(hyphenate_request, set_hyphenation_mode_default)
	(hyphenation_line_max_request, adjust, do_input_trap)
	(field_characters_request):
	* src/roff/troff/input.cpp (shift, activate_color, compatible)
	(substring_request, line_file, set_character_flags_request)
	(hyphenation_patterns_file_code, set_warning_mask_request):
	* src/roff/troff/node.cpp (mount_font_at_position)
	(associate_style_with_font_position, read_font_identifier)
	(zoom_font, constantly_space_font, set_ligature_mode)
	(set_kerning_mode): Update call sites.

2025-11-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp: Trivially refactor.  Update
	preprocessor macro `TEXT_BLOCK_STAGGER_MACRO` definition to
	indicate its purpose rather details of its implementation.  This
	is to help anyone having to debug tbl's output maintain their
	sanity.

2025-11-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp: Trivially refactor.  Rename
	preprocessor macro `TEXT_BLOCK_STAGGERING_MACRO` to
	`TEXT_BLOCK_STAGGER_MACRO`.

2025-11-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp (table::init_output): Fix
	inappropriately hard-coded string literal.  Invoke the text
	block staggering macro via its existing preprocessor macro, not
	by its literal name.  Things will go wrong if we ever change
	that preprocessor macro's definition.  Continues commit
	2c8e354f22, 4 August 2023.  See Savannah #64454.

2025-11-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Slightly refactor; boolify `charinfo` member functions.

	* src/roff/troff/charinfo.h (class charinfo): Demote integer
	arguments to `set_translation()` and `set_special_translation()`
	from `int` to `bool`.
	(charinfo::get_special_translation): Rename argument from
	`for_transparent_throughput` to `transparently`.
	* src/roff/troff/input.cpp (charinfo::set_translation): Demote
	argument types as above, and rename from the cryptic `tt` and
	`ti` to `transparently` and `as_input`, respectively.
	(charinfo::set_special_translation): Demote argument types as
	above.  Rename `c` to `cc` ("character code", as abbreviated
	elsewhere in this file), and `tt` to `transparently`.
	(do_translate): Demote integer arguments `translate_transparent`
	and `translate_input` from `int` to `bool`, and rename them to
	`transparently` and `as_input`, respectively, to obviously
	correspond with `charinfo` class member functions to which they
	are passed.
	(transparent_translate, translate, translate_no_transparent)
	(transparent_input): Update call sites to use Boolean literals
	and annotate argument correspondence.

2025-11-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (charinfo::set_hyphenation_code): Fix
	code style nit; explicitly compare value of pointer type to null
	pointer literal instead of letting it pun down to a Boolean.  In
	so doing, parenthesize formally complex expression.

2025-11-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `get_name()` to
	`read_identifier()`.  Part of the idea here is to use the verb
	"read" to suggest that the function advances the token pointer
	through the input stream (and it does).  Another part is to
	reduce confusion, since the `font_info` and `tfont` classes have
	an unrelated accessor member function `get_name()`.

	* src/roff/troff/token.h (get_name): Rename declaration from
	this...
	(read_identifier): ...to this.
	* src/roff/troff/input.cpp  (get_name): Rename definition from
	this...
	(read_identifier): ...to this.
	* src/roff/troff/div.cpp (do_divert, when_request)
	(diversion_trap, change_trap, mark):
	* src/roff/troff/env.cpp (select_fill_color_request)
	(select_stroke_color_request, select_font_request)
	(family_change, do_input_trap, select_hyphenation_language):
	* src/roff/troff/input.cpp (print_color_request)
	(diagnose_invalid_identifier, eoi_macro, blank_line_macro)
	(leading_spaces_macro, do_request, process_input_stack)
	(print_macro_request, map_composite_character)
	(do_define_string, do_define_macro, remove_macro, rename_macro)
	(alias_macro, chop_macro, do_string_case_transform)
	(substring_request, length_request, asciify_request)
	(unformat_macro, device_macro_request)
	(is_conditional_expression_true, open_file, close_request)
	(write_macro_request, define_class_request):
	* src/roff/troff/node.cpp (translate_font)
	(mount_font_at_position, associate_style_with_font_position)
	(read_font_identifier, zoom_font):
	* src/roff/troff/reg.cpp (define_register_request)
	(inline_define_register [0], assign_register_format_request)
	(remove_register_request, alias_register_request)
	(rename_register_request, print_register_request): Update call
	sites.

2025-11-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (length_request): Drop erroneous
	assertion that failed and cored on `.length \&`.

2025-11-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename
	class-defining request handler.
	(define_class): Rename this...
	(define_class_request): ...to this.  Mark it `static` since it
	does not require external linkage.
	(init_input_requests): Update `init_request()` wiry-uppery.

2025-11-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (define_class): Fix code style nits.
	Explicitly compare values of pointer type to null pointer
	literals instead of letting them pun down to Booleans.  Arrange
	equality comparison to avoid inadvertent lvalue assignment.

2025-11-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[hpftodit,troff]: Fix code style nit.

	* src/roff/troff/input.cpp (charinfo::dump):
	* src/roff/troff/node.cpp (glyph_node::asciify):
	* src/utils/hpftodit/hpftodit.cpp (unicode_to_ucode_name): Make
	the compiler do the work of computing sufficiently large static
	buffer sizes (for C strings), and in so doing express the
	maximal expected output to that buffer.

2025-11-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Describe
	character class objects distinctly from special characters.
	(print_character_request): Update error diagnostic to recognize
	that a character class is also worthy argument fodder to the
	`pchar` request.
	(charinfo::dump): Report totally different information for a
	character class.  Call the `dump()` member function of the its
	associated (empty) macro from the previous change.  This way the
	user troubleshooting character classes (or character
	class/special character collisions) can simply _ask_ the
	formatter where a character class is defined.  Report the only
	properties a character class has: a list of (potentially
	singleton) code point ranges and a list of nested classes.

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

2025-11-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/request.h (class macro): Declare new member
	function `dump()`, for specialized use with macros that always
	have zero-length contents.  What are these?  They correspond to
	the character class `charinfo` objects created by the `class`
	request.
	* src/roff/troff/input.cpp (define_class): Create a macro object
	with no contents and associate it with the character class being
	created.
	(macro::dump): New member function dumps file name and line
	number information.

2025-11-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* Makefile.am: Include "contrib/install-font/install-font.am".

2025-11-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Withdraw "right-brace" warning category.

	* src/roff/troff/troff.h (enum warning_type): Drop
	`WARN_RIGHT_BRACE` enumeration constant.
	* src/roff/troff/input.cpp: Drop "right-brace" element from
	`warning_table` static array.

	* doc/groff.texi.in (Warnings):
	* src/roff/troff/troff.1.man (Warnings): De-document it.

	* NEWS: Report change.

	Fixes <https://savannah.gnu.org/bugs/?67698> (2/2).

2025-11-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Withdraw "number" warning category.  The previous
	change left it without any instances.

	* src/roff/troff/troff.h (enum warning_type): Drop `WARN_NUMBER`
	enumeration constant.
	* src/roff/troff/input.cpp: Drop "number" element from
	`warning_table` static array.  Update default warning mask to
	exclude it.

	* doc/groff.texi.in (Warnings):
	* src/roff/troff/troff.1.man (Warnings): De-document it.

	* NEWS: Report change.

	Fixes <https://savannah.gnu.org/bugs/?67698> (1/2).

2025-11-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp: Refactor numeric expression parser
	to simplify and heighten severity of diagnostics.  This isn't
	a behavior change; character sequences that were invalid as
	numeric expressions were ignored before and remain so.  But
	since we're aborting interpretation of an argument to a request
	or escape sequence, where in at least one case AT&T troff did
	not--it would read through spurious tab characters to reach a
	valid numeric expression afterward--an error seems more
	appropriate.
	(is_valid_expression_start): Drop special handling of tab and
	right-brace escape sequences.  These get handled anyway when the
	term at the start of the expression gets interpreted...
	(is_valid_term): ...thus.  Raise diagnostic severity from
	warning (in "number" category) to error.

2025-11-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Improve
	quotation of special character names.

2025-11-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Improve
	diagnostics when encountering an indexed character.

2025-11-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `environment` class's
	member function `handle_tab()` to `advance_to_tab_stop()`.
	Rename its argument from `is_leader` to `use_leader`.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp: Do it.
	* src/roff/troff/input.cpp (unbreakable_space_node::need_reread)
	(token::process): Update call sites.

2025-11-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (unbreakable_space_node::need_reread)
	(token::process): Stop explicitly specifying argument of same
	value as `environment::handle_tab()`'s default.
	(token::process): Call environment object's `handle_tab()`
	member function with Boolean, not integer, literal.  Continues
	commit 023083d16d, 27 April 2024.

2025-11-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (is_conditional_expression_true):
	Tweak wording of syntax warning thrown only in compatibility
	mode.  Say that the conditional expression operator is "not
	portable to AT&T troff", for parallel phrasing with the escape
	sequence warning added in commit 589a724eca, 2 November, and
	because a person authoring or formatting a document presumably
	knows whether they're using compatibility mode.  (If they don't
	know, they can find out with `.tm compatibility mode is \n(.C`.)
	Prompted by discussion with James Youngman.

2025-11-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/color.cpp (color::get_rgb, color::get_cmy)
	(color::get_cmyk, color::get_gray):
	* src/preproc/eqn/pile.cpp (pile_box::output)
	(matrix_box::output, column::debug_print)
	* src/preproc/eqn/common.cpp (common_output::rounded_box):
	* src/preproc/pic/lex.cpp (get_delimited):
	* src/preproc/pic/object.cpp (object_spec::position_rectangle)
	(object_spec::make_move, object_spec::make_line)
	(object_spec::make_object):
	* src/preproc/pic/tex.cpp (tex_output::spline)
	(tex_output::circle, tex_output::ellipse):
	* src/preproc/pic/troff.cpp (simple_output::line)
	(simple_output::ellipse, simple_output::circle):
	* src/preproc/refer/command.cpp (check_args):
	* src/preproc/refer/label.ypp (format_serial)
	(extractor_expr::evaluate):
	* src/utils/hpftodit/hpftodit.cpp (main):
	* src/utils/lkbib/lkbib.cpp (main): Replace `assert(0)` calls
	with communicative predicates.

2025-11-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/pic/lex.cpp (get_delimited): Drop `switch` case
	that is present only "to shut cfront 2.0 up".  Cfront is long
	dead.

2025-11-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[refer]: Slightly refactor (boolify).

	* src/preproc/refer/token.h: Declare `get_token` as returning a
	`bool` rather than an `int`.
	* src/preproc/refer/token.cpp (get_token): Demote return type
	from `int` to `bool`.  Return Boolean, not integer, literals.

2025-11-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/TODO: Rename this file...
	* tmac/TODO-ms: ...to this, since it discusses only contemplated
	changes to the ms(7) package.
	* tmac/tmac.am (EXTRA_DIST): Reflect rename.

2025-11-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	Reform terminology: "conditional operator" -> "conditional
	expression operator".

	* src/roff/troff/input.cpp (is_conditional_expression_true):
	Update wording in diagnostic message.

	* doc/groff.texi.in (Selecting Fonts, Diversions):
	* man/groff.7.man (Diversions): Update documentation.

2025-11-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/pic/pic.ypp (ordinal): Replace C-style type cast
	with value construction.

2025-11-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	Retire our fmod(3) replacement in favor of gnulib's.  James
	Clark wrote groff's in 1989; it's changed very little since.

	* Makefile.am: Drop fmod-referencing annotations.
	* bootstrap.conf (gnulib_modules): Add "fmod".
	* configure.ac: Drop `fmod` from `AC_REPLACE_FUNCS()` call.
	* src/libs/libgroff/fmod.c: Delete.
	* src/libs/libgroff/libgroff.am (EXTRA_DIST): Drop "fmod.c".
	* src/preproc/pic/pic.ypp: Drop conditional declaration of
	`fmod()` symbol.

	Continues fixing Savannah #66518.

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

	Retire our putenv(3) replacement in favor of gnulib's.  groff's
	was copied from glibc in 1991 and changed very little since.

	* Makefile.am: Drop putenv-referencing annotations.
	* bootstrap.conf (gnulib_modules): Add "putenv".
	* configure.ac: Drop `GROFF_NEED_DECLARATION([putenv])` call.
	Drop `putenv` from `AC_REPLACE_FUNCS()` call.
	* src/devices/grops/ps.cpp:
	* src/devices/grops/psrm.cpp:
	* src/roff/groff/groff.cpp:
	* src/roff/troff/input.cpp: Drop conditional declaration of
	`putenv()` symbol.
	* src/libs/libgroff/putenv.c: Delete.
	* src/libs/libgroff/libgroff.am (EXTRA_DIST): Drop "putenv.c".

	Continues fixing Savannah #66518.

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

	[grops,groff,troff]: Parallelize diagnostic messages relating to
	putenv(3).

	* src/devices/grops/ps.cpp (main):
	* src/devices/grops/psrm.cpp (resource_manager::output_prolog):
	* src/roff/groff/groff.cpp (xputenv):
	* src/roff/troff/input.cpp (main): Consistently compare
	`putenv()`'s return value to an integer literal, rather than
	letting it pun down to a Boolean.  Phrase diagnostic message
	consistently.  Consistently report `strerror(errno)` on failure.

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

	[troff]: Improve "asciification" of more special characters.

	* src/roff/troff/node.cpp (glyph_node::asciify): Fix and clarify
	logic.  First, if a glyph has an "asciify code", use that.
	Then, if it has a nonzero "ASCII code", use that.  Next, if it
	has a Unicode mapping, write out an appropriate escape sequence
	using the default escape character.  (This source file has no
	insight into what a user's selected escape character is.)  Map
	code points U+0022, U+0027, U+002D, U+005C, U+005E, U+0060, and
	U+007E to predefined special character escape sequences (see
	groff_char(7)).  For all other Unicode code points, write out an
	escape sequence of the form `\[uYXXXX]`.  Finally, if none of
	the foreging mappings exist, throw an error diagnostic and dump
	the glyph's "charinfo", as if `pchar` were invoked on a
	corresponding GNU troff character.

	* src/roff/groff/tests/asciify-request-works.sh: Adjust test
	expectations.  Reset the escape character to the default before
	interpolating an "asciified" diversion; see above.  Surrender to
	a regression; the new logic doesn't know how to cope with the
	fallback character definition for the `fl` special character
	defined in "ps.tmac".  (Possibly, the PDF device should delete
	this fallback character.)

	Fixes <https://savannah.gnu.org/bugs/?67680>.  Thanks to Deri
	James for the report.

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

	[groff]: Regression-test Savannah #67680.

	* src/roff/groff/tests/asciify-special-characters-correctly.sh:
	Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

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

	* src/roff/troff/input.cpp (charinfo::dump): Report glyph
	properties in the same order that `glyph_node::asciify()` uses
	to attempt conversion of a glyph node back to a GNU troff input
	character sequence.

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

	* src/roff/troff/input.cpp (transparent_translate): Fix code
	style nit.  Align type of local variable with that returned by
	the function we call to populate it; demote `int` to `unsigned
	char`.  Compare this value to an unsigned literal, not a
	character literal of implementation-defined signedness.

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

	* src/roff/groff/groff.cpp (main): Tweak wording of notice about
	notices.  Many groff users encounter it via a package, and it
	seems churlish to expect distributors to rewrite this notice--
	though they still might want to do so to name the _specific_
	package in which they provide the files it mentions.

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

	* src/devices/gropdf/TODO: Drop stale item.

	Fixes <https://savannah.gnu.org/bugs/?67661>.  Thanks to Deri
	James for the discussion.

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

	* src/roff/groff/tests/check-delimiter-validity.sh: Add negative
	testing.  Verify that conditional expression operators and
	characters constitutive of numeric expressions are invalid as
	output comparison expression delimiters in compatibility mode.

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

	* src/roff/groff/tests/check-delimiter-validity.sh: Add negative
	testing.  Verify that *roff arithmetic operators are invalid as
	numeric expression delimiters in compatibility mode.

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

	* src/roff/troff/input.cpp (token::is_usable_as_delimiter): In
	compatibility mode, permit control characters as delimiters that
	DWB 3.3 troff accepts.  (Actually, this is slightly overbroad--
	AT&T troff does _not_ permit ^A, ^D, ^H, ^I, or ^L.  But this
	stuff is tedious to test (and the old "use-a-control-character-
	as-a-delimiter trick" is commonplace in historical documents, so
	we really should support it in at least approximate form).

	* src/roff/groff/tests/check-delimiter-validity.sh: Test them.

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

	* src/roff/troff/input.cpp (token::is_usable_as_delimiter):
	Accept many more conditional expression delimiters in
	compatibility mode, namely punctuation characters that AT&T
	troff doesn't reject in that context.
	* src/roff/groff/tests/check-delimiter-validity.sh: Test it.

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

	* src/roff/groff/tests/check-delimiter-validity.sh: Test many
	more numeric expression delimiters in compatibility mode,
	namely punctuation characters that AT&T troff doesn't reject in
	that context.

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

	* src/roff/groff/tests/check-delimiter-validity.sh: Test many
	more string expression delimiters in compatibility mode),
	including numerals and punctuation characters.

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

	* src/roff/groff/tests/check-delimiter-validity.sh: Test many
	more delimiters when not compatibility mode), including
	punctuation characters and control characters that are valid as
	input.

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

	* src/roff/troff/input.cpp (do_overstrike)
	(do_bracket)
	(do_name_test)
	(do_expr_test)
	(do_zero_width_output)
	(get_line_arg)
	(do_width)
	(do_device_extension): Slightly refactor.  Delay collecting the
	input level (interpolation depth) until we're sure the escape
	sequence we're interpreting is validly delimited.

2025-11-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::is_usable_as_delimiter): Fix
	spurious warning in category "delim" when using a tab character
	as an escape sequence as a delimiter.  AT&T troff doesn't allow
	that, but GNU troff has, historically.

	Continues commit 39c1176bfa, 25 January.  See Savannah #66686
	and Savannah #66526.

2025-11-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/pfbtops/pfbtops.c (main):
	* src/utils/xtotroff/xtotroff.c (main): Trivially refactor; use
	idiomatic ISO C99 null pointer constant literal.

2025-11-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grolbp/lbp.cpp (main): Eliminate dead store.

2025-11-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn, groff, grotty, hpftodit, indxbib, lkbib, lookbib, pic,
	soelim, tbl, tfmtodit]: Trivially refactor; use idiomatic C++98
	null pointer constant literal.

	* src/devices/grotty/tty.cpp (main):
	* src/preproc/eqn/main.cpp (main):
	* src/preproc/pic/main.cpp (main):
	* src/preproc/soelim/soelim.cpp (main):
	* src/preproc/tbl/main.cpp (main):
	* src/roff/groff/groff.cpp (main):
	* src/utils/hpftodit/hpftodit.cpp (main):
	* src/utils/indxbib/indxbib.cpp (main):
	* src/utils/lkbib/lkbib.cpp (main):
	* src/utils/lookbib/lookbib.cpp (main):
	* src/utils/tfmtodit/tfmtodit.cpp (main): Do it.

2025-11-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/soelim/soelim.cpp (do_file): Slightly refactor.
	Mark function as `static` since it does not require external
	linkage.  Demote return type from `int` to `bool`; return
	Boolean rather than integer literals.  Reorder equality
	comparison to avoid inadvertent lvalue assignment.

2025-11-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (psbb_locator::psbb_locator): Clarify
	error diagnostic.

2025-11-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Trivially refactor.  Rename `open_file_cautious()`
	function to `open_file_cautiously()`.

	* src/include/searchpath.h (class search_path): Do it.
	* src/libs/libgroff/searchpath.cpp
	(search_path::open_file_cautious): Rename this...
	(search_path::open_file_cautiously): ...to this.
	* src/devices/grops/psrm.cpp
	(resource_manager::supply_resource):
	* src/preproc/soelim/soelim.cpp (do_file):
	* src/roff/troff/input.cpp (next_file)
	(do_source)
	(psbb_locator::psbb_locator)
	(transparent_throughput_file_request)
	(process_input_file):
	* src/roff/troff/node.cpp (troff_output_file::really_copy_file):
	Update call sites.

2025-11-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp (main): Update copyright notice
	reported in `--version` output.  Increment most recent year to
	2025, acknowledge fact of additional copyright holders (already
	the case for decades; see our "LICENSES" file), and direct
	reader attention to availability of that file and others in the
	source distribution that clarify the permissions attaching to
	various parts of groff as built and distributed.

2025-11-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp (main): Drop ersatz '(C)' symbol from
	copyright notice.

	Software developers have long labored under the no-longer-
	correct misconception that omitting a copyright symbol from
	one's notice was a fatal defect that effectively placed the work
	in the public domain.  That stopped being true as of 1 March
	1989.[1]  Further, prior to guidance issued by the U.S.
	Copyright Office in the decades since, the use of "(C)" as a
	substitute for a copyright sign _may not have sufficed_ to
	prevent the copyright notice from being regarded as defective.
	The Copyright Office, then and now, prefers the abbreviation
	"copr." when © is typographically unavailable.[ibid.]  Nowadays,
	its advice is that "c" (note lowercase) is an "acceptable
	variant", that _may_ retain the efficacy of the copyright
	notice.  The word "copyright", spelled out in full, also
	suffices per that resource, and is already present in this
	notice.

	[1] https://www.copyright.gov/circs/circ03.pdf

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

	* src/devices/gropdf/gropdf.pl (usage): Tweak synopsis syntax.
	Rename option argument from "advanced-opts" to "option-bits" to
	align with man page change below.

	* src/devices/gropdf/gropdf.1.man (Synopsis, Options): Respell
	"optbits" as "option-bits".

	* src/devices/gropdf/gropdf.pl (usage):
	* src/devices/gropdf/gropdf.1.man (Synopsis): Put braces around
	multi-character expressions used in alternation (that is, with
	`|` notation), for clarity; few people seem to keep in their
	heads a rigorous grammar for synopsis notation that includes
	operator precedence.

2025-11-04  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Problem including pdfs produced by ghostscript 10

	* src/devices/gropdf/gropdf.pl (ParsePDFValue): Improve parser
	to handle multiple "/key/value" on one line.

2025-11-04  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Document --opt and --pdfver

	* src/devices/gropdf/gropdf.1.man: Add option entries.

	Fixes https://savannah.gnu.org/bugs/?67616

	Thanks to Dave for the report.

2025-11-04  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Reinstate -W to set exit code 2 on warning, and
	downgrade two Warnings to Notices.

	* src/devices/gropdf/gropdf.pl: Do it.

	Fixes https://savannah.gnu.org/bugs/?67612

	Thanks to Dave and Branden.

2025-11-04  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Reinstate using -W flag when building pdfs. Baby was thrown
	out with the bathwater by me.

	* doc/doc_am:
	* contrib/mom/mom.am: Reinstate -W flag to provide exit code
	if a warning is produced during build.

	Thanks to Dave for report in:-

	https://savannah.gnu.org/bugs/?67612

	and apologies to Branden for exfiltrating the baby.

2025-11-04  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[sboxes]: Handle situation where a box is ended at the
	bottom of a page, but the indent gap triggers a new page.

	* contrib/sboxes/sboxes.tmac (BOXSTOP): Turn off vertical
	position traps before advancing for bottom indent.

2025-11-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::next): Throw warnings in
	category "syntax" when a document uses GNU troff extension
	escape sequences while in compatibility mode.
	* doc/groff.texi.in (Warnings):
	* src/roff/troff/troff.1.man (Warnings): Document this.

2025-11-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix Savannah #67408.  As I've observed before in the
	groff 1.24 development cycle, the delimiter situation is a mess.
	AT&T troff actually has three different, context-dependent, sets
	of delimiters; getting too adventurous, though, leads to core
	dumps, as with `\D0l 1 20' or `.if %0%0% .tm true`.  Last
	November, I attempted to streamline groff's delimiter handling,
	but inadvertently broke compatibility mode.  I still think it's
	valuable for GNU troff users to be able to rely upon a single
	set of delimiters when not exercising AT&T compatibility mode,
	so change the formatter to handle four cases of delimiter
	context: "groff" (not in compatibility mode), AT&T string
	expressions (as used in `\o` or `\b` or the `tl` request), AT&T
	numeric expressions (`\s`, the first argument to `\l` or `\L`),
	and output comparison operators.

	* src/roff/troff/token.h: Introduce new `delimiter_context`
	enumerated type.
	(class token): Add parameter to `is_usable_as_delimiter()`
	member function, defaulting its value to
	`DELIMITER_GROFF_EXPRESSION` since we expect that to be the most
	common case.

	* src/roff/troff/input.cpp (is_usable_as_delimiter): Implement
	the three special cases for AT&T troff compatibility.
	(do_overstrike)
	(do_bracket)
	(do_name_test)
	(do_expr_test)
	(do_zero_width_output)
	(get_line_arg)
	(read_size)
	(do_register)
	(do_width)
	(do_device_extension)
	(read_drawing_command)
	(read_delimited_number): Distinguish compatibility mode.  If in
	it and given invalid delimiter, throw warning in category
	"delim" and unwind the operation, behaving more like AT&T troff.
	{Outside of compatibility mode, GNU troff uses the delimiter
	anyway, but warns of its ambiguity.}
	(is_conditional_expression_true): Refactor, introducing new
	Boolean local variable `perform_output_comparison`.  Throw
	syntax warning if `v` expression conditional operator used in
	compatibility mode, as no variant of AT&T troff available to me
	recognizes it.  Distinguish compatibility mode once the letteral
	conditional expression operators are ruled out.

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

2025-10-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/check-delimiter-validity.sh: Expand test
	coverage of delimiter usage in compatibility mode to account for
	the three different contexts in which delimiters can occur (and
	consequently the three different subsets of Unicode Basic Latin
	that are valid as delimiters in AT&T troff).

2025-11-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Unit-test logical predicates.

	* src/roff/groff/tests/logical-predicates-work.sh: Test behavior
	of logical predicates (the first argument to `if`, `ie`, and
	`while` requests).
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2025-10-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Slightly refactor.
	(is_conditional_expression_true): Parenthesize formally complex
	expressions.

2025-10-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Refactor.
	(are_comparands_equal): Pull performance of
	output comparison operation into its own function...
	(is_conditional_expression_true): ...from here.

2025-10-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grotty/tests/h-option-works.sh: Add unit test for
	function of grotty's '-h' option.
	* src/devices/grotty/grotty.am (grotty_TESTS): Run test.

2025-10-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grotty]: Rename test scripts to match modern naming convention.

	* src/devices/grotty/tests/basic_latin_glyphs_map_correctly.sh:
	Rename this...
	* src/devices/grotty/tests/basic-latin-glyphs-map-correctly.sh:
	...to this.

	* src/devices/grotty/tests/osc8_works.sh: Rename this...
	* src/devices/grotty/tests/osc8-works.sh: ...to this.

	* src/devices/grotty/grotty.am (grotty_TESTS): Update macro.

2025-10-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/doc.tmac (doc-get-arg-type*): Slightly refactor.  Drop
	unnecessary `el` branch (the argument type is already
	presumptively made '2' at the top of the macro definition);
	thanks to Ingo Schwarze for the suggestion.  Convert its
	counterpart `ie` request to `if` accordingly.  Migrate comment
	outside of macro definition, which seems more idiomatic when the
	escape character is disabled.  Consequently no empty requests
	remain and we can drop the brace escape sequences around the
	single chain of `if` requests remaining.

2025-10-16  Dave Kemper <saint.snit@gmail.com>

	* tmac/fallbacks.tmac: Update annotations.  Clean up a handful
	of small issues left over from bug #63354.  Details are in
	comment #55 there.
	- Explain meaning of U+200B, whose name (ZERO WIDTH SPACE) does
	  not make its purpose obvious.
	- Change commented-out definition of \[u200B] to one that will
	  work once the offending bug is fixed.
	- Document why \[u0082] should be treated the same as \[u200B].
	- Correct a bug number.
	- Document a possible future refinement of \[u2052].

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

2025-10-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/doc.tmac (doc-get-arg-type*): Handle the *roff internal
	string '.T' specially in an mdoc macro argument sequence; it is
	defined in the formatter, which _also_ defines a '.T'
	_register_, colliding perfectly with mdoc's argument type
	system.  This change prevents `.T` from being called as a macro
	and interpolating its value, a surprising outcome to mdoc users.

	Fixes <https://savannah.gnu.org/bugs/?67646>.  Thanks to onf for
	the report.  Problem dates back "all the way"; not only does
	groff 1.22.3 (November 2014) have it, but the 4.4BSD-Lite2
	implementation of mdoc does as well.  mdoc as a *roff macro
	package implements its own bespoke type system to accompany its
	bespoke macro processor; the type of a macro argument (a string
	or macro) is determined by looking up its name as a _register_.
	mandoc(1) does not exhibit this problem because it does not use
	roff(7) registers to distinguish mdoc(7) child macros from
	plain-text macro arguments, so the .T register does not clash
	with the .T predefined string in the way it did in
	groff mdoc(7).

2025-10-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Regression-test Savannah #67646.

	* tmac/tests/doc_infer-correct-type-of-dot-T-string.sh: Add
	test.
	* tmac/tmac.am (tmac_TESTS): Run test.

2025-10-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/s.tmac (TE): Clarify logic.  Predicate early return on
	undefinedness of `TW` register, not whether we've issued a
	warning diagnostic regarding tbl failure.  While these two
	conditions are logically coupled (one complementing the other),
	we avoid performing post-tbl cleanup actions because tbl didn't
	run, not because we diagnosed that fact.

2025-10-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp (table::do_bottom): Annotate
	generated *roff requests that avoid overprinting the bottom of a
	boxed table on nroff devices, to help anyone having to debug
	tbl's output maintain their sanity.

2025-10-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Revise diagnostics.

	* src/preproc/tbl/main.cpp (process_format): Demote error
	diagnostics when ignoring excess vertical lines in row
	descriptions to warnings, and recast them.
	* src/preproc/tbl/table.cpp (process_format): Demote error
	diagnostics when ignoring vertical lines at boxed table edges to
	warnings.

2025-10-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp: Rename macro storing name of *roff
	register containing remainder when using the "expand" region
	option and dividing the amount of unused line length by the
	number of inter-column gaps, from `LEFTOVER_FACTOR_REG` to
	`EXPANSION_REMAINDER_REG`.
	(table::compute_separation_factor)
	(table::compute_column_positions): Update interpolation sites.

2025-10-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grotty/tty.cpp (tty_printer::end_page): When using
	hard tabs (per the `-h` option), use a space instead of a tab to
	advance the output position when the distance to the next tab
	stop is only one character cell.  This behavior more closely
	resembles that of AT&T nroff.
	* src/devices/grotty/TODO: Delete.  Its only item is resolved.
	* src/devices/grotty/grotty.am (EXTRA_DIST): Drop "TODO".

	Fixes <https://savannah.gnu.org/bugs/?67633>.  Problem
	originally recorded by James Clark in groff 1.06, September
	1992.

2025-10-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grotty/tty.cpp (tty_printer::special_link): Fix
	code style nits.  Parenthesize formally complex expressions.
	Reorder equality comparisons to avoid inadvertent lvalue
	assignment.

2025-10-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am: Build PDF documents more carefully.
	(DOC_PDFMOM): Add environment variable `GROFF_COMMAND`, newly
	recognized by pdfmom(1), to make it run the build tree's groff
	via "test-groff", rather than (potentially) a "groff" in the
	build environment's $PATH.
	(PROCESSEDFILES_DEPS_PDF): Add "test-groff" script.

2025-10-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (process_input_stack
	<token::TOKEN_SPACE>): Diagnose ignored spaces after an output
	line continuation escape sequence (`\c`) on an input line.
	* src/roff/troff/env.cpp (environment::space_newline): Add
	assertion on falsity of `was_line_interrupted` since this member
	function should now be unreachable when that condition obtains.

	* doc/groff.texi (Warnings) <syntax>:
	* src/roff/troff/troff.1.man (Warnings) <syntax>: Document it.

2025-10-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	[gropdf]: Add negative testing to new unit tests; check that
	`man:` URIs are not incorrectly rewritten as internal links when
	no corresponding bookmark exists.

	* tmac/tests/an_MR-internal-hyperlinks-work-with-pdfmom.sh:
	* tmac/tests/andoc_internal-hyperlinks-work-with-pdfmom.sh:
	* tmac/tests/doc_Xr-internal-hyperlinks-work-with-pdfmom.sh: Do
	it.

2025-10-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[gropdf]: Add unit tests for pdfmom(1)'s replacement of external
	man page reference hyperlinks with internal links to document
	bookmarks.

	* tmac/tests/an_MR-internal-hyperlinks-work-with-pdfmom.sh:
	* tmac/tests/andoc_internal-hyperlinks-work-with-pdfmom.sh:
	* tmac/tests/doc_Xr-internal-hyperlinks-work-with-pdfmom.sh: Do
	it.
	* tmac/tmac.am (tmac_TESTS): Run tests.

2025-10-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[gropdf]: Make pdfmom able to run the build tree's groff.

	* src/devices/gropdf/pdfmom.pl: Add new global scalar `groff` to
	store the name/location of the groff command to run.  Default
	its value to "groff", but override it with the contents of the
	environment variable `GROFF_COMMAND` if that exists.  Update
	hard-coded "groff" literals with interpolations of this scalar.
	This interface is deliberately not documented in the man page,
	since it's intended for the use of groff's build system.

	Fixes <https://savannah.gnu.org/bugs/?67618>.  Problem appears
	to date back to pdfmom's birth in commit f2a501fff5, 31 August
	2012.

2025-10-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[gropdf]: Make pdfmom disclose version of groff it runs.

	* src/devices/gropdf/pdfmom.pl: When handling `-v`/`--version`
	option, run "groff" with the `--version` option as well, as our
	other wrapper programs nroff(1) and groff(1) do.  This makes it
	easy to see if the versions of the various programs in the
	pipeline are askew.

2025-10-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor recent change (to diagnose ignored characters
	on input lines after `\c` escape sequence) to catch the problem
	earlier in processing and report more information (before it is
	lost by calling into member functions of the `environment`
	class).

	* src/roff/troff/env.cpp (environment::add_char): Drop
	just-added logic to handle case when `was_line_interrupted` is
	true.  Add initial `assert()` to check desired invariant: we
	shouldn't reach this member function when a line has been
	interrupted.
	* src/roff/troff/env.h (class environment): Add accessor member
	function `get_was_line_interrupted()` for private Boolean member
	variable `was_line_interrupted`.
	* src/roff/troff/input.cpp (process_input_stack): Check line
	interruption status of current environment when processing
	tokens of type `TOKEN_CHAR`, `TOKEN_INDEXED_CHAR`, and
	`TOKEN_SPECIAL_CHAR`; skip the usual actions taken if that
	status is true, and throw a warning in category "syntax"
	instead.

2025-10-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (process_input_stack): Rename
	`suppress_next` local variable to `ignore_next_token`, and
	demote it from `int` to `bool`.  Assign to it with Boolean
	rather than integer literals.

2025-10-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::add_char): Throw syntax
	warning upon encountering formattable ordinary or special
	characters after `\c` escape sequence on an input line.
	* src/roff/troff/troff.1.man (Warnings): Document it.

2025-10-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (an*end-hyperlink): Work around apparently
	overpowered--or buggy--`chop` request.  Annotate landmine.

2025-10-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (charinfo::dump): Drop duplicate line
	of output to the standard error stream introduced in commit
	148b65b1ed, 12 September.

2025-10-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Fix code style nits.
	(environment::add_hyphen_indicator): Wrap long input line and
	break lengthy conditional for better legibility.  Parenthesize
	formally complex expression.
	(environment::newline): Compare integer variable explicitly to
	integer literal value instead of punning down to a Boolean.

2025-10-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `line_interrupted` member
	variable of class `environment` to `was_line_interrupted`; since
	it stores a Boolean value, its name should clearly imply a
	logical predicate.  Rename `environment`'s member variable
	`was_previous_line_interrupted` analogously--even though it is
	an `int` because it is a kludgy three-valued Boolean.  (The
	extra value encodes whether a formatter exit is underway, I
	think.)  Rename member function `get_prev_line_interrupted()` to
	`get_was_previous_line_interrupted()` analogously.  Rename (and
	unabbreviate) `saved_prev_line_interrupted` member variable of
	class `diversion` to `saved_was_previous_line_interrupted`
	analogously.

	* src/roff/troff/div.h (class diversion):
	* src/roff/troff/env.h (class environment): Do it.
	* src/roff/troff/div.cpp (do_divert):
	* src/roff/troff/env.cpp (environment::add_char)
	(environment::add_node, environment::add_hyphen_indicator)
	(environment::space_newline, environment::space)
	(environment::set_font, environment::set_family)
	(environment::set_size, environment::set_char_height)
	(environment::set_char_slant, environment::set_stroke_color)
	(environment::set_fill_color, environment::environment)
	(environment::copy, environment::interrupt)
	(environment::newline, environment::final_break)
	(environment::do_break, environment::dump, init_env_requests):
	* src/roff/troff/input.cpp (process_input_stack): Update call
	and dereference sites.

2025-10-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	[ms]: Support floating keeps on cover page.  (Traditionally, a
	cover page is exactly that--a page, singular, and therefore
	support for floating keeps should be unnecessary.  But letting a
	content reviewer scold a document author for letting a keep
	float to a second "cover" page seems less bad than the macro
	package throwing difficult-to-comprehend diagnostic messages.)

	* tmac/s.tmac: Initialize new Boolean-valued global register
	`@is-initialized` as false on startup.  Initialize the `k` and
	`nf` environments at startup, and copy their properties from
	environment `0`.
	(@init): Stop initializing `nf` environment here.  Make
	`@is-initialized` true.
	(KF): Call `par@reset-env` and `par@reset` only if the package
	is initialized.  If it isn't, these macros are not yet defined.

2025-10-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/s_start-document-with-keep-quietly.sh: Test more
	scenarios involving documents using keeps on a cover page.

	Prompted by feedback from Doug McIlroy; see
	<http://lists.gnu.org/archive/html/groff/2025-10/msg00045.html>.

2025-10-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/an_degenerate-input-uses-sane-page-length.sh: Make
	test more adaptable to degenerate documents or `PT` and `BT`
	redefinitions.  This test's concern is with man(7) not putting
	an insane number of blank lines on the output.

2025-10-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Initialize more state to prevent warnings when
	formatting degenerate documents.

2025-10-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (usage): Resync usage message with
	man page synopsis.

2025-10-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/pdf.tmac (pdfnote, pdfbookmark, pdfhref)
	(pdf:href.options,clear, pdf*href-M, pdf*href, pdf*href-I): Fix
	code style nit; put a space after each `d` conditional
	expression operator, for better code legibility.

2025-10-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* font/devpdf/Foundry.in:
	* m4/groff.m4 (GROFF_URW_FONTS_CHECK): Add
	"/usr/share/ghostscript/Resource/Font" directory to search path
	for URW font files.  That is apparently the location Arch Linux
	keeps them in.

	Fixes <https://savannah.gnu.org/bugs/?65974>.  Thanks to Morten
	Bo Johansen for the report.

2025-10-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/s.tmac: Issue helpful diagnostic if it looks like the
	user failed to preprocess a document calling `TE`.  Add new
	register `tbl*was-tbl-failure-reported` and new macro
	`tbl*check-for-tbl`, which sets the register.
	(TE): Call the new macro.  If the failure has been reported,
	tbl has not run, so we can skip the rest of this macro.

2025-10-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[ms]: Fix Savannah #64529.

	* tmac/s.tmac: Manage keeps and initialize package more
	robustly.
	(TS): If the first macro call seen in a document is `TS`, call
	`cov*ab-init` directly instead of going through `LP`, which
	automatically closes an open diversion.
	(KE): Track whether we closed a diversion in new module register
	`kp*did-closure-succeed`, initializing its Boolean value to
	zero.  After existing logic calling appropriate closure macros,
	test the register again, and issue a diagnostic only if it is
	not true.
	(kp*end, kp*fend): Set `kp*did-closure-succeed`.

	Fixes <https://savannah.gnu.org/bugs/?64529>.  Thanks to Doug
	McIlroy for the report (way back in 2011!).  Problem is at least
	that old.

2025-10-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[ms]: Regression-test Savannah #64529.

	* tmac/tests/s_start-document-with-keep-quietly.sh: Add test.
	* tmac/tmac.am (tmac_TESTS): Run test.

2025-10-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	Update with respect to Unicode 17, per procedure in
	"FOR-RELEASE" file.

	* src/libs/libgroff/uniuni.cpp:
	* src/utils/afmtodit/afmtodit.tables: Do it.

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

2025-10-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/mdoc/doc-common (doc-end-document): Fix code style nit.
	Favor `nop` over text line inside a conditional within a macro
	definition.

2025-10-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mandoc]: Regression-test useful output file line numbers
	reported in diagnostics when continuously rendering and
	switching macro packages.

	* tmac/tests/andoc_report-useful-line-numbers-in-diagnostics.sh:
	Add test.
	* tmac/tmac.am (tmac_TESTS): Run test.

2025-10-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Regression-test useful output file line numbers reported
	in diagnostics when continuously rendering.

	* tmac/tests/an_report-useful-line-numbers-in-diagnostics.sh:
	Add test.
	* tmac/tmac.am (tmac_TESTS): Run test.

2025-10-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/mdoc/doc-common (doc-end-document): Fix syntax/logic
	error arising from forgetting that groff's mdoc macros are
	mostly defined with the escape character switched off, meaning
	one has to pay extra attention when copying and pasting between
	groff man and groff mdoc.  When continuously rendering, truncate
	page length to vertical drawing position only after formatting
	the last document on the input stream.  This way, when troff
	emits diagnostic messages regarding the output, it reports a
	position of the form "page 1, line N", where "N" is a number you
	can usefully give to `sed -n Np` in a pipeline after
	nroff/troff/groff/grotty.

2025-10-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Regression-test useful output file line numbers reported
	in diagnostics when continuously rendering.

	* tmac/tests/doc_report-useful-line-numbers-in-diagnostics.sh:
	Add test.
	* tmac/tmac.am (tmac_TESTS): Run test.

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

	* bootstrap: Resync with upstream.

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

	* gnulib: Update to stable/2025-07.

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

	[groff]: Enable "locking" safer mode (3/3).

	* src/roff/groff/groff.cpp (main): Add new Boolean variables
	`is_safer_mode_locked` and `want_unsafe_mode`.  Drop unused
	variable `want_safer_mode`.  If the `-S` flag is encountered,
	"lock" safer mode and unset `want_unsafe_mode`.  If the `-U`
	flag is encountered and safer mode is locked, throw an error
	diagnostic.  Otherwise, continue as before.  If safer mode has
	been explicitly requested, supply pic(1) and troff(1) with the
	`-S` option.

	* src/roff/groff/groff.1.man (groff-specific options)
	(Transparent options): Document it.

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

	[pic]: Enable "locking" safer mode (2/3).

	* src/preproc/pic/main.cpp (main): New Boolean
	`is_safer_mode_locked` indicates whether the `-S` command-line
	option has been seen.  Accept new `-S` option.  If encountered,
	unset `want_unsafe_mode` Boolean and set `is_safer_mode_locked`.
	When encountering `-U` option, throw diagnostic and ignore it if
	`is_safer_mode_locked` is set.

	* src/prepic/pic/pic.1.man (Options): Document it.

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

	[troff]: Enable "locking" safer mode.

	* src/roff/troff/input.cpp (main): New Boolean
	`is_safer_mode_locked` indicates whether the `-S` command-line
	option has been seen.  Accept new `-S` option.  If encountered,
	unset `want_unsafe_requests` Boolean and set
	`is_safer_mode_locked`.  When encountering `-U` option, throw
	diagnostic and ignore it if `is_safer_mode_locked` is set.

	* src/roff/troff/input.cpp (usage):
	* src/roff/troff/troff.1.man (Synopsis, Options): Document it.

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

	* src/roff/groff/groff.cpp (main): Demote variable `safer_flag`
	from `int` to `bool` and rename it to `want_safer_mode`.  Assign
	to it using Boolean, not integer, literals.

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

	[pic]: Invert sense of global Boolean.

	Rename global Boolean from `want_safer_mode` to
	`want_unsafe_mode`.  Invert assignments and tests.

	* src/preproc/pic/pic.h:
	* src/preproc/pic/main.cpp:
	* src/preproc/pic/pic.ypp: Do it.

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

	[pic]: Boolify global variable.

	* src/preproc/pic/pic.h: Demote global variable `safer_flag`
	from `int` to `bool` and rename it to `want_safer_mode`.

	* src/preproc/pic/main.cpp: Update its definition to match
	declaration.  Assign to it using Boolean, not integer, literals.

	* src/preproc/pic/main.cpp (main):
	* src/preproc/pic/pic.ypp (placeless_element): Update.

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

	* src/preproc/pic/main.cpp (main): Sort _optstring_ argument to
	`getopt_long()` in U.S. English collation order for better
	intelligibility to maintainers.

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

	* src/roff/troff/input.cpp (main): Sort _optstring_ argument to
	`getopt_long()` in U.S. English collation order for better
	intelligibility to maintainers.

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

	Reform terminology ("hyphenation flags" -> "hyphenation mode").
	The latter usage is already strongly preponderant.

	* src/roff/troff/TODO:
	* tmac/cs.tmac:
	* tmac/de.tmac:
	* tmac/es.tmac:
	* tmac/fr.tmac:
	* tmac/it.tmac:
	* tmac/ru.tmac:
	* tmac/sv.tmac: Do it.

	* src/roff/troff/env.cpp (hyphenate_request): Update diagnostic
	messages, and recast where necessary.

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

	[man]: Test and document `TP` interaction with `MT`/`ME` and
	`UR`/`UE`.

	* tmac/tests/an_MT-works.sh:
	* tmac/tests/an_UR-works.sh: Add test cases for use of
	hyperlinks as paragraph tags without link text.

	* tmac/groff_man.7.man.in (Hyperlink macros): Document this
	detail of behavior.

2025-10-05  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Update default cmap so that it works correctly
	with acrobat on windows.

	* src/devices/gropdf/gropdf.pl (begincmap): fix for windows
	acrobat.
	(sub do_x): Comment redundant code.

	Thanks to Grisha Levit for report of problem with some pdf
	viewers.

2025-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/ja.tmac:
	* tmac/ru.tmac:
	* tmac/zh.tmac: Fix misleading diagnostic messages.  Report the
	actual name of the macro file issuing the message.

2025-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Regression-test continuously rendered degenerate output;
	a sane quantity of output lines should be produced.

	* tmac/tests/doc_format-degenerate-input-sanely.sh: Add test.
	* tmac/tmac.am (tmac_TESTS): Run test.

2025-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Handle degenerate documents more robustly; if given
	formattable input text with no macro calls, and continuously
	rendering, don't put 1.3 million blank lines (`\n[.R]/1v`) on
	the output.

	* tmac/an.tmac ([initialization]): Initialize registers and
	strings accessed by trap-called macros, since the end of input
	springs several of them.
	(TH): Move end-of-input macro setup from here...
	([initialization]): ...to here.
	(TH): We now no longer need the `an-TH-was-called` register, so
	stop creating it...
	(an*end-document): ...stop removing it, and stop checking its
	existence.  Also, when continuously rendering, update the page
	length immediately after writing the footer, just as our mdoc(7)
	package does.

2025-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Regression-test continuously rendered degenerate output;
	a sane quantity of output lines should be produced.

	* tmac/tests/an_format-degenerate-input-sanely.sh: Add test.
	* tmac/tmac.am (tmac_TESTS): Run test.

2025-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Regression-test non-hyphenation of lengthy URIs that
	format as their own link text due to the document specifying
	none after the first argument to an `Lk` macro call.

	* tmac/tests/\
	doc_do-not-hyphenate-hyperlink-with-no-link-text.sh: Add test.
	* tmac/tmac.am (tmac_TESTS): Run test.

2025-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (an*end-hyperlink): Suppress automatic
	hyphenation when rendering a hyperlink as its own link text.

	Fixes a post-groff-1.23.0 regression (meaning the bug has only
	been observable in Git, not a groff release).  Problem exposed
	by commit 5d2e49f818, 9 August 2023, but may be a little older.

2025-10-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Regression-test non-hyphenation of lengthy URIs that
	format as their own link text due to the document specifying
	none between `MT` and `ME` or `UR` and `UE` macro calls.

	* tmac/tests/an_do-not-hyphenate-hyperlink-with-no-link-text.sh:
	Add test.
	* tmac/tmac.am (tmac_TESTS): Run test.

2025-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor for clarity.

	* src/roff/troff/node.h (enum hyphenation_type): Rename symbols.
	    `HYPHENATE_MIDDLE`   -> `HYPHENATION_PERMITTED`
	    `HYPHENATE_BOUNDARY` -> `HYPHENATION_UNNECESSARY`
	    `HYPHENATE_INHIBIT`  -> `HYPHENATION_INHIBITED`
	* src/roff/troff/env.cpp (environment::possibly_hyphenate_line):
	* src/roff/troff/node.cpp (glyph_node::get_hyphenation_type)
	(hyphen_inhibitor_node::get_hyphenation_type)
	(break_char_node::get_hyphen_list)
	(node::get_hyphenation_type)
	(dbreak_node::get_hyphenation_type)
	(kern_pair_node::get_hyphenation_type)
	(dummy_node::get_hyphenation_type)
	(transparent_dummy_node::get_hyphenation_type)
	(hmotion_node::get_hyphenation_type)
	(space_char_hmotion_node::get_hyphenation_type)
	(space_node::get_hyphenation_type)
	(unbreakable_space_node::get_hyphenation_type)
	(composite_node::get_hyphenation_type)
	(left_italic_corrected_node::get_hyphenation_type): Update.

2025-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (class device_extension_node): Declare
	new `get_hyphenation_type()` member function to specialize the
	base class's version.
	* src/roff/troff/node.cpp
	(device_extension_node::get_hyphenation_type): Return an
	enumeration symbol reflecting the permissibility of hyphenation
	where a device extension node occurs.

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

2025-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #67577.

	* src/roff/groff/tests/\
	backslash-X-is-transparent-to-hyphenation.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2025-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (node::add_char): Compare integer-
	valued variable to integer literal instead of letting it pun
	down to a Boolean.

2025-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	Tidy up the name space a bit.  We had two `enum`s declaring
	symbols starting with `HYPHEN_` (and another variable of
	`symbol` type that does as well).  Reduce those two to one,
	renaming the elements of the `enum` that manage the hyphenation
	state of the node list in the pending output line (cf. the
	hyphenation properties of characters themselves) to start with
	`HYPHENATE_` instead.

	* src/roff/troff/node.h (enum hyphenation_type): Do it.
	* src/roff/troff/env.cpp (environment::possibly_hyphenate_line)
	* src/roff/troff/node.cpp (glyph_node::get_hyphenation_type)
	(hyphen_inhibitor_node::get_hyphenation_type)
	(break_char_node::get_hyphen_list)
	(node::get_hyphenation_type)
	(dbreak_node::get_hyphenation_type)
	(kern_pair_node::get_hyphenation_type)
	(dummy_node::get_hyphenation_type)
	(transparent_dummy_node::get_hyphenation_type)
	(hmotion_node::get_hyphenation_type)
	(space_char_hmotion_node::get_hyphenation_type)
	(space_node::get_hyphenation_type)
	(unbreakable_space_node::get_hyphenation_type)
	(composite_node::get_hyphenation_type)
	(left_italic_corrected_node::get_hyphenation_type): Update.

2025-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	The `environment` class's member function `hyphenate_line`
	doesn't necessarily hyphenate the line; it can break the line
	without hyphenation.

	* src/roff/troff/env.cpp (environment::hyphenate_line): Rename
	this...
	(environment::possibly_hyphenate_line): ...to this.  Also
	parenthesize formally complex expression.
	(environment::possibly_break_line): Update call site.
	* src/roff/troff/env.h: Rename in declaration.

2025-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Slightly refactor.

	Nothing outside of "env.cpp" calls the global function
	`hyphenate()`.  In fact, it has only one call site.

	* src/roff/troff/env.cpp: Add forward declaration.
	  (hyphenation): Mark function as `static`.
	* src/roff/troff/node.h: Drop declaration.

2025-09-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an-ext.tmac: Tweak `EX`/`EE` behavior for more flexible
	customization of typeface when using typesetters.  Stop
	assigning value "R" to string `mC` in nroff mode.  This way it's
	straightforwardly overridable in a "man.local" file, and the
	user doesn't have to override it differently for nroff mode.
	(EX): Select font "R" explicitly in nroff mode; a typesetter's
	constant-width font name won't be meaningful to a terminal
	output driver, except in the (unlikely?) case that an
	installation configures a style name as `mC`'s value.  (Unless
	man(7) pages are then formatted with "troff -fC -man" or
	similar to force a monospaced font for the entire document,
	doing this would largely trash the utility of example displays.)

2025-09-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/html-device-works-with-grn-and-eqn.sh:
	Make test more sensitive.  While the infinite loop introduced in
	commit c71b4ef4aa and later fixed has not regressed, the input
	document does not produce usable output.  Look for that usable
	output.  That makes the test fail.  Unfortunately this is not
	evidence of a recent defect; groff 1.23.0, 1.22.4, and 1.22.3
	fail the same way with this input.  Therefore...
	* src/roff/groff/groff.am (XFAIL_TESTS): Mark it as an expected
	failure.

2025-09-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/hvunits.h (hunits operator -): Fix misleading
	warning diagnostic arising from copy-and-paste error; the
	saturating operation is multiplication, not subtraction (when
	not decrementing, "-256" <=> "-1*256").

2025-09-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Refactor.
	(dbreak_node::asciify): Replace call of
	`asciify_reverse_node_list()` with a more idiomatic recursive
	call of the `none` contained node's `asciify()` member function.
	(asciify_reverse_node_list): Drop function with no remaining
	call sites.

	Fixes <https://savannah.gnu.org/bugs/?67509> (considered in
	combination with many other recent asciification changes).

2025-09-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac:
	* tmac/doc.tmac: Man pages more often use the neutral double
	quote `"` as a "code literal" than as a quotation character.
	Give it the same (empty) set of character flags as its special
	character equivalent, \[dq].  This means that it is no longer
	transparent to sentence endings.

	Fixes <https://savannah.gnu.org/bugs/?67474>.  Thanks to Alex
	Colomar and Russ Allbery for the discussion.

2025-09-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/fallbacks.tmac: Define different fallbacks for accented
	non-Latin-1 Latin characters, using one ordering for nroff-mode
	devices and another for troff-mode devices.  We assume that the
	former can't constructively overstrike and the latter can.

	On troff-mode devices, it can make sense to use the `asciify`
	request to serialize special characters in device extension
	commands, and in that case we want to write the base glyph
	before any combining ones.

	On non-constructively overstriking devices, the last character
	written at the drawing position "wins"; we want that to be the
	base glyph.

	Fixes <https://savannah.gnu.org/bugs/?66653>.  Thanks to Deri
	James for pushing device extension commands to the limit,
	exposing this defect.

2025-09-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #66653.

	* src/roff/groff/tests/asciify-composite-nodes-correctly.sh: Do
	it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2025-09-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor `node` class hierarchy.  Make `node` an
	abstract class.  The `asciify` feature had several bugs, and I
	think it's because the class design permitted derived classes to
	reuse the `node` base class's `asciify` member function, which
	robotically appended the `this` object to the macro pointed to
	in the function argument.  In most cases, the correct
	"asciification" of a node is to do nothing, discarding it.
	Rather than making the member function empty in the base class,
	I prefer to make the base class abstract to force conscious
	consideration of how objects of each derived class should be
	"asciified".

	* src/roff/troff/node.h: Mark `add_char()`, `asciify()`, and
	`add_italic_correction()` member functions as `virtual`.
	Further mark `asciify` as _pure_ virtual (notation: "= 0").
	* src/roff/troff/node.cpp (node::asciify): Delete.

2025-09-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test case
	for transformation of nodes produced by diverted `trf` requests.

2025-09-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(asciify_macro, copy_file, transparent_file): Rename these...
	(asciify_request, unsafe_transparent_throughput_file_request)
	(transparent_throughput_file_request): ...to these.
	(process_input_stack, init_input_requests): Update call sites
	and request-name-to-handler-function correspondences.

2025-09-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Mark the
	`transparent_file()` request handler as `static` since it does
	not require external linkage.

2025-09-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (transparent_file): Test whether
	the current diversion is the top-level diversion.  If so,
	proceed as we have to date.  But if not, call `copy_file()`
	member function of the current diversion.

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

2025-09-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #67532.

	* src/roff/groff/tests/trf-request-works.sh: Add unit tests of
	`trf` request functionality when used inside and outside of a
	diversion.

2025-09-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (class zero_width_node): Declare
	`asciify` member function, thus overriding base class.
	* src/roff/troff/node.cpp (zero_width_node::asciify): New member
	"asciifies" each contained node unless output is suppressed.

2025-09-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test case
	for transformation of nodes produced by `\Z` and `\z` drawing
	position reset escape sequences.

2025-09-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (class suppress_node): Declare
	`asciify` member function, thus overriding base class.
	* src/roff/troff/node.cpp: New file-scoped global variable
	`is_output_supressed` tracks whether output is suppressed with
	the `\O` escape sequence.
	(suppress_node::asciify): New member function assigns to
	`is_output_supressed` per the escape sequence argument
	{indirectly, via the unhelpfully named `is_on` tri-state
	member variable.}
	(node::asciify, glyph_node::asciify, kern_pair_node::asciify)
	(dbreak_node::asciify, ligature_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, composite_node::asciify):
	Textify node contents only if output is not suppressed.

2025-09-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (class overstrike_node): Declare
	`asciify` member function, thus overriding base class.
	* src/roff/troff/node.cpp (overstrike_node::asciify): New member
	function simply does nothing.

2025-09-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test case
	for transformation of nodes produced by `\o` overstriking escape
	sequences.

2025-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (class vline_node): Declare `asciify`
	member function, thus overriding base class.
	* src/roff/troff/node.cpp (vline_node::asciify): New member
	function simply does nothing.

2025-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test case
	for transformation of nodes produced by `\L` vertical rule
	escape sequences.

2025-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (class hline_node): Declare `asciify`
	member function, thus overriding base class.
	* src/roff/troff/node.cpp (hline_node::asciify): New member
	function simply does nothing.

2025-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test case
	for transformation of nodes produced by `\l` horizontal rule
	escape sequences.

2025-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (class extra_size_node): Declare
	`asciify` member function, thus overriding base class.
	* src/roff/troff/node.cpp (extra_size_node::asciify): New member
	function simply does nothing.

2025-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test case
	for transformation of nodes produced by `\x` extra leading
	escape sequences.

2025-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (class draw_node): Declare `asciify`
	member function, thus overriding base class.
	* src/roff/troff/node.cpp (draw_node::asciify): New member
	function simply does nothing.

2025-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test case
	for transformation of nodes produced by `\D` drawing escape
	sequences.

2025-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (class diverted_space_node): Declare
	`asciify` member function, thus overriding base class.
	* src/roff/troff/node.cpp (diverted_space_node::asciify): New
	member function simply does nothing.

2025-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test case
	for transformation of nodes produced by diverted `sp` requests.

2025-09-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (glyph_node::asciify)
	(kern_pair_node::asciify, dbreak_node::asciify)
	(asciify_reverse_node_list, ligature_node::asciify)
	(break_char_node::asciify, italic_corrected_node::asciify)
	(left_italic_corrected_node::asciify)
	(space_char_hmotion_node::asciify, space_node::asciify)
	(word_space_node::asciify, unbreakable_space_node::asciify)
	(line_start_node::asciify, vertical_size_node::asciify)
	(dummy_node::asciify, transparent_dummy_node::asciify)
	(tag_node::asciify, device_extension_node::asciify)
	(vmotion_node::asciify, bracket_node::asciify)
	(hyphen_inhibitor_node::asciify, composite_node::asciify): Stop
	deleting the `this` object.  I added many of these deletions
	recently, but several {`glyph_node`, `kern_pair_node`,
	`dbreak_node`, `ligature_node`, `break_char_node`,
	`italic_corrected_node`, `left_italic_corrected_node`,
	`hmotion_node`, `space_char_hmotion_node`, `space_node`,
	`word_space_node`, `unbreakable_space_node`, `line_start_node`,
	`vertical_size_node`, and `composite_node`} already were in
	groff 1.23.0, and for untold years before--sometimes only
	conditionally depending on the node contents.  Why stop deleting
	them?  Because the node list is actually a list of (potential)
	trees; some nodes can contain further nodes, and so on
	recursively.  It's difficult, and there is no need, to mark the
	root of each tree in the list so that we can return to it later
	to delete it; instead what we can do is have the `asciify`
	request walk the list again and perform a delete operation,
	which due to the class hierarchy design will automatically be a
	complete, recursive operation.  There is no reason _not_ to do
	this because the whole point of `asciify` is to convert nodes
	back into some form of text; the idiomatic application (and only
	one, as seen in "om.tmac" and "e.tmac") is to convert diversions
	into PDF bookmarks or HTML URLs that are embedded in a document
	as metadata or markup, not as formatted text.
	* src/roff/troff/input.cpp (asciify_macro): When asciifying a
	node in a macro/string/diversion, copy the node first, asciify
	the copy (which in many cases produces nothing), and delete the
	original.  This should be less wasteful of memory, as there's no
	need to carry around node data that is unrepresentable as text
	in an irreversibly transformed macro/string/diversion.
	* src/roff/troff/node.cpp (dbreak_node::asciify)
	(break_char_node::asciify, italic_corrected_node::asciify)
	(left_italic_corrected_node::asciify): Revert (from commit
	d445aee94e, 10 September) formerly dead stores nulling out
	pointers to contained nodes.  Since the parent object is no
	longer deleted, these stores are no longer dead, and I expect
	the nullification to matter when asciifying node lists that
	contain `suppress_node`s.

2025-09-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.am (EXTRA_DIST): Ship "throughput-file"
	test artifact in distribution archive.

	Continues commit 09060903cf, 3 March.

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: "Asciify" bracket nodes as nothing.  (Bracket nodes are
	produced by the `\b` bracket-building escape sequence.)

	* src/roff/troff/node.h (class bracket_node): Declare `asciify`
	member function, thus overriding base class.
	* src/roff/troff/node.cpp (bracket_node::asciify): New member
	function simply deletes `this`.

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test case
	for transformation of nodes produced by `\b` (bracket-building
	escape sequence).

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor.  Explicitly "asciify" hyphen inhibitor nodes
	as nothing.  These correspond to the `\%` escape sequence at the
	beginning of a word.

	* src/roff/troff/input.cpp (class hyphen_inhibitor_node):
	Declare `asciify` member function, thus overriding base class.
	(hyphen_inhibitor_node::asciify): Delete the `this` object and
	return.

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor.  Explicitly "asciify" non-interpreted `char`
	nodes as nothing.  These correspond to the `\a` and `\t` escape
	sequences.

	* src/roff/troff/input.cpp (class non_interpreted_char_node):
	Declare `asciify` member function, thus overriding base class.
	(non_interpreted_char_node::asciify): Delete the `this` object
	and return.

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor.  Explicitly "asciify" non-interpreted nodes
	as nothing.  These correspond to what is bracketed by `\?`
	escape sequences.

	* src/roff/troff/input.cpp (class non_interpreted_node): Declare
	`asciify` member function, thus overriding base class.
	(non_interpreted_node::asciify): Delete the `this` object and
	return.

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test case
	for transformation of nodes produced by `\%` (hyphenation
	control escape sequence) when it leads a word.

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test case
	for transformation of nodes produced by `\?` (uninterpreted
	character sequence escape sequence).  Check functionality when
	used inside and outside of a diversion.

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test cases
	for transformation of nodes produced by leaders and tabs.

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test case
	for transformation of node produced by `\a` (uninterpreted
	leader) escape sequence.

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: "Asciify" token nodes as nothing.  Token nodes are used
	only internally to manipulate the input stream; they don't
	directly correspond to any sort of document feature.

	* src/roff/troff/node.h (class token_node): Declare `asciify`
	member function, thus overriding base class.
	* src/roff/troff/node.cpp (token_node::asciify): Plant land mine
	with `assert()`.  Delete the `this` object and return.

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: "Asciify" (plain) space nodes as nothing.  (Plain space
	nodes--contrast word space nodes and others--are produced by the
	formatter with a width of zero (`H0`) in nearly all cases.  The
	exception is when a space node is copied, in which case the
	destination space node gets whatever width its source had.)

	* src/roff/troff/node.cpp (space_node::asciify): Simplify;
	member function now simply deletes `this`.

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test case
	for transformation of node produced by `\:` (hyphenless
	breakpoint) escape sequence.

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (unbreakable_space_node::asciify):
	Asciify an unbreakable space node (the kind produced by the `\~`
	escape sequence) as an ordinary space instead of an
	`ESCAPE_TILDE` token.  The latter is not necessary for the
	`asciify` request's revised charter (and only known application
	to date) of making diversion contents fit for use as device
	extension command arguments.

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test case
	for transformation of node produced by `\~` (unbreakable space)
	escape sequence.

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (space_char_hmotion_node::asciify):
	Asciify a space character horizontal motion node (the kind
	produced by the `\ ` unadjustable space escape sequence) as an
	ordinary space instead of an `ESCAPE_SPACE` token.  The latter
	is not necessary for the `asciify` request's revised charter
	{and only known application to date} of making diversion
	contents fit for use as device extension command arguments.

2025-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/asciify-request-works.sh: Add test case
	for transformation of node produced by `\ ` (unadjustable space)
	escape sequence.

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

	* src/roff/troff/node.cpp (hmotion_node::asciify): Stop
	asciifying a horizontal motion node that was a tab character as
	a tab; instead delete it like any other horizontal motion.  We
	have no semantics for tab characters in, for example, the
	parameters of device extension commands.  Ensure that the node
	object is deleted on every path through the function (now
	trivial).
	* src/roff/groff/tests/asciify-request-works.sh: Add test cases
	for transformation of nodes produced by `\t` and `\h` escape
	sequences.

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

	* src/roff/troff/node.cpp: Add more `assert()`ions and validity
	checks to node classes' `asciify()` member functions, eliminate
	unnecessary statements, and more consistently delete node
	objects after `asciify`-ing them.  (The `asciify` request
	modifies a macro/string/diversion--usually a diversion--in
	place.)
	(kern_pair_node::asciify, ligature_node::asciify): `assert()`
	that each of the contained nodes is not a null pointer and do
	not recursively `asciify()` them if they are.
	(asciify_reverse_node_list): `assert()` that macro and node
	pointer arguments are not null, and return early if they are.
	(dbreak_node::asciify): `assert()` that macro pointer argument
	is not null, and do not call `asciify_reverse_node_list()` on it
	if it is.  Also drop dead store (pointless assignment) to member
	variable just before deleting the object.
	(break_char_node::asciify, italic_corrected_node::asciify)
	(left_italic_corrected_node::asciify): `assert()` that macro
	pointer argument is not null, and do not recursively `asciify()`
	it if it is.  Also drop dead store (pointless assignment) to
	member variable just before deleting the object.

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

	* src/roff/troff/node.cpp (class charinfo_node): Make class more
	obviously abstract--the obvious intention of the hierarchy--by
	annotating it and marking member functions (apart from the
	constructor) as `virtual`.

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

	* src/roff/groff/tests/asciify-request-works.sh: Add test cases
	for null transformation (removal) of `\&`, `\(`, `\c`, `.tag`,
	`\X`, and `\v`.

2025-09-11  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Fix.

	* src/devices/gropdf/gropdf.pl (AssignGlyph): Check if the glyph
	has a Unicode value before testing it!!!

	Fixes <https://savannah.gnu.org/bugs/?67501> thanks to Branden
	for the "heads up".

2025-09-11  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Handle TTF->PFB converted fonts better, and restore
	cut'n'paste handling of '\-' mapped to U+2212.

	* src/devices/gropdf/gropdf.pl (FindChr): Some fonts invent
	Unicode Code Points for characters which have no sanctioned UCP,
	use the base UCP.
	(LoadFont): Handle 6 char UCPs.
	(LoadFont, AssignGlyph): Restore functionality of mapping U+2212
	{minus} to U+002D (hyphen) when cutting and pasting from a pdf.
	(Subset): Other 'naughty' fonts use hyphen(s) when assigning a
	postscript name to a glyph (e.g. 'f-f-i'), allow it.

2025-09-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (DOC_GROFF): Move `-M` option that is present only
	for the sake of building "grnexampl.ps" from this macro...
	(doc/grnexampl.ps): ...to this target rule.

2025-09-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	Drop `GROFF_ISC_SYSV3` Autoconf macro.  ISC Unix has been end-
	of-lifed since 2006, per Wikipedia.

	* m4/groff.m4 (GROFF_ISC_SYSV3): Delete.
	* configure.ac: Drop its expansion.

2025-09-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: "Asciify" vertical motion nodes as nothing, suppressing
	non-actionable diagnostic message.  (Vertical motion nodes are
	produced by the `\v` escape sequence and other formatter
	facilities.)

	* src/roff/troff/node.h (class vmotion_node): Declare `asciify`
	member function, thus overriding base class.
	* src/roff/troff/node.cpp (vmotion_node::asciify): New member
	function does "nothing" in the same way that those of
	`line_start_node` and `vertical_size_node`s do: delete the
	`this` object and return.

2025-08-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: "Asciify" device extension nodes as nothing,
	suppressing non-actionable diagnostic message.  (Device
	extension nodes are produced by the `device` and `devicem`
	requests, and the `\X` and `\Y` escape sequences.)

	* src/roff/troff/node.h (class device_extension_node): Declare
	`asciify` member function, thus overriding base class.
	* src/roff/troff/node.cpp (device_extension_node::asciify): New
	member function does "nothing" in the same way that those of
	`line_start_node` and `vertical_size_node`s do: delete the
	`this` object and return.

2025-08-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: "Asciify" tag nodes as nothing, suppressing
	non-actionable diagnostic message.  (Tag nodes are produced by
	the undocumented `tag` request.)

	* src/roff/troff/node.h (class tag_node): Declare `asciify`
	member function, thus overriding base class.
	* src/roff/troff/node.cpp (tag_node::asciify): New member
	function does "nothing" in the same way that those of
	`line_start_node` and `vertical_size_node`s do: delete the
	`this` object and return.

2025-08-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: "Asciify" transparent dummy nodes as nothing,
	suppressing non-actionable diagnostic message.  (The output line
	continuation escape sequence produces a transparent dummy node
	when formatted.)

	* src/roff/troff/node.h (class transparent_dummy_node): Declare
	`asciify` member function, thus overriding base class.
	* src/roff/troff/node.cpp (transparent_dummy_node::asciify): New
	member function does "nothing" in the same way that those of
	`line_start_node` and `vertical_size_node`s do: delete the
	`this` object and return.

2025-08-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: "Asciify" dummy nodes as nothing, suppressing
	non-actionable diagnostic message.  (The dummy character escape
	sequence produces a dummy node when formatted.)

	* src/roff/troff/node.h (class dummy_node): Declare `asciify`
	member function, thus overriding base class.
	* src/roff/troff/node.cpp (dummy_node::asciify): New member
	function does "nothing" in the same way that those of
	`line_start_node` and `vertical_size_node`s do: delete the
	`this` object and return.

	Thanks to Deri James for the discussion and proof of concept.

2025-09-04  G. Branden Robinson <g.branden.robinson@gmail.com>

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

	* src/roff/groff/tests/asciify-request-works.sh: Test
	undiversion of ordinary character and some special character
	types.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2025-09-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (charinfo::dump): Report Unicode
	mapping corresponding to character.

2025-09-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `charinfo` class's member
	function `get_unicode_code()` to `get_unicode_mapping()`.

	* src/roff/troff/charinfo.h (class charinfo): Do it.
	* src/roff/troff/input.cpp (charinfo::get_unicode_code): Rename
	this...
	(charinfo::get_unicode_mapping): ...to this.
	(define_class, charinfo::get_flags): Update call sites.

2025-09-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(read_long_escape_parameters, do_get_long_name)
	(get_delimited_name, do_register_assignment)
	(do_string_assignment): Explicitly cast unused function return
	values to `void`.

2025-09-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/html.tmac:
	* tmac/tty.tmac: Define special character `ru` for device.

2025-08-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (encode_character_for_device_output):
	Add advice to warning diagnostic.

2025-08-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::environment):
	* src/roff/troff/input.cpp: Trivially refactor.  Explicitly
	construct default values of control and escape characters as
	values of `unsigned char` type.

2025-08-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/glyphuni.cpp: Stop mapping the special
	character `ru` (baseline rule) to U+005F.  The Unicode "LOW
	LINE" is a not a baseline rule (while my DEC VT525's character
	set disagrees, the fonts on my GNU/Linux box do not).  `ru` and
	`bs` (the Bell System logo) are the only special characters
	groff internally defines that have no Unicode representation.
	GNU troff offers the `char` request, enabling a document to
	define `\[ru]` as equivalent to `_` if it wishes.

2025-08-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (real_output_file::off): Work around
	internal bug.  Comment out assertion that fails when attempting
	to format our "ms.ms" document for HTML.

	Discovered while looking into Savannah #66653.

2025-08-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Trivially refactor.  `unsigned char`
	is a _numeric_ type, not a character type (properly considered).
	Compare values of this type to unsigned numeric literals, not to
	character literals that are to be used with `char`, which is of
	undefined signedness.  Reorder equality comparisons to avoid
	inadvertent lvalue assignment.
	(troff_output_file::put_char_width, troff_output_file::put_char)
	(glyph_node::get_hyphenation_type, node::asciify)
	(composite_node::dump_properties, make_glyph_node): Do it.
	(charinfo_node::dump_properties): Perform explicit comparison to
	unsigned numeric literal instead of letting its value pun down
	to a Boolean.

2025-08-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Make `-c` option neuter the `color` request.

	* src/roff/troff/input.cpp: Add `permit_color_output` static
	Boolean variable.
	(activate_color): Introduce `is_color_desired` local Boolean.
	If `permit_color_output` is false and color enablement is
	attempted, refuse with an error diagnostic.
	(main): `-c` option configures value of `permit_color_output`
	rather than `want_color_output`.

	* doc/groff.texi.in (Groff Options) <-c>:
	* src/roff/troff/troff.1.man (Options) <-c>:
	* NEWS: Document it.

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

2025-08-28  Dave Kemper <saint.snit@gmail.com>

	* tmac/fallbacks.tmac: Add fallback character definitions for
	more code points from Unicode's General Punctuation code chart.
	- U+2008 PUNCTUATION SPACE
	- U+2012 FIGURE DASH
	- U+202F NARROW NO-BREAK SPACE
	- U+203D INTERROBANG

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

2025-08-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* font/devpdf/devpdf.am: Rationalize use of make(1) macros for
	intelligibility and to fix a missing-prerequisite bug.
	(DEVPDFFONTFILES_FROM_DEVPS): Rename this...
	(devpdffont_descriptions_from_devps): ...to this.  Not all
	"files" are font descriptions, and we need a macro to track only
	the latter.
	(DEVPDFFONTFILES_FOR_URW): Rename this...
	(devpdffont_descriptions_for_urw): ...to this for similar
	reasons.
	(DEVPDFFONTFILES): Rename and rescope this...
	(devpdffontdescriptions): ...to this.  Retain the "SS" font
	description file in its expansion but drop "symbolsl.{afm,pfb}"
	and "download"...
	(devpdffontdata): ...moving them here, along with the expansion
	of `devpdffontdescriptions`.
	(font/devpdf/download): Depend on the expansion of
	`devpdffont_descriptions_from_devps`.

	Fixes <https://savannah.gnu.org/bugs/?67415>.  Thanks to Bjarni
	Ingi Gislason for the report and analysis.  Problem introduced
	{I think--its exposure required "make --shuffle"} by me in
	commit bace292caf, 29 June.

2025-08-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp (table::print_single_hrule): When
	drawing a horizontal rule in a boxed table, also draw vertical
	rules at the table edges in nroff mode such that grotty(1)
	correctly detects horizontal and vertical rule intersections,
	producing correct box-drawing glyphs on the "utf8" device.

	Fixes <https://savannah.gnu.org/bugs/?67420>.  This bug could be
	characterized as an incomplete feature requiring cooperation
	between tbl and grotty.  One could date the problem back to the
	introduction of "utf8" output device support in January 2000
	{released in groff 1.16, May 2000}, or the addition of Unicode
	box-drawing character support to represent rule intersections in
	grotty in July 2003 (released in groff 1.19.1, May 2004).

2025-08-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/tests/boxed-TH-tables-work-on-utf8-device.sh:
	Add test.
	* src/preproc/tbl/tbl.am (tbl_TESTS): Run test.

2025-08-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp (table::print_single_hrule):
	Refactor.  Clarify generated *roff logic by restricting
	performance of operations that are no-ops in nroff mode (type
	size changes and quarter-vee vertical motions) to when the `t`
	*roff condition is true.

2025-08-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/s.tmac: Trivially refactor.
	(@TS, tbl*print-header, TH, TE): Rename diversion
	`tbl*header-div` to `tbl*heading-diversion`.
	([initialization], tbl@top-hook, TH, TE, tbl@bottom-hook):
	Rename register `tbl*have-header` to `tbl*has-heading`.
	(tbl@top-hook, TH): Rename register `tbl*header-ht` to
	`tbl*heading-height`.
	(tbl*print-header): Rename this...
	(tbl*print-heading): ...to this.
	(tbl@top-hook, TH): Update call sites.

2025-08-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/groff.texi.in (Page Geometry):
	* man/roff.7.man (Page geometry): Clarify how the origin of the
	page's coordinate system is determined in the *roff language.

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

2025-08-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/an_paragraph-reset-restores-hyphenation-mode.sh:
	Add test.
	* tmac/tmac.am (tmac_TESTS): Run test.

	Prompted by discussion with Russ Allbery in Savannah #67363.

2025-08-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/ms.ms.in: Fix missing brace escape sequence.

	Fixes <https://savannah.gnu.org/bugs/?67411>.  Continues commit
	ca42eb2c73, 7 August.  Thanks to Bjarni Ingi Gislason for the
	report.

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

	* src/preproc/tbl/table.cpp (table::add_entry): Improve
	diagnostic.  Indexed characters are also valid fodder for the
	`\R` character repetition token.

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

	* doc/ms.ms.in: Revise parameter table layout.  Make it fit
	better on nroff-mode devices.  It now requires 74n instead of
	87n, which makes it good enough for an 80-column terminal.

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

	* doc/ms.ms.in: Reformat nroff-mode page headers.  Stop
	distinguishing recto and verso pages; if formatting in nroff
	mode, we're likely going to a video terminal (or emulator).

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

	* doc/ms.ms.in: Report groff version in page footers.

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

	[ms]: Generate "ms.ms" document from "ms.ms.in".  This way we
	can embed groff's version string in it.

	* doc/ms.ms: Rename this...
	* doc/ms.ms.in: ...to this.
	* doc/doc.am (DOCFILES_INST): Drop "doc/ms.ms".
	(DOCFILES_NOINST): Add "doc/ms.ms.in".
	(GENERATEDDOCFILES): Add "doc/ms.ms".
	(SUFFIXES): Add "ms.in" and ".ms", in that order, duplicating
	the dubious, nonstandard, but apparently portable and effective
	make(1) trick we use for our me(7) manuals.
	(.ms.in.ms): New suffix rule creates "ms.ms" from "ms.ms.in".
	(doc/ms.ps): Revise rule to look for prerequisite in the build
	instead of the source directory.

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

	* tmac/s.tmac ([initialization], pg@top): Alter placement of
	page footer, shifting it upward by one vee, so that the size of
	the "footer margin" (register `FM`) measures as documented, and
	consistently with the "header margin" (register `HM`).  While a
	bug fix, and consistent with DWB 3.3 ms, it is inconsistent with
	Seventh Edition Unix ms and Heirloom Doctools ms.

	* tmac/tests/s_vertical-margins-are-correct.sh: Update test
	expectations.

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

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

	* tmac/tests/s_vertical-margins-are-correct.sh: Add unit test of
	correct vertical margins.
	* tmac/tmac.am (tmac_TESTS): Run test.

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

	* src/utils/afmtodit/afmtodit.pl: Stop throwing duplicate
	mapping warning diagnostics in a handful of cases where we
	expect them.  (All are cases of classical Greek letters
	repurposed for technical applications.)  Per James Cloos, some
	redundant character code points, and thus duplicate Unicode->AGL
	mappings, exist to preserve round-trip compatibility when
	converting between character sets.

2025-08-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/afmtodit/afmtodit.pl: Fix up new diagnostic message
	with proper white space and correct grammar when only one
	duplicate mapping is encountered.

2025-08-03  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[devpdf]: Improve diagnostics from "BuildFoundries" script.

	* font/devpdf/util/BuildFoundries.pl (RunAfmtodit): Diagnose
	return code from running afmtodit.

	Fixes <https://savannah.gnu.org/bugs/?67390> thanks to G.
	Branden Robinson for report and patch.

2025-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/groff_man.7.man.in: Un-deprecate `HP` macro.  Retain
	cautionary language addressing its limited utility.

	Fixes <https://savannah.gnu.org/bugs/?67387>.  Thanks to Alan
	Coopersmith and Thomas Dickey for the discussion in
	<https://gitlab.freedesktop.org/xorg/lib/libxt/-/\
	merge_requests/74> and those evidently silently assenting to
	<https://lists.gnu.org/r/groff/2024-04/msg00118.html>.

2025-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tfmtodit]: Improve usage message upon `--help`.

	* src/utils/tfmtodit/tfmtodit.cpp (usage): Summarize purpose of
	command when help is requested.

2025-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[pfbtops]: Improve usage message upon `--help`.

	* src/utils/pfbtops/pfbtops.c (usage): Summarize purpose of
	command when help is requested.

2025-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[hpftodit]: Improve usage message upon `--help`.

	* src/utils/hpftodit/hpftodit.cpp (usage): Summarize purpose of
	command when help is requested.

2025-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grolbp,grotty,pre-grohtml,preconv,groff]: Slightly refactor.
	Get `usage()` functions out of the business of `exit()`ing,
	which they were doing only in successful cases.  (The calling
	scope `exit()`s with status 2 on usage errors.)  This was
	discrepant with grodvi, post-grohtml, grolj4, grops, eqn, grn,
	pic, refer, soelim, tbl, addftinfo, hpftodit, indxbib, lkbib,
	lookbib, pfbtops, tfmtodit, and xtotroff.

	* src/devices/grolbp/lbp.cpp (usage, main):
	* src/devices/grotty/tty.cpp (main, usage):
	* src/preproc/html/pre-html.cpp (usage, scanArguments):
	* src/preproc/preconv/preconv.cpp (usage, main):
	* src/roff/groff/groff.cpp (main, usage): Do it.

2025-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/grog/grog.pl: Trivially refactor to fix a Perl
	warning.
	(warn): Rename this subroutine...
	(gripe): ...to this.
	(infer_man_or_ms_package, construct_command): Update call sites.

2025-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/grog/grog.pl: Fix code style nit.  Stop using `&`
	sigil in subroutine calls; that's nonidiomatic Perl, an
	exception to the language's otherwise relentless dedication to
	sigil prefixes.

2025-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Trivially refactor.  Rename `an-end` to
	`an*end-document`.

	* tmac/an.tmac (an-end, an*end-document): Do it.
	* tmac/andoc.tmac (reload-doc):
	* tmac/an.tmac (TH): Update call sites.
	* tmac/an.tmac ([initialization]): Configure it under new name.

2025-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Trivially refactor.  Rename `doc-end-macro` to
	`doc-end-document`.

	* tmac/mdoc/doc-common.tmac (doc-end-macro, doc-end-document):
	Do it.
	* tmac/andoc.tmac (reload-man):
	* tmac/mdoc/doc-common.tmac (Dd): Update call sites.
	* tmac/doc.tmac ([initialization]): Configure it under new name.

2025-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/doc.tmac ([initialization]): Configure end-of-input macro
	unconditionally, even on degenerate inputs that never call `Dd`.
	This prevents an insane page length from being used when
	continuous rendering is enabled.
	* tmac/mdoc/doc-common (Dd): Stop doing so here.

	Fixes <https://savannah.gnu.org/bugs/?67385>.  Continues commit
	d8cd70f3a8c, 18 May.  Discovered in conversation with Ingo
	Schwarze.

2025-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/an_degenerate-input-uses-sane-page-length.sh:
	* tmac/tests/doc_degenerate-input-uses-sane-page-length.sh: Add
	tests.
	* tmac/tmac.am (tmac_TESTS): Run tests.

2025-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* font/devpdf/util/BuildFoundries.pl (RunAfmtodit): Run
	`afmtodit` with the new `-q` flag.  Recent versions of the URW
	fonts have tons of duplicate mappings (for groff's purposes) and
	to our knowledge these are all harmless; we don't want to
	distress people attentive to the messages scrolling by in an
	otherwise unremarkable groff build.

2025-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/afmtodit/afmtodit.pl: Add `-q` command-line option
	to suppress diagnostics reporting duplicate mappings in favor of
	a count thereof.  Add new `opt_q` and `duplicate_mappings_count`
	scalars.  Update `GetOptions()` call.  Implement the logic.
	_Don't_ report the flag in the header of the generated file.
	If the option was given and any duplicate mappings were
	encountered, report the count to the standard error stream
	before exiting.
	* src/utils/afmtodit/afmtodit.1.man (Options, Diagnostics):
	Document it.

2025-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/afmtodit/afmtodit.pl: Trivially refactor, renaming
	scalar `prog` to `program_name`.
	(usage): Use that scalar instead of `$0` when reporting
	program's identity.  Drop incorrect annotation.  This new
	behavior is consistent with groff's other installed programs.

2025-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/soelim/soelim.cpp (do_so): Throw warning if input
	document backslash-escapes a space in a `so` token argument.  As
	the diagnostic message notes, doing so is not compatible with
	{any} troff's syntax, and is (now, in GNU soelim and troff)
	unnecessary for handling of spacey file names.

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

	[mdoc]: Make man page rendering more robust against meddling
	with the adjustment mode by individual pages.  In part this is
	to ensure that meddling doesn't persist outside the meddlesome
	document when rendering multiple pages, but it also makes user
	preferences more reliably discernible.  Prompted by a discussion
	with Russ Allbery (about man(7)) in late 2023.

	* tmac/doc.tmac ([initialization]): When rendering a man page,
	this macro file is read before any mdoc(7) document; therefore,
	if the `AD` string is set, we know it was specified on the
	command line or by the "mdoc.local" file.  Stash its value in
	new string `andoc*AD` so it can be recovered after meddling by
	the document.
	* tmac/mdoc/doc-common (Dd): Remove the potentially page-local
	`AD` string when starting a new document, and call
	`an*reset-adjustment-mode` interpolating `andoc*AD` as an
	argument to impose the user's preference (or the package
	default) at each new document.
	(doc-reset-adjustment-mode): New macro assumes responsibility
	for configuring adjustment.  Accept an argument, and if valid,
	assign its contents to the `AD` string.
	(Sh): Configure adjustment _after_ determining formatting
	parameters dependent on the name of the section heading.  Move
	`na` request out of control branch matching the `doc-sec-head`
	and `doc-section-synopsis` strings.  Later, invoke `na` if we're
	in a synopsis section and `doc-reset-adjustment-mode` otherwise.
	(Ss): Invoke `na` if we're in a synopsis section and
	`doc-reset-adjustment-mode` otherwise.

	* tmac/tests/doc_user-preferred-adjustment-restored.sh: Add test
	to verify preservation of user-selected adjustment mode.
	* tmac/tmac.am (tmac_TESTS): Run test.

	Fixes <https://savannah.gnu.org/bugs/?67363> (4/4).  Thanks to
	Russ Allbery for posing the challenge.

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

	[mdoc]: Make man page rendering more robust against meddling
	with the hyphenation mode by individual pages.  In part this is
	to ensure that meddling doesn't persist outside the meddlesome
	document when rendering multiple pages, but it also makes user
	preferences more reliably discernible.  Prompted by a discussion
	{about adjustment in man(7)} with Russ Allbery in late 2023.

	* tmac/doc.tmac ([initialization]): When rendering a man page,
	this macro file is read before any mdoc(7) document:track
	man/mdoc initialization status in new register
	`andoc*is-initialized`.  When initializing, if the `HY` register
	is set, we know it was specified on the command line or by the
	"man.local" file.  Stash its value in new register `andoc*HY` so
	it can be recovered after meddling by the document.
	* tmac/mdoc/doc-common (Dd): Remove the potentially page-local
	`HY` register when starting a new document, and call
	`doc-reset-hyphenation-mode` interpolating `andoc*HY` as an
	argument to impose the user's preference (or the package
	default) at each new document.
	(doc-reset-hyphenation-mode): Accept an argument, and if valid,
	assign its value to the `HY` register.
	(Sh): Configure hyphenation _after_ determining formatting
	parameters dependent on the name of the section heading.  Move
	`nh` request out of control branch matching the `doc-sec-head`
	and `doc-section-synopsis` strings.  Later, invoke `nh` if we're
	in a synopsis section and `doc-reset-hyphenation-mode`
	otherwise.
	(Ss): Invoke `nh` if we're in a synopsis section and
	`doc-reset-hyphenation-mode` otherwise.  As a side effect, this
	subjects subsection headings to hyphenation.  (Section headings
	produced by the `Sh` macro already were.)

	* tmac/tests/doc_hyphenation-mode-restoration-works.sh: Add test
	to verify preservation of document- and user-selected
	hyphenation modes.
	* tmac/tmac.am (tmac_TESTS): Run test.

	Fixes <https://savannah.gnu.org/bugs/?67363> (3/4).  Thanks to
	Russ Allbery for posing the challenge.

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

	[man]: Make man page rendering more robust against meddling with
	the adjustment mode by individual pages.  In part this is to
	ensure that meddling doesn't persist outside the meddlesome
	document when rendering multiple pages, but it also makes user
	preferences more reliably discernible.  Prompted by a discussion
	with Russ Allbery in late 2023.

	* tmac/an.tmac ([initialization]): When rendering a man page,
	this macro file is read before any man(7) document: therefore,
	when interpreting a man page package macro file for the first
	time (which we know thanks to the `andoc*is-initialized`
	register), if the `AD` string is set, we know it was specified
	on the command line or by the "man.local" file.  Stash its value
	in new string `andoc*AD` so it can be recovered after meddling
	by the document.
	(an*reset-adjustment-mode): New macro assumes responsibility for
	configuring adjustment.  Accept an argument, and if valid,
	assign its contents to the `AD` string.
	(an*reset-paragraph-parameters): Stop manipulating adjustment in
	favor of calling the new macro.
	(TH): Remove the potentially page-local `AD` string when
	starting a new document, and call `an*reset-adjustment-mode`
	interpolating `andoc*AD` as an argument to impose the user's
	preference (or the package default) at each new document.

	* tmac/tests/an_adjustment-mode-restoration-works.sh: Add test
	to verify preservation of document- and user-selected adjustment
	mode.
	* tmac/tmac.am (tmac_TESTS): Run test.

	Fixes <https://savannah.gnu.org/bugs/?67363> (2/4).  Thanks to
	Russ Allbery for posing the challenge.

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

	[man]: Make man page rendering more robust against meddling with
	the hyphenation mode by individual pages.  In part this is to
	ensure that meddling doesn't persist outside the meddlesome
	document when rendering multiple pages, but it also makes user
	preferences more reliably discernible.  Prompted by a discussion
	{about adjustment} with Russ Allbery in late 2023.

	* tmac/an.tmac ([initialization]): When rendering a man page,
	this macro file is read before any man(7) document: track
	man/mdoc initialization status in new register
	`andoc*is-initialized`.  When initializing, if the `HY` register
	is set, we know it was specified on the command line or by the
	"man.local" file.  Stash its value in new register `andoc*HY` so
	it can be recovered after meddling by the document.
	(an*reset-hyphenation-mode): Accept an argument, and if valid,
	assign its value to the `HY` register.
	(TH): Remove the potentially page-local `HY` register when
	starting a new document, and call `an*reset-hyphenation-mode`
	interpolating `andoc*HY` as an argument to impose the user's
	preference (or the package default) at each new document.

	* tmac/tests/an_hyphenation-mode-restoration-works.sh: Add test
	to verify preservation of document- and user-selected
	hyphenation mode.
	* tmac/tmac.am (tmac_TESTS): Run test.

	Fixes <https://savannah.gnu.org/bugs/?67363> (1/4).  Thanks to
	Russ Allbery for posing the challenge.

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

	* src/preproc/html/pre-html.cpp (get_resolution)
	(get_image_generator): Read devices' "DESC" files as libgroff
	does and as documented in groff_font(5) (and CSTR #54 [1992]);
	upon encountering a "charset" directive, we stop interpreting
	directives.

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

	* src/preproc/html/pre-html.cpp (get_line): Clear heap-allocated
	memory and annotate how we could do so in-language in C++03.

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

	* src/preproc/html/pre-html.cpp (get_resolution)
	(get_image_generator): Fix off-by-one errors in line counting.

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

	* doc/groff.texi.in (Debugging): Expand `ab`, `fl` discussion.

	Fixes <https://savannah.gnu.org/bugs/?67380>.  Thanks to Dave
	Kemper for bringing details of `ab` behavior to my attention.

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

	[troff]: Make `pev` request report previous and current stroke
	and fill colors.  They are properties of the environment, this
	request already reports plenty of data that are otherwise
	available via built-in registers, and the _previous_ values
	thereof are not thus exposed.

	* src/roff/troff/env.h (class environment): Declare new public
	member functions `get_prev_stroke_color_string()` and
	`get_prev_fill_color_string()`.
	* src/roff/troff/env.cpp
	(environment::get_prev_stroke_color_string):
	(environment::get_prev_fill_color_string): Define them.
	(environment::dump): Report the data.

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

	* src/roff/troff/env.cpp: Trivially refactor, continuing naming
	reform of functions that are troff request handlers and that
	list objects or properties thereof.  Also mark these request
	handlers as `static` since they do not require external linkage.
	(fill_color_change): Rename this...
	(select_fill_color_request): ...to this...
	(stroke_color_change): ...and this...
	(select_stroke_color_request): ...to this...
	(override_sizes): ...and this...
	(override_available_type_sizes_request): ...to this...
	(set_tabs): ...and this...
	(configure_tab_stops_request): ...to this.

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

	* font/devpdf/devpdf.am (font/devpdf/download): Drop `--strict`
	option from rule command.  The `BuildFoundries` script no longer
	supports it.

	Fixes <https://savannah.gnu.org/bugs/?67366>. Thanks to Bjarni
	Ingi Gislason for the report.

2025-07-27  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Error reporting.

	* src/devices/gropdf/gropdf.pl (GetType1, GetChunk): Perform
	rudimentary check we are given an Adobe type 1 font, and die
	immediately if binary format invalid. Include font filename
	in error messages.

	Fixes <https://savannah.gnu.org/bugs/?67295>. Thanks to
	G. Branden Robinson for report.

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

	* tmac/an.tmac: Refactor.
	(an*reset-text-parameters): New macro configures the type size
	and vertical spacing registers, a task formerly done by `TH`,
	and (re-)sets the font style, type size, and vertical spacing, a
	task formerly done by `an*reset-paragraph-parameters`, `TH`, and
	`an*input-trap`.
	(an*reset-paragraph-parameters, TH, an*input-trap): Call new
	macro instead of doing the work ourselves.

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

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

	[man]: Unit-test handling of degenerate documents.

	* tmac/tests/an_degenerate-documents-work.sh: Add test.
	* tmac/tmac.am (tmac_TESTS): Run test.

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

	[man]: Unit-test `S` register behavior.

	* tmac/tests/an_S-register-works.sh: Add test.
	* tmac/tmac.am (tmac_TESTS): Run test.

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

	* tmac/an.tmac (an*input-trap): Stop calling
	`an*reset-paragraph-parameters`, instead invoking `ft`, `ps`,
	and `vs` directly.  The former macro is indeed responsible for a
	"paragraph reset", but this input trap is also (and
	predominantly) used by macros that perform "inline" style
	changes (`B`, `I`, `SM`, and so on).  A paragraph reset can
	alter adjustment and hyphenation modes, and we _don't_ want that
	here--it makes synopses format incorrectly.

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

	* tmac/tests/an-ext_synopses_do_not_automatically_adjust.sh: Add
	test.
	* tmac/tmac.am (tmac_TESTS): Run it.

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

	* tmac/tests/an-ext_synopses_do_not_automatically_hyphenate.sh:
	Add test.
	* tmac/tmac.am (tmac_TESTS): Run it.

2025-07-24  Deri James  <deri@chuzzlewit.myzen.co.uk>

	* font/devpdf/util/BuildFoundries.pl: If any warnings issued
	during run, exit code 2 at end of run. This will abort any
	build. Change to Notice any information only messages.
	Remove code which copied grops fonts to gropdf (Branden added
	this to devpdf.am so is now unnecessary).

	* src/devices/gropdf/gropdf.pl: Exit with code 2 if any
	warnings issued during run (this will stop a 'make'). Report
	a 'Notice' if duplicate font entries and 1 is incorrect.
	Report path of download file in messages.

	* src/devices/gropdf.1.man: Document exit status.

	* contrib/mom/mom.am:
	* doc/doc.am: -W flag no longer required

	Continues fixing Savannah #67207 and #67268.

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

	* tmac/an.tmac ([initialization]):
	* tmac/doc.tmac ([initialization]): Parallelize loading of
	site-local customization.  Use `msoquiet`, but only if it's
	available--that way we avoid a hard dependency on groff 1.23 or
	later.  If not, use `mso` as groff 1.22.4 and earlier did.

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

	* tmac/mdoc/doc-common (Sh, Ss): Fix missing brace escape
	sequences.

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

	[mdoc]: Refactor to simplify hyphenation handling.

	* tmac/mdoc/doc-common (doc-reset-hyphenation-mode): Refactor to
	simplify.  Now that continuous rendering mode is handled via a
	humongous page length, it's no longer necessary for this macro
	package to use a different hyphenation mode in continuous
	rendering mode.  (It formerly was, because the [invisible]
	bottom of each output page had what our documentation terms an
	"implicit page trap", causing hyphenation to be suppressed on
	some output lines for no obvious reason.)  We no longer have to
	dance around that: kill the logic for it.

	* tmac/tests/localization-works.sh: Add test cases for use of
	mdoc with every locale supported by groff.

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

	[mdoc]: Refactor hyphenation mode handling.

	* tmac/doc.tmac: Refactor.
	([initialization]): Stop assigning `HY` register a default value
	if it's unspecified by the user (on the command line or via
	"man.local").
	(doc-reset-args): Stop resetting hyphenation mode here;
	replacing it with a call to `doc-reset-hyphenation-mode` causes
	infinite macro recursion.  (Will this bite us later?)
	(doc-print-reference): Call `doc-reset-hyphenation-mode` instead
	of manipulating automatic hyphenation mode directly.
	* tmac/mdoc/doc-common ([initialization]): Drop logic that sets
	up `doc-hyphen-flags` register, which we're retiring in favor of
	a new macro.
	(Dd, Nd): Call `doc-reset-hyphenation-mode`.  The lack of a
	hyphenation mode reset in the latter macro was apparently an
	oversight, caught by a forthcoming automated test.
	(doc-reset-hyphenation-mode): New macro works if the `HY`
	register is not defined.  Use new local register
	`doc-want-hyphenation` to determine which hyphenation mode
	ultimately gets set (that of the locale, or zero).  Remove
	register when done.
	(Sh): Call `doc-reset-hyphenation-mode` instead of manipulating
	automatic hyphenation mode directly.

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

	[mdoc]: Disable hyphenation less aggressively.

	* tmac/doc.tmac (doc-parse-args, doc-parse-arg-vector)
	(doc-enclose-close, doc-inset-list, doc-hang-list)
	(doc-ohang-list, doc-diag-list, doc-tag-list, Fc)
	(doc-print-reference): Stop invoking `nh` request.  This
	package's bespoke internal macro reprocessing system
	aggressively exercises Savannah #67310 (a missing feature in the
	formatter); with these requests in place, automatic hyphenation
	was getting disabled in far more places than it should have
	been, and because there appears to be no mechanism for
	reënabling it when departing the appropriate nested scope, it's
	simpler to just stop trying.  Making this change had little
	effect on formatting of groff_mdoc(7), except for the following.
	  {1} URL link text, when it was the URL itself (as on output
	      devices that don't support hyperlinking) was undesirably
	      hyphenated, but see below;
	  {2} text not otherwise marked up between `Rs` and `Re` macros
	      is now subject to automatic hyphenation; and
	  {3} text marked with the `Me` macro is now subject to
	      automatic hyphenation.
	Changes {2} and {3} seem correct.
	(Lk): Macro now does what more mdoc(7) documents should probably
	have already been doing: employ the `\%` escape sequence in
	appropriate places.  (Alternatively, those who enjoy mandoc(1)'s
	approach can disable automatic hyphenation altogether at
	formatting time by setting the `HY` register to zero in
	"mdoc.local" or on the command line.)  This change eliminates
	the one regression noted above.

	* tmac/tests/doc_indents-correctly.sh: Update test expectations,
	now that (sub)section headings that are so long that they break
	can also hyphenate.

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

	* tmac/mdoc/doc-common (Sh): Fix missing brace escape sequence.

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

	* tmac/mdoc/doc-common (Sh): Stop disabling adjustment in troff
	mode in "See also" sections.  That seemed like an odd choice;
	typically, adjustment is uglier in _nroff_ mode, not troff mode.

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

	* tmac/mdoc/doc-syms (doc-str-Lb-*): Protect literals from
	hyphenation, in preparation for a planned change to make the
	mdoc(7) package employ `nh` requests less promiscuously.

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

	* tmac/an.tmac: Refactor adjustment management.
	(TH): Stop handling adjustment here, instead relying on
	`an*reset-paragraph-parameters`.
	([initialization]): Stop assigning `AD` string a default value
	if it's unspecified by the user (on the command line or via
	"man.local").

	* tmac/tests/\
	an_adjustment-mode-preserved-after-paragraph-tag.sh: Revise test
	expectations.

	* man/groff_font.5.man: Stop assuming `AD` string is defined in
	a hairy bit of typesetting.

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

	* tmac/an.tmac (an*reset-paragraph-parameters): Call
	`an*reset-hyphenation-mode`.
	(TH): Stop calling `an*reset-hyphenation-mode`.
	* tmac/groff_man.7.man.in (Paragraphing macros): Document
	paragraphing macros' restoration of configured hyphenation mode.

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

	* tmac/an.tmac: Refactor to simplify.
	(an*reset-hyphenation-mode): Now that continuous rendering mode
	is handled via a humongous page length, it's no longer necessary
	for this macro package to use a different hyphenation mode in
	continuous rendering mode.  (It formerly was, because the
	{invisible} bottom of each output page had what our
	documentation terms an "implicit page trap", causing hyphenation
	to be suppressed on some output lines for no obvious reason.)
	We no longer have to dance around that: kill the logic for it.

	* tmac/tests/localization-works.sh: Drop sensitivity to
	continuous rendering mode.

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

	* tmac/an.tmac: Refactor.
	(an*reset-hyphenation-mode): Update to work if the `HY` register
	is not defined.  Use new local register `an*want-hyphenation` to
	determine which hyphenation mode ultimately gets set (that of
	the locale, or zero).  Remove register when done.
	([initialization]): Stop assigning `HY` register a default value
	if it's unspecified by the user (on the command line or via
	"man.local").

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

	* tmac/an.tmac: Refactor.
	(an*reset-paragraph-parameters): New macro resets the font
	style, type size, and vertical spacing, but not the line length.
	(TH, an*input-trap, an*break-paragraph): Call it instead of
	invoking the corresponding requests directly.
	(TH, P, HP): Reset line length to configured `LL` register
	value.
	(TH): Reset indentation to zero.  A well-formed man(7) document
	formats no text between a `TH` call and an `SH` call, but a
	predictable indentation is useful for crafting test cases.

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

	* tmac/an.tmac: Refactor.
	(an*reset-section-parameters): Perform restoration of configured
	font family for body text here...
	(TH, SH, SS): ...instead of here.

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

	* tmac/tests/an_paragraph-reset-preserves-line-length.sh: Add
	test.
	* tmac/tmac.am (tmac_TESTS): Run it.

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

	* tmac/an.tmac (TH): Rationalize; organize register and string
	initialization before macro calls and requests that alter
	formatting parameters.

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

	* tmac/an.tmac: Slightly refactor.
	(TH, SH, SS): Rearrange macro calls to place
	`an*reset-section-parameters` before calls of macros that adjust
	formatting parameters of smaller scope.  This should (and, per
	our automated tests, does) produce no behavioral changes; it's
	for clarity to macro package maintainers and source divers.

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

	* tmac/an.tmac: Trivially refactor, continuing a name space
	reform in progress since 2022.
	(an-break-paragraph): Rename this...
	(an*break-paragraph): ...to this...
	(an-reset-paragraph-spacing): ...and this...
	(an*reset-paragraph-spacing): ...to this...
	(an-reset-margin-and-inset-level): ...and this...
	(an*reset-section-parameters): ...to this...
	(an-reset-tab-stops): ...and this...
	(an*reset-tab-stops): ...to this...
	(an-input-trap): ...and this...
	(an*input-trap): ...to this.

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

	* src/devices/grolj4/lj4.cpp (lookup_paper_size): Return
	type-correct constructed values.

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

	* font/scripts/gendesc.sh:
	* font/scripts/genfonts.sh: Fix shell style nits.  Stop using
	semicolons to simulate K&R C brace style.

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

	* font/scripts/gendesc.sh:
	* font/scripts/genfonts.sh: Exit with status 2, not 255, on
	usage error.  The latter value is not good practice per
	POSIX--shells use the eighth bit of the exit status to indicate
	that a signal was received.

	See <https://pubs.opengroup.org/onlinepubs/9799919799/\
	utilities/V3_chap02.html#tag_19_08_02>.

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

	* font/scripts/gendesc.sh:
	* font/scripts/genfonts.sh: Prevent recurrence of previous
	problem by computing the basename of the script file, storing it
	in a variable `progname`, and using that variable in
	diagnostics.

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

	* font/scripts/gendesc.sh: Fix copy and paste error causing
	script's error diagnostic to misreport its own name.

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

	[troff]: Trivially refactor, continuing naming reform of
	functions that are troff request handlers and which lists of
	objects or properties thereof.  Revert to using `print` for
	{debugging} request handlers, and reserve `dump` for member
	functions of classes.  (One might use the latter from within
	GDB, for example.)

	* src/roff/troff/env.cpp:
	(dump_environment_request): Rename this...
	(print_environment_request): ...to this...
	(dump_pending_output_line_request): ...and this...
	(print_pending_output_line_request): ...to this.
	(init_env_requests): Update request handler setup.
	* src/roff/troff/input.cpp:
	(set_character_flags): Rename this...
	(set_character_flags_request): ...to this...
	(warn_request): ...and this...
	(set_warning_mask_request): ...to this.
	(init_input_requests): Update request handler setup.
	* src/roff/troff/node.cpp:
	(dump_font_mounting_positions_request): Rename this...
	(print_font_mounting_position_request): ...to this...
	(dump_font_translations): ...and this...
	(print_font_translation_request): ...to this.
	(init_node_requests): Update request handler setup.
	* src/roff/troff/reg.cpp:
	(dump_register_request): Rename this...
	(print_register_request): ...to this.
	(init_reg_requests): Update request handler setup.

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

	* src/roff/troff/env.cpp (environment::dump): Flush the standard
	error stream after writing an environment's properties to it.

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

	* src/roff/troff/input.cpp (print_macros, get_flags)
	(charinfo::get_flags): Use explicit `reinterpret_cast` C++
	operator instead of C-style cast.  Annotate why we use this
	footgun.

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

	* tmac/eqnrc: Drop unneccessary setup.  Since commit 4b3e5417d5,
	18 February 2017, GNU eqn self-serves by synthesizing
	conditional empty fallback definitions of `EQ` and `EN` in its
	output.

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

	[pic]: Stop validating non-intepreted input for character codes
	acceptable to GNU troff.

	* src/preproc/eqn/main.cpp (top_input::get, top_input::peek)
	(do_file): Stop diagnosing errors on and discarding GNU
	troff-invalid input characters in portions of the input that are
	passed through without alteration.  pic, like eqn, grn, refer,
	soelim, and tbl, is a _filter_.  Its job is to transform only
	_part_ of its input stream and leave the rest unaltered.

	* src/preproc/pic/tests/\
	passes-through-input-with-eighth-bit-set.sh: Add test.
	* src/preproc/pic/pic.am (pic_TESTS): Run test.

	Continues fixing Savannah #67285.

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

	* src/utils/addftinfo/addftinfo.cpp: Fix code style nits.  Give
	the anonymous `struct` type used for `param_table` a name,
	`parameter`, so it can be passed to a template function
	C++98-conformantly.
	(main): Use `array_length()` on `param_table` instead of
	`sizeof` and division.

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

	* src/preproc/refer/label.ypp: Give the anonymous `struct` types
	used for `dig` and `str` names, so that they can be passed to a
	template function C++98-conformantly.  Lamely, apply an `_s`
	suffix to the object names to create the type names.

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

	* src/preproc/preconv/preconv.cpp: Fix code style nits.  Spell
	null pointer constant the idiomatic C++98 way (`0`) instead of
	as `NULL`.  Boolify: demote global variable `raw_flag` from
	`int` to `bool`, and rename it to `want_raw_output`.
	(get_BOM): Give the anonymous `struct` type used for `BOM_table`
	a name, and move it into the global scope (it was already
	`static`), so that it can be passed to a template function
	C++98-conformantly.  Use `array_length()` on `BOM_table` instead
	of `sizeof` and division.
	(is_comment_line, do_file): Demote return type from `int` to
	`bool`, and return Boolean rather than integer literals.
	(do_file): Boolify: demote variable `must_free_encoding` from
	`int` to `bool`, and assign Boolean rather than integer literals
	to it.  Demote variable `success` from `int` to `bool`, rename
	it to `was_successful`, and assign Boolean rather than integer
	literals to it.
	(emacs2mime, check_coding_tag, detect_file_encoding, do_file)
	(main): Explicitly compare values of pointer type to null
	pointer literals instead of letting them pun down to Booleans.
	(conversion_iconv, do_file): Favor C++ `static_cast<>` and
	`const_cast<>` operators over omnipotent C-style casts.
	(conversion_iconv, main): Parenthesize (formally) complex
	pexpressions.
	(do_file): Assign character rather than integer literal to
	element of `char` array.

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

	* src/preproc/pic/pic.ypp (object_spec): Revert "workaround for
	bug in Compaq C++ V6.5-033 for Compaq Tru64 UNIX V5.1A (Rev.
	1885)" on the assumption that this compiler version has reached
	its end-of-support date.

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

	* src/preproc/pic/pic.ypp: Fix code style nit.  Give the
	anonymous `struct` types used for `pair`, `if_data`, `lstr`,
	`dv`, and `by` name, so that they can be passed to a template
	function C++98-conformantly.  Lamely, apply an `_s` suffix to
	the object names to create the type names.

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

	* src/preproc/eqn/lex.cpp: Fix code style nits.  Sort libgroff
	header files before program-specific ones.  Give the anonymous
	`struct` type used for `token_table` a name, so that it can be
	passed to a template function C++98-conformantly.
	(init_table): Use `array_length()` on `token_table`,
	`common_defs`, `troff_defs`, and `mathml_defs` instead of
	`sizeof` and division.

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

	* src/libs/libgroff/font.cpp: Fix code style nits.  Give the
	anonymous `struct` type used for `table` a name, so that it
	can be passed to a template function C++98-conformantly.  Give
	`table` a better name: `numeric_directive_table`.  Now that
	their enclosures have better names, give the `numeric_directive`
	`struct` element `numeric_directive` the better name `name`.
	(font::load_desc): Track renames.  Use a `size_t` as the loop
	index.  Parenthesize (formally) complex pexpressions.  Use
	`array_length()` on `numeric_directive_table` instead of
	`sizeof` and division.

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

	* src/devices/grolj4/lj4.cpp (lookup_paper_size): Sanity-check
	the size of the `paper_table` array.  It's statically defined,
	so only hacking on the source can violate the invariant.

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

	* src/devices/grolj4/lj4.cpp: Relocate definition of
	`lookup_paper_size()`, eliminating need for forward declaration.

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

	* src/devices/xditview/DviP.h: Fix code style nit.  Give the
	anonymous `struct` type used for `DviPart` a name, so that it
	can be passed to a template function C++98-conformantly.

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

	* src/devices/grolj4/lj4.cpp: Fix code style nits.  Give the
	anonymous `struct` type used for `paper_table` a name, so
	that it can be passed to a template function C++98-conformantly.
	(lookup_paper_size): Use a `size_t` as the loop index.  Use
	`array_length()` on `paper_table` instead of `sizeof` and
	division.  Change return type to `ssize_t` so that we can
	continue to return `-1` meaning "not found".
	(main): Change type of local variable `n` to match altered
	return type of `lookup_paper_size()`.

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

	* src/devices/grolbp/lbp.cpp: Fix code style nits.  Give the
	anonymous `struct` type used for `lbp_papersizes` a name, so
	that it can be passed to a template function C++98-conformantly.
	(set_papersize): Use `array_length()` on `lbp_papersizes`
	instead of `sizeof` and division.
	(wp54charset, lbp_printer::vdmflush): `sizeof` is an operator,
	not a function, so don't parenthesize its operand when it's an
	lvalue (as opposed to a type name).

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

	[troff]: Catch `std::bad_alloc` exceptions from `new` operator.
	Throw a fatal error indicating how much memory we couldn't
	allocate.

	* src/roff/troff/input.cpp (read_long_escape_parameters)
	(do_get_long_name, get_delimited_name): Do it.

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

	* src/roff/troff/input.cpp: Refactor to simplify.  As an
	apparent optimization (dating back as far as groff 1.02, 1991)
	parts of the input parser that needed to read arbitrarily far
	ahead in the input stream to consume a token used an initial
	stack-allocated buffer of 16 bytes.  (Also known as "automatic"
	storage, thus the name "abuf", I think.)  If 16 bytes wasn't
	enough, open-coded logic would allocate a buffer from the heap
	and double it in size until the token fit.  Simplify by
	converting `ABUF_SIZE` from a preprocessor macro to a `const`
	symbol named `default_buffer_size`, and _always_ allocate from
	the heap.  In the future, we can convert stuff like this to a
	C++ STL `vector` and let the standard library worry about
	dynamic storage management.
	(read_long_escape_parameters, do_get_long_name)
	(get_delimited_name): Do it.

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

	* src/roff/troff/input.cpp: Fix code style nits.
	(read_long_escape_parameters, read_escape_parameter)
	(do_get_long_name): Parenthesize (formally) complex expressions.
	Reorder equality comparisons to avoid inadvertent lvalue
	assignment.  Compare objects of `char` type to character, not
	integer, literals.

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

	* src/roff/troff/input.cpp (read_long_escape_parameters):
	Slightly refactor.  Test for an empty argument (or argument
	sequence) earlier, before worrying about whether the input
	buffer just populated is still the stack-allocated one or was
	relocated to the heap.  This is to facilitate a simplification
	of input buffer management.

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

	* src/roff/troff/input.cpp (read_rest_of_line_as_argument):
	Trivially refactor.  Rename local variable `len` to `buf_size`,
	for consistency with several other functions in this file that
	handle memory buffers.  Reorder equality comparisons to avoid
	inadvertent lvalue assignment.  Parenthesize (formally) complex
	expressions.

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

	* src/preproc/html/pre-html.cpp (get_line): Catch
	`std::bad_alloc` exceptions from `new` operator.  Throw a fatal
	error indicating how much memory we couldn't allocate and which
	line of which file we were reading when we had trouble.

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

	* src/preproc/html/pre-html.cpp (get_resolution)
	(get_image_generator): Track the line number in the files we
	read to process the "resolution" and "image_generator"
	directives (see groff_font(5)).  Pass the line number and
	resolved file name for the file thus opened to `get_line()`.
	(get_line): Update definition to accept these new arguments.
	{We don't yet do anything with them.}

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

	* src/preproc/html/pre-html.cpp (get_resolution)
	(get_image_generator): Slightly refactor.  Free `pathp` _after_
	we've looped through all the lines in the file we've opened
	instead of before.  This is to prepare for a change where we
	pass `pathp` to `get_line()` as a new argument.

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

	* src/preproc/html/pre-html.cpp (get_line): Slightly refactor.
	Use named variables more and constant literals less.

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

	* src/preproc/html/pre-html.cpp (get_line): Fix code style nits.
	Boolify: demote return type from `int` to `bool`, and return
	Boolean rather than integer literals.  Mark as `static` since
	this function requires no external linkage.  Reorder equality
	comparisons to avoid inadvertent lvalue assignment.

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

	[libgroff, eqn, pic, refer, soelim, tbl]: Trivially
	refactor.  Rename `interpret_lf_args()` library function to
	`interpret_lf_request_arguments()` so that its purpose is
	obvious.

	* src/include/lf.h:
	* src/libs/libgroff/lf.cpp: Rename it.

	* src/preproc/eqn/main.cpp (do_file):
	* src/preproc/pic/main.cpp (do_file):
	* src/preproc/refer/refer.cpp (do_file):
	* src/preproc/soelim/soelim.cpp (do_file):
	* src/preproc/tbl/main.cpp (process_input_file, process_data):
	Update call sites.

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

	[libgroff, eqn, pic, preconv, refer, soelim, tbl]: Trivially
	refactor.  Rename `normalize_for_lf()` library function to
	`normalize_file_name_for_lf_request()` so that its purpose and
	argument are obvious.

	* src/include/lf.h:
	* src/libs/libgroff/lf.cpp: Rename it.

	* src/preproc/eqn/main.cpp (main):
	* src/preproc/pic/main.cpp (main):
	* src/preproc/preconv/preconv.cpp (do_file):
	* src/preproc/refer/refer.cpp (do_file):
	* src/preproc/soelim/soelim.cpp (do_file):
	* src/preproc/tbl/main.cpp (main):
	* src/preproc/tbl/table.cpp (set_troff_location): Update call
	sites.

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

	* src/libs/libgroff/font.cpp (text_file::next_line): Handle
	ludicrously long input line lengths by diagnosing the problem
	and cleanly aborting.

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

	* src/libs/libgroff/font.cpp (text_file::next_line): Trivially
	refactor.  Reorder equality comparisons to avoid inadvertent
	lvalue assignment.

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

	Retire our `strerror()` implementation.  It was specified in
	ANSI C89, we require ISO C99 anyway, and on top of that we use
	gnulib's "strerror" module to patch any egregious hole of that
	name on any host system.

	* src/libs/libgroff/strerror.c: Delete it.
	* src/libs/libgroff/libgroff.am (EXTRA_DIST): Stop shipping it.

	Continues fixing Savannah #66518.

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

	* [grn,soelim,tbl]: Add tests verifying pass-through of 8-bit
	input.

	* src/preproc/grn/tests/\
	passes-through-input-with-eighth-bit-set.sh: Add test.
	* src/preproc/grn/grn.am (grn_TESTS): Run test.
	(TESTS): Add test to suite.
	(EXTRA_DIST): Ship test in distribution archive.

	* src/preproc/soelim/tests/\
	passes-through-input-with-eighth-bit-set.sh: Add test.
	* src/preproc/soelim/soelim.am (soelim_TESTS): Run test.

	* src/preproc/tbl/tests/\
	passes-through-input-with-eighth-bit-set.sh: Add test.
	* src/preproc/tbl/tbl.am (tbl_TESTS): Run test.

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

	* src/preproc/soelim/soelim.am (soelim_TESTS): Actually run the
	test we added back in November to fix Savannah #66027.

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

	* src/preproc/eqn/main.cpp (read_line): Revise fix for Savannah
	#67285; stop tracking whether a *roff comment has been seen in
	the input, and thus stop throwing an invalid character
	diagnostic under any circumstance (within this function;
	"lex.cpp" continues to, when interpreting eqn input proper).
	The idea is that eqn, like grn, pic, refer, soelim, and tbl, is
	a _filter_.  Its job is to transform only _part_ of its input
	stream and leave the rest unaltered.

	* src/preproc/eqn/tests/\
	diagnostics-report-correct-line-numbers.sh: Comment out now-
	inapplicable checks.

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

	* tmac/de.tmac (_td_format) [@R]: Fix German date localization
	for me(7) package; don't put a dot after the month name.

	* tmac/tests/e_ld-works.sh: Update test expectations.

	Fixes <https://savannah.gnu.org/bugs/?67303>.  Thanks to Stefan
	Möding for the report and patch.  Problem appears to date back
	to the introduction of German localization to groff, in commit
	9ed99d14cb, 19 December 2006.

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

	* doc/doc.am: Rationalize Texinfo document installation targets.
	(install-txt-local)
	(install-info-local)
	(install-dvi-local)
	(install-pdf-local)
	(install-html-local): Name as prerequisites (only) the macros
	conditionally populated when `HAVE_MAKEINFO` and `USE_TEX` are
	defined.  Thus we (re)build each document only if we can
	actually do so.  If not, the user gets the "stock" version from
	distribution archive.

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

	* doc/doc.am: Trivially refactor.  Rename `install_infodoc`
	target to `install-info-local` and `install-txt` to
	`install-txt-local` for consistency with
	`install-{dvi,pdf,html}-local`.

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

	[devpdf]: Ship AFM file for slanted symbol font.

	* font/devpdf/devpdf.am (DEVPDFFONTFILES): Add it.
	(EXTRA_DIST): Distribute its (contrived) ".in" file.
	($(devpdf_builddir)/symbolsl.afm): Add rule to contrive it.

	* src/devices/gropdf/gropdf.1.man (Files): Document it.

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

	[devpdf]: Add Makefile script for regenerating slanted symbol
	font.

	* font/devpdf/generate/Makefile: New file (re)creates AFM and
	PFB files for slanted symbol font from SFD source.  We emplace
	the files with ".in" suffixes so that they'll work with the
	groff build process in both in-tree and out-of-tree scenarios.
	* font/devpdf/generate/symbolsl.sfd: Update metadata to credit
	Deri with modifications.
	* font/devpdf/symbolsl.afm.in: New file.

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

	[devpdf]: Rename slanted symbol font.  It's not a standard PDF
	font, so it's less misleading to omit "Standard" from its name.

	* font/devpdf/generate/StandardSymSL.sfd: Rename this...
	* font/devpdf/generate/symbolsl.sfd: ...to this...
	* font/devpdf/StandardSymSL.pfb.in: ...and this...
	* font/devpdf/symbolsl.pfb.in: ...to this.
	* font/devpdf/devpdf.am (DEVPDFFONTFILES): Update macro
	definition.
	(EXTRA_DIST): Update macro appendment.
	($(devpdf_builddir)/StandardSymSL.pfb): Rename target from
	this...
	($(devpdf_builddir)/symbolsl.pfb): ...to this.  Update
	prerequisite and rule to use new names.

	* font/devpdf/download.in: Update embeddable font file name.

	* src/util/pfbtops/tests/smoke-test.sh: Update test.

	* src/devices/gropdf/gropdf.1.man (Files): Reflect rename.

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

	* src/devices/gropdf/gropdf.pl (LoadFont): Tweak warning
	diagnostic emitted when a "download" file entry is invalid
	{typically because the font file named there doesn't exist}.

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

	* src/utils/afmtodit/afmtodit.pl: Fix missing word in fatal
	diagnostic message.

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

	* src/devices/gropdf/gropdf.pl (LoadDownload): Trivially
	refactor.  Rename scalar `anyDownloadFilefound` to
	`anyDownloadFileFound` for proper camel casery.

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

	[troff]: Trivially refactor, continuing naming reform of
	functions that are troff request handlers such that their names
	end with `_request`, and of member functions that write class
	object data to the standard error stream to `dump`.

	* src/roff/troff/env.h (class environment): Rename public member
	function `print_env` to `dump` in declaration.

	* src/roff/troff/env.cpp (environment::print_env): Rename
	this...
	(environment::dump): ...to this in definition.
	(dump_environment_request): Update call sites.
	(print_nodes_from_input_line): Rename this...
	(dump_pending_output_line_request): ...to this.
	(init_env_requests): Track latter rename in handler setup.

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

	* src/roff/troff/env.cpp (environment::print_env): Tweak output;
	describe current and previous font selections as "resolved",
	since if the font position of an abstract style is selected,
	that's not what shows up here, because the abstract style is
	combined with the default family.

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

	[eqn]: Fix Savannah #67285.

	* src/preproc/eqn/main.cpp (read_line): Stop discarding invalid
	input characters, as this function doesn't know whether we're
	reading an eqn region.  Keep track of whether we've seen the
	default *roff escape character (`\`) and a `"` or `#`
	immediately after one.  If so, stop throwing warnings about
	these characters as well.  ("lex.cpp"'s
	`file_input::read_line()` independently checks for invalid
	character codes encountered when _interpreting_ the input.)

	Fixes <https://savannah.gnu.org/bugs/?67285>.  Problem dates
	back at least to groff 1.02, 2 June 1991.

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

	[eqn]: Regression-test Savannah #67285.

	* src/preproc/eqn/tests/\
	passes-through-input-with-eighth-bit-set.sh: Do it.
	* src/preproc/eqn/eqn.am (eqn_TESTS): Run test.

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

	* src/preproc/eqn/main.cpp (main): Actually set
	`want_startup_file` to `false` when `-R` option is seen.
	Problem introduced by me in commit d22a547b9b, 27 August 2023.

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

	[pic]: Adjust new polygon feature.  Adopt the term "reference
	points" for object-relative locators, and rename the `.p[oint]`
	specimen thereof to `.mid[point]`.

	* src/preproc/pic/lex.cpp (get_token_after_dot):
	* src/preproc/pic/yex.cpp: Rename `DOT_P` symbol/token to
	`DOT_MID`.
	* src/preproc/pic/lex.cpp (get_token_after_dot): Recognize `mid`
	and `midpoint`, rather than `p` and `point`, as token `DOT_MID`
	instead of `DOT_P`.

	Fixes <https://savannah.gnu.org/bugs/?67250>.  Thanks to Doug
	McIlroy for the discussion.

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

	* src/utils/addftinfo/addftinfo.cpp (usage): Summarize purpose
	of command when help is requested.

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

	* src/roff/troff/env.cpp: Trivially refactor.  Use better data
	type for `deprecated_font_identifiers`; make a vector of
	`symbol`s rather than of `string`s.
	(warn_if_font_name_deprecated): Use compatible type for vector
	iterator.

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

	[devps]: Stop generating "symbol.map" from "symbolchars".

	* font/devpdf/devpdf.am (devpdffontdata): Drop
	"font/devpdf/map/symbolchars".
	* font/devps/devps.am (DEVPSGENFILES): Drop "symbol.map" and
	"symbolchars".  Add "symbolsl.awk".
	* font/devps/generate/Makefile ($(srcdir)/symbol.map): Drop
	target.
	(clean): Stop cleaning "$(srcdir)/symbol.map".
	* font/devps/generate/symbolchars: Delete.

	Begins a build refactoring motivated by Savannah #66876.

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

	* src/utils/afmtodit/afmtodit.pl: Throw separate diagnostic
	messages for failures to open "DESC" files attempted from two
	separate locations.

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

	* src/utils/afmtodit/afmtodit.pl: Fix code style nits.  Stop
	using `&` sigil in subroutine calls; that's nonidiomatic Perl,
	an exception to the language's otherwise relentless dedication
	to sigil prefixes.

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

	* doc/doc.am ($(GROFF_INFO)) [HAVE_MAKEINFO]: Make target
	creation depend on `HAVE_MAKEINFO` configuration variable.

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

	* tmac/tty.tmac: Fix misspelled special character identifiers
	when defining fallback characters for accented basic Latin
	letters.

	Fixes <https://savannah.gnu.org/bugs/?67259>.  Problem
	introduced by me in commit 8f9988d4eb, 25 August.  Thanks to
	Bjarni Ingi Gislason for the report.

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

	* src/devices/gropdf/gropdf.pl: Trivially refactor.  Rename
	global list `idirs` to `includeDirs` so its purpose is clearer.
	Update dereference sites.

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

	* src/devices/gropdf/gropdf.pl (OpenFontFile): Refactor.  This
	subroutine no longer does anything with its second argument (of
	three), so eliminate it.
	(LoadDesc, LoadFont, GetType1): Update call sites.

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

	[gropdf]: Use stricter MS-DOS/Windows filespec check.

	* src/devices/gropdf/gropdf.pl (OpenFontFile)
	(OpenIncludedFile): Make check for MS-DOS/Windows-style absolute
	filespec stricter; not only must the second character be ':',
	but the first must now be an uppercase Basic Latin letter.

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

	* src/devices/gropdf/gropdf.pl: Refactor.
	(OpenInc): Rename this subroutine...
	(OpenIncludedFile): ...to this.  Also rename local scalars for
	clarity, and give them clearer semantics.  `fn` becomes `arg`,
	and is the untransformed actual parameter passed in.  Rename
	`fnm` to `fileName`, which is used only when the subroutine
	performs a transformation on `arg` (when it is not an absolute
	filespec, the code tries to locate it by prefixing with elements
	of the `idirs` list).
	(do_x): Update call site.

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

	* src/devices/gropdf/gropdf.pl (do_x): Trivially refactor.
	Rename scalar `FDnm` to `fileName`.

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

	* src/devices/gropdf/gropdf.pl (LoadDownload): Drop scalar `f`;
	we won't need it anymore.  Rename scalar `found` to
	`anyDownloadFilefound`, and manipulate it like a Boolean, not a
	counter.  Attempt `open()` of "download" in each directory in
	the groff font search path directly, instead of indirectly
	through `OpenFontFile()`; we want to read all download files
	available, not stop at the first one encountered.  Use an
	ordinary file handle (`DL`) for this `open()`; we don't need a
	scalar for it because we don't return it.  Issue `Notice()`s of
	each open, whether successful or failed.  Recast diagnostics.
	Annotate and motivate logic.

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

	* src/devices/gropdf/gropdf.pl (OpenFontFile): Refactor.  Rename
	scalar `fnm` to `fileName`.  Add scalar `resolvedFileName`,
	recording the file specification actually opened in the event of
	success.  Eliminate multiple returns.  Use global scalar
	`fontPath` instead of `dirs` argument to search for files.

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

	* src/devices/gropdf/gropdf.pl (OpenFile): Rename this...
	(OpenFontFile): ...to this, reflecting the specificity of its
	operation--it opens files corresponding to the output device in
	the `$GROFF_FONT_PATH` (or given to the program as `-F`
	arguments).

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

	* src/devices/gropdf/gropdf.pl: Trivially refactor.  Rename
	global scalar `fontdir` to `fontPath` to better reflect its
	syntax.
	(LoadDownload, LoadDesc, LoadFont, GetType1): Update dereference
	sites.

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

	* src/devices/gropdf/gropdf.pl: Recast diagnostic messages to
	describe the default foundry in a less confusing way.  Add new
	scalar, `foundryDescription`, to store the string "default
	foundry" when the foundry would otherwise be reported as an
	empty string, which could mislead the user into thinking that a
	variable has gone unintentionally unpopulated.
	(LoadFont): Update phrasing of diagnostics to work with new
	scalar.

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

	* src/devices/gropdf/gropdf.pl (LoadFont): Recast diagnostic
	message.

	Continues fixing Savannah #66519.

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

	* src/devices/gropdf/gropdf.pl (LoadFont): Add a `Notice()` of
	the key we're looking up in the `download` hash (or, if that
	fails, the `missing` hash).

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

	* doc/doc.am (DOC_PDFMOM): Build documents more verbosely,
	passing `-P -d` option to pdfmom(1) (and ultimately `-d` to
	gropdf(1)).

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

	* font/devpdf/util/BuildFoundries.pl (LoadFoundry): Stop
	throwing notice about grops(1) font [description file] being
	copied; this notification was far away from where the rewrite
	was actually happening.  Drop now-unused `gotf` scalar.
	(UseGropsVersion): If we're being strict and the destination
	font description file name (scalar `gfontbase`) already exists,
	emit a `Notice()` that we're not overwriting it.  If we are
	rewriting it, emit the aforementioned notice here, where it
	happens.  Drop redundant/unnecessary (depending on whether a
	file open was successful) close of `GF` file handle.

	* font/devpdf/devpdf.am: Tidy up for better build reliability.
	(font/devpdf/util/BuildFoundries): Stop manipulating the
	"download" file.
	(font/devpdf/download): Move the file's comment header from
	here...
	* font/devpdf/download.in: ...to here.
	* font/devpdf/devpdf.am (font/devpdf/download): Use
	"BuildFoundries"'s new `--download` option to construct the
	target from "download.in".  Stop setting write permission on the
	generated download file in the build tree; it's no longer
	necessary.  Stop giving "BuildFoundries" a search path in the
	"font/devps" directory; use "font/devpdf" instead.  This is what
	ultimately angered "make distcheck"; now that make(1) produces
	the "pdf" device's font description files for the default
	foundry (copying them from "font/grops", there's no need for
	"BuildFoundries" to rewrite them, in either directory.

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

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

	* font/devpdf/util/BuildFoundries.pl: Support new `--download`
	option, taking an input download file as argument and storing it
	to new `downloadFile` scalar.  Default to "download" as before.

	Continues fixing Savannah #67268.

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

	* font/devpdf/util/BuildFoundries.pl: Make `--strict` option
	stricter, turning more warnings fatal...
	(LoadFoundry): ...when an embeddable font file is known to be
	unavailable, when a grops(1) font description file is
	unreadable, when afmtodit(1) fails [the inference is
	indirect]...
	(RunAfmtodit): ...when a font description file has an unexpected
	format...
	(UseGropsVersion): ...when a font description file can't be
	created ("copied" with potential modification of relative file
	specifications), when one being read lacks an `internalname`
	directive, and when the file can't be opened for reading.

	Continues fixing Savannah #67268.

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

	* font/devpdf/util/BuildFoundries.pl: Throw more
	`Notice` (debugging) diagnostic messages...
	(RunAfmtodit): ...when running `afmtodit`...
	(UseGropsVersion): ...when trying to open a font description
	file for writing...
	(LoadDownload): ...and when the download file cannot be opened.

	Continues fixing Savannah #67268.

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

	* src/devices/gropdf/gropdf.pl (LoadDownload): Skip lines that
	consist only of whitespace.

	Continues fixing Savannah #67268.

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

	[doc]: Use new gropdf `-W` option.

	* doc/doc.am (DOC_PDFMOM): Append `-P -W` to `pdfmom` arguments.

	Continues fixing Savannah #67268.

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

	[gropdf]: Add `-W` option to make font embedding warnings fatal.

	* src/devices/gropdf/gropdf.pl: Add global scalar
	`makeWarningsFatal`.  Recognize option when calling
	`GetOptions()`.
	(LoadFont): Fall over dead if embedding fails and if
	`makeWarningsFatal` is true.

	* src/devices/gropdf/gropdf.pl (usage):
	* src/devices/gropdf/gropdf.1.man (Options): Document it.

	Begins fixing Savannah #67268.

2025-07-01  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf] More rational handling of duplicate font entries.

	* src/devices/gropdf/gropdf.pl (LoadFont): The primary entry
	has a proper postscript name such as 'iota' whereas
	alternatives tend to have 'uniXXXX' or 'afiiNNNNN'. So
	choose the primary.

2025-07-01  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf] Changes for greek glyphs

	* src/devices/gropdf/gropdf.pl (Clean): More permissive re
	to allow for \(+h etc.
	(Loadfont): Cater for (unintentional?) change to afmtodit
	output format by GBR. Handle duplicate font entries more
	sanely - keep first entry and preserve duplicate so it can
	be used with \N'nnn' the same as unnamed ("---") glyphs.
	Not ideal but forced compromise because groff uses decomposed
	unicode names which can lead to duplicate entries.

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

	[troff]: Add experimental, undocumented global node dumping
	feature.  Except for line numbers and margin characters, this
	essentially produces a graph of the internal representation of
	the entire output--except for line numbers and margin
	characters.  (It's a forest, with one tree per output line.)

	* src/roff/troff/input.h: Declare new global Boolean,
	`want_nodes_dumped`.
	* src/roff/troff/input.cpp: Define new global Boolean,
	`want_nodes_dumped`, defaulting false.
	(main): Set it to true if the environment variable
	`GROFF_DUMP_NODES` exists (with any value).
	* src/roff/troff/env.cpp (environment::do_break): Check the new
	global variable; if it is true and if output is going to the
	top-level diversion, dump the pending output line's node list in
	JSON format (to the standard error stream) just prior to writing
	it as *roff output (to the standard output stream).

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

	* tmac/pdf.tmac (pdf:SS): Delete now-unused macro.

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

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

	* font/devpdf/devpdf.am: Ships font description file names for
	the "pdf" output device corresponding to the 8 new font
	description files for CJK script support recently added for the
	"{x,}html", "ps", and "utf8" devices.

	These are intended as abstractions of faces to permit consistent
	naming while permitting customization, just as with the 12 text
	typefaces supported across output devices for Latin scripts in
	groff (three families of four styles each).  These CJK font
	descriptions are not organized into groff font families, but are
	similar.  They are not mounted by default.

		CSH: Simplified Chinese, Hei style
		CSS: Simplified Chinese, Song style
		CTH: Traditional Chinese, Hei style
		CTS: Traditional Chinese, Song style
		JPG: Japanese, Gothic style
		JPM: Japanese, Mincho style
		KOG: Korean, Gothic style
		KOM: Korean, Mincho style

	* font/devpdf/devpdf.am (DEVPDFFONTFILES_FROM_DEVPS): Add them.

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

	* font/devpdf/devpdf.am: Refactor.  Make this script
	more Automake-idiomatic (I think) and resemble other groff
	Automake scripts more closely.
	(devpdf_builddir): Define macro.
	(GROFF_FONT_FILES, ENC_FILES, MAP_FILES): Drop macros populated
	by shell command substitution in favor of static file lists...
	(DEVPDFFONTFILES_FROM_DEVPS): ...like this...
	(DEVPDFFONTFILES_FOR_URW) [HAVE_URW_FONTS]: ...and this.
	(DEVPDFFONTFILES): New macro contains only
	`DEVPDFFONTFILES_FROM_DEVPS` plus the "download", "DESC", "SS",
	and "StandardSymSL.pfb" files (all generated by the build, the
	last two trivially).
	(devpdffontdata, devpdffontencdata): Rationalize contents,
	aligning files and macro contents with installation requirements
	so Automake takes care of installing and uninstalling them.
	(MOSTLYCLEANFILES): Add `devpdffontdata`, `devpdffontencdir`,
	`devpdffontmapdir`, so that Automake takes care of cleaning
	them.
	($(DEVPDFFONTFILES_FROM_DEVPS)): New target copies "ps" device's
	font descriptions to build's "pdf" device data directory.
	($(devpdffontencdata)): Now that the "text.enc" encoding file
	name is stored in a macro, use it and compute its basename
	instead of using literals.
	($(DEVPDFFONTFILES_FOR_URW)): Make the "pdf" device's "download"
	file depend on this macro's contents, which may be empty if
	`HAVE_URW_FONTS` is not defined by the "configure" script.
	(font/devpdf/stamp): Respell dependencies using above macros.
	(mostlyclean-local, mostlyclean_devpdf_extra)
	(install-data-local, install_devpdf)
	(uninstall_groffdirs, uninstall_devpdf): Drop targets made
	redundant by better population of `devpdf*data` macros above.

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

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

	* font/devpdf/DESC.in: Mount `SS`, `S`, and `ZD` fonts in same
	positions as "ps" device.  This should have little effect other
	than to minimize differences between the devices, however the
	"ps" device continues to have a font, `ZDR`, mounted after all
	of the foregoing, that the "pdf" device lacks and does not
	require.
	* font/devpdf/SS: Annotate file's hand-maintained status.

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

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

	Fix Savannah #67244.

	* font/devps/AB:
	* font/devps/ABI:
	* font/devps/AI:
	* font/devps/AR:
	* font/devps/BMB:
	* font/devps/BMBI:
	* font/devps/BMI:
	* font/devps/BMR:
	* font/devps/CB:
	* font/devps/CBI:
	* font/devps/CI:
	* font/devps/CR:
	* font/devps/HB:
	* font/devps/HBI:
	* font/devps/HI:
	* font/devps/HNB:
	* font/devps/HNBI:
	* font/devps/HNI:
	* font/devps/HNR:
	* font/devps/HR:
	* font/devps/NB:
	* font/devps/NBI:
	* font/devps/NI:
	* font/devps/NR:
	* font/devps/PB:
	* font/devps/PBI:
	* font/devps/PI:
	* font/devps/PR:
	* font/devps/TB:
	* font/devps/TBI:
	* font/devps/TI:
	* font/devps/TR:
	* font/devps/ZCMI: Replace/rename entry for `*m` glyph to `mc`,
	removing `mc` as an alias thereof; annotate the corresponding
	code point as U+00B5, not U+03BC.  The micro sign (groff: \[mc])
	is a styled glyph often found in text faces.  `*m` is an
	unstyled, but traditionally slanted, lowercase Greek mu used
	overwhelmingly in mathematical or scientific typesetting
	contexts.  It is not appropriate for setting the modern Greek
	language.
	* font/devps/generate/symbol.map:
	* font/devps/generate/text.map: Remove spurious mappings of
	groff's `\[mc]` to PostScript's `mu`.  This prevents afmtodit(1)
	from resurrecting the aforementioned problem, though for
	unrelated reasons we don't regenerate the font description files
	for grops(1) when building groff--we should, someday.  (Among
	other manual changes, we added kerning pairs; see Savannah
	#58897.)
	* font/devps/generate/text.map: Drop all mappings of symbolic/
	mathematical/unstyled Greek special characters `*[A-Za-z]` to
	PostScript glyph names.  As noted above, such mappings are not
	appropriate for text fonts, which (typically) have multiple
	styles available.
	* src/libs/libgroff/uniglyph.cpp (struct S): Delete mappings
	of code points from Unicode Greek and Coptic block
	{U+0370..U+03FF} to *roff's special character identifiers for
	"technical" use of classical Greek; see above.

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

	[pfbtops]: Add test for `pfbtops` command.

	* src/util/pfbtops/tests/smoke-test.sh: Do it.
	* src/util/pfbtops/pfbtops.am (pfbtops_TESTS): Run test.
	(TESTS): Add test to suite.
	(EXTRA_DIST): Ship test in distribution archive.

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

	* src/utils/grog/grog.pl (interpret_line): Recognize new `pfp`
	and `pftr` request names.

2025-06-28  Deri James  <deri@chuzzlewit.myzen.co.uk>

	* font/devpdf/generate/StandardSymSL.sfd: Adjust glyph positions
	within cell to match grops rendering.
	* font/devpdf/StandardSymSL.pfb: Regenerate from changes above.

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

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

	* font/devpdf/generate/StandardSymSL.sfd: Add human-readable
	source format for new font.  Everything in groff is available
	under the GNU GPL, so we should provide a "preferred form for
	modification".  (We already do so for "freeeuro.sfd".)
	* font/devpdf/devpdf.am (EXTRA_DIST): ...and ship it in the
	distribution archive.  At this time, we also ship the "compiled"
	PFB file; the build process does not perform any transformation
	of the source SFD file.  That can change in the future if we can
	tolerate a build-time dependency on fontforge(1).

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

	* src/roff/troff/input.cpp (composite_glyph_name)
	(charinfo_to_node_list): Reform terminology in diagnostic
	messages.  Use the term "character" when dealing with input;
	it's up to the output driver to elicit "glyphs" from a device.
	(charinfo_to_node_list): Refer to "special", not "composite",
	characters, when processing a user-defined character with a
	string iterator.

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

	* doc/groff.texi.in (Strings) <length>:
	* man/groff_diff.7.man (New requests) <length>: Document
	pitfall.

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

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

	* doc/GMPfront.t.in: Rename this...
	* doc/groff-man-pages-cover.groff.in: ...to this.
	* doc/doc.am (DOC_GMP_COVER_PAGE): Update macro definition
	accordingly.

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

	* src/preproc/preconv/preconv.cpp (do_file): Tweak diagnostic
	message; drop extra layer of quoting of file name, and migrate
	to "cannot" from "unable to" phrasing.

	Continues the long process of fixing Savannah #66519.

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

	* bootstrap.conf: Migrate to contemporary names for gnulib
	modules.
	  stdbool-c99 -> stdbool-h-c99
	  stdckdint   -> stdckdint-h
	  stdint      -> stdint-h
	  sys_wait    -> sys_wait-h

	Fixes <https://savannah.gnu.org/bugs/?66731>.  Thanks to Collin
	Funk for the report.

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

	[man]: Fix inaccurately reported revision date of groff_man(7)
	and groff_man_style(7) man pages.  Since they're generated by m4
	from a common `.in` file, our Perl `mdate` script was replacing
	the center footer with, effectively, the build time of the
	m4-generated document rather then the revision date of the
	maintained source file.

	* tmac/groff_man.7.man.in: Replace `@MDATE@` with newly
	contrived substitutum [dog Latin], `REVISION_DATE`.  It works
	just like the former, but has a new name to reflect the
	distinguishable process of its replacement.
	* tmac/tmac.am (tmac/groff_man.7.man)
	(tmac/groff_man_style.7.man): Make m4(1) write to a temporary
	file, then process the temporary file with `mdate.pl` to replace
	the aforementioned subtitutum.  As a side effect, there is no
	longer an `@MDATE@` in the file for the ".man" suffix rule in
	"Makefile.am" to affect.

2025-06-21  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Remove unneccessary call to pdf parser.

	* src/devices/gropdf/gropdf.pl (do_X) </OUT>: Parse Title/Level
	manually.

2025-06-21  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Saner ordering of perl switch statement.

	* src/devices/gropdf/gropdf.pl (do_X): handle pdfmark commands
	first.

2025-06-20  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[devpdf, gropdf]: Add `SS` slanted-symbol font support.  Replace
	pseudo-slanted characters with a real font, improving typography
	of, e.g., slanted lowercase Greek letters as used in eqn(1).

	* font/devpdf/DESC.in: Mount new font `SS` prior to `S`.
	* font/devpdf/SS: New file describes new slanted-symbol font.
	The metrics are hand-tweaked.  We can't run afmtodit on the
	symbolsl.afm file in grops because it produces incorrect
	metrics--the width/height values do not take into account the
	rescaling of the glyph sizes by .89.
	* font/devpdf/StandardSymSL.pfb: New PostScript font supplies
	slanted versions of glyphs in the standard Symbol font.
	* font/devpdf/devpdf.am (GROFF_FONT_FILES): Update macro
	definition to scan the build directory for file names matching
	font descriptions, excluding both symbol fonts.  Relocate
	definition to be closer to use.
	(devpdffont_DATA): Add new files "SS", "StandardSymSL.pfb", and
	"download.in".
	(font/devpdf/SS): New target is generated by copying from source
	tree to build tree if they differ.  As a side effect, also copy
	"StandardSymSL.pfb".
	(font/devpdf/util/BuildFoundries): Copy "download.in" file from
	source tree to build tree with new name "download".
	(font/devpdf/download): Set write permission on the target to
	work around GNU Automake "distcheck" feature that makes
	make(1)-generated files read-only; however we want
	"BuildFoundries" to rewrite the file in place.
	(mostlyclean_devpdf_extra): Clean the new files "SS" and
	"StandardSymSL.pfb", as well as "S" since the new regex used to
	populate the `GROFF_FONT_FILES` now overlooks it.
	(install_devpdf, uninstall_devpdf): Explicitly handle "S" font
	description file since the new regex used to populate the
	`GROFF_FONT_FILES` now overlooks it.
	* src/devices/gropdf/gropdf.pl: Support multiple specifications
	of `-F` option, populating new list `fdlist`.  Use the runtime
	path separator to populate scalar `fd` if `fdlist` is not a
	singleton.
	* tmac/pdf.tmac: Drop all 28 calls of `pdf:SS` macro for 24
	lowercase Greek letters and 4 variant forms; the slanted-symbol
	font now supplies these.

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

2025-06-16  Dave Kemper <saint.snit@gmail.com>

	* src/roff/troff/env.cpp (distribute_space): Fix expression
	involving C++ `static_cast<>` operator to stop permitting
	integer division within, leading to undesired loss of precision
	when reporting the amount of "spread" applied when performing
	adjustment, as configured by the `spreadwarn` request.

	Fixes <https://savannah.gnu.org/bugs/?67218>.  [Problem
	introduced by me in commit 8b6ccbce48, 13 May.  --GBR]

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

	* tmac/tests/an-ext_SY-and-YS-work.sh: Use printf(1), not
	echo(1), when an argument contains backslashes.  Thanks to Dave
	Kemper and Deri James for reporting test failures arising from
	the non-portability of backslash usage in echo(1) arguments,
	which frustratingly did not create problems on any systems
	readily available to me.

	Problem introduced by me in commit 4bdcefea1d, 6 June.

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

	* font/devutf8/devutf8.am (DEVUTF8FONTS): Tweak ordering of
	mounted CJK faces in "DESC" file generated for "utf8" output
	device.  Consistently arrange the Hei (~serif) faces before the
	Song (~sans-serif) ones.

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

	* src/devices/grohtml/post-html.cpp (html_printer::set_style):
	Disclose name of font description file lacking `internalname`
	directive in fatal diagnostic when this is the case.

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

	* src/roff/troff/input.cpp (charinfo::dump): Fix thinko when
	initializing static `char` array literals.  `none` requires only
	one null terminator.  Append one to `comma`.

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

	[pic]: Add unit test for `polygon` command.

	* src/preproc/pic/tests/polygon-command-works.sh: Do it.
	* src/preproc/pic/pic.am (pic_TESTS): Run test.
	(TESTS): Add test to suite.
	(EXTRA_DIST): Ship test in distribution archive.

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

	* src/preproc/pic/object.cpp (object::point): Fix compiler
	warning when building paranoiacally; don't give an actual
	parameter a name when it's unused.

2024-11-19  Duncan Losin <dlosin@protonmail.com>

	[pic]: Extend to allow drawing arbitrary polygons.

	* src/preproc/pic/lex.cpp (get_token_after_dot): Add new checks
	for `.v[er[tex]]` and `.p[oint]` syntax for polygons.

	* src/preproc/pic/object.h (enum object_type, object_type)
	(object_type_name):
	* src/preproc/pic/lex.cpp (lookup_keyword): Add `polygon`
	keyword and object type.

	* src/preproc/pic/object.h (struct object): Declare new virtual
	functions for determining polygon vertices and edge midpoints.

	* src/preproc/pic/object.h (class path): Add new `vertex_number`
	and `is_edge` member variables to determine what position should
	be accessed.

	* src/preproc/pic/pic.ypp (tokens): Add new tokens `POLYGON`,
	`DOT_P`, and `DOT_V`.

	* src/preproc/pic/pic.ypp (object_spec): Add new rule `POLYGON`
	to create new object_spec of type `POLYGON_OBJECT`.  Add new
	rule `object_spec WITH vertex` to locate polygons.

	* src/preproc/pic/pic.ypp (place): Add new rules `label vertex`
	and `vertex OF label` to locate polygons.

	* src/preproc/pic/pic.ypp (vertex):
	* src/preproc/pic/object.h (struct vertex): Define new `vertex`
	structure and grammar rule for describing polygon vertices and
	edge midpoints.

	* src/preproc/pic/object.cpp (object::vertex, object::point):
	(object::set_vertex_number): Define default behavior for new
	functions.

	* src/preproc/pic/object.cpp (object_spec::object_spec): Set
	defaults for `vertex_number` and `is_edge`.

	* src/preproc/pic/object.cpp (class polygon_object)
	(polygon_object::polygon_object)
	(polygon_object::center)
	(polygon_object::point)
	(polygon_object::set_fill)
	(polygon_object::set_vertex_number)
	(polygon_object::vertex)
	(polygon_object::print): Add new `polygon` class and implement
	member functions.

	* src/preproc/pic/object.cpp (object_spec::make_line): Modify
	line segment array from n-1 to n segments if a polygon has been
	requested.  Create offsets for positioning new polygons.

	* src/preproc/pic/object.cpp (object_spec::make_object): Add
	check for the `POLYGON_OBJECT` object type.

	* doc/pic.ms:
	* src/preproc/pic/pic.1.man (Other changes): Document it.

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

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

	* src/roff/troff/input.cpp (is_char_usable_as_delimiter): Loosen
	the choke on prohibited delimiters.  To eliminate syntactic
	ambiguity in conditional expressions, we need only reject
	characters that can _begin_ numeric expressions; those in the
	set '/*%<>=&:)' cannot, so permit them as delimiters once more.
	(do_overstrike, do_bracket, do_name_test, do_zero_width_output)
	(read_size, do_register, do_width, do_device_extension)
	(read_drawing_command): Clarify warning diagnostic accordingly.

	* doc/groff.texi.in (Compatibility Mode):
	* man/groff_diff.7.man (Compatibility mode): Update.

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

	* tmac/an-ext.tmac (SY): The single-argument form of `SY` need
	not set an ubreakable space and output line continuation escape
	sequence after formatting the argument.  That distinction is in
	fact the whole point of accepting a second argument (a new
	post-1.23 feature), which is set in bold like the first.  (It is
	why you would write `.SY foo bar` rather than `.SY "foo bar".)
	* tmac/groff_man.7.man.in (Synopsis macros) <SY>: Document this
	fact.

	Fixes a regression from groff 1.23.0.  Thanks to Alex Colomar
	for the report.

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

	* src/devices/grohtml/post-html.cpp: Fix code style nits.
	(files::next_file_name)
	(style::operator==)
	(char_buffer::add_string)
	(list::move_to)
	(assert_state::add)
	(replace_negate_str)
	(html_printer::determine_header_level)
	(html_printer::do_indent)
	(html_printer::do_space)
	(html_printer::draw)
	(html_printer::html_printer)
	(html_printer::set_char)
	(html_printer::set_numbered_char)
	(html_printer::set_char_and_width): Parenthesize formally
	complex expressions.
	(style::operator==)
	(text_glob::is_nf)
	(text_glob::is_fi)
	(text_glob::is_br)
	(html_printer::emit_raw)
	(html_printer::do_title)
	(html_printer::do_heading)
	(html_printer::is_courier_until_eol)
	(html_printer::do_indent)
	(html_printer::do_check_center)
	(html_printer::remove_tabs)
	(html_printer::lookahead_for_tables)
	(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::handle_assertion)
	(html_printer::special): Put operators subjected to input line
	wrapping at the beginning of the continuation line, not at the
	end of the broken one.  The former is preponderant groff style.
	(header_desc::write_headings)
	(html_printer::emit_line)
	(html_printer::emit_raw)
	(generate_img_src)
	(html_printer::do_title)
	(html_printer::write_html_anchor)
	(html_printer::write_xhtml_anchor)
	(html_printer::determine_header_level)
	(html_printer::do_linelength)
	(html_printer::do_check_center)
	(html_printer::insert_split_file)
	(html_printer::do_job_name)
	(html_printer::is_font_courier)
	(html_printer::do_font)
	(html_printer::draw)
	(html_printer::write_title)
	(html_printer::do_file_components)
	(html_printer::writeHeadMetaStyle)
	(html_printer::~html_printer)
	(get_str)
	(make_val)
	(html_printer::round_width)
	(html_printer::handle_valid_flag): Reorder equality comparisons
	to avoid inadvertent lvalue assignment.
	(generate_img_src): Explicitly compare value of pointer type to
	null pointer literal instead of letting it pun down to a
	Boolean.

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

	* src/devices/grohtml/post-html.cpp: Rename `none` enumeration
	constant to `none_tag` for conformity with other constants in
	the same (anonymous) enum.  C++ enums weren't name-spaced or
	properly type-checked until C++11, and C's still aren't.  (Ada
	had proper sum types back in 1983.)

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

	* src/devices/grohtml/post-html.cpp (main): Spell null pointer
	constant the idiomatic C++98 way (`0`) instead of as `NULL`.

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

	* src/devices/grohtml/post-html.cpp
	(struct file)
	(class files)
	(struct style)
	(struct char_block)
	(class char_buffer)
	(class text_glob)
	(struct element_list)
	(class list)
	(class page)
	(class html_font)
	(class header_desc)
	(class assert_state)
	(class html_printer): Comment member function formal argument
	names as a compromise with the Stroustrup-style C++ used in most
	of groff.

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

	* src/devices/grohtml/post-html.cpp (class html_printer): Delete
	unused member function declarations.  They appear to have been
	pasted from grops.

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

	* src/devices/grops/ps.cpp
	(class ps_font)
	(struct subencoding)
	(struct style)
	(class ps_printer): Comment member function formal argument
	names as a compromise with the Stroustrup-style C++ used in most
	of groff.
	(main): Spell null pointer constant the idiomatic C++98 way
	{`0`} instead of as `NULL`.
	(ps_font::handle_unknown_font_command)
	(handle_unknown_desc_command): Rename argument from `filename`
	to `fn` to preëmpt `-Wshadow` compiler warning with planned
	refactoring of `class font`.
	(ps_printer::do_file): Rename local variable from `filename` to
	`resource_filename` for clarity.

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

	* src/devices/grolj4/lj4.cpp: Fix code style nits.
	(lj4_font::handle_unknown_font_command, is_unprintable)
	(lj4_printer::draw, main): Reorder equality comparisons to avoid
	inadvertent lvalue assignment.
	(lj4_printer::draw, lj4_printer::moveto1): Parenthesize formally
	complex expressions.
	(lj4_printer::draw): Eschew cleverness.  Use modulus and
	equality operators to determine even cardinality of integer
	value instead of a bitwise operator and letting the result pun
	to a Boolean.

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

	* src/devices/grolj4/lj4.cpp
	(class lj4_font): Comment member function formal argument names
	as a compromise with the Stroustrup-style C++ used in most of
	groff.
	(struct option)
	(main): Spell null pointer constant the idiomatic C++98 way
	{`0`} instead of as `NULL`.
	(lj4_font::handle_unknown_font_command): Rename argument from
	`filename` to `fn` to preëmpt `-Wshadow` compiler warning with
	planned refactoring of `class font`.

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

	* src/devices/grolbp/lbp.cpp
	(class lbp_font): Comment member function formal argument names
	as a compromise with the Stroustrup-style C++ used in most of
	groff.
	(lbp_font::~lbp_font)
	(lbp_printer::set_line_thickness)
	(struct option)
	(main): Spell null pointer constant the idiomatic C++98 way
	{`0`} instead of as `NULL`.
	(lbp_font::handle_unknown_font_command)
	(handle_unknown_desc_command): Rename argument from `filename`
	to `fn` to preëmpt `-Wshadow` compiler warning with planned
	refactoring of `class font`.

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

	[troff]: Implement new `pfp` request.

	* src/roff/troff/node.cpp
	(dump_font_mounting_positions_request): Add.

	(init_node_requests): Wire up `pfp` request name to
	`dump_font_mounting_positions_request()`.

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

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

	[troff]: Extend `font_info` class.  I need this so I can
	implement a font mounting position dumper.

	* src/roff/troff/node.cpp (class font_info): Declare new
	`get_font()` member function, returning pointer to contained
	`font` object.
	(font_info::get_font): Implement accessor member function.

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

	* src/roff/troff/node.cpp (mount_font_no_translate): Clarify
	error diagnostic when the `fp` request is given a too-huge
	mounting position; disclose both the rejected argument and value
	of the next available font position.

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

	* src/roff/troff/node.cpp (mount_font_no_translate): Rename
	argument from `external_name` to `filename` for clarity.  This
	argument only ever stores the name of the font description file,
	which is usually also the font identifier in GNU troff (but can
	differ if the `fp` request's three-argument form is used).
	(mount_font_at_position): Rename local variable `external_name`
	to `filename` for the same reason.

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

	* src/devices/grodvi/dvi.cpp
	(class dvi_font): Comment member function formal argument names
	as a compromise with the Stroustrup-style C++ used in most of
	groff.
	(dvi_font::handle_unknown_font_command): Rename argument from
	`filename` to `fn` to preëmpt `-Wshadow` compiler warning with
	planned refactoring of `class font`.
	(dvi_printer::define_font, dvi_printer::set_font): Rename
	argument from `i` to `mounting_position` for clarity.
	(main): Spell null pointer constant the idiomatic C++98 way
	{`0`} instead of as `NULL`.

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

	* src/roff/troff/node.cpp: Fix code style nits.
	(get_font_translation, mount_font_no_translate, lookup_family):
	Favor C++ `static_cast<>` operator over omnipotent C-style
	casts.
	(mount_font_no_translate): Drop braces around single-statement
	control flow branch; groff generally eschews these.

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

	[libgroff, troff]: Refactor.

	* src/include/font.h (class font): Promote constructor from
	`protected` visibility to `public`.  This is so that GNU troff
	can create a `nonexistent_font` object with which to mark font
	mounting positions that fail to mount a font.
	* src/roff/troff/node.cpp: Do so at the global scope.
	(mount_font_no_translate): Drop `static char a_char` formerly
	used for this purpose.  It felt squicky to me to store an object
	of the "wrong" type in the `font_dictionary`.  Reorder equality
	comparisons to avoid inadvertent lvalue assignment.

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

	[libdriver,grohtml,grops]: Revise diagnostic messages.

	* src/devices/grohtml/post-html.cpp
	(html_printer::set_style)
	(html_printer::set_numbered_char)
	(html_printer::set_char_and_width):
	* src/devices/grops/ps.cpp (ps_printer::set_style):
	* src/libs/libdriver/printer.cpp (printer::set_char_and_width):
	Clarify diagnostics; state what operation failed and
	characterize source of invalid data as "font _description_
	file", not simply a "font".

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

	* src/devices/grohtml/post-html.cpp
	(html_printer::set_numbered_char): Compare integer-valued
	variable to integer literal instead of letting it pun down to a
	Boolean.

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

	* src/devices/grohtml/post-html.cpp
	(char_buffer::add_string)
	(assert_state::add)
	(replace_negate_str)
	(exists)
	(html_printer::determine_header_level)
	(html_printer::do_check_center)
	(html_printer::do_eol_ce)
	(html_printer::lookahead_for_tables)
	(html_printer::draw)
	(html_printer::html_printer)
	(html_printer::sbuf_continuation)
	(html_printer::set_numbered_char)
	(html_printer::set_char_and_width): Reorder equality comparisons
	to avoid inadvertent lvalue assignment.

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

	* src/devices/grohtml/post-html.cpp
	(html_printer::do_tab_te)
	(html_printer::do_tab)
	(html_printer::do_tab0)
	(html_printer::do_col)
	(html_printer::set_char_and_width): Explicitly compare value of
	pointer type to null pointer literal instead of letting it pun
	down to a Boolean.

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

	* src/devices/grohtml/post-html.cpp
	(assert_state::~assert_state)
	(assert_state::add)
	(replace_negate_str)
	(replace_str)
	(html_printer::do_title)
	(html_printer::do_heading)
	(html_printer::troff_tag)
	(get_html_translation)
	(html_printer::special): Remove unnecessary C-style type casts.
	(html_printer::troff_tag)
	(get_str)
	(make_val)
	(html_printer::handle_state_assertion): Favor C++-style
	`const_cast` over C-style omnipotent casts.

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

	* src/devices/grohtml/post-html.cpp
	(files::add_new_file)
	(text_glob::get_tab_args)
	(list::is_less)
	(page::add_and_encode)
	(header_desc::write_headings)
	(assert_state::add)
	(assert_state::compare)
	(assert_state::close)
	(replace_negate_str)
	(replace_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)
	(generate_img_src)
	(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::add_table_end)
	(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)
	(usage): Add `assert()`ions as null pointer dereference booby
	traps.

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

	[libgroff]: Trivially refactor `font` class for clarity.  Fonts
	have up to three names in groff: (1) a font description file
	name; (2) a GNU troff identifier used for its selection [and
	often, but not necessarily, the same as (1); see the `fp`
	request]; (3) an "internalname" that serves multiple purposes--
	for some output drivers, it's a file name of an actual digital
	font file, and for others, it's an integer that encodes styling
	properties.  [Item (3) screams for further refactoring.]  It's
	important to know which of these names we're dealing with, so
	eliminate the unqualified term "name" in the API.

	* src/include/font.h (class font): Rename public member function
	`get_name()` to `get_filename()`.  Rename private member
	variable `name` to `filename`.
	* src/libs/libgroff/font.cpp
	(font::font): Rename constructor argument from `s` to `fn`.
	(font::~font): Delete `filename`, not `name`.
	(font::get_name): Rename this...
	(font::get_filename): ...to this.
	(font::load_font): Rename `s` argument to `fn`.
	(font::get_filename, font::load): Track rename of member
	variable.

	* src/libs/libdriver/printer.cpp (printer::find_font)
	(printer::set_char_and_width, printer::set_numbered_char):
	* src/devices/grohtml/post-html.cpp (html_printer::set_style)
	(html_printer::is_bold, html_printer::make_bold)
	(html_printer::is_font_courier, html_printer::do_font)
	(html_printer::set_numbered_char)
	(html_printer::set_char_and_width)
	* src/devices/grops/ps.cpp (ps_printer::set_style): Update call
	sites.

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

	* src/libs/libdriver/printer.cpp: Fix code style nits.
	(printer::load_font): Reorder equality comparison to avoid
	inadvertent lvalue assignment.
	(printer::set_ascii_char, printer::set_special_char)
	(printer::set_char_and_width, printer::set_numbered_char):
	Explicitly compare value of pointer type to null pointer literal
	instead of letting it pun down to a Boolean.
	(printer::set_char_and_width, printer::set_numbered_char):
	Parenthesize formally complex expressions.

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

	* src/roff/troff/node.cpp (mount_font_at_position)
	(font_lookup_error): Clarify error diagnostics; distinguish
	problems with loading a font description (to mount it) from
	problems with _selecting_ a font.

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

	* src/devices/grotty/tty.cpp: Refactor and fix code style nits.
	Convert manifest constant `DEFAULT_COLOR_IDX` from preprocessor
	macro to global variable of type `const int`.
	(tty_printer::put_color): Reorder equality comparisons to avoid
	inadvertent lvalue assignment.  Compute buffer length for
	formatted string using `sizeof()` on string literal representing
	expected output of maximal length.  Drop `static` qualifier from
	same buffer; the buffer's contents do not need to outlive the
	function call, and allocating ~18 bytes from the stack should
	never be a problem.  Convert `sprintf()` call to `snprintf()`
	and save its return value instead of discarding it.  Use
	`assert()` to check for truncation of formatted string.  This
	is merely an `assert()` because we don't expect truncation to
	ever occur in a production environment, because the buffer is
	sized for output of maximal length.

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

	* src/devices/grotty/tty.cpp (tty_printer::put_color): Fix
	`-Wformat` compiler warning; use `%lu` instead of `%u`
	conversion with `sprintf()` with `long` arguments.

2025-05-24  Deri James  <deri@chuzzlewit.myzen.co.uk>

	* src/devices/grotty/tty.cpp: Add support for devices supporting
	ECMA-48/ISO 6429 SGR 38 and 48 escape sequences for specifying
	24-bit color values in the RGB color space.  Add global Boolean
	variable `want_sgr_truecolor`.
	(class tty_glyph): Promote `back_color_idx` and
	`fore_color_idx` member variables from `schar` (signed char) to
	`long`.
	(class tty_printer): Promote `curr_fore_idx` and `curr_back_idx`
	member variables from `schar` (signed char) to `long`.  Promote
	return value of `color_to_idx()` member function from
	pointer-to-`schar` to pointer-to-`long`.  Promote fourth
	argument of `has_color()` member function from
	pointer-to-`schar` to pointer-to-`long`.  Promote first argument
	of `put_color()` member function from `schar` to `long`.
	(tty_printer::has_color): Promote `idx` argument from
	pointer-to-`schar` to pointer-to-`long`.  Guard existing
	color-definition logic behind test of `want_sgr_truecolor` for
	falsity; otherwise, compute `idx` using bitwise shifts and
	addition.
	(tty_printer::tty_printer): Promote `dummy` local variable
	from `schar` to `long`.
	(tty_printer::color_to_idx): Promote return value from
	pointer-to-`schar` to pointer-to-`long`.  Promote `idx` local
	variable from `schar` to `long`.
	(tty_printer::put_color): Promote `color_index` argument from
	`schar` to `long`.  Guard existing SGR color escape sequence
	emission logic (which uses SGR 30-37 and 40-47) behind test of
	`want_sgr_truecolor` for falsity; otherwise, emit SGR 38 and 48
	sequences.
	(main): Recognize new `-t` option to select use of SGR 38 and 48
	escape sequences.  If specified, configure `want_sgr_truecolor`
	as true.
	* src/devices/grotty/grotty.1.man (Synopsis, Description)
	(Options):
	* src/devices/grotty/tty.cpp (usage): Document new `-t` option.

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

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

	* src/devices/grotty/tty.cpp (class tty_printer): Rename member
	function `tty_color` to `has_color`; since it returns a Boolean,
	the name should imply a logical predicate.
	(tty_printer::tty_color): Rename this...
	(tty_printer::has_color): ...to this.
	(tty_printer::tty_printer, tty_printer::color_to_idx): Update
	call sites.

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

	* src/devices/grotty/tty.cpp (tty_printer::color_to_idx):
	Clarify error diagnostic: the problem isn't that a color is
	unrecognized, but that it is unsupported by the device.

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

	* src/roff/troff/input.cpp (token::next): Drop unnecessary
	temporary variable from `\F` escape sequence handler.

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

	* src/roff/troff/input.cpp (token::next): Replace most of the
	`\f` escape sequence handler with a call to `select_font()`.

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

	* src/roff/troff/input.cpp (token::next): Drop dead code from
	`\f` and `\F` escape sequence handlers;
	`read_escape_parameter()` never returns a null pointer.  (It can
	return `NULL_SYMBOL`, but that is an object with an address.)

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

	[troff]: Refactor, moving font selection logic into a dedicated
	function (so that the `\f` escape handler can also use it).

	* src/roff/troff/env.h: Give new `select_font()` function
	external linkage.
	* src/roff/troff/env.cpp (select_font_request): Move bulk of
	logic from here...
	(select_font): ...to here.  Also recognize an empty symbol, in
	addition to a null one, as equivalent to `.ft P`, to accommodate
	what the `\f` escape sequence handler will pass as an argument.

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

	[troff]: Trivially refactor, continuing reform of functions that
	are troff request handlers such that their names end with
	`_request`.

	* src/roff/troff/env.cpp (select_font): Rename this...
	(select_font_request): ...to this.

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

	* src/roff/troff/env.cpp (select_font): Emit warning diagnostic
	in "range" category when the `ft` request is given an
	out-of-range mounting position.

2025-06-02  Deri James  <deri@chuzzlewit.myzen.co.uk>

	* src/utils/afmtodit/afmtodit.pl: Fix logic error; when falling
	back to system map file, associate scalar `sys_map` with `MAP`
	file handle, not `DESC`.

	Re-fixes <https://savannah.gnu.org/bugs/?66564>.  [Problem
	introduced by me in commit 658f7afb8e, 2 January.  --GBR]

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

	[troff]: Trivially refactor, continuing reform of functions that
	are troff request handlers such that their names end with
	`_request`.

	* src/roff/troff/env.cpp
	(tab_character): Rename this...
	(tab_character_request): ...to this.
	(leader_character): Rename this...
	(leader_character_request): ...to this.
	(hyphen_char): Rename this...
	(hyphenation_character_request): ...to this.
	(field_characters): Rename this...
	(field_characters_request): ...to this.  Also mark it `static`
	because the `environment` class has no need for `friend` access
	to it, unlike the foregoing.
	(init_env_requests): Wire up request names to new handler
	function names.
	* src/roff/troff/input.cpp
	(set_page_character): Rename this...
	(page_character_request): ...to this.  Also mark it `static`
	because the `environment` class has no need for `friend` access
	to it.
	(init_input_requests): Wire up request name to new handler
	function name.
	* src/roff/troff/node.cpp
	(set_soft_hyphen_character): Rename this...
	(soft_hyphen_character_request): ...to this.
	(init_node_requests): Wire up request name to new handler
	function name.

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

	* src/roff/troff/input.cpp (read_title_parts): Fix code style
	nit; parenthesize formally complex expressions.

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

	[troff]: Trivially refactor, continuing naming reform of
	functions that advance the input stream pointer to use the verb
	"read" instead of "get" or "has", which are more general, and
	can refer to accessor functions that don't mutate the state of
	the formatter.

	* src/roff/troff/token.h:
	* src/roff/troff/input.cpp:
	(get_optional_char): Rename this...
	(read_character): ...to this.
	* src/roff/troff/env.cpp (tab_character, leader_character)
	(hyphen_char, field_characters):
	* src/roff/troff/input.cpp (set_page_character):
	* src/roff/troff/node.cpp (set_soft_hyphen_character): Update
	call sites.

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

	* src/roff/troff/node.cpp (set_soft_hyphen_character):
	Explicitly compare value of pointer type to null pointer literal
	instead of letting it pun down to a Boolean.

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

	* src/roff/troff/input.cpp (warn_request): Disclose value of
	invalid argument encountered when warning of its out-of-range
	status.

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

	* src/roff/troff/div.cpp (do_divert): Fix code style nit.
	Assign Boolean, not integer, literal, to variable of type
	`bool`.

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

	[troff]: Fix Savannah #67139.  Make diversion objects track
	whether they're "boxed" diversions; GNU troff does not deal
	gracefully with opening a diversion as the regular kind but
	trying to close it as a boxed one.

	* src/roff/troff/div.h (class diversion): Add public member
	variable `is_box`.  Add Boolean argument to constructor with
	default value of `false`.
	(class macro_diversion): Add Boolean argument to constructor.
	* src/roff/troff/div.cpp (diversion::diversion): Constructor now
	takes `boxing` Boolean argument and sets `is_box` from it in the
	initializer list.
	(do_divert): Throw error diagnostics and ignore diversion
	closure attempt if the request mismatches the box property of
	the current diversion.  It's a plain error in the `.box foo,
	.di` case and a fatal one in `.di foo, .box` because (only) the
	latter causes invalid memory access.

	Fixes <https://savannah.gnu.org/bugs/?67139>.  Thanks to an
	anonymous submitter for the report.  Problem reproducible with
	groff 1.22.3 (2014), and appears to date back at least to commit
	dc3c168c3b, 10 October 2004.  Another guess would be the
	introduction of box diversions in groff 1.17 (2001).

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

	[groff]: Regression-test Savannah #67139 (attempted closure of a
	regular diversion with the `box` request causes invalid memory
	access).

	* src/roff/groff/tests/\
	  do-not-crash-on-mismatched-diversion-request.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

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

	* src/preproc/html/pre-html.cpp: Enable debugging code, ripping
	out use of preprocessor to disable it.

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

	* src/preproc/html/pre-html.cpp: Add `const` qualifier to `char
	*`-typed globals `macroset_template`, `image_dir`, and
	`antiAlias`.
	(make_strike): `const`-qualify `char *` return type.
	(imageList::createImage): Declare local variable `s` closer to
	point of use, and `const`-qualify its `char *` type.  Use C++
	`const_cast` operator when passing it to free(3).

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

	* src/include/lib.h (xtmpfile): Update declaration to add
	`const` qualifier to `char **` argument `namep`.
	* src/libs/libgroff/tmpfile.cpp (xtmpfile): Do the same for the
	definition.  This way C++ string literals can be passed to these
	functions without provoking `-Wwrite-string` complaints from the
	compiler.
	* src/preproc/html/pre-html.cpp: Add `const` qualifier to `char
	*` globals `psFileName`, `psPageName`, `regionFileName`,
	`imagePageName`, `troffFileName`, and `htmlFileName`.
	(generateImages): Add `const` qualifier to `char *` argument.
	* src/preproc/html/pushback.h: Add `const` qualifier to `char *`
	private member variable `fileName` and to argumentful
	constructor.
	* src/preproc/html/pushback.cpp
	(pushBackBuffer::pushBackBuffer): Add `const` qualifier to `char
	*` argument.

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

	* src/preproc/html/pre-html.cpp (imageList::createImage)
	[DEBUGGING]: Fix syntax error in disabled code.

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

	[mdoc]: Refactor continuous rendering mode to use an "infinite
	page length" method facilitated by the new semantics of the `.R`
	register.

	* tmac/mdoc/doc-common (doc-ne): Drop unneeded macro.
	(doc-bp): Define with `de1` to temporarily disable compatibility
	mode, and replace definition.  No longer altering the page
	length, it works like `br`, including control-character-
	sensitive behavior.
	(doc-set-up-continuous-rendering): Drop macro in favor of
	open-coded initialization logic.
	([initialization]): If continuously rendering, set up
	replacement macro for `bp` request and set the page length to
	"infinite".
	(Dd): Call `doc-break-page-with-new-number` only if _not_
	continuously rendering.
	(doc-end-macro): If continously rendering, stop incrementing the
	page length prior to writing the footer and document separation
	rule, and upon encountering the end of the last document (the
	input file name register `.F` becomes empty), set the page
	length to the vertical drawing position.

	Fixes <https://savannah.gnu.org/bugs/?65190> (2/2).

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

	[man]: Refactor continuous rendering mode to use an "infinite
	page length" method facilitated by the new semantics of the `.R`
	register.

	* tmac/an.tmac (an-ne): Drop unneeded macro.
	(an-bp): Rename this...
	(an*bp): ...to this, define it with `de1` to temporarily disable
	compatibility mode, and replace definition.  No longer altering
	the page length, it works like `br`, including
	control-character-sensitive behavior.
	(an-end): If continously rendering, stop incrementing the page
	length prior to writing the footer and document separation rule,
	and upon encountering the end of the last document (the input
	file name register `.F` becomes empty), set the page length to
	the vertical drawing position.
	(an-end, TH): Call `an*break-page-with-new-number` only if _not_
	continuously rendering.
	(an-set-up-continuous-rendering): Drop macro in favor of
	open-coded initialization logic.
	(PT, BT): Stop manipulating the page length when continuously
	rendering.
	([initialization]): If continuously rendering, set up
	replacement macro for `bp` request and set the page length to
	"infinite".

	Fixes <https://savannah.gnu.org/bugs/?65190> (1/2).

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

	[troff]: Improve warning diagnostics.

	* src/roff/troff/env.cpp (space_size, hyphenate_request):
	* src/roff/troff/input.cpp (set_character_flags): Phrase notice
	of ignored argument(s) consistently with other GNU troff
	diagnostic messages.
	(hyphenate_request): Disclose valid range of argument to `hy`
	request when warning of a value beyond it.
	(adjust): Disclose valid range of argument (and the set of
	preferred letter synonyms) to `ad` request when warning of a
	value beyond it.
	* src/roff/troff/input.cpp (set_character_flags): Disclose value
	of invalid argument encountered when warning of its out-of-range
	status.

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

	[troff]: Make reported character flags scrutable.

	* src/roff/troff/input.cpp (charinfo::dump): When dumping
	character information with the `pchar` request, convert
	character flags bit mask to comprehensible human language.

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

	[troff]: Warn on contradictory `cflags` request argument.

	* src/roff/troff/input.cpp (set_character_flags): Throw warning
	in category "syntax" and ignore request if contradictory flag
	bits are set in the first argument.

	* doc/groff.texi.in (Warnings):
	* src/roff/troff/troff.1.man (Warnings): Document it.

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

	* src/roff/troff/dictionary.cpp (dictionary::lookup):
	* src/roff/troff/node.cpp (suppress_node::tprint): Favor
	function-style construction for temporaries over C-style type
	casts.
	* src/roff/troff/env.cpp (environment::make_tag):
	* src/roff/troff/input.cpp (set_string): Favor C++-style
	`static_cast` over C-style omnipotent casts.
	* src/roff/troff/mtsm.cpp (state_set::incl, state_set::excl)
	(state_set::is_in): Discard unnecessary C-style type casts of
	objects of enumerated type to `int`.  Pre-C++11 `enum`s like
	these are always backed by `int`s.

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

	* src/roff/troff/input.cpp: Trivially refactor.  Give the
	anonymous `struct` type used for `warning_table` a name, so that
	it can be passed to a template function C++98-conformantly.
	Preprocessor-include "lib.h" so we can use `array_length()`.
	(lookup_warning): Use `array_length()` to compute size of
	`warning_table` object.

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

	* src/roff/troff/input.cpp: Use an _unsigned_ `int` to handle
	the warning mask.  An unsigned type is more idiomatic for bit
	vectors like this.  Update type of `warning_mask`, and its type
	in the `warning_table` structure of anonymous type.  We still
	can't (or shouldn't) use the most significant bit, because all
	*roff arithmetic is signed.  That problem is still 11 warning
	categories away (not counting bit 4, temporarily unused).
	(lookup_warning): Add `unsigned` to return type.
	(lookup_warning, warning, output_warning): Use `0U` literal in
	assignments and comparisons to `unsigned int` objects, and in
	return values instead of `0`.
	(enable_warning, disable_warning): Add `unsigned` to type of
	local variable `mask`.  Explicitly compare value of integral
	type to integral literal instead of letting it pun down to a
	Boolean.
	(do_expr_test): Add `unsigned` to type of local variable
	`saved_warning_mask`.
	(init_input_requests): Create `.warn` built-in register as
	object of type `readonly_mask_register` instead of
	`readonly_register`, since the storage backing it is of unsigned
	integral type.

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

	* src/roff/troff/input.cpp: Add new class
	`readonly_mask_register` so we can represent unsigned values.
	(class readonly_mask_register): Do it.
	(readonly_mask_register::readonly_mask_register): Constructor
	takes pointer to `unsigned int`.
	(readonly_mask_register::get_string): Member function
	dynamically constructs a string representation of unsigned
	integral value.

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

	* src/roff/troff/input.cpp: Fix code style nit.
	(file_iterator::backtrace)
	(input_stack::check_end_diversion)
	(input_stack::shift)
	(input_stack::get_location)
	(input_stack::backtrace)
	(input_stack::set_location)
	(do_stroke_color)
	(do_fill_color)
	(define_color)
	(do_zero_width_output)
	(token::next)
	(do_request)
	(transparent_translate)
	(word_space_node::need_reread)
	(macro::append_str)
	(string_iterator::fill)
	(arg_list::arg_list)
	(macro_iterator::add_arg)
	(interpolate_macro)
	(macro_iterator::macro_iterator)
	(map_composite_character)
	(composite_glyph_name)
	(spring_trap)
	(read_request)
	(define_character)
	(remove_character)
	(do_define_macro)
	(read_size)
	(device_macro_request)
	(device_extension_node::tprint)
	(line_file)
	(set_character_flags)
	(token::add_to_zero_width_node_list)
	(pipe_output)
	(in_output_page_list)
	(do_register_assignment)
	(main)
	(read_drawing_command)
	(do_error)
	(fatal_with_file_and_line)
	(error_with_file_and_line)
	(debug_with_file_and_line): Explicitly compare values of pointer
	type to null pointer literals instead of letting them pun down
	to Booleans.

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

	* src/roff/troff/input.cpp: Handle input characters, which are
	of type `unsigned char`, more scrupulously.  Declare
	`escape_char` and `saved_escape_char` using that type instead of
	`int`.
	(assign_escape_character): Declare local variable `ec`
	as `unsigned char` instead of `char` (of undefined signedness).
	(assign_escape_character, escape_off, assign_control_character)
	(assign_no_break_control_character, get_copy, token::next)
	(skip_branch, asciify, token::get_char)
	(token::add_to_zero_width_node_list, token::process): Use `0U`
	literal in assignments and comparisons to `unsigned char`
	objects instead of `0` or '\0'.
	(get_copy): Use better relational operator with unsigned value
	when comparing to zero.
	(charinfo_to_node_list): Declare local variable
	`previous_escape_char` as `unsigned char` instead of `char` (of
	undefined signedness).

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

	* src/roff/troff/input.cpp (get_copy, token::next, skip_branch)
	(asciify): Fix code style nits.  Parenthesize formally complex
	expressions.  Reorder equality comparisons to avoid inadvertent
	lvalue assignment.

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

	* src/roff/troff/input.cpp (open_file): Un-pessimize.  Stop
	senselessly recomputing string literal selection when we already
	have a `char` pointer we can use.

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

	* src/roff/troff/input.cpp (print_streams): Mark as `static`
	since this function requires no external linkage.

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

	[troff]: Continue fixing Savanah #64104 after two years.

	* src/roff/troff/input.cpp (assign_control_character): Fix bug
	when `cc` request given no arguments; don't try to make the
	control character `\` (which fails unless the user has already
	changed the escape character).  Make it `.` instead, as
	documented.
	(assign_no_break_control_character): Fix bug when `c2` request
	given no arguments; don't try to make the no-break control
	character `\` (which fails unless the user has already changed
	the escape character).  Make it `'` instead, as documented.

	Continues fixing <https://savannah.gnu.org/bugs/?64104>.
	Problem introduced by me in a branch on 7 March 2023, but not
	merged onto the trunk until 10 July of that year, after the
	groff 1.23.0 release (fortunately).

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

	src/roff/troff/input.cpp: Fix code style nit.

	* src/roff/troff/input.cpp (token::next, exit_troff): Assign
	Boolean, not integer, literal, to variable of type `bool`.

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

	* src/roff/troff/node.cpp (class real_output_file): Demote
	member variable `piped` from `int` to `bool`, and rename it
	to `is_output_piped`.
	(real_output_file::real_output_file): Track rename and
	boolification in use of constant literals of Boolean type.
	(real_output_file::~real_output_file): Track rename.

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

	* src/roff/troff/node.cpp (class real_output_file): Demote
	member variable `printing` from `int` to `bool`, and rename it
	to `want_page_printed`.
	(real_output_file::real_output_file): Track rename and
	boolification in initializer and use of constant literal of
	Boolean type.
	(real_output_file::is_selected_for_printing)
	(real_output_file::begin_page)
	(real_output_file::copy_file)
	(real_output_file::transparent_char)
	(real_output_file::print_line): Track rename.

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

	[troff]: Boolify member function of `output_file` class that
	indicates whether the current page is selected for printing (as
	with troff's `-o` option).

	* src/roff/troff/node.h (class output_put): Demote
	member function `is_printing` from `int` to `bool`, and rename
	it to `is_selected_for_printing`.
	* src/roff/troff/node.cpp (class real_output_file): Update
	declaration and definition accordingly in derived class.

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

	* src/roff/troff/node.cpp (real_output_file::on): Comment out
	assertion that fails when formatting "pic.ms" as HTML.

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

	[groff]: Fix Savannah #67133; fail when piped command gets a
	SIGPIPE signal.

	* src/roff/groff/pipeline.c (run_pipeline) [!_WIN32 &&
	!__MSDOS__ && !_UWIN && !__CYGWIN__ && !__EMX__]:
	_Unconditionally_ set bit 2 of the return value in the event of
	_any_ signal hitting a pipelined process.  A workaround that
	James Clark put in for a SunOS 4.1.1 X11-related bug in groff
	1.06 (1992) appears to have led us to grief; if any of the child
	processes in the pipeline being wait(2)ed on was signaled with
	SIGPIPE, this alteration of the return value was not being done.
	If that child was the last in the pipeline (gxditview, the code
	presumes), he walks the list of commands in the pipeline and
	kill(2)s them all with SIGPIPE.  If a process has multiple fatal
	signals pending, which one wins?  Apparently, on Linux 5.10, in
	a fight between SIGPIPE and SIGABRT (raised by abort(3), called
	by assert(3)), SIGPIPE always wins.  So bit 2 of this function's
	return value, which (after a left shift) ultimately becomes
	groff(1)'s exit status, never got set, and so groff happily
	reported success when it should have screamed hideously of
	failure.  Likely the SunOS 4 workaround should be ripped out
	entirely, but this fix adequately detects grohtml failures.

	Fixes <https://savannah.gnu.org/bugs/?67133>.  Problem appears
	to date back to groff 1.06 (1992).

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

	Make build more sensitive to failure of HTML output.

	* doc/doc.am (doc/pic.html, doc/webpage.html): Create output as
	a ".tmp"-suffixed file at first, then check for the first of
	multiple associated image files we know should exist, moving the
	target into place only if it does.

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

	* src/roff/troff/node.cpp (real_output_file::on)
	(real_output_file::off): Add `assert()`ions of complementary
	Boolean state before unconditionally assigning the other.
	One of them fails, in a quiet and underhanded way, when using
	grohtml to format "doc/pic.ms", which scandalously doesn't
	provoke a build failure.  No automated tests trip it, either.  A
	document in the wild could conceivably trip either.  If one
	does, we want to hear about it, preferably with a core file
	generated by an unstripped troff executable.

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

	[troff]: Boolify output enablement-related (meaning: not
	suppressed by `\O[0]`) member variables and functions.

	* src/roff/troff/node.cpp (class real_output_file): Demote
	member variable `output_on` from `int` to `bool`, and rename it
	to `is_output_on`, to imply a logical predicate.  Demote public
	member function `is_on()` from `int` to `bool`.  Drop annotation
	of three-valued status; that unfortunate fact applies only to
	the `is_on` member variable of the `suppress_node` class.
	(real_output_file::real_output_file): Track rename and
	boolification in initializer and use of constant literal of
	Boolean type.
	(real_output_file::copy_file)
	(real_output_file::transparent_char): Track rename.
	(real_output_file::is_on): Track rename and demotion of return
	type.
	(real_output_file::on, real_output_file::off): Assign Boolean,
	rather than integer, literal to `is_output_on` member variable.
	(real_output_file::on): Express `if` statement as
	straightforward test of logical predicate.

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

	[troff]: Trivially refactor.  Respell the `unsigned` data type
	as `unsigned int`.  Use of `signed` and `unsigned` as if they
	were types of themselves rather than qualifiers on types is a
	slovenly practice from pre-ANSI C.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp (environment::get_hyphenation_mode)
	(environment::get_hyphenation_mode_default)
	(class unsigned_env_reg):
	(unsigned_env_reg::get_value):
	(hyphenate): Do it.

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

	[troff]: Refactor margin character flag handling.  Namespace it
	inside the `environment` class and use enumeration constants
	rather than global ones.

	* src/roff/troff/env.h: Drop global constant unsigned `int`s
	`MARGIN_CHARACTER_ON` and `MARGIN_CHARACTER_NEXT` in favor of...
	(class enviromment): ...a public anonymous enum type with
	constant values `MC_ON` and `MC_NEXT`.
	* src/roff/troff/env.cpp (environment::environment): Use
	unsigned integer literal when initializing
	`margin_character_flags` member variable.
	(margin_character, environment::print_env): Migrate to the
	namespaced enumeration constants.
	(margin_character, environment::output_line): Use unsigned
	integer literal when comparing to `margin_character_flags`
	member variable.

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

	* src/roff/troff/input.cpp (do_translate): Fix code style nit.
	Reorder equality comparisons to avoid inadvertent lvalue
	assignment.

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

	* src/roff/troff/input.cpp (charinfo::charinfo)
	(charinfo::get_unicode_code): Fix code style nit.  Use unsigned
	integer literals when initializing and comparing to character
	flags, "ASCII codes", and "asciify codes" which are of type
	`unsigned int`.

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

	* src/roff/troff/input.cpp (exit_troff)
	(composite_glyph_name)
	(do_define_macro)
	(charinfo::get_flags) [0]: Favor C++-style `static_cast` over
	C-style omnipotent casts.
	(exit_troff): Use explicit `reinterpret_cast` C++ operator
	instead of C-style cast.  Annotate why we use this footgun.

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

	[troff]: Warn on out-of-range `cflags` request argument.

	* src/roff/troff/charinfo.h (class charinfo): Add `CFLAGS_MAX`
	enumeration constant.

	* src/roff/troff/input.cpp (set_character_flags): Throw warning
	in category "range" and ignore request if first argument is a
	valid integer but out of range.

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

	[troff]: Fix code style nit; use unsigned integer literals when
	assigning to or comparing with hyphenation codes, which are of
	type `unsigned char`.

	* src/roff/troff/charinfo.h (charinfo_node::get_asciify_code):
	* src/roff/troff/env.cpp (environment::hyphenate_line)
	(add_hyphenation_exceptions)
	(hyphenate):
	* src/roff/troff/input.cpp (set_hyphenation_codes)
	(charinfo::charinfo)
	(charinfo::set_translation):
	* src/roff/troff/node.cpp (break_char_node::add_self)
	(composite_node::asciify)
	(overstrike_node::get_hyphen_list): Do it.

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

	* src/roff/troff/node.cpp: Fix code style nits.
	(font_info::get_tfont)
	(tfont::get_lig)
	(troff_output_file::flush_tbuf)
	(troff_output_file::put_char_width)
	(troff_output_file::put_char)
	(troff_output_file::set_font)
	(troff_output_file::really_copy_file)
	(node::add_discretionary_hyphen)
	(break_char_node::add_self)
	(space_node::split)
	(node_list_split)
	(composite_node::asciify)
	(hline_node::tprint)
	(vline_node::tprint)
	(overstrike_node::tprint)
	(node::add_char)
	(same_node): Reorder equality comparisons to avoid inadvertent
	lvalue assignment.

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

	* src/roff/troff/node.cpp (container_node::dump_node): Give
	contained node list a JSON key name.

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

	* src/roff/troff/node.cpp (troff_output_file::fill_color)
	(troff_output_file::stroke_color): Emit motion commands prior to
	changing fill or stroke color only in nroff mode.  Annotate why.

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

	* src/roff/troff/node.cpp (make_glyph_node): Assign Boolean, not
	integer, literal, to variable of type `bool`.

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

	* src/roff/troff/node.cpp (troff_output_file::fill_color)
	(troff_output_file::stroke_color): Rename local variable from
	`cs` to `scheme`; `cs` can be confusing in a troff context.

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

	* src/roff/troff/node.cpp: Fix code style nits.
	(font_info::is_style)
	(tfont::is_kerned)
	(dbreak_node::split)
	(node::add_char): Reorder equality comparisons to avoid
	inadvertent lvalue assignment.
	(make_tfont)
	(font_info::get_tfont)
	(font_info::set_conditional_bold)
	(font_info::conditional_unbold)
	(tfont::tfont)
	(ascii_output_file::outs)
	(kern_pair_node::merge_glyph_node)
	(kern_pair_node::add_discretionary_hyphen)
	(kern_pair_node::last_char_node)
	(dbreak_node::last_char_node)
	(node_list_character_type)
	(node_list_vertical_extent)
	(overstrike_node::copy)
	(overstrike_node::overstrike)
	(bracket_node::copy)
	(word_space_node::asciify)
	(dbreak_node::split)
	(composite_node::width)
	(composite_node::vertical_width)
	(word_space_node::did_space_merge)
	(overstrike_node::tprint)
	(bracket_node::tprint)
	(make_node)
	(character_exists)
	(node::add_char)
	(left_italic_corrected_node::merge_glyph_node)
	(remove_font_specific_character)
	(env_digit_width): Explicitly compare values of pointer type to
	null pointer literals instead of letting them pun down to
	Booleans.

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

	[troff]: Slighty refactor (boolify, rename).

	* src/roff/troff/node.cpp (glyph_node::tprint)
	(glyph_node::zero_width_tprint, composite_node::tprint): Rename
	`bold` and `cs` local variables to `is_emboldened` and
	`is_constantly_spaced` to express logical predication.
	(glyph_node::zero_width_tprint, composite_node::tprint): Demote
	same local variables from `int` to `bool`.

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

	[troff]: Slighty refactor (boolify, rename).

	* src/roff/troff/node.cpp (class tfont_spec): Demote member
	variable `is_constant_spaced` from `char` to `bool`, and rename
	it to `has_constant_spacing`.  It only ever takes two values, so
	the use of a `char` instead of an `int` (in pre-standard C++)
	might have been a premature space optimization.  The new name
	avoids collision with the member function `is_constantly_spaced`
	and also somewhat better implies a process applied to a font
	rather than an inherent property of a typeface.  Both senses of
	"constant spacing" exist in *roff (contrast proportional with
	monospaced typefaces); this is the one manipulated by the `cs`
	request.
	(tfont_spec::tfont_spec): Use Boolean, not integer, literal for
	it in initializer list.
	(tfont_spec::tfont_spec, font_info::get_tfont, tfont::get_width)
	(tfont::is_constantly_spaced): Track rename.
	(font_info::get_tfont): Use Boolean, not integer, literals in
	assignments to variable of type `bool`.

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

	[troff]: Slighty refactor (boolify, rename).

	* src/roff/troff/node.cpp (class font_info, class tfont_spec):
	Demote member variable `is_bold` from `char` to `bool`, and
	rename it to `has_emboldening`.  It only ever takes two values,
	so the use of a `char` instead of an `int` (in pre-standard C++)
	might have been a premature space optimization.  The new name
	avoids collision with the member function `is_emboldened` and
	also somewhat better implies a process applied to a font rather
	than an inherent property of a typeface.  Both senses of "bold"
	exist in *roff; this is the one manipulated by the `bd` request.
	(font_info::font_info, tfont_spec::tfont_spec): Use Boolean, not
	integer, literal for it in initializer list.
	(font_info::font_info, tfont_spec::tfont_spec)
	(font_info::get_tfont, font_info::is_emboldened)
	(font_info::unbold, font_info::set_bold, tfont_spec::operator==)
	(tfont::get_width, tfont::is_emboldened): Track rename.
	(font_info::get_tfont, font_info::is_emboldened)
	(font_info::unbold, font_info::set_bold, tfont_spec::operator==)
	(tfont::get_width, tfont::is_emboldened): Use Boolean, not
	integer, literals in assignments to variables of type `bool`.

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

	* src/roff/troff/env.cpp (compare_ranges, distribute_space)
	(hyphen_trie::read_patterns_file): Favor C++-style `static_cast`
	and `const_cast` over C-style omnipotent casts.

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

	* tmac/doc.tmac (Bd): Fix code style nit.  Perform "strict"
	string comparison when using formatted output comparison
	operator to peform matching on macro argument.  See
	subsection/node "Operators in Conditionals" in groff's Texinfo
	manual.

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

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

	[mdoc]: Revise font customization feature.

	groff's mdoc(7) package now expects the strings that designate
	font names to be precisely that: font _names_ (or abstract
	styles, or mounting positions), rather than arbitrary *roff
	syntax.  This undocumented customization feature is analogous to
	one in 4.4BSD mdoc(7) but has no counterpart in mandoc(1).

	This change also makes groff mdoc's (complex) internal logic
	easier to follow in the `Nm`, `Pa`, `doc-bullet-list`,
	`doc-dash-list`, `Xr`, `Ot`, `doc-do-func`, `Fn`, `Fo`, `Rv`,
	`doc-header`, and `doc-footer` macro definitions.

	* tmac/mdoc/doc-ditroff:
	* tmac/mdoc/doc-nroff: Update default definitions of
	`doc-*-font` strings to omit font selection escape sequence,
	leaving only font names or string interpolations like `\*[MF]`
	and `\*[HF]` that are themselves specified as naming fonts.

	* tmac/doc.tmac (Fl, doc-generic-macro, Ar, Cd, Fd, In, Nm, Pa)
	(Tn, Bf, Bd, doc-bullet-list, doc-dash-list, doc-diag-list, Xr)
	(Vt, Ft, Ot, Fa, doc-do-func, Fn, Fo, %B, %I, %J, %T, Rv, Mt)
	(Lk):
	* tmac/mdoc/doc-common (doc-header, doc-footer, Sh, Ss):
	* tmac/mdoc/doc-nroff (Dl): Bracket interpolations of
	`doc-*-font` strings with font selection escape sequence syntax.

	* NEWS: Add item warning of incompatible change.

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

	[troff]: Implement new `pftr` request.

	* src/roff/troff/node.cpp (dump_font_translations): Add.
	(init_node_requests): Wire up `pftr` request name to
	`dump_font_translations()`.

	* doc/groff.texi (Selecting Fonts, Debugging):
	* man/groff.7.man (Request short reference, Debugging):
	* man/groff_diff.7.man (New requests, Debugging):
	* NEWS: Document it.

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

	* tmac/mdoc/doc-syms (Lb): Stop throwing warning if no
	description is available for the argument.  `Lb` usage is not
	universal among mdoc(7) documents; per Ingo Schwarze, FreeBSD
	and NetBSD use it, but OpenBSD does not.  (And in my opinion,
	maintaining a central registry for library descriptions is not
	tractable.)

	Fixes <https://savannah.gnu.org/bugs/?66410>.  Thanks to Andrew
	Bower for the report.

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

	* tmac/doc.tmac: Unconditionally initialize `doc-do-capitalize`,
	to avoid warnings when formatting degenerate documents lacking
	an `Sh` call.

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

	* tmac/doc.tmac: Save and restore AT&T troff compatibility mode,
	as man(7) does.

	Fixes <https://savannah.gnu.org/bugs/?65702>.  Thanks to Bjarni
	Ingi Gislason for the report.

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

	* tmac/doc.tmac (Nm): Stop suppressing use of bold (or typeface
	configured via the `doc-Nm-font` string) when rendering
	occurrence in the "Name" section of a document.

	Fixes <https://savannah.gnu.org/bugs/?65101>.  Thanks to наб for
	the report.  Reverts a change I made in groff 1.23.0.

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

	[libgroff]: Drop dead code.

	* src/libs/libgroff/assert.cpp: Delete.
	* src/libs/libgroff/libgroff.am (libgroff_a_SOURCES): Remove
	aforementioned file from macro definition.

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

	[indxbib]: Drop dead code (unused function).

	* src/utils/indxbib/indxbib.cpp (fatal_error_exit): Do it.
	Revealed by `-Wunused-function` when marking this function as
	`static`.

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

	[troff]: Drop dead code (unused function).

	* src/roff/troff/input.cpp (get_output_registers): Do it.
	Revealed by `-Wunused-function` when marking these functions as
	`static`.

2025-04-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grolj4, pic]: Improve C++98 conformance.

	* src/devices/grolj4/lj4.cpp (struct lj4_command_table):
	* src/preproc/pic/pic.ypp (struct pic_defaults_table): Give
	anonymous structure types names; anonymous structs cannot be
	passed to templates prior to C++11.

2025-04-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp (string::json_length):
	* src/libs/libgroff/symbol.cpp (symbol::json_length): Drop
	unnecessary/tautologous comparisons of integer literals with
	objects of plain `char` type, which are of undefined signedness.

2025-04-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/nametoindex.cpp (glyph_to_name): Use
	explicit `reinterpret_cast` C++ operator instead of C-style
	cast.  Annotate why we use this footgun.

2025-04-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/nametoindex.cpp: Fix code style nits.
	(character_indexer::ascii_char_glyph)
	(character_indexer::numbered_char_glyph)
	(name_to_glyph): Reorder equality comparisons to avoid
	inadvertent lvalue assignment.
	(character_indexer::named_char_glyph)
	(character_indexer::numbered_char_glyph)
	(name_to_glyph): Parenthesize formally complex expressions.
	(character_indexer::named_char_glyph): Slightly refactor;
	replace series of individual character comparisons with a
	`strncmp()` call.

2025-04-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (glyph_to_name): Parenthesize
	formally complex expression.

2025-04-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (glyph_to_name): Use explicit
	`reinterpret_cast` C++ operator instead of C-style cast.
	Annotate why we use this footgun.

2025-04-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Fix code style nits.
	(is_valid_font_mounting_position): Parenthesize formally complex
	expression.
	(read_font_identifier): Favor C++-style `const_cast` over
	C-style omnipotent cast.

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

	[troff]: Favor C++-style `static_cast` over C-style omnipotent
	casts.

	* src/roff/troff/column.cpp (vjustify_node::same) [COLUMN]:
	* src/roff/troff/dictionary.cpp (object_dictionary::lookup)
	(object_dictionary::rename, object_dictionary::remove)
	(object_dictionary::alias):
	* src/roff/troff/env.cpp (hyphen_trie::do_match)
	(hyphen_trie::do_match):
	* src/roff/troff/input.cpp
	(non_interpreted_char_node::is_same_as, lookup_color)
	(token_node::is_same_as, interpolate_macro, do_define_string)
	(non_interpreted_node::is_same_as, get_charinfo_by_index):
	* src/roff/troff/node.cpp (dbreak_node::merge_glyph_node)
	(suppress_node::is_same_as, tag_node::is_same_as, get_register)
	(get_string, draw_node::is_same_as, extra_size_node::is_same_as)
	(vertical_size_node::is_same_as, hmotion_node::is_same_as)
	(space_char_hmotion_node::is_same_as, vmotion_node::is_same_as)
	(hline_node::is_same_as, vline_node::is_same_as)
	(italic_corrected_node::is_same_as)
	(left_italic_corrected_node::is_same_as)
	(composite_node::is_same_as, glyph_node::is_same_as)
	(kern_pair_node::is_same_as, break_char_node::is_same_as)
	(space_node::is_same_as, word_space_node::is_same_as): Do it.

2025-04-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/stringclass.h (operator+): Fix code style nit:
	reorder equality comparisons to avoid inadvertent lvalue
	assignment.

2025-04-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/stringclass.h (operator[], string::empty)
	(operator+, string::substring): Fix code style nit: parenthesize
	formally complex expressions.

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

	* src/include/stringclass.h (operator+): Dump workaround for
	ancient (~1995) compiler bug affecting ternary operator.  Sun
	C++ 4.0 is no longer relevant.

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

	[troff]: Fix code style nits.

	* src/roff/troff/input.cpp (temp_iterator::temp_iterator):
	* src/roff/troff/node.cpp (same_node): Un-guard `inline` keyword
	from preprocessor.  `inline` is a standard C++98 keyword, and
	not (any longer?) a GNU extension.
	* src/roff/troff/node.h: Rationalize "#include"s.  Include C
	standard library header file we require.

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

	[troff]: When input blows out the stack, say how big it was.

	* src/roff/troff/input.cpp (input_stack::push)
	(input_stack::next_file): In fatal diagnostics complaining of
	excessive *roff language stack use (not the process stack),
	disclose how many levels of stack were configured.

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

	[troff]: Fix build failure with Clang 20, GCC 9.3 and likely
	some other compilers.

	* src/roff/troff/node.cpp (is_valid_font_mounting_position):
	Drop `inline` from definition of externally visible function.
	"[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)

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

	* src/roff/troff/node.cpp (env_font_emboldening_offset)
	(env_half_narrow_space_width)
	(env_narrow_space_width): Trivially refactor.  Return
	type-correct constant for a horizontal measure of zero.

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

	[troff]: Slighty refactor (boolify, rename).

	* src/roff/troff/node.h (struct node)
	(class left_italic_corrected_node): Demote return type
	of `overlaps_horizontally()` and `overlaps_vertically()` virtual
	member functions from `int` to `bool`.
	* src/roff/troff/node.cpp (class charinfo_node)
	(class italic_corrected_node)
	(class break_char_node): Same for classes with no visibility
	external to this translation unit.
	(charinfo_node::overlaps_horizontally)
	(charinfo_node::overlaps_vertically)
	(italic_corrected_node::overlaps_horizontally)
	(italic_corrected_node::overlaps_vertically)
	(break_char_node::overlaps_horizontally)
	(break_char_node::overlaps_vertically)
	(node::overlaps_horizontally)
	(node::overlaps_vertically)
	(left_italic_corrected_node::overlaps_horizontally)
	(left_italic_corrected_node::overlaps_vertically): Same for
	function definitions.
	(node::overlaps_horizontally)
	(node::overlaps_vertically)
	(left_italic_corrected_node::overlaps_horizontally)
	(left_italic_corrected_node::overlaps_vertically): Return
	Boolean instead of integer literals.
	(vline_node::tprint): Demote local variable `overlaps`
	similarly.

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

	[troff]: Slighty refactor (boolify, rename).

	* src/roff/troff/node.cpp (class tfont_spec): Demote return type
	of `operator==` from `int` to `bool`.
	(tfont_spec::operator==): Same for function definition.

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

	[troff]: Slighty refactor (boolify, rename).

	* src/roff/troff/node.cpp (class tfont): Demote return type of
	`get_kern()` member function from `int` to `bool` and rename to
	`is_kerned()`.
	(tfont::get_kern): Same for function definition, renaming
	this...
	(tfont::is_kerned): ...to this.  Return Boolean instead of
	integer literals.
	(glyph_node::merge_glyph_node): Update call site.

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

	[troff]: Slighty refactor (boolify, rename).

	* src/roff/troff/node.cpp (class tfont): Demote return type of
	`get_constant_space()` member function from `int` to `bool` and
	rename to `is_constantly_spaced()`.
	(tfont::get_constant_space): Same for function definition,
	renaming this...
	(tfont::is_constantly_spaced): ...to this.  Return Boolean
	instead of integer literals.
	(composite_node::width)
	(glyph_node::tprint)
	(glyph_node::zero_width_tprint)
	(composite_node::tprint): Update call sites.

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

	[troff]: Slighty refactor (boolify, rename).

	* src/roff/troff/node.cpp (class font_info)
	(class tfont): Demote return type of `get_bold()` member
	functions from `int` to `bool` and rename to `is_emboldened()`.
	(font_info::get_bold, tfont::get_bold): Same for function
	definitions, renaming these...
	(font_info::is_emboldened, tfont::is_emboldened): ...to these.
	Return Boolean instead of integer literals.
	(composite_node::width)
	(glyph_node::tprint)
	(glyph_node::zero_width_tprint)
	(composite_node::tprint)
	(env_font_emboldening_offset): Update call sites.

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

	[troff]: Slightly refactor (boolify).

	* src/roff/troff/node.h (struct node):
	* src/roff/troff/node.cpp (node::interpret): Demote return type
	of `interpret` virtual member function from `int` to `bool`.
	* src/roff/troff/input.cpp (class non_interpreted_char_node)
	(non_interpreted_char_node::interpret)
	(class non_interpreted_node)
	(non_interpreted_node::interpret): Same.
	* src/roff/troff/input.cpp
	(non_interpreted_char_node::interpret)
	(non_interpreted_node::interpret): Return Boolean instead of
	integer literals.

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

	[troff]: Slightly refactor.

	* src/roff/troff/env.h (get_bold): Rename this declaration...
	(get_emboldening_offset): ...to this.  Change return type from
	`int` to `hunits`.
	* src/roff/troff/env.cpp (get_bold):
	(get_emboldening_offset): Same for definition.
	(init_env_requests): Wire up `.b` register to
	`get_emboldening_offset()` using `init_hunits_env_reg()` instead
	of `init_int_env_reg()`.

	* src/roff/troff/node.h (get_bold_fontno): Rename this
	declaration...
	(env_font_emboldening_offset): ...to this, because it doesn't
	return a "fontno" (mounting position) at all.  Change return
	type from `int` to `hunits`.

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

	* src/roff/troff/node.cpp (embolden_font): Add diagnostics.
	Throw error when input attempts to apply emboldening request to
	syntactically invalid object (e.g., ".bd \N'12'" or ".bd 1
	\N'12'").  Add new Boolean local variable
	`emboldening_may_be_conditional` to improve diagnostics when the
	argument count makes the request ambiguous.  Throw warning if
	we're ignoring the third argument because the first two were
	interpreted as a mounting position and emboldening amount,
	respectively.  As annotated in comments, 'Does ".bd 1 2" mean
	"embolden font position 1 by 2 units" (really one unit), or
	"stop conditionally emboldening font 2 when font 1 is
	selected"?'  Also parenthesize complex expression.

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

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

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

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

	* src/roff/troff/node.cpp (font_lookup_info): Improve diagnostic
	message.  When complaining, for example, that a font can't be
	loaded because its mounting position was unresolvable, don't
	report a mounting position of "-1" in the message.  That's an
	internal sentinel value and meaningless to the user.

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

	[troff]: Fix Savannah #67038.

	* src/roff/troff/node.h: Declare `get_bold_fontno` as taking a
	new first argument, a pointer to an `environment`.
	* src/roff/troff/node.cpp (get_bold_font): Likewise with
	definition, and resolve the environment's currently selected
	font so that we report the correct emboldening amount even if an
	abstract style is the current font selection.  Like
	`env_get_zoom()`, use a temporary variable to avoid yard-long
	expression.  This behavior comports better with DWB and Heirloom
	Doctools troffs.

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

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

	[groff]: Regression-test Savannah #67038 (behavior of `.b`
	register).

	* src/roff/groff/tests/dot-b-register-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

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

	* src/roff/troff/node.cpp: Trivially refactor, continuing naming
	reform of functions that advance the input stream pointer to use
	the verb "read" instead of "get" or "has", which are more
	general, and can refer to accessor functions that don't mutate
	the state of the formatter.
	(has_font): Rename this...
	(read_font_identifier): ...to this.
	(select_underline_font)
	(define_font_specific_character)
	(remove_font_specific_character)
	(read_special_fonts)
	(set_font_specific_special_fonts)
	(embolden_font)
	(configure_track_kerning)
	(constantly_space_font): Update call sites.

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

	* src/roff/troff/node.cpp (env_sentence_space_width): Trivially
	refactor for readability.  Introduce local variable to store
	return value of member function that is called invariantly.

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

	[troff]: Slightly refactor.  Boolify and rename
	`is_good_fontno()` to `is_valid_font_mounting_position()`, and
	use it in more places instead of complex expressions meaning the
	same thing.

	* src/roff/troff/node.h: Update declaration.
	* src/roff/troff/node.cpp: Update definition, and define earlier
	to avoid necessity of forward declaration.

	* src/roff/troff/env.cpp (environment::set_font)
	(environment::environment): Update call sites.

	* src/roff/troff/node.cpp (has_font, get_bold_fontno)
	(env_space_width)
	(env_sentence_space_width)
	(env_half_narrow_space_width)
	(env_narrow_space_width): Add call sites, replacing complex
	expressions.

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

	[troff]: Slightly refactor.  Use a manifest constant for
	failures to look up a font.  Aping libc-style, `errno`-using
	functions conceals more than it reveals here since we have no
	analog to `errno`.  (`errno` was a blind alley anyway, being as
	reentrant and concurrency-friendly as a global lock, but worse
	because it led to indeterminate program states instead of
	slow-but-correct operation.  Option types, error-storing
	function parameters, and exceptions are all better solutions.)

	* src/roff/troff/node.h: Declare `FONT_NOT_MOUNTED`.
	* src/roff/troff/node.cpp: Define it.
	* src/roff/troff/node.cpp (font_lookup_info::font_lookup_info)
	(troff_output_file::really_begin_page)
	(troff_output_file::really_copy_file)
	(font_family::font_family)
	(font_family::resolve)
	(font_family::invalidate_fontno)
	(has_font)
	(symbol_fontno): Use it instead of a `-1` literal.

	* src/roff/troff/env.cpp (environment::set_font)
	(environment::set_family)
	(environment::environment): Determine font lookup failure by
	explicit comparison to `FONT_NOT_MOUNTED` instead of checking
	for any negative value.
	(font_family::resolve): Add assertion to spit up if caller tries
	to smuggle us a nonsense mounting position.

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

	[troff]: Trivially refactor.

	* src/roff/troff/node.cpp (env_definite_font): Rename this...
	(env_resolve_font): ...to this.  Also mark it `static` since it
	requires no external linkage.
	(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.

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

	[troff]: Trivially refactor.  Rename
	`font_family::make_definite()` to `font_family::resolve()`, to
	better align internal naming practices with our documentation.

	* src/roff/troff/node.h (class font_family): Do it.
	* src/roff/troff/node.cpp (font_family::make_definite): Rename
	this...
	(font_family::resolve): ...to this.

	* src/roff/troff/env.cpp (environment::set_font)
	(environment::set_family,environment::environment):
	* src/roff/troff/node.h (env_definite_font, env_get_zoom)
	(has_font): Update call sites.

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

	[troff]: Fix code style nits.

	* src/roff/troff/input.cpp (do_suppress): Drop unnecessary cast
	of `0` when performing null pointer comparison.  "A constant
	expression ... that evaluates to 0 can be implicitly converted
	to any pointer or pointer to member type." (_The C++ Programming
	Language, Special Edition_, Stroustrup, 1997, p. 835).

	* src/roff/troff/input.cpp (do_suppress):
	* src/roff/troff/node.cpp (has_font, env_space_width)
	(env_sentence_space_width, env_half_narrow_space_width)
	(env_narrow_space_width): Reorder equality comparisons to avoid
	inadvertent lvalue assignment.

	* src/roff/troff/input.cpp (do_suppress): ...and apply
	DeMorgan's Law to the same end.

	* src/roff/troff/input.cpp (device_extension_node::tprint):
	Invert sense of and reorder `if` statement to (1) avoid
	inadvertent lvalue assignment and (2) execute the common case
	first, for the human reader's benefit as well as a gesture at
	assisting branch prediction.

	* src/roff/troff/node.cpp: Initialize global `last_position` of
	type `char` to a meaningful default.  This datum should be of an
	`enum` type, but enum types in C and C++ prior to C++11 were
	feeble and rewarded sloppy programming techniques.  ("An
	enumerated type can be seen as a degenerate tagged union of unit
	type." [Wikipedia].  Because C is really B++ and B was typeless
	{see Ritchie 1993, HOPL 2}, disciples of Ritchie blessed the
	world with countless billion-dollar mistakes; see Hoare 2009.)
	(font_info::contains, font_info::is_special)
	(font_info::is_style, make_composite_node, make_glyph_node)
	(mount_font_no_translate, mount_style)
	(font_family::make_definite, has_font, zoom_font, symbol_fontno)
	(is_good_fontno, get_bold_fontno, env_space_width)
	(env_sentence_space_width, env_half_narrow_space_width)
	(env_narrow_space_width): Parenthesize complex expressions.
	(suppress_node_put): Compare element of `char` array to
	character literal rather than an integer literal with a C-style
	typecast to `char`.

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

	* src/roff/troff/input.cpp (open_file, close_stream)
	(do_write_request, write_macro_request): Fix code style nit,
	using C++-style (static) type cast instead of C-style cast.

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

	* src/roff/troff/input.cpp: Tidy up `grostream` type definition.
	(class grostream): Convert (back) from this...
	(struct grostream): ...to this, since all its members are public
	anyway.  Also drop `public` access specifier from `object` base
	class since we require no visibility of its members.  Also mark
	member variables as `const` since they should be immutable after
	construction.

2025-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Refactor `grostream` class for
	memory safety.
	(struct grosteam): Convert from this...
	(class grostream): ...to this, inheriting from class `object` so
	that it casts less dangerously thence and thither when stashing
	`grostream`s into and retrieving them from `object_dictionary`
	objects.
	(class grostream): Also re-type `filename` and `mode` member
	variables from (groff) `string` to `symbol`, since they won't
	have embedded null characters (and take up half as much space;
	`sizeof (string)` is 16 on GNU/Linux amd64 whereas that of
	`symbol` is 8).  Making this change by itself exposed memory
	corruption problems, resolved by resituating `grostream` in the
	class hierarchy.
	(grostream::grostream): Drop now unnecessary explicit null
	termination.  That property is implied by the `symbol` class.
	(open_file): Make newly created object anonymous, and drop
	frightening C-style typecast.  Now a `grostream` casts safely
	and implicitly to and from `object`.

	Problem likely introduced by me in commit 6d32f2492, 24
	September, but it was latent (requiring the `symbol` change
	noted above), and without JSON dumpers for `string` and `symbol`
	objects, visibility into memory mischief was limited if it
	didn't cause a SEGV on a developer's machine.

2025-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/symbol.cpp: Fix code style nits.
	(symbol::symbol): Parenthesize complex expressions.  Drop braces
	guarding single-statement control structure bodies.

2025-04-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (print_streams): Report open streams
	using JSON syntax.

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

2025-04-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (grostream::grostream):
	Null-terminate `mode` structure member as well.

2025-04-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_write_request): Fix SEGV when
	attempting to write to a stream that doesn't exist.

2025-04-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (macro_header::json_dump): If a macro
	has non-zero "length", always dump both its "contents" _and_ its
	"node list".  The `asciify` and `unformat` requests produce a
	hybrid macro-diversion containing both.  Each null character in
	the "contents" corresponds to a node in the "node list".

2025-04-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Adjust debugging/dump output.

	* src/roff/troff/node.cpp (dump_node_list): Drop label from
	dumped list, making its identification the caller's
	responsibility.
	* src/roff/troff/input.cpp (macro_header::json_dump_diversion):
	Embrace said responsibility.

2025-04-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* m4/groff.m4 (GROFF_PROG_SH): Search for more shells.  A recent
	message to the Austin Group mailing list revealed which shells
	they routinely work with.  Search for shells named ksh93, ksh88,
	mksh, and yash as well.

	"Using the test script in Mantis bug 1915 we have observed four
	different behaviors among shells whose behavior we usually
	consider when investigating issues: one shared by dash, ksh93
	and yash; and one each from bash, mksh and ksh88."

	See <https://www.mail-archive.com/austin-group-l@opengroup.org/\
	msg13723.html>.

2025-04-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (file_iterator::get_location): Add
	`assert()`; a file iterator should always have a defined file
	name.

2025-04-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/html-device-smoke-test.sh: Use printf(1)
	more portably (`\(` is not well-defined in a format string).
	Thanks to Lennart Jablonka for the report and a proposed patch.

2025-03-30  Lennart Jablonka <humm@ljabl.com>

	Don't use non-POSIX syntax `\+` in BREs.

	It's implementation-defined whether \+ behaves like literal + or
	like \{1,\}.  (The same applies to \? and \|; I didn't find uses
	of those.)  As it happens, OpenBSD treats it as literal '+'.

	* m4/groff.m4 (GROFF_PAGE):
	* makevarescape.sed:
	* src/libs/libgroff/make-uniuni:
	* src/roff/groff/tests/html-device-smoke-test.sh:
	* src/utils/afmtodit/make-afmtodit-tables: Use more portable
	sed(1) and grep(1) syntax.

	Found through a failure of html-device-smoke-test.sh.

	See <https://pubs.opengroup.org/onlinepubs/\
	9799919799.2024edition/basedefs/V1_chap09.html#tag_09_03_02>.

2025-04-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[font]: Update and parallelize `DESC` file generation.

	* font/devdvi/devdvi.am (font/devdvi/DESC):
	* font/devlbp/devlbp.am (font/devlbp/DESC):
	* font/devlj4/devlj4.am (font/devlj4/DESC):
	* font/devpdf/devpdf.am (font/devpdf/DESC): When constructing
	file by stages, write to the target name suffixed with `.tmp`,
	then move it into place once it is complete.

	* font/devpdf/devpdf.am (font/devpdf/DESC):
	* font/devps/devps.am (font/devps/DESC): Replace hard-coded
	directory name with output of `dirname` command on Make's `$@`
	internal variable.

	* font/devpdf/devpdf.am (font/devpdf/DESC): Replace hard-coded
	target name with Make's `$@` internal variable.

2025-04-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* font/devdvi/devdvi.am (font/devdvi/DESC):
	* font/devlbp/devlbp.am (font/devlbp/DESC):
	* font/devlj4/devlj4.am (font/devlj4/DESC):
	* font/devpdf/devpdf.am (font/devpdf/DESC):
	* font/devps/devps.am (font/devps/DESC): Write the "configure"d
	paper format to generated device description files, instead of
	only ever "a4" or "letter".

	* NEWS: Add item.

	Fixes <https://savannah.gnu.org/bugs/?67013>.  Thanks to Lennart
	Jablonka for prompting this idea.

2025-04-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* Makefile.am: Drop comments documenting `PAGE` and
	`GHOSTSCRIPT` as appearing in "config.h".  Neither appears there
	because they are `AC_SUBST()`ed (into generated Make files), not
	`AC_DEFINE()`d (in "config.h").  Further, the Ghostscript-
	related macro that we expand is named `ALT_GHOSTSCRIPT_PROGS`,
	not `GHOSTSCRIPT`.  Prompted by a report and proposed patch by
	Lennart Jablonka.

2025-04-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::possibly_break_line): Fix
	build error with GCC 5.5 on Solaris 10.  Introduce a temporary
	variable `dsd` to store `space_deficit` as a `double`, and use
	it in divisions when computing the size of overset or underset
	reported in diagnostics.  Use `fabs()` instead of `abs()`.

2025-04-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::possibly_break_line):
	Improve "break" warning diagnostic messages when adjustment is
	frustrated.  In troff mode, use the scaling unit configured by
	the `warnscale` request.  In nroff mode, use ens (which, since
	they are defined in a typeface-proportional manner, are not an
	acceptable scaling unit for `warnscale`).

	* doc/groff.texi.in (Warnings):
	* src/roff/troff/troff.1.man (Warnings): Document it.

	* NEWS: Update item regarding output warnings in nroff mode.

2025-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor break/adjustment warning production.

	* src/roff/troff/env.cpp (environment::choose_breakpoint): Stop
	throwing break warnings here...
	(distribute_space): ...and here...
	(environment::possibly_break_line): ...instead doing so here.

2025-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Test for presence of over-/underset line diagnostics
	when filling.

	* src/roff/groff/tests/warn-on-overset-adjusted-line.sh:
	* src/roff/groff/tests/warn-on-overset-unadjusted-line.sh:
	* src/roff/groff/tests/warn-on-underset-adjusted-line.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run tests.

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

	[troff]: Slightly refactor to clarify adjustment logic in
	difficult cases.

	* src/roff/troff/env.cpp (distribute_space): Promote return type
	from `void` to `bool`, communicating whether this function
	successfully adjusted spaces.  Add/update `return` statements.
	(environment::possibly_break_line): Populate `output_width`
	variable in stages, adding `extra_space` only if the
	`distribute_space()` call was successful.  Annotate early
	return scenario for comprehensibility.
	(environment::wrap_up_field): Cast return value of
	`distribute_space()` to `void`; since that's what was happening
	implicitly before, this is a trivial type-correctness change.

	This change might finally solve the mystery of Savannah #44018.

2025-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::possibly_break_line):
	Trivially refactor.  Lift computation that is performed in 3 of
	6 cases into a variable, `space_deficit`, whose value is
	computed unconditionally.  (It's an integer subtraction--not too
	spendy.)  Rename `extra_space_width` to `extra_space`.  Simplify
	expressions and annotate logic.

2025-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/\
	do-not-loop-infinitely-when-breaking-cjk.sh: Make test case more
	illustrative.  Conform better to modern groff test conventions.

2025-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (macro::json_dump): Always print a
	comma before dumping contents, since the "length" datum always
	precedes it.  Fixes malformed output of `.pm .T`.

2025-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (print_macros): Fix infloop when
	`pm` is given an invalid argument.  Continues commit 52f93e69dd,
	20 March.

2025-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (file_iterator::set_location)
	(next_file, line_file, do_source, open_file, copy_file)
	(transparent_file, do_macro_source): Stop freeing memory
	dynamically allocated to store file names encountered in (and
	copied from) the input document.  *roff is a powerful enough
	language that the lifetimes of these file name strings are
	highly variable, and moreover their pointers tend to get copied
	into internal data structures.  Overly aggressive freeing can
	cause garbage to appear in lieu of file names in backtrace
	reports, dumped macros, and so forth.  Add comments musing about
	a future approach to management of this storage.

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

2025-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #66981.

	* src/roff/groff/tests/do-not-free-file-name-pointers-early.sh:
	Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2025-04-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Slightly refactor and fix code style nits.

	* src/roff/troff/input.cpp (file_iterator::backtrace)
	(string_iterator::backtrace): Favor `errprint()` over
	`fprintf()`.
	(string_iterator::backtrace): Explicitly compare values of
	pointer type to null pointer literals instead of letting them
	pun down to Booleans.  Parenthesize (formally) complex
	expressions.  Always terminate backtrace message with newline if
	anything at all was written.
	(lookup_color): Reorder equality comparison to avoid inadvertent
	lvalue assignment.

2025-04-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (macro::json_dump): Add more
	information when dumping a macro (or diversion or string):
	report name of file where it's defined if this information is
	available.  Also report line number and length.  Also favor
	`errprint()` over `fputs()`.

2025-04-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (file_iterator::get_location): This
	`bool`-returning function always returned true.  Return `false`
	if no file name information is available; one should always be
	available, and the line number is meaningless without a file
	name (we handle the standard input stream specially, and it
	_has_ a file name for our purposes).

2025-04-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp (string::json_extract):
	* src/libs/libgroff/symbol.cpp (symbol::json_extract): Since we
	return a pointer-to-const-char, null-terminate what we hand
	back.  Impedance matching (or, more precisely, conversion)
	between C strings and groff strings is just too hard otherwise.

2025-03-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/nroff/tests/verbose-option-works.sh: Indirect
	invocation of "nroff" command through a shell variable to ensure
	that we test the one that has been built, not one in the $PATH.
	Most other groff automated tests already work this way.  Also
	check for POSIX-non-comforming shell, and skip test if a
	conforming one doesn't seem to be present.

2025-03-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	[nroff]: Now that our "configure" script searches for a shell
	that is at least minimally competent, and has an Automake macro
	to expand its name, use it in the "nroff" shell script.  This
	change doesn't obviate the need for run-time checks for features
	that we rely upon but which buggy shells mis-implement; we
	_search_ for a good shell, but an unsatisfactory "/bin/sh" might
	be all we find.  Also, we don't rely on the semantics of an
	empty interpreter name (`#!` followed by a newline), because
	some of our scripts need to invoke a subshell by name: 'test `sh
	-c "echo foo"` && status=good' works; 'test ` -c "echo foo"` &&
	status=good' does not.

	* src/roff/nroff/nroff.sh: Update shebang line to use macro.
	* src/roff/nroff/nroff.am (nroff): Perform macro substitution.

2025-03-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* m4/groff.m4 (GROFF_PROG_SH): Search more aggressively for
	Bourne/Korn-style shells that stand a better chance of being
	POSIX-conforming in ways we require than, oh, say, Solaris 10
	/bin/sh.  Search for bash, ksh, dash, and ash in that order.
	If none are found, use /bin/sh anyway and surrender to our
	run-time fate.

2025-03-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::next): Drop warning
	diagnostic.  DWB troff accepts a negative argument to the `\N`
	escape sequence; so should we.  (Interestingly, it seems to be
	difficult or impossible to get Heirloom Doctools to emit a
	"trout" `N` command--some table maps negative character indices
	to special character names.  For instance, we expect `N-1` but
	get `Chy`.  If no mapping exists for `\N`'s argument, it emits
	_no_ trout command for the character.)

2025-03-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* m4/groff.m4 (GROFF_PROG_SH_IS_POSIX_8_CONFORMING): Rename
	this...
	(GROFF_PROG_SH): ...to this.  We may have demands on the shell
	other than POSIX Issue 8 conformance.
	* configure.ac: Track rename.

2025-03-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::possibly_break_line):
	Supply more information in "cannot adjust line" diagnostic;
	since we now have two others of this form that warn when an
	output line (1) has no adjustable spaces or (2) oversets, in
	this case disclose that it's (3) underset, and say by how much.

2025-03-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* m4/groff.m4 (GROFF_PROG_TEST_SUPPORTS_EF_OPTION): Force
	Autoconf to test "/bin/sh", not a more capable and more
	POSIX-conforming shell it might manage to scare up, because we
	need to know whether to update our script programs' declared
	shell interpreter.

2025-03-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* m4/groff.m4 (GROFF_PROG_SH_IS_POSIX_8_CONFORMING): Add
	`AC_REQUIRE` on `GROFF_PROG_TEST_SUPPORTS_EF_OPTION`, because we
	need the shell variable `test_ef_works` to be populated.  Also
	fix latent m4 syntax error.
	* configure.ac: Drop `GROFF_PROG_TEST_SUPPORTS_EF_OPTION`, now
	depended-upon inside "groff.m4".

2025-03-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* gnulib: Update stable/2025-01 branch to commit 3fbc2c7bb3, 3
	March.

2025-03-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	Rename `read_string()` to `read_rest_of_line_as_argument()`.
	What it reads does not necessarily become a *roff language
	string.

	* src/roff/troff/input.cpp: Do it.
	* src/roff/troff/token.h: Update declaration.
	* src/roff/troff/env.cpp (override_sizes)
	(read_hyphenation_patterns_from_file)
	(load_hyphenation_patterns_from_file)
	(append_hyphenation_patterns_from_file):
	* src/roff/troff/input.cpp (next_file, line_file)
	(do_source, pipe_source_request, open_file, open_request)
	(opena_request, abort_request, pipe_output, system_request)
	(copy_file, transparent_file, do_macro_source): Update call
	sites.

2025-03-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/json-encode.h (struct json_char): Use explicitly
	`unsigned` character type when employing it as a numeric value
	{counting the number of `char`s necessary to JSON-encode a C/C++
	character}.  See CMU SEI INT07-C.

2025-03-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.c (main): Finish migrating to modern
	getopt_long(3) usage: drop `opterr` assignment.

2025-03-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/grog/grog.pl (interpret_line): Recognize `pchar` as
	a GNU troff request.

2025-03-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Fix potentially
	misleading diagnostics.  When describing a non-Basic Latin
	printable character in a diagnostic message (or `pchar` output),
	remove Unicode-style annotation ("U+XXXX").  While accurate if
	"latin1.tmac" is loaded, it can be incorrect if any of
	"latin[259].tmac" or "koi8-r.tmac" is loaded.

2025-03-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (report_character_request): Make
	`pchar` request accept space between characters, as documented.

	Continues commit d84dd6ddc7, 4 February.

2025-03-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::next): Discard local array
	variable `errbuf`.  Pass a null pointer instead of it to
	`valid_unicode_code_sequence()`, so that the latter function
	does not waste resources constructing a diagnostic message that
	we are not going to emit.

	Continues commit b4397231a0, earlier today.  Thanks to Dave
	Kemper for pointing out the lingering pessimization.

2025-03-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/json_encode.cpp (json_encode_char): Kill off
	tautological assertion.

	Fixes "-Wtautological-constant-out-of-range-compare" warning
	from GCC.

2025-03-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::next): Stop throwing an error
	diagnostic and aborting interpretation of a special character
	identifier when it starts with "u" and is of length > 2.  For
	example, `\[unhappy]` is a valid special character
	interpolation, simply not a _Unicode_ special character
	interpolation.  Also solves the same problem when reading
	special character identifiers from font description files.

	Fixes <https://savannah.gnu.org/bugs/?66675>.  Thanks to Dave
	Kemper for the report.  Problem introduced by me in commit
	6bf627403c, 4 September.

2025-03-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/afmtodit/afmtodit.pl (croak, whine): Fix my
	misunderstanding of uninitialized Perl scalars.  Initialize
	scalars used as strings to explicit empty strings.

	Continues commit 658f7afb8e, 2 January.

2025-03-13  Dave Kemper <saint.snit@gmail.com>

	* tmac/fallbacks.tmac: Allow recognition of more Unicode
	characters in output formats where Savannah #63332 isn't an
	issue.

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

2025-03-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Fix Savannah #66931.

	* src/preproc/tbl/table.cpp (set_troff_location): Fix logic
	error.  When writing a *roff `lf` request with a file name
	argument, write out the actual corresponding input file line
	number instead of "1".

	Fixes <https://savannah.gnu.org/bugs/?66931>.  Thanks to Bjarni
	Ingi Gislason for the report.  Problem introduced by me in
	commit 25ef9f6bda, 26 February.

2025-03-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Regression-test Savannah #66931.

	* src/preproc/tbl/tests/emit-accurate-lf-requests.sh: Do it.
	* src/src/preproc/tbl/tbl.am (tbl_TESTS): Run test.

2025-03-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Warn on failure to adjust the output line.

	* src/roff/troff/env.cpp (distribute_space): I planted an
	`assert()` land mine for myself back in December and it finally
	went off.  Remove assertion that the amount of `desired_space`
	for adjustment must be nonnegative.  While rare, this can in
	fact happen with perverse inputs such as long, unhyphenable
	character sequences or short output line lengths.  Throw new
	warnings in category "break" when adjustment is desired but
	impossible: (1) the output line has no adjustable spaces on it,
	or (2) any adjustable spaces would have to be squeezable/
	shrinkable to achieve a fit, and that is not yet implemented in
	GNU troff (see Savannah #40963).  (Even if/when we do implement
	it, there will be a [likely configurable] limit to how narrow an
	adjustable space can become.)

	* doc/groff.texi.in (Warnings):
	* src/roff/troff/troff.1.man (Warnings): Document additional
	circumstances under which warnings in "break" category are
	thrown.  Clarify existing circumstances.

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

2025-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Implement macro/string/diversion dumper.

	* src/roff/troff/input.cpp: Do it.  Add inelegant `extern`
	declaration roping in `dump_node_list()` function from
	"node.cpp".
	(class macro_header): Replace `json_dump()` member function with
	`json_dump_macro()` and `json_dump_diversion()`, since how we
	dump depends on what component objects we contain.
	(macro::json_dump): Call appropriate aforementioned function;
	`json_dump_macro` on macros and strings, `json_dump_diversion`
	on diversions.
	(macro_header::json_dump_diversion): Call `dump_node_list()` on
	the `head` member of this object's `node_list` `struct`.
	(macro::json_dump): Rename this...
	(macro::json_dump_macro): ...to this.  Also use `errprint()`
	instead of `fputc()`.
	(print_macros): Check for arguments.  If given any, interpret
	them as macro/string/diversion names and dump the contents of
	each, JSON-encoded.  If not, proceed with previously
	unconditional behavior.

	* doc/groff.texi.in (Debugging) <pm>:
	* man/groff.7.man (Request short reference) <pm>:
	* man/groff_diff.7.man (Other differences): Document it.

2025-03-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Add internal facility for writing trout/grout comments
	to GNU troff output.  This is a developers' aid.

	* src/roff/troff/node.cpp (class troff_output_file): Declare new
	`comment()` member function, taking a groff string and returning
	void.
	(troff_output_file::comment): Define it.

2025-03-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Trivially refactor.
	(class hyphen_inhibitor_node): Declare member functions in the
	same order as they appear in `struct node`'s declaration; in the
	latter, there are many: some are virtual, and some are pure
	virtual.
	(hyphen_inhibitor_node::causes_tprint)
	(hyphen_inhibitor_node::is_tag): Define them in the same order,
	too.
	(dbreak_node::add_discretionary_hyphen): Explicitly compare
	return value of pointer type to null pointer literal instead of
	letting it pun down to a Boolean.

2025-03-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/mtsm.h: Rationalize "#include"s.  Include C
	standard library and libgroff header files we require.  Annotate
	why we don't "#include" a GNU troff header file.

2025-03-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (set_hyphenation_codes): Use
	character, not integer, literals when assigning and comparing to
	local variables of `char` type.

2025-03-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Slightly refactor.  Boolify and rename global and
	local variables, class member functions, and member function
	arguments relating to diversion re-reading and interpreter state
	tracking whether the input stream is being read at the beginning
	of an input line (or the predicate of a certain
	control-structure requests, where ordinary and no-break control
	characters are recognized).

	* src/roff/troff/column.cpp (class vjustify_node) [COLUMN]:
	* src/roff/troff/node.h (struct node, class word_space_node)
	(class unbreakable_space_node, class diverted_space_node)
	(class diverted_copy_file_node, hmotion_node): Rename `reread()`
	member function to `need_reread()` and demote its argument and
	return value to `bool` and pointer to `bool`, respectively.

	* src/roff/troff/column.cpp (vjustify_node::reread) [COLUMN]:
	Rename this...
	(vjustify_node::need_reread) [COLUMN]: ...to this, and update
	return and argument types.

	* src/roff/troff/input.cpp (bool::reread)
	(diverted_space_node::reread, diverted_copy_file_node::reread)
	(word_space_node::reread, unbreakable_space_node::reread)
	(hmotion_node::reread): Rename this...
	(bool::need_reread, diverted_space_node::need_reread)
	(diverted_copy_file_node::need_reread)
	(word_space_node::need_reread)
	(unbreakable_space_node::need_reread)
	(hmotion_node::need_reread): ...to this, and update return and
	argument types.
	(process_input_stack, do_define_macro, transparent_file): Rename
	`bol` to `reading_beginning_of_input_line` and demote it from
	`int` to `bool`.

2025-03-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Make bracket and overstrike nodes (created with `\b`
	and `\o`, respectively) produce approximate output.

	* src/roff/troff/node.h (class bracket_node)
	(class overstrike_node): Declare `ascii_print` member function.
	* src/roff/troff/node.cpp (bracket_node::ascii_print)
	(overstrike_node::ascii_print): Implement `ascii_print` member
	function.

2025-03-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (composite_node::ascii_print): When
	rendering a composite node for approximate output, traverse into
	it and write its nodes' representations in forward order.

	Fixes <https://savannah.gnu.org/bugs/?55799>.  Thanks to Dave
	Kemper for the report.  Problem appears to date back to groff's
	birth.

2025-03-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #55799.

	* src/roff/groff/tests/\
	composite-nodes-produce-approximate-output.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2025-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (class composite_node): Add
	`dump_node` member function, overriding virtual function in
	`node` (remote) base class.

	(composite_node::dump_node): Disclose more information, namely
	the contents of any defined nodes within.  Because these are
	stored in reverse order--a composite node strongly resembles an
	output line, including a `line_start_node` and tail-first
	ordering--list them in reversed order, putting them forward.

2025-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/font.cpp (glyph_to_ucs_codepoint)
	(glyph_to_unicode): Fix code style nit; explicitly compare
	return value of pointer type to null pointer literal instead of
	letting it pun down to a Boolean.

2025-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/unicode.cpp (valid_unicode_code_sequence):
	Stop writing newline character into error buffer.  It's the
	caller's responsibility to assemble an error message (and
	existing callers do so).  Avoids extraneous newlines on standard
	error stream.

2025-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (charinfo::dump): Dump user-defined
	character definitions' macro contents.  This is a JSON-encoded
	string, but the other character properties are traditionally
	reported.

2025-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (suppress_node::dump_properties):
	JSON-encode `position` member variable of this node type.
	(draw_node::dump_properties): JSON-encode `gcol` and `fcol`
	member variables of this node type.

	Problem introduced yesterday with landing of new JSON encoding
	feature.

2025-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Fix logic error when encoding characters ", \, and /
	as (or in) JSON strings.

	* src/libs/libgroff/json_encode.cpp (json_encode_char):
	* src/libs/libgroff/string.cpp (string::json_length):
	* src/libs/libgroff/symbol.cpp (symbol::json_length):
	Restructure control flow to handle them before other printable
	characters.

	Problem introduced yesterday with landing of new JSON encoding
	feature.

2025-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (macro::json_dump): A `macro` object
	is not guaranteed to contain a `macro_header`; check for a null
	pointer and report an empty JSON string if there's no header.

2025-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Implement dumping of device extension node contents.

	* src/roff/troff/request.h (class macro): Declare `json_dump()`
	member function.
	* src/roff/troff/node.cpp
	(device_extension_node::dump_properties): Call member variable
	`mac`'s `json_dump()` member function.
	* src/roff/troff/input.cpp (class macro_header): Declare
	`json_dump()` member function.
	(macro::json_dump): New member function calls `macro_header` `p`
	member variable's `json_dump()` member function.
	(macro_header::json_dump): New member function iterates though
	`char_list` `cl` member variable's elements, calling
	`json_encode_char()` on each one.

2025-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (class kern_pair_node): Add
	`dump_node` member function, overriding virtual function in
	`node` base class.
	(kern_pair_node::dump_node): Disclose more information, namely
	the contents of any contained nodes.

2025-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (dbreak_node::dump_node): Refactor to
	use new `dump_properties` member function of `node` base class.

2025-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (class ligature_node): Add `dump_node`
	member function, overriding virtual function in `node` base
	class.
	(ligature_node::dump_node): Disclose more information, namely
	the contents of any contained nodes.

2025-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Derive class `bracket_node` from struct
	`container_node`.

	* src/roff/troff/node.h (class bracket_node): Do it.  Drop
	pointer-to-node member variable and declaration of destructor.
	* src/roff/troff/node.cpp (bracket_node::bracket_node): Migrate
	constructors to use new base class.
	(bracket_node::~bracket_node): Drop; our base class handles
	destruction of contained node(s).

2025-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Derive class `overstrike_node` from struct
	`container_node`.

	* src/roff/troff/node.h (class overstrike_node): Do it.  Drop
	pointer-to-node member variable and declaration of destructor.
	* src/roff/troff/node.cpp (overstrike_node::overstrike_node):
	Migrate constructors to use new base class.
	(overstrike_node::~overstrike_node): Drop; our base class
	handles destruction of contained node(s).

2025-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Derive class `left_italic_corrected_node` from struct
	`container_node`.

	* src/roff/troff/node.h (class left_italic_corrected_node): Do
	it.  Drop pointer-to-node member variable and declaration of
	destructor.
	* src/roff/troff/node.cpp
	(left_italic_corrected_node::left_italic_corrected_node):
	Migrate constructors to use new base class.
	(left_italic_corrected_node::~left_italic_corrected_node): Drop;
	our base class handles destruction of contained node(s).

2025-03-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Derive class `break_char_node` from struct
	`container_node`.

	* src/roff/troff/node.h (class break_char_node): Do it.  Drop
	pointer-to-node member variable and declaration of destructor.
	* src/roff/troff/node.cpp (break_char_node::break_char_node):
	Migrate constructors to use new base class.
	(break_char_node::~break_char_node): Drop; our base class
	handles destruction of contained node(s).

2025-03-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Derive class `italic_corrected_node` from struct
	`container_node`.

	* src/roff/troff/node.h (class italic_corrected_node): Do it.
	Drop pointer-to-node member variable and declaration of
	destructor.
	* src/roff/troff/node.cpp
	(italic_corrected_node::italic_corrected_node): Migrate
	constructors to use new base class.
	(italic_corrected_node::~italic_corrected_node): Drop; our base
	class handles destruction of contained node(s).

2025-03-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Derive class `zero_width_node` from struct
	`container_node`.

	* src/roff/troff/node.h (class zero_width_node): Do it.  Drop
	pointer-to-node member variable and declaration of destructor.
	* src/roff/troff/node.cpp (zero_width_node::~zero_width_node):
	Drop; our base class handles destruction of contained node(s).
	(zero_width_node::zero_width_node): Migrate constructors to use
	new base class.

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

	[troff]: Derive class `vline_node` from struct `container_node`.

	* src/roff/troff/node.h (class vline_node): Do it.  Drop
	pointer-to-node member variable and declaration of destructor.
	* src/roff/troff/node.cpp (vline_node::~vline_node): Drop; our
	base class handles destruction of contained node(s).
	(vline_node::vline_node): Migrate constructors to use new base
	class.

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

	[troff]: Derive class `hline_node` from struct `container_node`.

	* src/roff/troff/node.h (class hline_node): Do it.  Drop
	pointer-to-node member variable and declaration of destructor.
	* src/roff/troff/node.cpp (hline_node::~hline_node): Drop; our
	base class handles destruction of contained node(s).
	(hline_node::hline_node): Migrate constructors to use new base
	class.

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

	[troff]: Create new `struct container_node` for node types that
	contain a {possibly singleton} list of other nodes.

	* src/roff/troff/node.h (container_node): Do it.  Declare
	constructors mirroring those of `struct node` (but with an extra
	argument for the contained node list); a destructor; and virtual
	member function `dump_node()`, overriding that of `struct node`.
	* src/roff/troff/node.cpp (dump_node_list): New function, a
	counterpart to `copy_node_list()` and `delete_node_list()`,
	walks a singly-linked list of nodes and directs each to dump
	itself.
	(container_node::container_node)
	(container_node::~container_node, container_node::dump_node):
	Define the foregoing.
	(container_node::~container_node): Destructor always calls
	`delete_node_list()` because some node types seem intended to
	contain only one other node, and others a list.  Unifying the
	destruction procedure seems more likely to avoid memory leaks,
	at a cost per destroyed object derived from `container_node`
	of an additional function call and a test of a pointer for
	nullity--but only for objects of classes where this wasn't
	already happening.

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

	[troff]: The property of the environment that holds the pending
	output line appears to be unique in storing the elements of its
	node list in reverse order.  Rename function to reflect its
	specialized purpose.

	* src/roff/troff/node.cpp (dump_node_list): Rename this...
	(dump_node_list_in_reverse): ...to this.
	* src/roff/troff/env.cpp (environment::add_char) [0]:
	(environment::dump_pending_nodes): Update call sites.

2025-03-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (class break_char_node):
	Specialize (override) `dump_properties()` for this class.
	* src/roff/troff/node.cpp
	(break_char_node::dump_properties): New member function reports
	values of `break code before`, `break code after`, and
	`terminal_color` properties.

2025-03-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (class italic_corrected_node):
	Specialize (override) `dump_properties()` for this class.
	* src/roff/troff/node.cpp
	(italic_corrected_node::dump_properties): New member function
	reports value of `hunits` property.

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

	* src/roff/troff/node.h (class kern_pair_node): Specialize
	{override} `dump_properties()` for this class.
	* src/roff/troff/node.cpp (kern_pair_node::dump_properties): New
	member function reports value of `amount` property.

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

	* src/roff/troff/node.h (class tag_node): Specialize (override)
	`dump_properties()` for this class.
	* src/roff/troff/node.cpp (tag_node::dump_properties): New
	member function reports values of `string` and `delayed`
	properties.

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

	* src/roff/troff/node.h (struct width_list): Declare `dump()`
	member function.
	(class word_space_node): Specialize (override)
	`dump_properties()` for this class.
	* src/roff/troff/node.cpp (width_list::dump): New member
	function traverses a singly-linked of `width_list` nodes, and
	reports values of `width` and `sentence_width` properties.
	(word_space_node::dump_properties): New member function
	reports values of `width_list` (if not a null pointer) and
	`unformat` properties.

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

	* src/roff/troff/node.h (class draw_node): Specialize (override)
	`dump_properties()` for this class.
	* src/roff/troff/node.cpp (draw_node::dump_properties): New
	member function reports values of `code`, `npoints`,
	`font_size`, `stroke_color`, `fill_color`, and `point`
	properties.

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

	* src/roff/troff/node.h (class suppress_node): Specialize
	{override} `dump_properties()` for this class.
	* src/roff/troff/node.cpp
	(suppress_node::dump_properties): New member function
	reports values of `is_on`, `emit_limits`, `filename` (if not
	null), `position` (if not a null character), and `image_id`
	properties.

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

	* src/roff/troff/node.h (class device_extension_node):
	Specialize {override} `dump_properties()` for this class.
	* src/roff/troff/node.cpp
	(device_extension_node::dump_properties): New member function
	reports values of `tfont`, `stroke_color`, and `fill_color`
	properties.

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

	* src/roff/troff/node.h (class bracket_node): Specialize
	{override} `dump_properties()` for this class.
	* src/roff/troff/node.cpp (bracket_node::dump_properties):
	New member function reports value of `max_width` property.

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

	* src/roff/troff/node.h (class overstrike_node): Specialize
	{override} `dump_properties()` for this class.
	* src/roff/troff/node.cpp (overstrike_node::dump_properties):
	New member function reports value of `max_width` property.

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

	* src/roff/troff/node.h (class left_italic_corrected_node):
	Specialize (override) `dump_properties()` for this class.
	* src/roff/troff/node.cpp
	(left_italic_corrected_node::dump_properties): New member
	function reports value of `hunits` property.

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

	* src/roff/troff/node.h (class vline_node): Specialize
	{override} `dump_properties()` for this class.
	* src/roff/troff/node.cpp (vline_node::dump_properties): New
	member function reports value of `vunits` property.

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

	* src/roff/troff/node.h (class hline_node): Specialize
	{override} `dump_properties()` for this class.
	* src/roff/troff/node.cpp (hline_node::dump_properties): New
	member function reports value of `hunits` property.

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

	* src/roff/troff/node.h (class vmotion_node): Specialize
	{override} `dump_properties()` for this class.
	* src/roff/troff/node.cpp (vmotion_node::dump_properties): New
	member function reports values of `vunits` and `terminal_color`
	properties.

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

	* src/roff/troff/node.h (class hmotion_node): Specialize
	{override} `dump_properties()` for this class.
	* src/roff/troff/node.cpp (hmotion_node::dump_properties): New
	member function reports values of `hunits`, `was_tab`,
	`unformat`, and `terminal_color` properties.

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

	* src/roff/troff/node.h (class vertical_size_node): Specialize
	{override} `dump_properties()` for this class.
	* src/roff/troff/node.cpp (vertical_size_node::dump_properties):
	New member function reports value of `vunits` property.

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

	* src/roff/troff/node.h (class extra_size_node): Specialize
	{override} `dump_properties()` for this class.
	* src/roff/troff/node.cpp (extra_size_node::dump_properties):
	New member function reports value of `vunits` property.

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

	* src/roff/troff/node.h (class diverted_copy_file_node):
	Specialize (override) `dump_properties()` for this class.
	* src/roff/troff/node.cpp
	(diverted_copy_file_node::dump_properties): New member function
	reports value of `filename` property.

2025-03-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (class diverted_space_node): Specialize
	{override} `dump_properties()` for this class.
	* src/roff/troff/node.cpp
	(diverted_space_node::dump_properties): New member function
	reports value of `vunits` property.

2025-03-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (class space_node): Specialize
	{override} `dump_properties()` for this class.
	* src/roff/troff/node.cpp (space_node::dump_properties): New
	member function reports value of `hunits` property.

2025-03-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (class charinfo_node): Declare
	member function `dump_properties()` overriding base here...
	(class glyph_node): ...instead of here.
	(composite_node::dump_properties): Rename this...
	(charinfo_node::dump_properties): ...to this (and relocate it to
	live alongside `charinfo_node`'s other member functions).
	(class glyph_node): Undeclare member function `dump_node()`.
	(glyph_node::dump_node): Drop.  The `charinfo_node` base class
	now does everything its derived classes need.

2025-03-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (class composite_node): Rename member
	function `dump_node()` to `dump_properties()`, altering its
	purpose.
	(composite_node::dump_node): Rename this...
	(composite_node::dump_properties): ...to this.  Now we override
	a different function, and can ditch repetitious code that
	reported properties of the base class.

2025-03-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (struct node): Add new virtual member
	function, `dump_properties()`, to support modular composition of
	node dumping.  All nodes have properties, but some dervived
	classes of `node` have _additional_ properties.  Also, we want
	to be able to distinguish property reporting from contained-node
	reporting, which is where recursion comes in.
	(node::dump_properties): Implement it.  This takes over most of
	the former function of `node::dump_node()`...
	(node::dump_node): ...which now just writes out braces `{` `}`
	with properties in between.

2025-03-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (struct node): Undeclare
	`dump_node_list()` virtual function.
	* src/roff/troff/node.cpp (node::dump_node_list): Rename this...
	(dump_node_list): ...to this.  Instead of being a member
	function, it is now an ordinary function taking a
	pointer-to-node as argument.  This is a temporary measure to
	keep node list dumping working.  Stop throwing assertion if the
	given node pointer is null.  Instead, we simply write an empty
	list (`[ ]`).
	* src/roff/troff/env.h (class environment): Rename member
	function `dump_node_list()` to `dump_pending_nodes()`.
	* src/roff/troff/env.cpp (environment::dump_node_list): Rename
	this...
	(environment::dump_pending_nodes): ...to this.
	(environment:add_char) [0]: Update call sites.
	(environment::dump_node_list): Rename this...
	(environment::dump_pending_nodes): ...to this.  Stop refusing to
	dump a null pointer.  Update call site as above.

2025-03-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Revise `pline` output style.  Use more JSON/YAML-ish
	syntax.  Present node properties in a consistent order: first,
	general node properties (read: member variables of the `node`
	abstract class); next, type-specific properties (read: member
	variables of classes derived from `node`); then, general node
	properties used only by MTSM/grohtml, which I hope one day to
	refactor away.

	* src/roff/troff/node.cpp (glyph_node::dump_node)
	(node::dump_node, node::dump_node_list)
	(composite_node::dump_node, dbreak_node::dump_node): Do it.
	(node::dump_node): Report the `is_special` Boolean property.
	(glyph_node::dump_node, composite_node::dump_node): Write string
	values with JSON-valid escaped characters.

2025-03-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Add `json_length()`, `json_extract()`, and
	`json_dump()` public member functions to `symbol` class.  The
	enhanced node printing feature will require them.

	* src/include/symbol.h (class symbol): Declare them.
	* src/libs/libgroff/symbol.cpp (symbol::json_length):
	(symbol::json_extract, symbol::json_dump): Implement them.

2025-03-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Add `json_length()`, `json_extract()`, and
	`json_dump()` public member functions to `string` class.  The
	enhanced node printing feature will require them.

	* src/include/stringclass.h (class string): Declare them.
	* src/libs/libgroff/string.cpp (string::json_length):
	(string::json_extract, string::json_dump): Implement them.

2025-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Support dumping of some object types in JSON format.

	* src/include/json-encode.h:
	* src/libs/libgroff/json_encode.cpp: Add new files.

	* src/libs/libgroff/libgroff.am (libgroff_a_SOURCES): Add
	"json_encode.cpp".

2025-03-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	Further rationalize header file inclusions.

	* src/libs/libgroff/string.cpp: Include assert.h and string.h.
	Annotate why.

2025-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Slightly refactor.

	* src/roff/troff/node.h: Boolify: demote some class member
	variables and member function return types from `int` to `bool`.
	(struct node, class space_node): Update `discardable()`
	declaration.
	(class space_node): Update `set` and `was_escape_colon`
	declarations.
	(class suppress_node): Update `emit_limits` declaration.
	* src/roff/troff/node.cpp (space_node::space_node): Use Boolean
	instead of integer literal in `was_escape_colon` initializer.
	(space_node::spread_space, space_node::freeze_space)
	(space_node::is_escape_colon): Use Boolean instead of integer
	literals when assigning to `bool` member variables.
	(node::discardable, space_node::discardable): Update return
	type.
	(space_node::discardable): Simplify expression.

2025-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/node.cpp:
	* src/roff/troff/node.h: Rename all `ch`, `n` and `list` member
	variables of node classes to `nodes` to later enable insertion
	of a `container_node` abstract class into the inheritance
	structure.  This change throws more light on a pitfall of GNU
	troff's class design; some node classes can contain other nodes
	by using pointers to `node`s, but this is done without recourse
	to any C++ language features to indicate whether such pointers
	are expected to be single elements or lists.  (Compounding the
	ambiguity is that `node` is inherently set up for use as a
	member of a doubly-linked list.)  Thus, this renaming
	unfortunately removes some information about class design
	intentions.  On the other hand, since only programmer knowledge
	and discipline were enforcing the singleton/list distinction
	already, the member variable names were _only_ documentary.  In
	the future, we might want to enhance some of these classes to
	enforce their containment of singleton nodes only.
	* src/roff/troff/node.cpp (hline_node::copy, vline_node::copy)
	(vline_node::width, left_italic_corrected_node::width)
	(left_italic_corrected_node::skew)
	(left_italic_corrected_node::subscript_correction)
	(left_italic_corrected_node::italic_correction)
	(left_italic_corrected_node::ends_sentence)
	(left_italic_corrected_node::overlaps_horizontally)
	(left_italic_corrected_node::overlaps_vertically)
	(left_italic_corrected_node::last_char_node)
	(left_italic_corrected_node::get_tfont)
	(italic_corrected_node::skew, glyph_node::tprint)
	(glyph_node::zero_width_tprint, hline_node::tprint):
	Parenthesize (formally) complex expressions.
	(bracket_node::copy, hline_node::copy, vline_node::copy)
	(reverse_node_list)
	(left_italic_corrected_node::asciify)
	(left_italic_corrected_node::copy)
	(left_italic_corrected_node::tprint)
	(left_italic_corrected_node::ascii_print)
	(left_italic_corrected_node::vertical_extent)
	(left_italic_corrected_node::get_hyphenation_type)
	(left_italic_corrected_node::add_self)
	(left_italic_corrected_node::width): Explicitly compare variable
	of pointer type to null pointer literal instead of letting it
	pun down to a Boolean.
	(glyph_node::asciify): Compare local variable of `char` type to
	character rather than integer literal.
	(overstrike_node::add_self): Rename parameter from `nodes` to
	`more_nodes`, since the former now collides with a class member
	variable.
	(space_node::space_node): Initialize member variable of `char`
	type with character rather than integer literal.

2025-03-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp (is_valid_term): When warning of an
	invalid scaling unit, report the character encountered.

2025-03-14  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: .pdfhref M fails with no -N/-D flag

	The documentation for this macro has always stated that the
	first word of "descriptive text" is used as the destination
	name if neither -N nor -D are present.

	* tmac/pdf.tmac: Do it.

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

2025-03-13  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: \X'pdf: pdfpic ...' scales incorrectly

	When no width is given (<=0), scaling should use height. If
	both are missing or <=0, don't scale.

	* src/devices/gropdf/gropdf.pl: No scaling if BOTH width and
	height are not given.

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

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

	[troff]: Add unit tests for `devicem` request and `\Y` escape
	sequence.

	* src/roff/groff/tests/backslash-Y-works.sh:
	* src/roff/groff/tests/devicem-request-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run tests.

2025-03-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/mtsm.cpp (statem::display_state):
	* src/roff/troff/node.cpp (glyph_node::dump_node)
	(node::dump_node, composite_node::dump_node)
	(dbreak_node::dump_node): Tweak format of debugging output.

2025-03-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Add new constructor for `node` type, permitting
	`is_special` member variable to be initialized in initializer
	lists.

	* src/roff/troff/node.h (struct node, node::node): Do it.
	* src/roff/troff/node.cpp
	(device_extension_node::device_extension_node)
	(suppress_node::suppress_node): Migrate constructors of derived
	classes to it where applicable.

2025-03-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.h (node::node): Fix code style nit;
	explicitly compare variable of pointer type to null pointer
	literal instead of letting it pun down to a Boolean.

2025-03-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (hline_node::~hline_node)
	(vline_node::~vline_node): Fix code style nit, simplifying.

2025-03-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (copy_file, transparent_file): Drop
	extraneous `tok.next()` calls; they are already performed just
	prior to function return.  They caused the input stream pointer
	to advance too far.

	Fixes <https://savannah.gnu.org/bugs/?66863>.  Problem
	introduced by me in commit f087165933, 7 December.

2025-03-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #66863.

	* src/roff/groff/tests/cf-request-works.sh:
	* src/roff/groff/tests/trf-request-works.sh: Add tests.
	* src/roff/groff/tests/artifacts/throughput-file: Add their
	input artifact.
	* src/roff/groff/groff.am (groff_TESTS): Run tests.

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

	* src/roff/troff/input.cpp (token::next): Clarify warning
	diagnostic; in `\N'-5'`, the index is invalid and the character
	is ignored.

2025-02-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (report_character_request):
	(remove_character, get_char, get_charinfo)
	(get_charinfo_by_index): Trivially refactor.  Rename
	`lookup_only` function arguments to `suppress_creation`, a name
	already used by register classes for the same purpose.

2025-02-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Make `pnr` request report autoincrement amounts.

	* src/roff/troff/reg.h (class reg): Declare `const` virtual
	functions `get_increment()` and `can_autoincrement()` returning
	`int` and `bool`, respectively.  These exist at the root of the
	register class hierarchy because the `dictionary` class that
	tracks defined registers effectively erases details of their
	types.  (groff doesn't use RTTI anywhere, and doing so seemed
	unnecessary, so I didn't explore it.)
	(class general_reg): Declare non-virtual versions of
	`get_increment()` and `can_autoincrement()`.
	* src/roff/troff/reg.cpp: Include "lib.h" since we now need its
	`INT_DIGITS` symbol.
	(reg::get_increment): Define as returning constant zero.
	(reg::can_autoincrement): Define as returning constant false.
	(general_reg::get_increment): Define.
	(general_reg::can_autoincrement): Define as returning constant
	true.
	(dump_register): If the register can autoincrement, report the
	autoincrement amount, with an explicit sign for clarity and easy
	distinction from the register's value and number format.

	* doc/groff.texi.in (Debugging) <pnr>:
	* man/groff.7.man (Request short reference) <pnr>:
	* man/groff_diff.7.man (New requests) <pnr>: Document it.

2025-02-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am: In `DOC_PDFMOM` macro, use `PDFMOMBIN` macro
	defined in "Makefile.am" to locate `pdfmom` executable; as with
	`GROFFBIN`, that's what it's there for.

2025-02-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Fix code style nit.
	(glyph_node::ascii_print): Spell null character using the C/C++
	language literal for expressing it.

2025-02-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Trivially refactor to align with terminology
	used in groff_man(7).
	(an*abbreviate-page-topic): Rename this...
	(an*abbreviate-page-identifier): ...to this.
	(TH): Update call site.

2025-02-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn,pic,preconv,refer,soelim,tbl]: Use `lf` requests _even
	more_ carefully.

	* src/preproc/eqn/main.cpp (do_file):
	* src/preproc/pic/troff.cpp (troff_output::set_location):
	* src/preproc/preconv/preconv.cpp (do_file):
	* src/preproc/refer/refer.cpp (do_file, output_pending_line):
	* src/preproc/soelim/soelim.cpp (set_location):
	* src/preproc/tbl/main.cpp (main):
	* src/preproc/tbl/table.cpp (set_troff_location): Output file
	name with leading double quote in generated `lf` request only if
	it doesn't already start with one.

2025-02-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	Implement approximate (`troff -a`) output of zero-width nodes
	{these are constructed from `\Z` escape sequences, and might be
	better termed "drawing position resetting nodes"}.

	* src/roff/troff/node.h (class zero_width_node): Declare
	`ascii_print` member function.

	* src/roff/troff/node.cpp (ascii_print_node_list): New static
	helper function iterates a node list, calling each of its
	elements' `ascii_print()` member functions.
	(zero_width_node::ascii_print): New member function calls the
	foregoing.

	Fixes <https://savannah.gnu.org/bugs/?66815>.  Thanks to Dave
	Kemper for the report.  Problem appears to date back to groff's
	birth.

2025-02-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Fix code style nits.
	Parenthesize complex expression.  Reorder equality comparisons
	to avoid inadvertent lvalue assignment.  Use Boolean literals
	for return values of function returning `bool`.

2025-02-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac ([initialization])
	* tmac/doc.tmac ([initialization]): Remap the text minus sign
	character `\-` to `\N'45'` (U+002D) on the "html" device.
	Annotate the limited scope of this remapping more thoroughly.

	Fixes <https://savannah.gnu.org/bugs/?66836>.  Thanks to Benno
	Schulenberg for the report.

2025-02-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn,preconv,refer,tbl]: Trivially refactor.

	* src/preproc/eqn/main.cpp (do_file):
	* src/preproc/preconv/preconv.cpp (do_file):
	* src/preproc/refer/refer.cpp (do_file):
	* src/preproc/tbl/main.cpp (main): Use a consistent pattern when
	writing `lf` requests to output; employ an {f,}printf(3) call
	parameterized in the line number and file name, explicitly
	discard its return value, and assign to the globals
	`current_lineno` and `current_filename` beforehand.

2025-02-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn,pic,preconv,refer,soelim,tbl]: Use `lf` requests more
	carefully.

	* src/preproc/eqn/main.cpp (do_file):
	* src/preproc/pic/troff.cpp (troff_output::set_location):
	* src/preproc/preconv/preconv.cpp (do_file):
	* src/preproc/refer/refer.cpp (do_file, output_pending_line):
	* src/preproc/soelim/soelim.cpp (set_location):
	* src/preproc/tbl/main.cpp (main):
	* src/preproc/tbl/table.cpp (set_troff_location): Output file
	name with leading double quote in `lf` request, in case the name
	starts with a space or double quote.

2025-02-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Treat `lf`'s second argument, if present, like string
	contents.

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

	* src/roff/groff/tests/lf-request-works.sh: Test it.

	* doc/groff.texi.in (Debugging) <lf>:
	* man/groff.7.man (Request short reference) <lf>:
	* man/groff_diff.7.man (Altered requests) <lf>:
	(Other differences): Document it.

	* NEWS: Update items.

	Thanks to onf for pointing out that soelim(1)'s injection of
	`lf` requests would make reported file names misleading.

2025-02-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	Add unit test for `lf` request.

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

2025-02-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: More reliably release heap memory
	allocated by `read_string()`.
	(next_file, do_source, pipe_source_request, pipe_output)
	(system_request, copy_file, transparent_file, do_macro_source):
	Do it.

2025-02-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (class file_iterator): Make class
	manage its own memory for storing file names, instead of reusing
	externally managed pointers (which sometimes refer to statically
	allocated storage, as with "-" representing the standard input
	stream).  De-`const` `filename` member variable.
	(file_iterator::file_iterator): Constructor now uses strdup(3)
	to copy the supplied file name instead of just a pointer to it
	via the initializer list.  (In C++, tastes differ whether a
	constructor should call [non-virtual] member functions.  In this
	case, I don't.)
	(file_iterator::next_file): Call member function
	`set_location()` instead of manipulating member variables, to
	ensure reliable memory management.
	(file_iterator::set_location): Use strdup(3) to allocate storage
	for the file name and use the returned pointer.  If the file
	name pointer is not null, free(3) it first.

2025-02-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/font.cpp: Include "string.h" standard header
	file, since we (now) use strerror(3).

2025-02-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor; make *roff character lookup without
	side-effect of creation it more explicit.  (This way it's easier
	to withdraw GNU troff's own `dictionary` class in the future in
	favor of an STL container.)

	* src/roff/troff/charinfo.h (get_charinfo):
	* src/roff/troff/token.h (get_char):
	* src/roff/troff/input.cpp (get_charinfo_by_index): Add new
	`bool` argument `lookup_only`, defaulting `false`.
	* src/roff/troff/input.cpp: Use these new facilities.
	(report_character_request): Explicitly prevent creation of each
	character we look up.  Improve diagnostics.  Report information
	about indexed characters (`\N'123'`) more intelligibly.
	(remove_character): Explicitly prevent creation of each
	character we remove.  Intelligibly report nonexistence of
	characters for which removal is attempted.  Throw error when
	attempt is made to remove a non-character, like `\~`.

2025-02-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Add member functions to `token` class to assist with
	runtime character analysis.

	* src/roff/troff/token.h (class charinfo): Declare new public
	member functions `is_character()`, `is_indexed_character()`, and
	`character_index()`.
	(token::is_character): New function returns whether the object
	has `type` of `TOKEN_CHAR`, `TOKEN_SPECIAL_CHAR`, or
	`TOKEN_INDEXED_CHAR`.
	(token::is_indexed_character): New function returns whether the
	object has `type` of `TOKEN_INDEXED_CHAR`.
	(token::character_index): New function returns value of `val`
	private member variable.  Throws assertion if token's `type` is
	not `TOKEN_INDEXED_CHAR`.

2025-02-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Validate character indices in font description files
	more rigorously.

	* src/libs/libgroff/font.cpp (font::load): Do it.  Refer to an
	index as an "index", not a "code", in diagnostic messages.
	Check for failure of strtol(3).  Reject indices that are out of
	`int` range.  Thus convinced that a narrowing conversion will be
	value-preserving, use C++ `static_cast` operator instead of
	C-style type cast.

	* doc/groff.texi.in (Font Description File Format):
	* man/groff_font.5.man (Font description file format): Rename
	"code" field to "index" and revise its description.

2025-02-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (get_charinfo_by_number): Rename
	function in declaration and definition from this...
	(get_charinfo_by_index): ...to this.
	(token::get_char)
	(token::add_to_zero_width_node_list, token::process)
	(name_to_glyph): Update call sites.

	* src/roff/troff/input.cpp: Rename global object of `dictionary`
	type from `numbered_charinfo_dictionary` to
	`indexed_charinfo_dictionary`.

	* src/roff/troff/input.cpp (get_charinfo_by_index): Rename
	static local array of `charinfo` type from `number_table` to
	`index_table`.

2025-02-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Unpublish function that doesn't need to be visible
	outside its translation unit.

	* src/roff/troff/charinfo.h (get_charinfo_by_number): Move
	declaration from here...
	* src/roff/troff/input.cpp (get_charinfo_by_number): ...to here.
	Declare and define it as `static`.

2025-02-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor; rename enumerator in `token` `enum`
	type from `TOKEN_NUMBERED_CHAR` to `TOKEN_INDEXED_CHAR`.

	* src/roff/troff/token.h (class token): Revise definition.
	* src/roff/troff/input.cpp (token::next, token::operator==)
	(token::description, token::get_char)
	(token::add_to_zero_width_node_list, token::process): Update
	sites of use.

2025-02-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (remove_character, get_optional_char)
	(get_charinfo_by_number): Fix code style nits.  Reorder equality
	comparison to avoid inadvertent lvalue assignment.  Explicitly
	compare variable of pointer type to null pointer literal instead
	of letting it pun down to a Boolean.

2025-02-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::next): Recast warning
	diagnostic issued when encountering an invalid character index
	{in an `\N'xxx'` escape sequence}.

2025-02-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (get_charinfo): Use C++ `static_cast`
	operator instead of C-style type cast.

2025-02-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (interpolate_environment_variable):
	Explicitly compare variable of pointer type to null pointer
	literal instead of letting it pun down to a Boolean.

2025-02-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/initialization-is-quiet.sh: Add new "es"
	and "ru" localization macro files as test scenarios.
	* tmac/LOCALIZATION: Document this step, since I forgot it.

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

	* src/roff/groff/groff.am (groff_XFAIL_TESTS): Add
	".../current-language-and-environment-in-sync.sh".

2025-02-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	Drop `phcode` request introduced on 4 November.  The
	experimental new `pchar` request handles that job and more.

	* src/roff/troff/input.cpp (report_hyphenation_codes): Drop
	request handler.
	(init_input_requests): Unwire `phcode` request from handler.

	* src/utils/grog/grog.pl (interpret_line): Unrecognize `phcode`
	as a GNU troff request.

	* NEWS: Drop item.
	* doc/groff.texi.in (Manipulating Hyphenation, Debugging):
	* man/groff.7.man (Request short reference, Debugging):
	* man/groff_diff.7.man (New requests, Debugging): Replace
	documentation of `phcode` with terse documentation of `pchar`,
	noting its experimental status.

2025-02-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Add experimental charinfo dump feature.

	* src/roff/troff/charinfo.h (class charinfo): Declare `dump()`
	member function, taking and returning no arguments.

	* src/roff/troff/input.cpp (charinfo::dump): Implement it.
	(report_character_request): Add request handler that iterates
	each ordinary or special character in the argument and calls
	`dump()` on it.
	(init_input_requests): Wire up `pchar` request to handler.

2025-02-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (define_character): Refactor and
	annotate.  Declare variables closer to their point of use.
	Reorder conditional branches to put the more common case first.
	Use C++ `static_cast` operator instead of C-style type cast.

2025-02-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Refactor.
	(define_character): Break out character mode description logic
	from here...
	(character_mode_description): ...into this new function, since a
	forthcoming change will also require it.

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

	* src/roff/troff/input.cpp (token::description): When describing
	special character, include its identifier.

2025-01-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (is_char_usable_as_delimiter):
	Restore `|` character as an invalid delimiter when not in
	compatibility mode.  This would regress the fix for Savannah
	#66481, but...

	(do_overstrike, do_bracket, do_name_test, do_zero_width_output)
	(read_size, do_register, do_width, do_device_extension)
	(read_drawing_command): Throw warning in "delim" category and
	explain ambiguity of delimiter instead of emitting error and
	refusing further interpretation of the escape sequence being
	parsed.  Leave behind "#if"ed code for restoration of former
	stricter behavior in a future groff release (which would fix
	Savannah #66009).

	(is_conditional_expression_true): Stop special-casing an
	exception for `|` that permitted it to be used as a formatted
	output comparison delimiter.  Savannah #66481 complained only
	about groff's rejection of `|` to delimit the argument to the
	`\w` (width measurement) escape sequence, not in general, and
	was seen in some man pages.  The usage Paul Eggert reported
	remains accepted, albeit warned about, per `do_width()` above.

	* src/roff/groff/tests/check-delimiter-validity.sh: Update test
	expectations.  We now expect `|` to be invalid once again to
	delimit a line-drawing escape sequence.

	Fixes <https://savannah.gnu.org/bugs/?66686>.  Thanks to Dave
	Kemper for the report.  Savannah #66526 is implicated.

2025-01-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::choose_breakpoint):
	Reparenthensize (very) complex expression, restoring documented
	behavior of hyphenation space feature.

	Fixes <https://savannah.gnu.org/bugs/?66723>.  Thanks to Dave
	Kemper for the report.  Problem introduced by me in commit
	d2dceabb83, 30 August.

2025-01-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #66723.

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

2025-01-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Slightly refactor.  Use more idiomatic C++ style,
	employing a function overload on the `charinfo` class's
	`set_macro()` member function instead of a separate "extended"
	version `setx_macro()` that takes an additional argument.

	* src/roff/troff/charinfo.h (class charinfo): Do it.
	* src/roff/troff/input.cpp (charinfo::setx_macro): Rename
	this...
	(charinfo::set_macro): ...to this, overloading the name.

	* src/roff/troff/input.cpp (define_character): Update the
	two-argument form's only call site.

2025-01-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (define_character_request): Promote
	scope of grammar computation describing the invoking request.
	I'm going to need it for further refactoring of this function
	anticipated to resolve Savannah #66675.

2025-01-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/e.tmac (m1, m2, m3, m4, ba, ip, @p, 2c, PS): Migrate from
	AT&T troff idiom of applying a default scaling unit
	{unconditionally appending one to a macro argument} to GNU
	troff's, using `do` and the `;` numeric expression operator.
	Since commit 2bd122bf56, 17 August, the old method provokes
	syntax warnings when the user supplies an explicit scaling unit.
	(PS): Convert an existing use of `;` to take place in a `do`
	context to ensure that it works in compatibility mode.

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

2025-01-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (define_font_specific_character)
	(remove_font_specific_character): Recast diagnostic messages.
	"Glyphs" are rendered by fonts; no *roff has a mechanism for
	constructing glyphs per se.  What we're throwing diagnostics
	about here are font-specific fallback character definitions.

2025-01-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Make more requests that take mandatory arguments--
	specifically `char`, `fchar`, and `schar`--throw warning
	diagnostics in category "missing" when they aren't given any.

	* src/roff/troff/input.cpp (define_character_request)
	(define_fallback_character_request)
	(define_special_character_request): Do it.

2025-01-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Rename enumeration constants for clarity.

	* src/roff/troff/token.h: Rename enumeration constants used for
	character definitions.
	    `CHAR_FONT_SPECIAL` -> `CHAR_FONT_SPECIFIC_FALLBACK`
	    `CHAR_SPECIAL`      -> `CHAR_SPECIAL_FALLBACK`
	The `char_mode` enumeration type involves the resolution order
	for a character, not its syntax ("ordinary" vs. "special").
	* src/roff/troff/charinfo.h (charinfo::is_special):
	* src/roff/troff/input.cpp (define_character)
	(define_fallback_character_request):
	* src/roff/troff/node.cpp (define_font_specific_character):
	Update usage sites.

2025-01-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (define_character): Improve
	diagnostic message: characterize failing character definition as
	"invalid", not "bad", identify which request is being handled,
	report expected input, and describe input actually received.

2025-01-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (define_character): Fix code style
	nits.  Reorder equality comparison to avoid inadvertent lvalue
	assignment.  Explicitly compare variable of pointer type to null
	pointer literal instead of letting it pun down to a Boolean.

2025-01-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename character-definition
	request handler functions to end with `_request`, and rename the
	workhorse function to simply `define_character`.  Mark them all
	`static` (except for `define_font_specific_character`, which
	already was) while we're at it.

	* src/roff/troff/token.h:
	* src/roff/troff/input.cpp:
	* src/roff/troff/node.cpp: Do it.

	* src/roff/troff/input.cpp (define_character_request)
	(define_fallback_character_request)
	(define_special_character_request):
	* src/roff/troff/node.cpp
	(define_font_specific_character_request): Update call sites.

	* src/roff/troff/input.cpp (init_input_requests): Update
	coupling of request names to request handler functions.

2025-01-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* NEWS: Add item at top making special note of incompatible
	change to `cf`, `hpf`, `hpfa`, `mso`, `msoquiet`, `nx`, `open`,
	`opena`, `so`, `soquiet`, and `trf` request syntax affecting
	users/documents that append comment escape sequences to them
	loosely.

	* doc/groff.texi.in (Manipulating Hyphenation, Using Symbols)
	(Strings, I/O):
	* man/groff.7.man (Strings): Apply cautionary note (even with
	respect to requests where behavior hasn't actually changed).

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

2025-01-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	Further rationalize header file inclusions.

	* src/include/driver.h: Drop inclusion of groff's "lib.h"; this
	header file itself uses none of its facilities.
	* src/include/font.h: Include stdio.h.  Annotate why.
	* src/include/symbol.h: Include stddef.h.  Annotate why.

2025-01-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grodvi,grohtml,grolbp,grolj4,grops,grotty,libdriver]: Further
	rationalize header file inclusions.

	* src/devices/grodvi/dvi.cpp:
	* src/devices/grohtml/html-table.cpp:
	* src/devices/grohtml/output.cpp:
	* src/devices/grohtml/post-html.cpp:
	* src/devices/grolbp/lbp.cpp:
	* src/devices/grolj4/lj4.cpp:
	* src/devices/grops/psrm.cpp:
	* src/devices/grotty/tty.cpp:
	* src/libs/libdriver/input.cpp:
	* src/libs/libdriver/printer.cpp: Include (only) the standard
	libc and groff internal header files we need, so that
	"driver.h", "font.h", and "symbol.h" needn't do this job.

2025-01-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	Reduce header file inclusion spam.

	* src/include/driver.h: Drop inclusion of standard libc header
	files.  This header file itself uses none of its facilities.

2025-01-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grohtml,grolbp]: Rationalize header file inclusions.

	* src/devices/grohtml/html-table.cpp:
	* src/devices/grohtml/post-html.cpp:
	* src/devices/grolbp/lbp.cpp: Include (only) the standard libc
	header files we need, so that "driver.h" needn't do this job.

2025-01-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grolj4]: Migrate `isdigit()` to `csdigit()`.

	* src/devices/grolj4/lj4.cpp (main): Use "libgroff.a"'s facility
	for determining character class membership, to conform with the
	rest of the code base.

2025-01-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grohtml]: Migrate `isspace()` to `csspace()`.

	* src/devices/grohtml/html-table.cpp (tabs::compatible)
	(tabs::init):
	* src/devices/grohtml/post-html.cpp (text_glob::get_arg)
	(text_glob::get_tab_args, html_printer::do_tab_te): Use
	"libgroff.a"'s facility for determining character class
	membership, to conform with the rest of the code base (except C
	code that doesn't link with that library).

2025-01-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grohtml]: Fix code style nits.

	* src/devices/grohtml/html-table.cpp (tabs::compatible)
	(tabs::init):
	* src/devices/grohtml/output.cpp (word::word):
	* src/devices/grohtml/post-html.cpp (text_glob::get_arg)
	(text_glob::get_tab_args, replace_negate_str)
	(html_printer::do_job_name, html_printer::set_char_and_width)
	(get_str): Spell null character using the C/C++ language literal
	for expressing it, instead of C-casting `0` to `char`.  Reorder
	equality comparisons to avoid inadvertent lvalue assignment.
	Parenthesize complex expressions.

2025-01-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (an*abbreviate-page-topic): (Actually, it's the
	_identifier_ we're abbreviating...)  Avoid crowding the middle
	header with a combination of line length and identifier text
	that is just right to exercise a corner case.

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

2025-01-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Regression-test Savannah #66664.

	* tmac/tests/an_title-abbreviation-works.sh: Add test case.

2025-01-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (do_input_trap): Directly copy Boolean
	value instead of using a control structure.

2025-01-07  Ingo Schwarze <schwarze@openbsd.org>

	* tmac/mdoc/doc-syms: Support .St -isoC-2023.
	* tmac/groff_mdoc.7.man: Document .St -isoC-2023.

	The mismatch of the year numbers is not a typo.  The official
	name is "ISO/IEC 9899:2024", so the "4" is correct there.

	But as a colloquial name, "C23" is more widespread than "C24",
	probably because __STDC_VERSION__ == 202311L: The final version
	of the standard was ready in 2023, only formally publishing it
	took about 11 months after it was ready.

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

	* tmac/an.tmac (SH): Restore closing brace escape sequence.

	This caused the package to stop formatting the document if `SH`
	was called without any arguments, a valid but uncommon usage.
	Problem introduced by me in commit f3944d6305, 3 March.

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

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

	[man]: Test argumentless `SH`, `SS` calls.

	* tmac/tests/an_SH-works-with-pending-input-trap.sh:
	* tmac/tests/an_SS-works-with-pending-input-trap.sh: Do it.
	* tmac/tmac.am (tmac_TESTS): Run tests.

2025-01-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Rationalize header inclusion.

	* src/preproc/tbl/table.h: Drop inclusion of system headers,
	relocating applicable ones...
	* src/preproc/tbl/main.cpp:
	* src/preproc/tbl/table.cpp: ...here.

2025-01-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/main.cpp (process_input_file, process_format)
	(process_data, process_table, main): Adjust wording of
	diagnostic messages for clarity and consistency with documented
	terminology.

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

2025-01-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/main.cpp (main): Distinguish `ferror()` status
	and `fflush(stdout)` failures when cleaning up before exit.

2024-12-24  Collin Funk  <collin.funk1@gmail.com>

	Use the `strcase` Gnulib module.

	* Makefile.am: Update comment.
	* bootstrap.conf (gnulib_modules): Add strcase.
	* configure.ac: Remove checks for strcasecmp and strncasecmp.
	* src/libs/libgroff/strcasecmp.c: Delete file.
	* src/libs/libgroff/strncasecmp.c: Likewise.
	* src/libs/libgroff/libgroff.am (EXTRA_DIST): Remove deleted
	files.
	* src/include/lib.h (strcasecmp, strncasecmp): Remove
	declarations.
	* src/roff/groff/pipeline.c (strcasecmp): Likewise.

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

2025-01-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* bootstrap: Resync with gnulib upstream.

2025-01-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* gnulib: Update to stable/2025-01.

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

	* src/utils/afmtodit/afmtodit.pl: Report input file name and
	line number in diagnostic messages.

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

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

	* src/utils/afmtodit/afmtodit.pl: Migrate diagnostics to newly
	developing wording convention.

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

2024-12-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* m4/groff.m4 (GROFF_MAKE_DEFINES_RM): Quote name of "make"
	command in "checking" message for clarity.

2024-12-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grog]: Use a proper "artifacts" directory for test scripts.

	* src/utils/grog/tests/foo.man: Rename this...
	* src/utils/grog/tests/artifacts/foo.man: ...to this.

	* src/utils/grog/grog.am (EXTRA_DIST): Update location of
	artifact.

	* src/utils/grog/tests/recognize-perl-pod.sh: Search for test
	artifact directory, and skip test if we can't find it.  Update
	expected output.

2024-12-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	Revamp build-time check of POSIX-conforming test(1) command.

	"test -ef", long depended upon by the contributed program
	gdiffmk(1) for certain functionality, is now standard as of
	POSIX Issue 8 (2024).  The Austin Group's threshold criteria for
	inclusion in the standard mean that such a feature is widely
	available, and one need not pessimistically assume that the Bash
	shell must be used to obtain the feature.  Refactor and revise
	our detection and fallback techniques accordingly.

	* m4/groff.m4 (GROFF_HAVE_TEST_EF_OPTION): Rename this...
	(GROFF_PROG_TEST_SUPPORTS_EF_OPTION): ...to this.  Simplify,
	making it a simple test of the feature, using "sh -c" since we
	don't care whether the shell itself or a 'test' executable in
	the $PATH provides it.
	(GROFF_BASH): Rename this...
	(GROFF_PROG_SH_IS_POSIX_8_CONFORMING): ...to this.  It's a
	mouthful, but reflects our concerns.  We don't care about Bash
	per se (groff does not employ Bashisms); we care about whether
	the shell conforms to POSIX Issue 8.  Rename the `AC_SUBST`ed
	macro `BASH_PROG` to `POSIX_SHELL_PROG`.  If we don't find a
	conforming shell, _then_ fall back to Bash for
	`POSIX_SHELL_PROG`, if it is available; if not, configure-time
	tests are fruitless and programs must perform runtime checks for
	POSIX non-conformance (since we're not shipping our own shell or
	test(1) to close the gap).
	* configure.ac: Update expansion sites of m4 macros to use their
	new names.

2024-12-22  onf <onf@disroot.org>

	Support building without makeinfo(1) installed.

	* m4/groff.m4 (GROFF_PROG_MAKEINFO): Simplify logic to not throw
	error if "groff.info" is older than "groff.texi"; that is now an
	accepted state of affairs during configuration.  (make(1) could
	fail later, though.)  Set new variable `groff_have_makeinfo`.
	Stop `AC_MSG_WARN`-ing if it's absent.
	(GROFF_MAKEINFO_PROGRAM_NOTICE): New macro warns user of the
	consequences of not having (a recent enough) makeinfo(1)
	installed.
	* configure.ac: Set Automake conditional `HAVE_MAKEINFO` if the
	corresponding new shell variable was assigned by
	`GROFF_PROG_MAKEINFO`.  Report in configuration summary whether
	the Info, plain text, and HTML forms of groff's Texinfo manual
	can be generated.  Call `GROFF_MAKEINFO_PROGRAM_NOTICE` macro.
	* doc/doc.am: Indirect the file names of the Info, plain text,
	and HTML forms of groff's Texinfo manual through new make(1)
	macros, `GROFF_INFO`, `GROFF_TXT`, and `GROFF_HTML`.  Assign
	them only if `HAVE_MAKEINFO` is true.
	(all): Expand the new macros in place of literals.

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

	Co-authored-by: "G. Branden Robinson"
	<g.branden.robinson@gmail.com>

2024-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/neqn.sh: Handle `-h` and `--help` options:
	display a usage message to the standard output and exit with a
	successful status.

2024-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/lf.h: Include "stringclass.h" header file, since
	we refer to groff's `string` type.

2024-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/stringclass.h: Introduce `GROFF_STRINGCLASS_H`
	include guard.

2024-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/tfmtodit/tfmtodit.cpp (main): Throw assertion on
	_any_ unhandled return value from `getopt_long()`, not just EOF.

2024-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/xtotroff/xtotroff.c (main): Throw assertion if we
	don't handle `getopt_long()`'s return value.

2024-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/hpftodit/hpftodit.cpp (main):
	* src/utils/indxbib/indxbib.cpp (main):
	* src/utils/lkbib/lkbib.cpp (main):
	* src/utils/lookbib/lookbib.cpp (main):
	* src/utils/pfbtops/pfbtops.c (main):
	* src/utils/tfmtodit/tfmtodit.cpp (main):
	* src/utils/xtotroff/xtotroff.c (main): Migrate to modern
	getopt_long(3) usage.  Drop `opterr` assignment; prefix the
	option string with ":" instead.  Handle return of `:`, emit an
	appropriate usage diagnostic, and exit with status 2.

2024-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/main.cpp (main):
	* src/preproc/html/pre-html.cpp (main):
	* src/preproc/pic/main.cpp (main):
	* src/preproc/preconv/main.cpp (main):
	* src/preproc/soelim/soelim.cpp (main):
	* src/preproc/tbl/main.cpp (main): Migrate to modern
	getopt_long(3) usage.  Drop `opterr` assignment; prefix the
	option string with ":" instead.  Handle return of `:`, emit an
	appropriate usage diagnostic, and exit with status 2.

2024-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grolj4/lj4.cpp (main): Align missing command-line
	option handling with refactoring underway.  Migrate from stdio.h
	functions for emitting diagnostics in favor of "libgroff.a"
	functions.  Continue to muddle through if `-d`'s option is
	missing, assuming long-side duplexing as before.  Emit usage
	message and exit with status 2 in all other cases.

2024-12-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* 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): Migrate to modern
	getopt_long(3) usage.  Drop `opterr` assignment; prefix the
	option string with ":" instead.  Handle return of `:`, emit an
	appropriate usage diagnostic, and exit with status 2.

2024-12-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (main): Migrate to modern
	getopt_long(3) usage.  Drop `opterr` assignment; prefix the
	option string with ":" instead.  Handle return of `:`, emit an
	appropriate usage diagnostic, and exit with status 2.

2024-12-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Fix thinkos in new test.

	* src/roff/groff/tests/artifacts/small-gnu-head.sh: Rename
	this...
	* src/roff/groff/tests/artifacts/small-gnu-head.png: ...to this.
	* src/roff/groff/tests/using-diversion-as-character-works.sh:
	Refer to image file by correct name instead of neither of the
	foregoing.

	This didn't actually break the test because all we're testing is
	the correct sequencing of grout commands in GNU troff output,
	not whether a graphic actually appears.  But having a test
	script that doesn't work right when you try it is a bad look.

2024-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp (main): Migrate to modern
	getopt_long(3) usage.  Drop `opterr` assignment; prefix the
	option string with ":" instead.  Handle return of `:`, emit an
	appropriate usage diagnostic, and exit with status 2.

2024-12-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #66587.

	* src/roff/groff/tests/using-diversion-as-character-works.sh:
	* src/roff/groff/tests/artifacts/small-gnu-head.sh: Add test and
	its input artifact.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2024-12-12  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Expose more attributes of pdfnotes

	* tmac/pdfpic: Add registers PDFNOTE.COLO(U)R and
	PDFNOTE.OPACITY which affect the rendering of the note.

	* src/devices/gropdf/gropdf.pl: Add creation date. If no window
	title given but the author's name has previously been given with
	.pdfinfo use the name as the title.

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

2024-12-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	[src/devices, tmac]: Improve build modularity.

	* tmac/tmac.am (TMACNORMALFILES, tmac_TESTS): Drop file names
	from these macros that are better declared elsewhere.

	* src/devices/grodvi/grodvi.am:
	* src/devices/grohtml/grohtml.am:
	* src/devices/grolbp/grolbp.am:
	* src/devices/grolj4/grolj4.am:
	* src/devices/gropdf/gropdf.am:
	* src/devices/grops/grops.am:
	* src/devices/grotty/grotty.am:
	* src/devices/xditview/xditview.am: ...like here (using
	appropriately particularized names).  Attempt to remove
	`$(DESTDIR)/$(tmacdir)` directory, ignoring failure, in case we
	just removed the last thing in it.

2024-12-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tmac.am (TMACNORMALFILES): Ship "psfig.tmac".

2024-12-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (.me.in.me): Fix inference rule to expand correct
	Automake macro in rule; use `AM_V_GEN`, not `GROFF_V` to report
	progress, since we're running sed(1), not groff.

2024-12-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[refer]: Improve build modularity.

	* tmac/tmac.am (TMACNORMALFILES): Stop shipping "refer.tmac"
	here...
	* src/preproc/refer/refer.am: ...in favor of defining
	appropriate module-specific Automake variables/make(1) macros
	here.
	(uninstall_refer_hook): Attempt to remove
	`$(DESTDIR)/$(tmacdir)` directory, ignoring failure, in case we
	just removed the last thing in it.

2024-12-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[pic]: Improve build modularity.

	* tmac/tmac.am (TMACNORMALFILES): Stop shipping "pic.tmac"
	here...
	* src/preproc/pic/pic.am: ...in favor of defining appropriate
	module-specific Automake variables/make(1) macros here.
	(uninstall_pic_hook): Attempt to remove `$(DESTDIR)/$(tmacdir)`
	directory, ignoring failure, in case we just removed the last
	thing in it.

2024-12-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn]: Improve build modularity.

	* tmac/tmac.am (TMACNORMALFILES): Stop shipping "eqnrc" here...
	* src/preproc/eqn/eqn.am: ...in favor of defining appropriate
	module-specific Automake variables/make(1) macros here.

	* tmac/tmac.am (uninstall_tmac_hook): Ignore failure of `rmdir`
	to remove `$(DESTDIR)/$(tmacdir)`.  Multiple Automake files
	place things there, and we might be racing with them.

	* src/preproc/eqn/eqn.am (uninstall_eqn_hook): Attempt to remove
	`$(DESTDIR)/$(tmacdir)` directory, ignoring failure, in case we
	just removed the last thing in it.

2024-12-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/afmtodit/afmtodit.pl: Use $0 in the usage message
	for consistency with groff's C++ programs.  This also informs
	the user with multiple versions available which they are
	running.

2024-12-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/afmtodit/afmtodit.am: Simplify.
	(afmtodit): Drop branch handling the case where the `PERL` macro
	is undefined or empty.  The groff configuration process has long
	required a Perl interpreter to be present, and its absence is a
	hard error; see `GROFF_PERL` in "m4/groff.m4".  Since
	construction of the target is an interruptible multi-step
	process involving sed(1) and chmod(1), `RM` the target before
	constructing it, and favor `$@` expansion over literally naming
	the target.

2024-12-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/lkbib/lkbib.cpp (usage): If asked for `--help`,
	summarize command purpose in message.

2024-12-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Disable `cf` request in safer mode.

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

	* doc/groff.texi.in (I/O) <cf>:
	* man/groff.7.man (Request short reference) <cf>:
	* man/groff_diff.7.man (Restricted requests): Document it.

	* NEWS: Add item.

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

2024-12-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/libgroff.am (libgroff_a_LIBADD): Add to
	ensure linkage with gnulib.
	* src/libs/libgroff/string.cpp: Align with modern groff
	conventions.  Include "<stdio.h>" header file to ensure
	visibility of `FILE`, `putc()` and `sprintf()` symbols.  Include
	"<string.h>" header file to ensure visibility of `memmem()`
	declaration; problem detected on Solaris 10.  Parenthesize
	complex expressions.
	(string::extract): Use C++ `static_cast` operator instead of
	C-style type cast.

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

	[troff]: The `open` and `opena` requests now accept leading and
	embedded spaces in their "file" arguments, just like `so`.

	* src/roff/troff/input.cpp (open_file): Gather the second
	argument with `read_string()` (which reads a potentially
	spaceful argument including a discardable leading double quote),
	not `get_long_name()` (which reads a GNU troff identifier).
	Call `tok.next()` at the end of the function as required by
	`read_string()`.
	(open_request, opena_request): Drop `skip_line()` call from end
	of function and annotate why.

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

	* NEWS: Update existing items.

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

	[troff]: The `nx` request now accepts leading and embedded
	spaces in its optional "file" argument, similarly to `so`.

	* src/roff/troff/input.cpp (next_file): Peek at the input stream
	for an argument, and if there is one, gather it with
	`read_string()` (which reads a potentially spaceful argument
	including a discardable leading double quote), not
	`get_long_name()` (which reads a GNU troff identifier).

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

	* NEWS: Update existing items.

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

	[troff]: The `hpf` and `hpfa` requests now accept leading and
	embedded spaces in their "file" arguments, just like `so`.

	* src/roff/troff/input.cpp
	(read_hyphenation_patterns_from_file): Gather the argument with
	`read_string()` (which reads a potentially spaceful argument
	including a discardable leading double quote), not
	`get_long_name()` (which reads a GNU troff identifier).  Call
	`tok.next()` afterwards.
	(load_hyphenation_patterns_from_file)
	(append_hyphenation_patterns_from_file): "Peek" at the input
	stream when checking for arguments to avoid advancing the input
	stream pointer past the first character in the `hpf` or `hpfa`
	request argument.  Annotate why we do not call `skip_next()` at
	the end of the request handler, as most do.

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

	* NEWS: Update existing items.

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

	[troff]: The `cf` and `trf` requests now accept leading and
	embedded spaces in their "file" arguments, just like `so`.

	* src/roff/troff/input.cpp (copy_file, transparent_file): Gather
	the argument with `read_string()` (which reads a potentially
	spaceful argument including a discardable leading double quote),
	not `get_long_name()` (which reads a GNU troff identifier).
	Call `tok.next()` afterwards.

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

	* NEWS: Update existing items.

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

	[nroff]: Rename test script to better fit recent conventions.
	We now use underscores only for structuring, as with the
	various macro packages in the "tmac" directory.

	* src/roff/nroff/tests/verbose_option_works.sh: Rename this...
	* src/roff/nroff/tests/verbose-option-works.sh: ...to this.

	* src/roff/nroff/nroff.am (nroff_TESTS): Reflect rename.

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

	[nroff]: Improve shell behavior check and fix goof in test
	script.

	* src/roff/nroff/nroff.sh: Replace proxy `unset`-based test with
	an actual measurement of parameter expansion.
	* src/roff/nroff/tests/verbose_option_works.sh: Fix spurious
	failure of test for grep(1) supporting `-q` and `-x` options.
	Continues commit e05cf6d3b3, 4 December.

	* HACKING: Document Solaris frustrations.

2024-12-09  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Data provided to .pso must terminate with \n.

	* tmac/pdfpic.tmac: Add terminating linefeed.

	Fixes <https://savannah.gnu.org/bugs/?66537> thanks to
	Bjarni Ingi Gislason for the report and solution.

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

	Avoid test failures on Solaris 11 arising from system tool
	limitations.  See "PROBLEMS" file.

	* tmac/tests/an_vertical-margins-are-correct.sh:
	* tmac/tests/doc-old_vertical-margins-are-correct.sh:
	* tmac/tests/doc_vertical-margins-are-correct.sh: Skip test if
	the system lacks a grep conforming to POSIX Issue 4 (1994).

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

	* src/roff/troff/env.cpp (do_error): Fix off-by-one error in
	output warnings in nroff mode.  By convention, lines on
	terminals are numbered starting at one; for example, using U.S.
	letter paper (with a nominal type size of 10 points on 12 point
	spacing), the lines of the 11-inch page length are numbered
	1-66, not 0-65.

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

	Stop pointlessly overwriting new CJK font descriptions for
	grohtml(1) and grotty(1).  Unlike the Latin script descriptions,
	they aren't generated from a ".proto" file.

	* font/devhtml/devhtml.am (DEVHTMLFONTS): Move CJK font
	description files from here...
	(DEVHTMLFONTSFILES_CJK): ...to this new macro.
	(devhtmlfont_DATA, EXTRA_DIST): Expand `DEVHTMLFONTSFILES_CJK`
	here.  The latter ensures their presence in the distribution
	archive.

	* font/devutf8/devutf8.am (DEVUTF8FONTS): Move CJK font
	description files from here...
	(DEVUTF8FONTSFILES_CJK): ...to this new macro.
	(devutf8font_DATA, EXTRA_DIST): Expand `DEVUTF8FONTSFILES_CJK`
	here.  The latter ensures their presence in the distribution
	archive.

2024-12-05  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Backport gropdf and pdfpic.tmac to Perl 5.8.

	* src/devices/gropdf/gropdf.pl:
	* tmac/pdfpic.tmac (pdfpic@get-image-dimensions): Use Perl
	5.8-compatible regular expressions.

	* src/devices/gropdf/gropdf.pl: Cope with pre-Perl-5.12
	semantics for applying the `length` built-in function to an
	undefined scalar.

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

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

	Document new CJK/UTF-16 font support features.

	* doc/groff.texi.in (Font Description File Format):
	* man/groff_font.5.man (Font description file format):
	* src/devices/grohtml/grohtml.1.man (Typefaces):
	* src/devices/grops/grops.1.man (Typefaces):
	* src/devices/grotty/grotty.1.man (Typefaces): Do it.

	* NEWS: Add item.

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

	[grolj4, indxbib]: Improve diagnostic messages.

	* src/devices/grolj4/lj4.cpp (main): When reporting out-of-range
	option arguments, include the erroneous user-supplied argument.
	Use interval notation correctly.
	* src/utils/indxbib/indxbib.cpp (check_integer_arg): Use
	interval notation correctly.  Annotate why we can't report the
	erroneous user-supplied argument.
	(read_common_words_file): Fix typo in diagnostic message.

2024-12-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[nroff]: Work around malicious non-compliance with POSIX.

	* src/roff/nroff/nroff.sh: We can use POSIX shell parameter
	expansion only if the shell supports it, but it's a hard feature
	to test for within a shell script because non-conforming shells
	reject it as bad syntax, aborting interpretation of the script.
	Use the error return status of `unset` applied to a nonexistent
	variable as a proxy.  If the shell is thus adjudged as lousy,
	use a cruder method of obtaining the basename of the script, and
	refuse to process option clusters, because we need parameter
	expansion to handle them.
	* src/roff/nroff/tests/verbose_option_works.sh: Skip test if
	the system lacks a grep conforming to POSIX Issue 4 (1994).

2024-12-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (is_conditional_expression_true):
	Stop treating `|` as a delimiter, but instead as beginning a
	numeric expression, _only_ as the predicate of a control
	structure request.  Improves compatibility with AT&T troff,
	including DWB 3.3 and Heirloom Doctools.  Problem appears to
	date back to groff 1.02.

	GNU troff has long thrown diagnostics in this context, of
	increasing detail in recent years.  For example:

	troff:mm/0.MT:271: warning: missing closing delimiter in output
	  comparison operator; expected character '|', got a newline

	However, this was easily overlooked in our automated tests
	because it didn't break formatting.

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

2024-12-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(do_if_request): Rename this...
	(is_conditional_expression_true): ...to this.
	(if_else_request, if_request, while_request): Update call sites.

2024-12-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	Adapt tests to feeble systems lacking a shell or grep conforming
	to POSIX Issue 4 (1994).

	* src/roff/groff/tests/msoquiet-request-works.sh:
	* src/roff/groff/tests/soquiet-request-works.sh:
	* tmac/tests/an_UR-works.sh: Do it.

	* tmac/tests/an_UR-works.sh: Also cope with versions of
	pdftotext(1) that transcribe "fi" as a ligature.

	* HACKING:
	* PROBLEMS: Update advice.

2024-12-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/main.cpp (usage): If asked for `--help`,
	summarize command purpose in message.

2024-12-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/main.cpp (usage): If asked for `--help`,
	summarize command purpose in message.

2024-12-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/grog/grog.pl (usage):
	* src/utils/indxbib/indxbib.cpp (usage): Stop shouting operand
	names.  We don't otherwise do this, and "FILE" in particular
	frustrates "git grep"s because it collides with the "stdio.h"
	data type.

2024-12-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/soelim/soelim.cpp (usage):
	* src/preproc/soelim/soelim.1.man: Revise program description.

2024-12-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/maxfilename.cpp: Include local "posix.h"
	header before "nonposix.h" (and both before "lib.h"), aligning
	better with other groff code, and fixing build on Android/Bionic
	libc/Termux.

2024-12-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/ps.cpp: Include local "posix.h" header
	before "nonposix.h" (and both before "lib.h"), aligning better
	with other groff code.

2024-12-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/tfmtodit/tfmtodit.cpp: Include system library
	headers before local ones.  Include local "posix.h" header
	before "nonposix.h", aligning better with other groff code.

2024-12-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (system_request, pipe_output):
	Consistently `return` early under invalid request invocation
	conditions (absent mandatory arguments, not in unsafe mode, or--
	in the case of `pi`--belated occurrence).  Drop the indentation
	level of rest of function accordingly.  Parallelize wording of
	"impossible" error diagnostics.

2024-12-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (system_request, pipe_output): Call
	`tok.next()` at end of non-error path.

	Fixes <https://savannah.gnu.org/bugs/?66512>.  Thanks to Deri
	James for the report.  Problem introduced by me in commit
	24e314b94c3, 12 November.

2024-12-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #66512.

	* src/roff/groff/tests/pi-request-works.sh:
	* src/roff/groff/tests/sy-request-works.sh: Add check of `tm`
	output to standard error stream immediately after request.

2024-12-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/xditview/xditview.c (Syntax): Align wording of
	usage message better with those of other output drivers.

2024-12-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	Rationalize and annotate header file inclusions.

	* src/devices/grohtml/output.cpp:
	* src/libs/libgroff/color.cpp:
	* src/libs/libgroff/maxfilename.cpp:
	* src/libs/libgroff/maxpathname.cpp:
	* src/libs/libgroff/tmpfile.cpp:
	* src/preproc/html/pre-html.cpp:
	* src/preproc/html/pushback.cpp:
	* src/roff/groff/pipeline.c:
	* src/utils/indxbib/indxbib.cpp:
	* src/utils/indxbib/signal.c: Do it.

2024-12-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/grn/hdb.cpp: Include "<stdlib.h>" header file to
	ensure visibility of `atoi()` declaration.  Problem detected on
	Solaris 10.

2024-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	Reduce header file inclusion spam.

	* src/include/lib.h: Drop inclusion of "<getopt.h>" header file,
	a GNU extension.  This header file itself uses none of its
	facilities.  Instead...
	* src/devices/grodvi/dvi.cpp:
	* 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/preproc/eqn/main.cpp:
	* src/preproc/html/pre-html.cpp:
	* src/preproc/pic/main.cpp:
	* src/preproc/preconv/preconv.cpp:
	* src/preproc/soelim/soelim.cpp:
	* src/preproc/tbl/main.cpp:
	* src/roff/groff/groff.cpp:
	* src/roff/troff/input.cpp:
	* src/utils/hpftodit/hpftodit.cpp:
	* src/utils/indxbib/indxbib.cpp:
	* src/utils/lkbib/lkbib.cpp:
	* src/utils/lookbib/lookbib.cpp:
	* src/utils/tfmtodit/tfmtodit.cpp: ...`#include` "<getopt.h>" in
	files that directly use the symbols it exposes.

2024-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/lib.h:
	* src/libs/libgroff/libgroff.am (libgroff_a_CPPFLAGS):
	* src/utils/pfbtops/pfbtops.c:
	* src/utils/xtotroff/xtotroff.c: Fix straggling definitions of
	`__GETOPT_PREFIX`, which broke the build on Solaris 10.
	Continues commit 68968197dc, 27 November.

2024-11-30  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Using \*[PDFLB] does not work.

	* tmac/pdf.tmac: Simplify string and fix misconception
	about PDFNOTE.WIDTH and PDFNOTE.HEIGHT.

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

2024-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	[lookbib]: Align with modern groff conventions.

	* src/utils/lookbib/lookbib.cpp (usage): If asked for `--help`,
	summarize command purpose in message.
	(main): Recast wording of diagnostic messages.  Use standard
	symbol `EXIT_SUCCESS` instead of `0` literal.  `sizeof` is an
	operator, not a function, so don't parenthesize its operand when
	it's an lvalue {as opposed to a type name}.

2024-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/lookbib/lookbib.cpp (main): Emit error diagnostic
	and exit with status 2, not 1, when given no operands.
	Continues commit 89283b0935, 18 October.

2024-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	Rename Makefile macro `DEVICE` to `DEFAULT_DEVICE`.

	* Makefile.am: Do it.
	* src/include/include.am (defs.h):
	* src/libs/libgroff/device.cpp:
	* src/devices/grodvi/grodvi.1.man:
	* src/devices/grohtml/grohtml.1.man:
	* src/devices/grolbp/grolbp.1.man:
	* src/devices/grolj4/grolj4.1.man:
	* src/devices/gropdf/gropdf.1.man:
	* src/devices/grops/grops.1.man:
	* src/devices/grotty/grotty.1.man:
	* src/preproc/eqn/eqn.1.man:
	* src/preproc/grn/grn.1.man:
	* src/roff/groff/groff.1.man:
	* src/roff/troff/troff.1.man: Reflect rename.

	* NEWS: Add item.

2024-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	[indxbib]: Align with modern groff conventions.

	* src/utils/indxbib/indxbib.cpp (main): Use standard symbol
	`EXIT_SUCCESS` instead of `0` literal.  Parenthesize complex
	expressions.
	(main, do_file): Replace `assert(0)` calls with communicative
	predicates.
	(main, store_reference, write_hash_table): `sizeof` is an
	operator, not a function, so don't parenthesize its operand when
	it's an lvalue {as opposed to a type name}.
	(main, check_integer_arg, get_cwd, read_common_words_file)
	(do_whole_file, do_file, write_hash_table, fwrite_or_die):
	Recast wording of diagnostic messages.
	(usage): If asked for `--help`, summarize command purpose in
	message.

2024-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	[indxbib]: Exit with status 2 on usage errors.

	* src/utils/refer/refer.cpp (main): Exit with status 2, not 1,
	on usage errors.  Continues commit 89283b0935, 18 October.
	* NEWS: Note the change.

2024-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/indxbib/indxbib.cpp: Include local "nonposix.h"
	header file, to try to ensure visibility of `getcwd()` symbol on
	non-POSIX systems.

2024-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/pipeline.c: Sort (and annotate) inclusions of
	standard header files.

2024-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	Rely on gnulib for `unlink()` if necessary.

	* bootstrap.conf: Add "unlink" to `gnulib_modules`.

	* src/libs/libgroff/tmpfile.cpp:
	* src/preproc/html/pre-html.cpp: Include "<unistd.h>" standard
	header file to ensure visibility of `unlink` declaration.  Wrap
	this in `HAVE_UNISTD_H` preprocessor conditional (a symbol we
	direct the user to define in "Makefile.am" if necessary).  I
	think gnulib obviates this, but the idiom is widely used in the
	groff codebase for this header file so I leave an experimental
	scrub-out for another day.  (It would also help to have a good
	communication loop with someone building groff on a non-POSIX
	system like native Windows; I don't have one handy.)

2024-11-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	Rely on gnulib for `strsignal()` if necessary.

	* bootstrap.conf: Add "strsignal" to `gnulib_modules`.
	* configure.ac: Drop "strsignal" and "sys_siglist" from
	`AC_CHECK_DECLS`; we don't need Autoconf's tests for these if
	we've got gnulib's replacements.
	* src/preproc/html/pre-html.cpp: Include "<string.h>" standard
	header file to ensure visibility of `strsignal` (and `strerror`)
	declarations.
	* src/roff/groff/pipeline.c: Drop declaration of `xstrsignal`,
	our own replacement for `strsignal`.
	(xstrsignal): Drop.
	(run_pipeline): Update call site.

2024-11-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	Rely on gnulib for `strerror()` if necessary.

	* bootstrap.conf: Add "strerror" to `gnulib_modules`.
	* configure.ac: Drop "sterror" from `AC_REPLACE_FUNCS`; we don't
	need Autoconf's replacement if we've got gnulib's.
	* Makefile.am: Drop mention of function/macro in comment.
	* src/include/lib.h: Drop C preprocessor conditional logic.
	* src/roff/groff/pipeline.c: Drop fallback definition.  Let
	existing "<config.h"> inclusion do the work, and include
	"<string.h>" unconditionally.

2024-11-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Align with modern groff conventions.

	* src/roff/troff/input.cpp: Include system library headers
	before local ones.
	(main): Use standard symbol `EXIT_SUCCESS` instead of `0`
	literal.

2024-11-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[refer]: Align with modern groff conventions.

	* src/preproc/refer/refer.cpp (main): Recast wording of
	diagnostic messages; communicate what is done with an invalid
	command-line option argument (it is ignored).  Reorder equality
	comparisons to avoid inadvertent lvalue assignment.  Use
	standard symbol `EXIT_SUCCESS` instead of `0` literal.
	Distinguish `ferror()` status and `fflush(stdout)` failures when
	cleaning up before exit.
	(usage): If asked for `--help`, summarize command purpose in
	message.
	(do_file, find_reference, do_bib): Recast wording of diagnostic
	messages.
	(do_file): Construct temporary value instead of using a C-style
	type cast.
	(rcompare): Use C++ `const_cast` operator nested inside
	`static_cast` operator instead of C-style type cast.

2024-11-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[refer]: Exit with status 2 on usage errors.

	* src/utils/refer/refer.cpp (main): Exit with status 2, not 1,
	on usage errors.  Continues commit 89283b0935, 18 October.
	* NEWS: Note the change.

2024-11-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/refer/refer.cpp (main): Skip rest of argument to
	`-l` option when encountering garbage, preventing the enclosing
	loop from attempting to interpret the garbage as more options.

2024-11-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[preconv]: Align with modern groff conventions.

	* src/preproc/preconv/preconv.cpp (emacs2mime)
	(conversion_iconv): Use C++ `const_cast` operator instead of
	C-style type cast.
	(conversion_latin1, conversion_utf8, conversion_cp1047)
	(conversion_iconv): Use C++ `reinterpret_cast` operator instead
	of C-style type cast for potentially narrowing conversions.
	(conversion_iconv): Reorder equality comparisons to avoid
	inadvertent lvalue assignment.
	(conversion_iconv, detect_file_encoding, do_file): Recast
	wording of diagnostic messages.
	(conversion_iconv, detect_file_encoding): Use C++ `static_cast`
	operator instead of C-style type cast.
	(conversion_iconv): Parenthesize complex expressions.
	(main): Use standard symbol `EXIT_SUCCESS` instead of `0`
	literal.  Replace `assert(0)` call with communicative predicate.
	Distinguish `ferror()` status and `fflush(stdout)` failures when
	cleaning up before exit.

2024-11-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[pic]: Align with modern groff conventions.

	* src/preproc/pic/main.cpp (top_input::get, top_input::peek)
	(do_file): Drop pointless construction of temporary value from
	argument that is already of the desired type.
	(do_file, do_whole_file, main): Recast wording of diagnostic
	messages.
	(do_file, main): Replace `assert(0)` call with
	communicative predicate.
	(usage): If asked for `--help`, summarize command purpose in
	message.
	(main): Use standard symbols `EXIT_SUCCESS` and `EXIT_FAILURE`
	instead of `0` and `1` literals, respectively.  Distinguish
	`ferror()` status and `fflush(stdout)` failures when cleaning up
	before exit.

2024-11-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grn]: Align with modern groff conventions.

	* src/preproc/grn/main.cpp (usage): If asked for `--help`,
	summarize command purpose in message.
	(main): Use standard symbol `EXIT_SUCCESS` instead of `0`
	literal.  Recast wording of diagnostic message.

2024-11-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grn]: Fix command-line option handling.

	* src/preproc/grn/main.cpp (main): Don't write diagnostic
	message when asked for `--help`.  Exit with status 2 on
	unrecognized option (for real this time, correcting commit
	89283b0935, 18 October).

2024-11-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[gxditview]: Exit with status 2 on usage errors.

	* src/devices/xditview/xditview.c (Syntax): Exit with status 2
	on usage error, not `EXIT_FAILURE`.
	* src/devices/xditview/gxditview.1.man (Exit status): Add
	section.
	* NEWS: Note the change.

2024-11-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[gxditview]: Align with modern groff conventions.

	* src/devices/xditview/xditview.c (Syntax): If asked for
	`--help`, summarize command purpose in message.
	(QuitAction): Use standard symbol `EXIT_SUCCESS` instead of `0`
	literal.

2024-11-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grops]: Align with modern groff conventions.

	* src/devices/grops/ps.cpp (ps_output::put_string)
	(ps_printer::flush_sbuf, main): Replace `assert(0)` call with
	communicative predicate.
	(ps_printer::set_style, ps_printer::draw, main): Recast wording
	of diagnostic messages.
	(ps_printer::~ps_printer): Use standard symbol `SEEK_SET`
	instead of `0` literal.

2024-11-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grolj4]: Align with modern groff conventions.

	* src/devices/grolj4/lj4.cpp
	(lj4_font::handle_unknown_font_command): Use libgroff's
	newfangled `array_length()` template function to measure arrays.
	(lj4_font::handle_unknown_font_command, lj4_printer::draw)
	(main): Recast wording of diagnostic messages.
	(main): Use standard symbol `EXIT_SUCCESS` instead of `0`
	literal.  Replace `assert(0)` call with communicative predicate.
	(usage): If asked for `--help`, summarize command purpose in
	message.

2024-11-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[post-grohtml]: Align with modern groff conventions.

	* src/drivers/grohtml/post-html.cpp: Update standard header file
	inclusions with respect to the symbols the file actually uses.
	(html_printer::do_file_components): Use standard symbol
	`SEEK_SET` instead of `0` literal.  Recast fatal error
	diagnostic to parallelize wording with others, and to disclose
	underlying system error.
	(assert_state::compare, assert_state::close)
	(replace_negate_str, assert_state::check_value_error)
	(html_printer::draw, make_val): Recast diagnostics.
	(main): Use standard symbol `EXIT_SUCCESS` instead of `0`
	literal.
	(usage): If asked for `--help`, summarize command purpose in
	message.

2024-11-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grodvi]: Align with modern groff conventions.

	* src/drivers/grodvi/grodvi.cpp (main): Use standard symbol
	`EXIT_SUCCESS` instead of `0` literal.  Replace `assert(0)` call
	with communicative predicate.
	(usage): If asked for `--help`, summarize command purpose in
	message.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	Drop local getopt_long implementation in favor of gnulib's.

	* src/include/getopt.h:
	* src/include/getopt_int.h:
	* src/include/gettext.h:
	* src/libs/libgroff/getopt.c:
	* src/libs/libgroff/getopt1.c: Delete.

	* src/libs/libgroff/libgroff.am: Drop foregoing `.c` files from
	`libgroff_a_SOURCES` macro.

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

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Improve header-file inclusion hygiene.

	* src/include/itable.h:
	* src/include/lib.h:
	* src/include/ptable.h:
	* src/include/stringclass.h: Drop Autoconf "<config.h>"-inclusion
	boilerplate.

	Per Paul Eggert, "You shouldn't need to put "#include
	<config.h>" at the start of every source file. It needs to be
	included first at the start of every compilation unit; that's
	good enough.  The .cpp or .c file should include config.h first,
	and .h files should therefore not need to include config.h."

	See
	<https://lists.gnu.org/archive/html/groff/2024-11/msg00154.html>.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tfmtodit]: Align with modern groff conventions.

	* src/utils/tfmtodit/tfmtodit.cpp: Include system library
	headers before local ones.
	(main): Use standard symbol `EXIT_SUCCESS` instead of `0`
	literal.

2024-11-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/tfmtodit/tfmtodit.cpp (main): Exit with status 2,
	not 1, on usage error (insufficient arguments).  Continues
	commit 89283b0935, 18 October.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[lookbib]: Align with modern groff conventions.

	* src/utils/lookbib/lookbib.cpp: Include system library headers
	before local ones.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[indxbib]: Align with modern groff conventions.

	* src/utils/indxbib/indxbib.cpp: Include system library headers
	before local ones.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/hvunits.h: Drop Autoconf "<config.h>"-inclusion
	boilerplate; troff's ".cpp" files reliably have it now.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Align with modern groff conventions.

	* src/roff/troff/dictionary.cpp:
	* src/roff/troff/env.cpp:
	* src/roff/troff/mtsm.cpp:
	* src/roff/troff/reg.cpp: Add Autoconf "<config.h>"-inclusion
	boilerplate to these translation units.

	* src/roff/troff/env.cpp:
	* src/roff/troff/node.cpp: Include system library headers before
	local ones.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Align with modern groff conventions.

	* src/roff/groff/groff.cpp: Include system library headers
	before local ones.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Align with modern groff conventions.

	* src/preproc/tbl/main.cpp:
	* src/preproc/tbl/table.cpp: Add Autoconf "<config.h>"-inclusion
	boilerplate to these translation units.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[soelim]: Align with modern groff conventions.

	* src/preproc/soelim/soelim.cpp: Include system library headers
	before local ones.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[refer]: Align with modern groff conventions.

	* src/preproc/refer/command.cpp:
	* src/preproc/refer/label.ypp:
	* src/preproc/refer/ref.cpp:
	* src/preproc/refer/refer.cpp:
	* src/preproc/refer/token.cpp: Add Autoconf "<config.h>"-
	inclusion boilerplate to these translation units.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[preconv]: Align with modern groff conventions.

	* src/preproc/preconv/preconv.cpp: Include system library
	headers before local ones.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[pre-grohtml]: Align with modern groff conventions.

	* src/preproc/html/pushback.cpp: Add Autoconf "<config.h>"-
	inclusion boilerplate to these translation units.

	* src/preproc/html/pre-html.cpp:
	* src/preproc/html/pushback.cpp: Include system library headers
	before local ones.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Align with modern groff conventions.

	* src/libs/libgroff/make-uniuni.cpp: Update script that
	generates "uniuni.cpp" to add Autoconf "<config.h>"-inclusion
	boilerplate.

	* src/libs/libgroff/curtime.cpp:
	* src/libs/libgroff/glyphuni.cpp:
	* src/libs/libgroff/htmlhint.cpp:
	* src/libs/libgroff/iftoa.cpp:
	* src/libs/libgroff/invalid.cpp:
	* src/libs/libgroff/itoa.cpp:
	* src/libs/libgroff/lf.cpp:
	* src/libs/libgroff/macropath.cpp:
	* src/libs/libgroff/maxfilename.cpp:
	* src/libs/libgroff/maxpathname.cpp:
	* src/libs/libgroff/paper.cpp:
	* src/libs/libgroff/symbol.cpp:
	* src/libs/libgroff/tmpfile.cpp:
	* src/libs/libgroff/tmpname.cpp:
	* src/libs/libgroff/unicode.cpp:
	* src/libs/libgroff/uniglyph.cpp:
	* src/libs/libgroff/uniuni.cpp: Add Autoconf "<config.h>"-
	inclusion boilerplate to these translation units.

	* src/libs/libgroff/color.cpp:
	* src/libs/libgroff/curtime.cpp:
	* src/libs/libgroff/font.cpp:
	* src/libs/libgroff/fontfile.cpp:
	* src/libs/libgroff/htmlhint.cpp:
	* src/libs/libgroff/lf.cpp:
	* src/libs/libgroff/maxfilename.cpp:
	* src/libs/libgroff/maxpathname.cpp:
	* src/libs/libgroff/nametoindex.cpp:
	* src/libs/libgroff/relocate.cpp:
	* src/libs/libgroff/tmpfile.cpp:
	* src/libs/libgroff/tmpname.cpp: Include system library headers
	before local ones.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libdriver]: Align with modern groff conventions.

	* src/libs/libdriver/input.cpp: Add Autoconf "<config.h>"-
	inclusion boilerplate to these translation units.  Include
	system library headers before local ones.
	* src/libs/libdriver/printer.cpp: Include required system
	library header files.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grotty]: Align with modern groff conventions.

	* src/devices/grotty/tty.cpp: Add Autoconf "<config.h>"-
	inclusion boilerplate to this translation unit.  Include
	required system library header files.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grops]: Align with modern groff conventions.

	* src/devices/grops/ps.cpp:
	* src/devices/grops/psrm.cpp: Add Autoconf "<config.h>"-
	inclusion boilerplate to these translation units.  Include
	system library headers before local ones.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grohtml]: Align with modern groff conventions.

	* src/devices/grohtml/html-table.cpp:
	* src/devices/grohtml/html-text.cpp:
	* src/devices/grohtml/output.cpp:
	* src/devices/grohtml/post-html.cpp: Add Autoconf "<config.h>"-
	inclusion boilerplate to these translation units.

	* src/preproc/grohtml/output.cpp:
	* src/devices/grohtml/post-html.cpp: Include system library
	headers before local ones.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[pic]: Align with modern groff conventions.

	* src/preproc/pic/common.cpp:
	* src/preproc/pic/lex.cpp:
	* src/preproc/pic/main.cpp:
	* src/preproc/pic/pic.ypp:
	* src/preproc/pic/tex.cpp:
	* src/preproc/pic/troff.cpp: Add Autoconf "<config.h>"-inclusion
	boilerplate to these translation units.

	* src/preproc/pic/pic.h: Move inclusions of system headers and
	fallback declarations for system symbols from here...
	* src/preproc/pic/pic.ypp: ...to here, where they're used.

	* src/preproc/pic/common.cpp:
	* src/preproc/pic/lex.cpp:
	* src/preproc/pic/main.cpp:
	* src/preproc/pic/object.cpp:
	* src/preproc/pic/pic.ypp:
	* src/preproc/pic/tex.cpp:
	* src/preproc/pic/troff.cpp: Include requisite system headers.

	* src/preproc/pic/pic.ypp: `sizeof` is an operator, not a
	function, so don't parenthesize its operand when it's an lvalue
	{as opposed to a type name}.  Use libgroff's newfangled
	`array_length()` template function to measure arrays.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grn]: Align with modern groff conventions.

	* src/preproc/grn/hdb.cpp:
	* src/preproc/grn/main.cpp: Include system library headers
	before local ones.

	* src/preproc/grn/hgraph.cpp:
	* src/preproc/grn/main.cpp: Add Autoconf "<config.h>"-inclusion
	boilerplate to these translation units.

	* src/preproc/grn/hpoint.cpp: Drop unnecessary inclusion of
	"<stdlib.h>".

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/lex.cpp:
	* src/preproc/eqn/limit.cpp:
	* src/preproc/eqn/list.cpp:
	* src/preproc/eqn/main.cpp:
	* src/preproc/eqn/mark.cpp:
	* src/preproc/eqn/over.cpp:
	* src/preproc/eqn/special.cpp:
	* src/preproc/eqn/sqrt.cpp: Add Autoconf "<config.h>"-inclusion
	boilerplate to these translation units.

	* src/preproc/eqn/other.cpp: Include "<stdio.h>" since
	`fprintf()` and `printf()` are used.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/lkbib/lkbib.cpp: Align with modern groff
	conventions.  Include system library headers before local ones.
	Use standard symbols `EXIT_SUCCESS` and `EXIT_FAILURE` instead
	of `0` and `1` literals, respectively.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/libbib/index.cpp:
	* src/utils/libbib/linear.cpp:
	* src/utils/libbib/search.cpp: Align with modern groff
	conventions.  Include system library headers before local ones.

	* src/utils/libbib/index.cpp: Add Autoconf "<config.h>"-
	inclusion boilerplate to this translation unit.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/hpftodit/hpftodit.cpp:
	* src/utils/hpftodit/hpuni.cpp: Align with modern groff
	conventions.  Add Autoconf "<config.h>"-inclusion boilerplate to
	these translation units.  Include system library headers before
	local ones.

	* src/utils/hpftodit/hpftodit.cpp: Use standard symbol
	`EXIT_SUCCESS` instead of zero literal.  Drop inclusion of
	"<ctype.h>"; none of its symbols (`is*()`) are directly used.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Align with modern groff conventions.

	* src/roff/troff/div.cpp:
	* src/roff/troff/input.cpp: Add Autoconf "<config.h>"-inclusion
	boilerplate to these translation units.  Include system library
	headers before local ones.

	* src/roff/troff/input.cpp: Fix code style nits. Include
	"<string.h>" header, since this file calls `strdup()`.  Declare
	a and use a constant object to store a magic number.  Use C++
	`static_cast` operator instead of C-style type cast.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Fix inclusion wart.  Include local
	"posix.h" header before "nonposix.h".  This aligns better with
	other groff code, and more importantly, "posix.h" itself
	includes "<unistd.h>", which defines `_POSIX_VERSION` on POSIX
	systems, and in turn prevents us from provoking compiler
	warnings by redeclaring `WIFEXITED` et al. in this file.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/ptable.h: Include "<stdlib.h>" header, since the
	macros this file defines use `malloc()` and `free()`.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/addftinfo/addftinfo.cpp: Align with modern groff
	conventions.  Add Autoconf "<config.h>"-inclusion boilerplate to
	this translation unit.  Use standard symbol `EXIT_SUCCESS`
	instead of zero literal.  Exit with status 2, not 1, on usage
	errors.

	* src/utils/addftinfo/addftinfo.1.man (Exit status): Add.

	* NEWS: Add addftinfo to list of programs with changed exit
	status conventions.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* bootstrap.conf: Add "getopt-gnu" to `gnulib_modules`.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp (main): When constructing
	`pre-grohtml` command line, inject `--` argument before `troff`
	command to help `getopt_long()` identify the end of
	`pre-grohtml` options, particularly in cases where the argument
	sequence is malformed (options that take arguments not getting
	them, for example).

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

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/html/pre-html.cpp (do_file): Nullify
	`current_filename` on failure to open file.  Fixes noise in
	error message.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grohtml]: Rename the `-U` option provided by Takuji to `-k`,
	and document it.

	* src/preproc/html/pre-html.cpp (scanArguments): Recognize but
	ignore `-k` (rather than `-U`) option.  Also, make the argument
	mandatory.  Nothing else in groff supports an optional option
	argument, which can be ambiguous to parse, especially in light
	of groff(1)'s `-P` option.
	* src/devices/grohtml/post-html.cpp (main): Recognize and
	interpret `-k` option, renamed from `-U`.  Make the argument
	mandatory, and expect values of "ascii", "mixed", or "utf-8"
	{case-insensitively}.  Throw warning if argument unrecognized.
	(usage): Update.

	* src/devices/grohtml/grohtml.1.man (Synopsis, Options):
	Document it.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	Fix Savannah #66479 (2/2).

	* HACKING: Document another macOS od(1) irritation.

	* src/roff/groff/tests/dvi-device-smoke-test.sh: Work around
	macOS od(1)'s injection of extra spaces into its "-tx1" output.

	Fixes <https://savannah.gnu.org/bugs/?66479>.  Thanks to Sven
	Schober for the report, analysis, and for proposing fixes.

2024-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	Fix Savannah #66479 (1a/2).

	* HACKING: Document macOS wc(1) irritation.

	* tmac/tests/an_vertical-margins-are-correct.sh:
	* tmac/tests/doc-old_vertical-margins-are-correct.sh:
	* tmac/tests/doc_vertical-margins-are-correct.sh: Work around
	macOS wc(1)'s right-alignment of its integer output field.

2024-11-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (is_char_usable_as_delimiter):
	Revert fix for bug #66009.  Unfortunately, `|` is in use in the
	wild as a delimiter, for instance in man pages for GNU awk, GNU
	grep, and GNU rcs.  Weaning people off of it (because it is a
	valid character in a numeric expression, and GNU troff has never
	accepted most other such characters as delimiters,{*} whereas
	AT&T troff accepted them all) looks to be a multi-stage,
	multi-year process.

	Fixes <https://savannah.gnu.org/bugs/?66481>.  Thanks to Paul
	Eggert for the report.

	{*} For distorted values of "most"--both GNU and AT&T troffs
	accept any basic Latin letter (A-Za-z]) as a delimiter, a
	collection of 52 exceptions that quantitatively swallows the
	rule.  Pragmatically, few *roff document authors past or present
	seem to have been adventurous enough to exercise this freedom.

2024-11-22  Paul Eggert  <eggert@cs.ucla.edu>

	* arch/djgpp/config.sed:
	* bootstrap.conf:
	* contrib/mm/tests/lists-indent-correctly.sh:
	* src/roff/groff/tests/backslash-X-works.sh:
	* src/roff/groff/tests/\
	device-control-special-character-handling.sh:
	* src/roff/groff/tests/device-request-works.sh: Use strict
	POSIX.1-2017 regexes with grep and sed.

	In POSIX.1-2017, the regular expression '\]' has undefined
	behavior.  In POSIX.1-2024 it's equivalent to ']', but the groff
	build process should not yet rely on this.

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

2024-11-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/font.cpp (font::load): Declare `start_code`
	and `end_code` as `unsigned` integers, since Unicode code points
	cannot be negative, and we are using the sscanf(3) conversion
	specifier `%X` to read them from a font description file.

	Fixes <https://savannah.gnu.org/bugs/?66473>.  Thanks to Bjarni
	Ingi Gislason for the report.

2024-11-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* m4/groff.m4 (GROFF_PROG_M4): Also search for `gm4`.  Obviates
	need to specify `M4=gm4` in `configure`'s environment on Solaris
	10.

2024-11-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* m4/groff.m4 (GROFF_DIFF_D): Report name of detected diff(1)
	program that supports `-D` option, instead of the rather lame
	"yes" or "no".

2024-11-20  TANAKA Takuji <ttk@t-lab.opal.ne.jp>

	Support CJK fonts encoded in UTF-16 (6/6).

	* src/roff/groff/tests/dvi-device-smoke-test.sh:
	* src/roff/groff/tests/ps-device-smoke-test.sh: New tests
	exercise output drivers and their encodings of CJK characters.
	* src/roff/groff/groff.am (groff_TESTS): Run tests.

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

2024-11-20  TANAKA Takuji <ttk@t-lab.opal.ne.jp>

	Support CJK fonts encoded in UTF-16 (5/6).  Ship font
	description files.  These are intended as abstractions of faces
	to permit consistent naming while permitting customization, just
	as with the 12 text typefaces supported across output devices
	for Latin scripts in groff (three families of four styles each).
	These CJK font descriptions are not organized into groff font
	families, but are similar.

		CSH: Simplified Chinese, Hei style
		CSS: Simplified Chinese, Song style
		CTH: Traditional Chinese, Hei style
		CTS: Traditional Chinese, Song style
		JPG: Japanese, Gothic style
		JPM: Japanese, Mincho style
		KOG: Korean, Gothic style
		KOM: Korean, Mincho style

	* font/devdvi/CSH:
	* font/devdvi/CSS:
	* font/devdvi/CTH:
	* font/devdvi/CTS:
	* font/devdvi/JPG:
	* font/devdvi/JPM:
	* font/devdvi/KOG:
	* font/devdvi/KOM:
	* font/devhtml/CSH:
	* font/devhtml/CSS:
	* font/devhtml/CTH:
	* font/devhtml/CTS:
	* font/devhtml/JPG:
	* font/devhtml/JPM:
	* font/devhtml/KOG:
	* font/devhtml/KOM:
	* font/devps/CSH:
	* font/devps/CSS:
	* font/devps/CTH:
	* font/devps/CTS:
	* font/devps/JPG:
	* font/devps/JPM:
	* font/devps/KOG:
	* font/devps/KOM:
	* font/devutf8/CSH:
	* font/devutf8/CSS:
	* font/devutf8/CTH:
	* font/devutf8/CTS:
	* font/devutf8/JPG:
	* font/devutf8/JPM:
	* font/devutf8/KOG:
	* font/devutf8/KOM: Ship font descriptions.

	* font/devdvi/devdvi.am (DEVDVIFONTFILES):
	* font/devhtml/devhtml.am (DEVHTMLFONTS, DEVHTMLFONTFILES):
	* font/devdvi/devps.am (DEVPSFONTFILES):
	* font/devutf8/devutf8.am (DEVUTF8FONTS, DEVUTF8FONTFILES): Add
	them.

2024-11-20  TANAKA Takuji <ttk@t-lab.opal.ne.jp>

	Support CJK fonts encoded in UTF-16 (4/6).

	* src/devices/grops/ps.h:
	* src/devices/grops/ps.cpp: Include C99 "stdint.h" header for
	desired `unit16_t` data type.
	(class ps_output): Change type of `put_string` member function's
	first argument from `const char *` to `const uint16_t *`.  Add
	third argument of Boolean type, `is_utf16le`.
	* src/devices/grops/ps.cpp (ps_output::put_string): Adjust
	computations of `len` and `col` locals if the font in use is
	UTF-16LE-encoding, and write out 4-digit instead of 2-digit
	hexadecimal numeric literals when that is the case.
	(class ps_printer): Change type of `sbuf` member variable from
	`char` to `uint16_t`.  Change type of third argument to
	`set_subencoding` member function from `unsigned char *` to
	`uint16_t *`.
	(ps_printer::set_subencoding): Rename third argument from
	`codep` to `code`--it's no longer an indirect reference to a
	single `char`, but a 2-element `uint16_t` array.  If the font's
	"internalname" directive contains the substring "-UTF16-",
	populate `code` argument with little-endian 16-bit value.
	(ps_printer::set_char): Declare `code` as above: a 2-element
	`uint16_t` array instead of an unsigned char.  Handle case of
	`code` using surrogate pairs (`code[1] > 0`).
	(ps_printer::flush_sbuf): Conditionalize form of output on font
	encoding.  Set the Boolean argument to `ps::put_string()` per
	the font's "internalname" directive matching the substring
	"-UTF16-".

2024-11-20  TANAKA Takuji <ttk@t-lab.opal.ne.jp>

	Support CJK fonts encoded in UTF-16 (3/6).

	* src/preproc/html/pre-html.cpp (scanArguments): Recognize but
	ignore new option `-U`, used by `grohtml` postprocessor.

	* src/devices/grohtml/post-html.cpp: Declare new constant
	integer objects `CHARSET_ASCII`, `CHARSET_MIXED`, and
	`CHARSET_UTF8` to configure representation of character entities
	in output.
	(main): New option `-U` takes argument configuring the means of
	encoding character entities.  If the argument is `0` or `-`,
	select `CHARSET_ASCII`; if `1`, select `CHARSET_MIXED`, and if
	`2` or `+`, select `CHARSET_UTF8`, which is also the default.
	(to_unicode): Replace this function with...
	(to_numerical_char_ref): ...this, which generates a hexadecimal
	HTML character entity.
	(html_printer::add_to_sbuf): Write out UTF-8 sequence if
	`charset_encoding` is not `CHARSET_ASCII`, otherwise a numerical
	character reference.
	(get_html_entity): Return UTF-8 sequence if `charset_encoding`
	is `CHARSET_UTF8`.  Otherise, Return UTF-8 sequence if
	`charset_encoding` is not `CHARSET_ASCII`, otherwise a numerical
	character reference.
	(html_printer::writeHeadMetaStyle): Describe document {XHTML:
	encoding and} content as UTF-8 if `charset_encoding` is not
	`CHARSET_ASCII`, otherwise as US-ASCII.

2024-11-20  TANAKA Takuji <ttk@t-lab.opal.ne.jp>

	Support CJK fonts encoded in UTF-16 (2/6).

	* src/include/font.h (class font): Declare private member
	variable `wch`, a pointer to an existing list type
	`font_char_metric`.  Declare private member function
	`get_font_wchar_metric()` to access it.
	* src/libs/libgroff/font.cpp (struct font_char_metric): Add
	members `next` (a pointer to the struct's own type) and
	`end_code` of type `int`.
	(glyph_to_ucs_codepoint): New function returns UCS code point
	from a (non-composite) `glyph` object, or -1 if invalid.
	(font::font): Constructor initializes `wch` member variable to
	null pointer.
	(font::~font): Destructor frees storage allocated in
	`font::load()` for `special_device_coding` member of `wcp`
	struct, and that of `wcp` itself.
	(font::contains): If `glyph_to_ucs_codepoint()` returns a valid
	value for the glyph, populate its wide character metrics and
	return true.
	(font::get_font_wchar_metric): New function obtains font metrics
	of input character by Unicode code point.
	(font::get_width, font::get_height, font::get_depth)
	(font::get_italic_correction, font::get_left_italic_correction)
	(font::get_subscript_correction, font::get_character_type)
	(font::get_code, font::get_special_device_encoding): If
	`glyph_to_ucs_codepoint()` returns a valid value for the glyph,
	populate its wide character metrics and return the appropriate
	parameter based on them.
	(font::get_width): Add conditional guard when computing width
	for a glyph from a "Unicode font"; use the computation only if
	the device description file ("DESC") didn't declare
	"unscaled_charwidths".
	(font::load): Recognize new directive in font description files:
	"charset-range", which works like the existing "charset"
	directive except that the glyph descriptions use a `name` of the
	form "uFFFF..uFFFF" (where "FFFF" is a hexadecimal digit
	sequence), and apply the metrics identically to all glyphs in
	the designated range.
	(font::load): When processing glyph descriptions in "charset"
	section and the device has declared the "unicode" directive,
	stop scaling the width of the glyph by what `wcwidth()` returns
	for it.  (Does this fix Savannah #44018?)

2024-11-20  TANAKA Takuji <ttk@t-lab.opal.ne.jp>

	Support CJK fonts encoded in UTF-16 (1/6).

	* src/include/unicode.h (to_utf8_string): Declare new function.
	* src/libs/libgroff/unicode.cpp (to_utf8_string): New function
	converts input integer into UTF-8 sequence (or an HTML character
	entity in hexadecimal if the integer is out of range).

2024-11-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/ps.cpp: Fix code style nits.  Parenthesize
	complex expressions.  Reorder equality comparisons to avoid
	inadvertent lvalue assignment.

2024-11-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (pipe_source_request): Refactor.
	Return early when unsafe requests are not enabled, dropping the
	rest of the function body by an indentation level.  Replace
	input scanning logic with a call to `read_string()`, which is
	written to do exactly the same thing (except that it knows how
	to handle a leading neutral double quote, which this function
	didn't).

	* man/groff.7.man (Request short reference) <pso>:
	* man/groff_diff.7.man (New requests) <pso>: Recast, strengthing
	parallel with `so` request.

	* NEWS: Document `pso` request's new handling of a leading
	neutral double quote.

2024-11-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp (is_valid_term): Accept scaling unit
	of `u` in contexts where `f` is expected; `u` is valid in all
	contexts.

	Continues commit 6f08ec9815, 4 September.  See
	<https://savannah.gnu.org/bugs/?60955>.

2024-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix Savannah #64484.  This change restores groff
	1.23.0's handling of characters in `device` request arguments,
	except that {1} special character escape sequences are
	interpreted (except for composite special characters, a planned
	future development) and {2} unprintable character codes such as
	ASCII 2 are no longer emitted in GNU troff output by this means.

	* src/roff/troff/input.cpp (device_request): Refactor and revise
	argument interpretation.  Reconstitute an encoded unbreakable
	space code point as its escape sequence (spelled with the
	default escape character).  Throw warning in category "syntax"
	if a valid but unprintable input character is encountered.
	Throw warning in category "syntax" if an escape sequence other
	than `\[` is encountered.  (A reconstituted `\~` is not warned
	about.)
	* src/roff/troff/troff.1.man (Warnings): Document additional
	circumstances under which warnings in "syntax" category are
	thrown.

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

2024-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Regression-test Savannah #64484.

	* src/roff/groff/tests/\
	device-request-passes-most-escape-sequences.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2024-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/soelim/soelim.1.man (Description):
	* src/preproc/soelim/soelim.cpp (usage): Revise description.

2024-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp (DIVERSION_LENGTH_MAX): Declare as
	`const`.

2024-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* Makefile.am (EXTRA_DIST): Ship "ChangeLog.123".

2024-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* Makefile.am (EXTRA_DIST): Re-sort with `LC_COLLATE=C`.

2024-11-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	Drop now-unused Autoconf macros.

	* configure.ac: Stop expanding `GROFF_AWK_NOTICE`,
	`GROFF_PDFROFF_DEPENDENCIES_CHECK`, and
	`GROFF_PDFROFF_PROGRAM_NOTICE` macros.  Drop `AM_CONDITIONAL`
	with `USE_PDFROFF` argument.
	* m4/groff.m4 (GROFF_AWK_NOTICE, GROFF_AWK_PATH)
	(GROFF_AWK_PREFS, GROFF_PDFROFF_DEPENDENCIES_CHECK)
	(GROFF_PDFROFF_PROGRAM_NOTICE): Drop unused macro definitions.

2024-11-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	Stop distributing pdfmark.  It is now separately maintained.
	Please visit <https://osdn.net/users/keith/pf/groff-pdfmark/>
	for the latest version.  (Update: In April 2025, hosting moved
	to <https://savannah.nongnu.org/projects/groff-pdfmark>.)

	* contrib/pdfmark: Recursively delete.
	* Makefile.am: Stop including its Automake file.
	* doc/doc.am (GROFF_MAN_PAGES1): Drop pdfroff man page.
	* src/utils/grog/tests/smoke-test.sh: Stop using
	"contrib/pdfmark/{cover,pdfmark}.ms" as test artifacts.

	* MANIFEST:
	* src/roff/groff/groff.1.man: De-document.

	* NEWS: Add item.

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

2024-11-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* NEWS: Explain changes to `\X` and `.device` argument
	processing.

	Fixes <https://savannah.gnu.org/bugs/?63074>.  Thanks to Nikita
	Ivanov for the report.

2024-11-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/psrm.cpp (resource_manager::output_prolog)
	(resource_manager::supply_resource): Migrate from using
	`font::open_file()` to `font::open_resource_file()`, restoring
	grops's ability from groff 1.22.4 and earlier to open arbitrary
	file specifications as PostScript prolog or font files.

	Fixes <https://savannah.gnu.org/bugs/?66419>.  Thanks to Rob
	Kolstad for the report.

2024-11-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/font.h (class font): Declare new
	`open_resource_file()` member function with same interface as
	`open_file()`, but intended to open arbitrary file
	specifications instead of only files within groff's font search
	path.  This is for use by drivers that need to embed auxiliary
	files in their output, such as font files for PostScript
	{contrast these with groff's font _description_ files}.
	* src/libs/libgroff/fontfile.cpp (font::open_resource_file):
	Implement new function.

2024-11-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* m4/groff.m4 (GROFF_CHECK_VERSION_FORMAT): Use a _basic_ (not
	extended) regular expression as the pattern operand to expr(1)'s
	`:` operator.  Should fix configuration failure on macOS.

	Fixes <https://savannah.gnu.org/bugs/?66438>.  Thanks to Sven
	Schober for the report.

2024-11-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (interpolate_macro, lookup_request):
	Recast warning diagnostic in "mac" category to report that a
	"name", rather than a "macro", is not defined.  While more
	vague, it's also less misleading, since requests, strings, and
	diversions all occupy the same name space and the warning is
	thrown only if no identifier of any of these types exists.

	* doc/groff.texi.in (Dummy Characters): Update example.

	Fixes <https://savannah.gnu.org/bugs/?66350>.  Thanks to Bjarni
	Gislason for the report.

2024-11-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (lookup_request): Use C++
	`static_cast` operator instead of C-style type cast.  Reorder
	equality comparison to avoid inadvertent lvalue assignment.

2024-11-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_source, do_macro_source):
	Refactor to use `read_string()` instead of `get_long_name()` to
	obtain the argument; this means that the argument consumes the
	rest of the input line instead of being treated as a groff
	identifier.  This change permits spaces in sourced file names.

	* doc/groff.texi.in (I/O) <so, soquiet, mso, msoquiet>
	(Other Differences):
	* man/groff.7.man (Request short reference) <so>:
	* man/groff_diff.7.man (New requests) <mso, msoquiet, soquiet>:
	(Other differences): Document it.

	* src/roff/groff/tests/\
	so-request-accepts-embedded-space-in-arg.sh: Test it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

	* NEWS: Add item.

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

2024-11-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	[soelim]: Read argument to `so` request in a more GNU troff-ish
	fashion (and a more AT&T troff-ish fasion, if one considers the
	`ds` and `as` requests).  Accept but discard a leading double
	quote to permit embedding of leading spaces in the file name,
	and accept unescaped literal spaces in argument.

	* src/preproc/soelim/soelim.cpp (do_so): Do it.
	* src/preproc/soelim/soelim.1.man (Description): Document it.

	* src/preproc/soelim/tests/space-in-argument-works.sh: Add unit
	test.
	* src/preproc/soelim/soelim.am (soelim_TESTS): Run test.

	* NEWS: Add item.

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

2024-11-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	[soelim]: Fix code style nits.

	* src/preproc/soelim/soelim.cpp: Boolify and rename some global
	variables.
	    `compatible_flag` -> `want_att_compat`
	    `raw_flag`        -> `want_raw_output`
	    `tex_flag`        -> `want_tex_output`
	(main, set_location, do_file): Track renames.
	(do_so): Boolify and rename local variable, demoting integer
	`success` to Boolean `is_filename_valid`.  Use Boolean literals
	for assignments.
	(do_file): Adjust language of diagnostic message.
	(usage): Expand usage message with an actual description.
	(main): Use standard C library symbols `EXIT_SUCCESS` and
	`EXIT_FAILURE` with `exit()` calls instead of integer literals.
	(main, do_file): Replace `assert(0)` calls with communicative
	predicates.
	(do_file): Check return value of `fclose()`, and exit with fatal
	error if it fails.
	(main): Distinguish `ferror()` status and `fflush(stdout)`
	failures when cleaning up before exit.

2024-11-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Slightly refactor.  Shift responsibility for calling
	`tok.next()` onto callers of `read_string()` instead of doing it
	internally.  For the purpose I have in mind (migrating `so` and
	`mso` to use `read_string()`), the latter advances the input
	stream pointer too early--better to let the caller control that.

	* src/roff/troff/input.cpp (read_string): Drop `tok.next()`
	call.
	* src/roff/troff/env.cpp (override_sizes): Add `tok.next()`
	call.

2024-11-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_string): Recognize a leading
	double quote in the argument and handle it like other
	"contents"-reading requests do; the best known of these is the
	string-definition request, `ds`, which however uses its own
	logic.  This change affects only the `pi` and `sy` requests.

2024-11-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(decode_args): Rename this...
	(decode_macro_call_arguments): ...to this.
	(decode_string_args): ...and this...
	(decode_escape_sequence_arguments): ...to this.
	(macro::invoke, composite_glyph_name, read_request)
	(interpolate_string_with_args): Update call sites.

2024-11-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (decode_args, decode_string_args):
	Boolify and rename local variable, demoting integer
	`done_tab_warning` to Boolean `was_warned`.  Use Boolean
	literals for assignments.

2024-11-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/groff_man.7.man.in (Options) <-rCHECKSTYLE>: Document
	feature introduced in groff 1.23.0.

	Fixes <https://savannah.gnu.org/bugs/?62042>.  Thanks to Alex
	Colomar for the report.

2024-11-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (diagnose_invalid_identifier): Avoid
	potentially reporting stale token description in diagnostic
	message, using same technique as commit 1277744e72, 20 August.
	I was unable to verify that the token description really is
	stale, however.  It might not be, since it is lazily computed
	and the class's `description()` member function is not called in
	the interim, but I also could not demonstrate to myself that the
	relevant diagnostic message is reachable.  Use strdup() to copy
	the token description (grabbing ~30 bytes from the heap) and
	free that storage later just in case.

2024-11-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Improve input validation.  Use `has_arg()` (inverted if
	necessary) more often to better distinguish between arguments
	that are truly absent and those for which attempts to read
	"symbol" (identifier) names result in their objects' `is_null()`
	member functions returning true, which happens both for absent
	and for syntactically invalid identifiers.

	* src/roff/troff/reg.cpp (define_register_request)
	(assign_register_format_request, alias_register_request): Remove
	assertions I added in commit 2f6a72b9e3, 3 September, that get
	tripped on invalid input.
	(assign_register_format_request): Skip remainder of input line
	and return early if the first argument is an invalid identifier.
	(remove_register_request): Explicitly break out of loop as soon
	as we run out of arguments.
	(alias_register_request, rename_register_request): Throw warning
	in category "missing" only if second argument is truly missing,
	not if it is invalid; in this scenario, `get_name()` has already
	thrown an error diagnostic.
	(alias_register_request): Check second argument for validity as
	identifier before attempting to look it up in the register
	dictionary.

2024-11-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (add_hyphenation_exceptions):
	* src/roff/troff/input.cpp (remove_character, read_title_parts)
	(set_hyphenation_codes, report_hyphenation_codes)
	(hyphenation_patterns_file_code): Drop unnecessary `tok.skip()`
	calls before `has_arg()`: the latter advances through spaces if
	needed.

2024-11-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (pipe_source_request): Drop branch
	unreachable since commit 6dee590de8, 12 September.

2024-11-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_request, do_terminal)
	(do_write_request, set_hyphenation_codes)
	(report_hyphenation_codes): Slightly refactor.  Replace
	`!(tok.is_newline() || tok.is_eof())` with `has_arg()`, for
	readability and consistency.

2024-11-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (pipe_source_request): Align wording
	of warning diagnostics with each other.

2024-11-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (file_iterator::file_iterator):
	Boolify and rename third argument, demoting integer `po` to
	Boolean `popened`.  Use Boolean literal for default argument.
	(pipe_source_request): Use Boolean literal at call site.

2024-11-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (has_args): Slightly refactor; use
	the same expression to compute the return value after having
	advanced the input pointer through spaces as is used at the top
	of the function.

2024-11-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (add_hyphenation_exceptions):
	* src/roff/troff/input.cpp (read_title_parts):
	* src/roff/troff/reg.cpp (assign_register_format_request):
	Slightly refactor.  Replace `tok.is_newline() || tok.is_eof()`
	with `!has_arg()`, for readability and consistency.

2024-11-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (set_character_flags): Check for
	arguments as the very first thing in the function, before trying
	to read an integer.

2024-11-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Make more requests that take mandatory arguments--
	specifically `pn`, `ti`, `rchar`, and `hpfcode`--throw warning
	diagnostics in category "missing" when they aren't given any.

	* src/roff/troff/div.cpp (page_number):
	* src/roff/troff/env.cpp (temporary_indent):
	* src/roff/troff/input.cpp (define_special_character)
	(hyphenation_patterns_file_code): Do it.

2024-11-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (has_arg): Return false at EOF, too.

2024-11-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man,mdoc,mdoc-old]: Unit-test vertical margins/gross layout.

	* tmac/tests/an_vertical-margins-are-correct.sh:
	* tmac/tests/doc-old_vertical-margins-are-correct.sh:
	* tmac/tests/doc_vertical-margins-are-correct.sh: Do it.
	* tmac/tmac.am (tmac_TESTS): Run tests.

2024-11-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man,mdoc]: Use more historically authentic margin of one
	half-inch between header and body text.

	* tmac/an.tmac (PT):
	* tmac/mdoc/doc-common (doc-header): Do it.

	Continues commit e9828b2927, 21 October 2023.

2024-11-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/doc-old.tmac ([initialization]): Set `cR` register only
	if not already defined on the command line.  This is so that the
	package's trap locations can be compared with the original from
	4.3BSD-Reno (1990) even in nroff mode.

2024-11-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/grog/grog.pl (construct_command): Check for
	truthiness of `main_package` scalar before using it in
	comparison, avoiding the emission of Perl warnings.

	Fixes <https://savannah.gnu.org/bugs/?66429>.  Problem
	introduced by me prior to groff 1.23.0 when I rewrote the tool.

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

	[grops]: Further revise fix for Savannah #61424.  Instead of
	checking for a nonpositive `errno` after calling
	`font::open_file()` and assuming that that means the function
	rejected the file name for having a slash character in it, check
	the file name at the call site and throw a fatal error there if
	it contains one.

	* src/devices/grops/ps.cpp (ps_printer::define_encoding):
	* src/devices/grops/psrm.cpp (resource_manager::output_prolog)
	(resource_manager::supply_resource): Do it.

	Begins to address <https://savannah.gnu.org/bugs/?66419>.
	Thanks to Rob Kolstad for the report and the suggestion.

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

	* src/devices/grops/ps.cpp (ps_printer::define_encoding):
	* src/devices/grops/psrm.cpp (resource_manager::output_prolog)
	(resource_manager::supply_resource)
	(resource_manager::read_download_file): Align diagnostic message
	wording with recent revisions to GNU troff.

	* src/devices/grops/ps.cpp (ps_printer::define_encoding):
	Substantially improve fatal diagnostic thrown when failing to
	parse a grops encoding file, replacing "bad second field" with
	information a user is more likely to be able to act on.

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

	* tmac/cs.tmac:
	* tmac/de.tmac:
	* tmac/es.tmac:
	* tmac/fr.tmac:
	* tmac/it.tmac:
	* tmac/ru.tmac:
	* tmac/sv.tmac: Migrate to new mm date format localization
	method; now one string definition is all we need.

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

	* tmac/ru.tmac: Stop enabling automatic hyphenation by default
	for the mm package.  Enablement is inconsistent with our
	documentation, with DWB 3.3 behavior, and with all of our other
	localization files.

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

	* tmac/cs.tmac:
	* tmac/de.tmac:
	* tmac/es.tmac:
	* tmac/fr.tmac:
	* tmac/it.tmac:
	* tmac/ru.tmac: Drop redundant requests from `ISODATE` macro
	redefinition and redundant re-aliasing of `cov*new-date`.  These
	are all identical to what is done for English in "m.tmac".

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

	* src/roff/troff/env.cpp (print_hyphenation_exceptions): Ensure
	that a current hyphenation language is defined before attempting
	to iterate its exception dictionary.

	Fixes:
	  $ ./build/test-groff
	  .hla
	  .phw
	  groff: error: troff: Segmentation fault (core dumped)

	Problem introduced by me in commit 0b40885e71, 3 November 2023.

2024-11-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tmac]: Follow groff mm(7) string renames.

	* tmac/cs.tmac:
	* tmac/de.tmac:
	* tmac/es.tmac:
	* tmac/fr.tmac:
	* tmac/it.tmac:
	* tmac/ru.tmac:
	* tmac/sv.tmac: Rename localized versions of
	`li{con,ec,ex,fg,tb}` strings to `cap{con,ec,ex,fg,tb}`.

	* tmac/trans.tmac: Rename aliases.

2024-11-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/sv.tmac: Fix typo in translation, present since birth
	{commit 4f906e7d0c, 3 March 2006}.

2024-11-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grog]: Recognize new `phcode` request.

	* src/utils/grog/grog.pl (do_line): Recognize new `phcode`
	request forthcoming in groff 1.24 release.

2024-10-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	Add test of hyphenation language as a global vs. environmental
	property.

	* src/roff/groff/tests/\
	current-language-and-environment-in-sync.sh: Add unit test.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

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

2024-10-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (select_hyphenation_language)
	(environment_switch): Use C++ `static_cast` operator instead of
	C-style type cast.

2024-10-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment_switch, environment_copy):
	Trivially refactor.  Relocate function definitions to prepare
	for feature change that will require additional type and global
	variable visibility within them.

2024-10-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::print_env): Describe
	automatic hyphenation mode in plain English.

2024-10-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (select_hyphenation_language)
	(add_hyphenation_exceptions, hyphenate)
	(read_hyphenation_patterns_from_file): Fix code style nit:
	explicitly compare variable of pointer type to null pointer
	literal instead of letting it pun down to a Boolean.

2024-10-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: The `pcolor` request now accepts color identifiers as
	arguments.

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

	* doc/groff.texi.in (Debugging) <pcolor>:
	* man/groff.7.man (Request short reference) <pcolor>:
	* man/groff_diff.7.man (New requests) <pcolor>: Document it.

	* NEWS: Update item.

2024-10-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/de.tmac:
	* tmac/fr.tmac: Spell string translations using groff special
	character escape sequences instead of Latin-1 or Latin-9 code
	points; this way they work with a document that uses them no
	matter what its own encoding.

2024-11-02  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Fix for 4-bit eps images

	* src/devices/gropdf/gropdf.pl: Use correct BitsPerComponent
	when converting to raw format.

2024-11-02  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Import change in perl 5.40.

	See <https://perldoc.perl.org/perl5400delta#Calling-the-import-
	method-of-an-unknown-package-produces-a-warning>.

	* src/devices/gropdf/pdfmom.pl:
	* src/devices/gropdf/gropdf.pl:
	* src/utils/afmtodit/afmtodit.pl: Warning issued for unknown
	method fixed.

	Fixes <https://savannah.gnu.org/bugs/?66386>.  Thanks to Bjarni
	Gislason for the report, see
	<https://lists.gnu.org/archive/html/groff/2024-10/
	msg00130.html>.

2024-10-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	Deprecate rather than withdrawing support for AT&T font names,
	on "pdf" and "ps" devices only.

	* tmac/ps.tmac: Restore font translations to groff font names.

	* src/roff/troff/env.cpp: New global vector
	`deprecated_font_identifiers` stores deprecated AT&T font names.
	Add external declaration of `is_device_ps_or_pdf`.
	(warn_if_font_name_deprecated): New function searches vector for
	given symbol `nm` (a font name); if found, throws a warning in
	category "font" and deletes the name from the vector.
	(environment::set_font): If `is_device_ps_or_pdf`, call
	`warn_if_font_name_deprecated()`.
	(init_env_requests): Populate new vector.

	* src/roff/troff/input.cpp: New global Boolean tracks whether
	the output device is named "pdf" or "ps".  We need this because
	"CW" is a valid, non-deprecated font name on the "dvi" device.
	(main): Once the name of the output device is determined, update
	`is_device_ps_or_pdf` if necessary.

	* NEWS: Revise item.

	Thanks to Deri James for the discussion; see
	<https://lists.gnu.org/archive/html/groff/2024-10/msg00066.html>
	and follow-ups.

2024-10-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	Abort the build if groff's version string is invalid.  This can
	happen when building from the Git repository using a shallow
	clone.

	* configure.ac: Move `AC_SUBST` of `SHORT_VERSION` from here...
	* m4/groff.m4 (GROFF_MAKE_SHORT_VERSION): ...into this new
	macro.

	* m4/groff.m4 (GROFF_CHECK_VERSION_FORMAT): New macro validates
	format of groff's version string.

	* configure.ac: Call the new macros.

	Thanks to наб for the discussion in Debian #1082520.

2024-10-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::print_env): Rearrange
	output.  Lead with all of the troff-specific environment data
	{if not in nroff mode}.  Report inter-word and inter-sentence
	space sizes after font data and before line length data.

2024-10-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (font_size::dump_size_list): Fix
	incorrect unit in reported list--it should be "s", not "z":
	these are not scaled/subdivisible points but the subdivided
	units themselves.

	* src/roff/groff/tests/sizes-request-works.sh: Update text
	expectations.

2024-10-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor, renaming the font size "table" to
	the font size "list"; it's not a two-dimensional structure.

	* src/roff/troff/env.h (class font_size): Rename member variable
	`size_table` to `size_list`.  Rename member functions
	`init_size_table()` and `dump_size_table()` to
	`init_size_list()` and `dump_size_list()`.
	* src/roff/troff/env.cpp: Update definition, call, and
	derefernce sites in the global scope and...
	(font_size::init_size_list, font_size::dump_size_list):
	(font_size::font_size, override_sizes, environment::print_env):
	...here.
	* src/roff/troff/input.cpp (main): Update call site (setting up
	size list for font used in default environment at startup).
	* src/roff/troff/node.h: Update external declaration.

2024-10-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/sv.tmac: Spell string translations using groff special
	character escape sequences instead of Latin-1 code points; this
	way they work with a document that uses them no matter what its
	own encoding.

2024-10-23  G. Branden Robinson <g.branden.robinson@gmail.com>
	* man/groff.7.man:
	* man/groff_diff.7.man:
	* src/preproc/eqn/eqn.1.man:
	* tmac/groff_mdoc.7.man: Fix spelling errors.

	Fixes <https://savannah.gnu.org/bugs/?66371> (2/2).  Thanks to
	Bjarni Ingi Gislason for the report.

2024-10-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* PROBLEMS: Document macOS/Homebrew/uchardet issue.  Add item
	and document workaround under "groff 1.22.4" because it likely
	affected that release as well; Bertrand added uchardet as an
	optional dependency in 2017, and the next groff release was in
	December 2018.

	Fixes <https://savannah.gnu.org/bugs/?66143>.  Thanks to Sven
	Schober for the report and for determining the workaround.

2024-10-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (troff_output_file::trailer): Clarify
	new warning diagnostic when `-o` option given but no output
	pages lie within the requested range.

2024-10-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (doc/groff-man-pages.pdf)
	(doc/groff-man-pages.utf8.txt): Run groff with "-K utf-8"
	instead of "-K latin-1" to correct Unicode mojibake now that
	groff_mmse(7) has been recoded to UTF-8.  Continues commit
	4fc7d977dd, 14 October.

2024-10-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Revise exit status computation.

	* src/roff/groff/groff.cpp (main): Avoid collision between
	groff's "own" exit status bits and those allocated to reporting
	pipeline status.  Left-shift return value of `run_command()` by
	two binary places.
	* src/roff/groff/groff.1.man (Exit status): Document this.

	* src/roff/groff/tests/ab-request-works.sh: Update test
	expectations.

	* NEWS: Add item.

2024-10-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* 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):
	* src/preproc/eqn/main.cpp (main):
	* src/preproc/grn/main.cpp (main):
	* src/preproc/html/pre-html.cpp (main):
	* src/preproc/pic/main.cpp (main):
	* src/preproc/preconv/preconv.cpp (main):
	* src/preproc/soelim/soelim.cpp (main):
	* src/preproc/tbl/main.cpp (main):
	* src/roff/troff/input.cpp (main):
	* src/utils/hpftodit/hpftodit.cpp (usage):
	* src/utils/indxbib/indxbib.cpp (main):
	* src/utils/lkbib/lkbib.cpp (main):
	* src/utils/lookbib/lookbib.cpp (main):
	* src/utils/tfmtodit/tfmtodit.cpp (main): Emit our own
	diagnostic for an invalid command-line option.

2024-10-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/xtotroff/xtotroff.c (main): Emit our own diagnostic
	for an invalid command-line option.

2024-10-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/pfbtops/pfbtops.c (main): Emit our own diagnostic
	for an invalid command-line option.

2024-10-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp (main): Emit our own diagnostic for
	an invalid command-line option.

2024-10-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/pfbtops/pfbtops.c (main): Call `assert()` to catch
	programmer error in command-line option handling.

2024-10-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/lookbib/lookbib.cpp (main): Make `assert()` message
	communicative.

2024-10-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	Make more commands exit with status 2 on usage error.

	* 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):
	* src/preproc/eqn/main.cpp (main):
	* src/preproc/grn/main.cpp (main):
	* src/preproc/html/pre-html.cpp (main):
	* src/preproc/pic/main.cpp (main):
	* src/preproc/preconv/preconv.cpp (main):
	* src/preproc/soelim/soelim.cpp (main):
	* src/preproc/tbl/main.cpp (main):
	* src/roff/groff/groff.cpp (main):
	* src/roff/troff/input.cpp (main):
	* src/utils/hpftodit/hpftodit.cpp (usage):
	* src/utils/indxbib/indxbib.cpp (main):
	* src/utils/lkbib/lkbib.cpp (main):
	* src/utils/lookbib/lookbib.cpp (main):
	* src/utils/tfmtodit/tfmtodit.cpp (main):
	* src/utils/xtotroff/xtotroff.c (main): Do it.

	* src/devices/grodvi/grodvi.1.man (Exit status):
	* src/devices/grohtml/grohtml.1.man (Exit status):
	* src/devices/grolbp/grolbp.1.man (Exit status):
	* src/devices/grolj4/grolj4.1.man (Exit status):
	* src/devices/grops/grops.1.man (Exit status):
	* src/devices/grotty/grotty.1.man (Exit status):
	* src/preproc/eqn/eqn.1.man (Exit status):
	* src/preproc/grn/grn.1.man (Exit status):
	* src/preproc/pic/pic.1.man (Exit status):
	* src/preproc/preconv/preconv.1.man (Exit status):
	* src/preproc/refer/refer.1.man (Exit status):
	* src/preproc/soelim/soelim.1.man (Exit status):
	* src/preproc/tbl/tbl.1.man (Exit status):
	* src/roff/troff/troff.1.man (Exit status):
	* src/utils/hpftodit/hpftodit.1.man (Exit status):
	* src/utils/indxbib/indxbib.1.man (Exit status):
	* src/utils/lkbib/lkbib.1.man (Exit status):
	* src/utils/lookbib/lookbib.1.man (Exit status):
	* src/utils/tfmtodit/tfmtodit.1.man (Exit status):
	* src/utils/xtotroff/xtotroff.1.man (Exit status): Add section.

	* NEWS: Add item.

2024-10-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.c (device_request): Drop declaration of
	unused variable (detritus from an attempt to finish Savannah
	#63074).

2024-10-18  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Use new \X''.

	* tmac/pdf.tmac: The new \X'' code does no flush, perfect
	for hotspots. Thanks Branden.

2024-10-18  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Foundries are only a single letter.

	* src/devices/gropdf/gropdf.pl: Look for single letter
	followed by '-'.

	Fixes <https://savannah.gnu.org/bugs/?66076>.  Thanks to наб for
	the report.

2024-10-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/xditview/xditview.c (NewFile): Fix code style
	nits.  Promote repeated expression to temporary variable.
	`sizeof` is an operator, not a function, so don't parenthesize
	its operand when it's an lvalue (as opposed to a type name).

2024-08-12  Lukas Javorsky <ljavorsk@redhat.com>

	* src/devices/xditview/xditview.c (NewFile): Populate
	`current_file_name` with `name` more cautiously since the latter
	originates in the `argv` array.

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

2024-08-14  Lukas Javorsky <ljavorsk@redhat.com>

	* src/preproc/refer/ref.cpp (same_reference): Fix array
	comparison warning by comparing elements individually.

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

2024-08-14  Lukas Javorsky <ljavorsk@redhat.com>

	* src/preproc/pic/object.cpp (object_spec::position_rectangle)
	(object_spec::make_line): Initialize "x" and "y" elements of the
	`here` structure.  Using uninitialized variables in
	`path::follow()` could cause undefined behavior.

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

2024-10-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/pic.ms: Fix omission of `linethick` variable from
	"Semi-Formal Grammar" section.

	Fixes <https://savannah.gnu.org/bugs/?66335>.  Thanks to an
	anonymous contributor for the report and patch.

2024-10-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Better handle inapplicable or out-of-bounds (but still
	numerically valid) output page selection list (`-o` argument).

	* src/roff/troff/node.cpp: New global Boolean
	`was_any_page_in_output_list` tracks this datum; defaults false.
	(troff_output_file::trailer): When finishing up, don't write a
	"trailer" grout command (and vertical motion) if no page ever
	began.  Instead, throw a warning in category `range`.
	(real_output_file::begin_page): Make
	`was_any_page_in_output_list` true if any page is written.

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

2024-10-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (parse_output_page_list): Enhance
	diagnostic message when `-o` option argument is nonsense; report
	the invalid expression and inform user that it's being ignored.

2024-10-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (in_output_page_list): Demote return
	type from `int` to `bool`.  Return Boolean, not integer,
	literals.
	* src/roff/troff/node.h: Boolify declaration.

2024-10-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (parse_output_page_list): `const`ify
	function argument.

2024-10-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/s.tmac (DS): Break line unconditionally, ensuring that
	that the top-of-page trap springs even if the document starts
	with a call of this macro.

	Fixes <https://savannah.gnu.org/bugs/?66339>.  Thanks to Joerg
	van den Hoff for the report.  Problem introduced by me in commit
	1887bbe68c, 5 November 2021.

2024-10-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	[ms]: Regression-test Savannah #66339.

	* tmac/tests/s_can-start-document-with-DS-call.sh: Do it.
	* tmac/tmac.am (tmac_TESTS): Run test.

2024-10-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	Rename some test scripts for clarity.

	* tmac/tests/doc_CS-works.sh:
	* tmac/tests/doc_CT-works.sh: Rename these...

	* tmac/tests/doc_CS-register-works.sh:
	* tmac/tests/doc_CT-register-works.sh: ...to these.

	* tmac/tmac.am (tmac_TESTS): Update.

2024-10-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/preconv/tests/smoke-test.sh: Comment out a test;
	we no longer have a specimen of a Latin-1 document in the build
	tree.

2024-10-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/meintro_fr.me.in: Add back old-style Emacs file-local
	variable to supply preconv(1) a "coding tag".  Doing so throws
	that program a bone if the "uchardet" library is not available
	and the program is asked to guess the file's input encoding.

	Fixes <https://savannah.gnu.org/bugs/?66287> (1/2).  Thanks to
	Dave Kemper for the report.

2024-10-14  Dave Kemper <saint.snit@gmail.com>

	* tmac/en.tmac: Map hcodes of Latin-1 characters with
	diacritical marks that are used in English words to their
	unadorned ASCII counterparts.

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

2024-10-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* man/groff_tmac.5.man:
	* src/devices/gropdf/gropdf.1.man: These man pages employ an
	unusual character, U+2717 "BALLOT X".  Define a fallback
	character for devices incapable of rendering that.

	* tmac/tty.tmac: Define fallback character for groff `OK`
	special character.

	Fixes <https://savannah.gnu.org/bugs/?66162>.  Thanks to Bjarni
	Ingi Gislason for the report.

2024-10-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/ps.cpp (ps_printer::special): Fix off-by-one
	error in diagnostic message's line number report.

2024-10-15  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Work around debian's ImageMagick policy.

	* src/devices/gropdf/gropdf.pl: Don't use perlmagick to embed
	PDFs

	Fixes <https://savannah.gnu.org/bugs/?66333>.  Thanks to Branden
	for the report.

2024-10-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/s.tmac (XA): Revert commit a6e09ca7fb, 2022-04-17.  The
	macro once again reduces the line length by eight ens for the
	entire TOC if used.  This looks a little funny (shouldn't it
	apply only to the entry augmentation?), but is consistent with
	4.2BSD and 4.3BSD-Reno ms behavior, whence comes this extension.

	Fixes <https://savannah.gnu.org/bugs/?66328>.  Thanks to Joerg
	van den Hoff for the report.

2024-10-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[ms]: Regression-test Savannah #66328.

	* tmac/tests/s_XA-reduces-line-length.sh: Do it.
	* tmac/tmac.am (tmac_TESTS): Run test.

2024-10-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp (table::add_entry): Refactor.  Since
	we use the C string `extract()`ion of the groff `string` table
	entry repeatedly, move logic that stores its pointer to an
	automatic variable much earlier, and reference that in
	diagnostic messages instead of repeatedly calling a member
	function.

2024-10-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/preconv/preconv.cpp (do_file): Fix incorrect
	handling of file name string (a post-groff 1.23.0 regression).

2024-10-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	Rename some test scripts for clarity.

	* tmac/tests/an_FT-bad-value-should-not-trash-titles.sh:
	* tmac/tests/an_LL-init-sanely.sh:
	* tmac/tests/an_ME-punct-hyphenates.sh:
	* tmac/tests/an_UE-punct-hyphenates.sh:
	* tmac/tests/doc_D-places-page-numbers-correctly.sh:
	* tmac/tests/s_PN-works.sh: Rename these...

	* tmac/tests/an_FT-register-value-should-not-trash-titles.sh:
	* tmac/tests/an_LL-register-initializes-sanely.sh:
	* tmac/tests/an_ME-second-argument-hyphenates.sh:
	* tmac/tests/an_UE-second-argument-hyphenates.sh:
	* tmac/tests/doc_D-register-places-page-numbers-correctly.sh:
	* tmac/tests/s_PN-register-works.sh: ...to these.

	* tmac/tmac.am (tmac_TESTS): Update.

2024-10-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Coalesce some tests.

	* tmac/tests/an_CS-register-off.sh:
	* tmac/tests/an_CS-register-on.sh:
	* tmac/tests/an_CS-register-unspecified.sh:
	* tmac/tests/an_CT-register-off.sh:
	* tmac/tests/an_CT-register-on.sh:
	* tmac/tests/an_CT-register-unspecified.sh: Delete files,
	replacing with...
	* tmac/tests/an_CS-register-works.sh:
	* tmac/tests/an_CT-register-works.sh: ...these new files.

	* tmac/tmac.am (tmac_TESTS): Update.

2024-10-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (AT, UC): Fix code style nits.  In formatted
	output comparisons, use `'` as the delimiter, as is done
	everywhere else in the file.  Drop leading quotation marks from
	string assignments when unnecessary (the value is known not to
	contain leading space).

2024-10-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (TH): Clarify language in style warning messages.

2024-10-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (TH): Simplify logic populating center header.

2024-10-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Rename internal strings and registers.
	    `an*topic`             -> `an*ident`
	    `an*topic-abbv`        -> `an*ident-abbv`
	    `an*topic-string`      -> `an*ident-string`
	    `an*topic-length`      -> `an*ident-length`
	    `an*topic-length-prev` -> `an*ident-length-prev`
	    `an*topic-style`       -> `an*ident-style`

2024-10-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/psrm.cpp (read_uint_arg): When complaining
	of invalid input (that we expect to be an ISO 646-encoded
	decimal integer), disclose what that input is.

2024-10-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/psrm.cpp (read_uint_arg): Boolify.

2024-10-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/psrm.cpp (read_uint_arg): Migrate from
	`strtol()` to `strtoul()`.  Thirty years ago {see
	"ChangeLog.old"}, James Clark converted some code in grolj4(1)
	from strtoul(3) to strtol(3), possibly because the function was
	not widespread or standardized.  Presumably that lesson was
	applied here as well.  It's standard now, in ISO C99, for which
	we require compiler support.  Migrate text-to-integer conversion
	and discard diagnosis of negative value.

2024-10-11  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Don't use inbuilt pdf parser on user supplied data.

	* src/devices/gropdf/gropdf.pl: Another example of using it
	in an inappropriate situation.

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

	* tmac/doc.tmac (doc-enclose-string): Add warning.  mdoc input
	like this

	  .Sq ,

	...is something I see from time to time; it's a conspicuous
	hazard of mdoc's macro system within a macro system.  It leads
	to an unhelpful diagnostic when GNU troff warnings are dialed
	up.

	  warning: register 'doc-type0' not defined

	Throw document maintainers, if not readers, a bone.

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

	* tmac/an.tmac:
	* tmac/doc.tmac: Fix code style nits; parallelize handling of
	rendering option registers and strings.

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

	* tmac/refer.tmac (ref*biblio-item-sfx): Define new string (if
	not already defined) to specify trailing punctuation for a
	bibliographic entry list item.  The default is a dot.
	(ref*end-print): Interpolate the new string instead of a literal
	dot.

2024-10-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp (table::add_entry): Quote the
	contents of ordinary (that is, non-text-block) table entries
	when throwing diagnostics about their contents.

2024-10-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp (table::add_entry): Fix logic error
	in *roff escape sequence detection, exposed by UTP document
	<https://github.com/larrykollar/Unix-Text-Processing/tree/1.0>.

2024-10-11  Deri James  <deri@chuzzlewit.myzen.co.uk>

	* src/devices/gropdf/gropdf.pl: When switching writing
	direction (\X'pdf: xrev') ensure any buffered output is
	flushed.

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

	* src/preproc/tbl/table.cpp (table::add_entry): Refactor match
	attempts for `\R` and `\z` in table entries to use new `find()`
	member function of `string` class.

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

	* src/preproc/tbl/table.cpp (table::add_entry): Refactor to
	avoid overreading memory allocated to `string` objects, which
	don't null-terminate their contents.  Use string class's
	existing `search` and new `find` member functions to perform
	character and substring matches, respectively, instead of
	`strchr()` and `strstr()`.  As a side benefit, the code now
	looks cleaner and reads easier.

	Fixes a SEGV reported by Lennart Jablonka that I can't reproduce
	but which made sense once he pointed it out.  Problem introduced
	by me in commit a91cd457d9, 26 September.

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

	* src/include/stringclass.h (class string): Declare new `find`
	public member function; it works like `search` but takes a
	pointer to `const char`, making it a substring locator.

	* src/libs/libgroff/string.cpp (string::find): Implement it.

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

	* bootstrap.conf: Add "memmem" to `gnulib_modules`.

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

	* src/include/stringclass.h (class string): Fix code style nit:
	`const`-ify argument to `search` public member function.

	* src/libs/libgroff/string.cpp (string::search): `const`-ify
	argument and local variable.  Use C++ `static_cast` operator
	instead of C-style type cast.  Explicitly compare variable of
	pointer type to null pointer literal instead of letting it pun
	down to a Boolean.  Parenthesize complex expression.

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

	* src/roff/troff/reg.cpp (dump_register): Remove garbage from
	`errprint()` format string.

	Fixes <https://savannah.gnu.org/bugs/?66293>.  Thanks to Bjarni
	Ingi Gislason for the report.

2024-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp (table::init_output): Migrate to use
	of `.R` register for a huge value in generated groff language,
	instead of hard-coding (2^31)-1 as a numeric literal.

2024-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp: Add C preprocessor macro storing
	the name of a groff register for saving the state of line
	numering enablement.
	(table::init_output): Save the value of the `.nm` register to
	this groff register.
	(table::do_bottom): Test the value of that register (instead of
	the saved line number itself) when deciding whether to reënable
	line numbering after leaving the table region.

	Fixes <https://savannah.gnu.org/bugs/?66290>.  Problem
	introduced by me in commit 950f92e25f, 28 November 2022, when
	fixing Savannah #61040.  Thanks to Deri James for the report.

2024-10-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/tests/save-and-restore-line-numbering.sh: Add
	regression test for Savannah #66290.

2024-10-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/\
	write-request-handles-empty-second-arg.sh: Revise signal
	handling.

2024-09-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (class input_iterator)
	(class string_iterator, class macro_iterator):
	Demote `get_break_flag()` member function from `int` to `bool`.
	Return Boolean, not integer, literal from it.
	(class string_iterator, class macro_iterator): Demote member
	variable `with_break` from `int` to `bool`.

2024-09-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_write_request): Fix code style
	nits.  Restyle loops to more closely resemble similar logic in
	this file.  Reorder equality comparisons to avoid inadvertent
	lvalue assignment.

2024-09-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_write_request): Check for a
	second argument before proceeding as if it's there.  This makes
	`write` and `writec` behave more like other requests that read
	`contents` or `anything` arguments.

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

2024-09-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Add regression test for Savannah #66255.

	* src/roff/groff/tests/\
	write-request-handles-empty-second-arg.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2024-09-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (close_all_streams): Drop
	copy-and-wasted line.  Harmless but pointless (we're no
	longer reading input when this function is called).

2024-09-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (pipe_output): Shorten diagnostics.

2024-09-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	[gropdf]: Make pdfom handle errors and abnormal exits.

	* src/devices/gropdf/pdfmom.pl: Handle signaled and error exits
	from groff pipeline.  Improve diagnostics.  Store "basename" of
	executing command into `prog` scalar.  Gather the wait status
	returned by every use of `system()`.
	(abort): New subroutine writes a fatal diagnostic message and
	exits with status 1.
	(autopsy): New subroutine decodes a POSIX wait status to
	determine the fate of an unlucky process, and returns it as a
	human-readable string scalar.  (The interesting part is cribbed
	from Perl documentation.)

2024-09-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp (table::add_entry): Throw warnings
	if comment (`\"`, `\#`) or transparent throughput (`\!`) escape
	sequences encountered in table entry.  Because these escape
	sequences cause the formatter to consume the rest of the input
	line as their argument, they don't play well with tbl, which
	tries to measure a table entry's width by interpolating it
	inside the delimited `\w` escape sequence.  You can sometimes
	get away with this (especially in simple table layouts), hence
	the mere warning, but it can't be relied upon.

2024-09-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp (table::add_entry): When erroring
	about a table entry ending with (an incomplete) zero-motion
	escape sequence, spell out the escape sequence in the diagnostic
	for the benefit of *roff non-experts.

2024-09-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/nroff/nroff.sh: Support `-v` non-finally in option
	clusters.  "nroff -tv" worked while "nroff -vt" did not.  That
	was silly.  Continues commit 24d4975ebe, 12 July.

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

2024-09-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* mdate.pl: Report dates in ISO 8601 format (for man page center
	footers).  That is what we prescribe in an `-rCHECKSTYLE`
	diagnostic; it's only fair that we dog food our own
	recommendation.

2024-09-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* Makefile.am (set-man-page-time-stamps): New maintainer-mode
	rule sets time stamps of man page source documents to match the
	Git "author date" of their most recent commits.  This is to make
	the date reported in the center footer of the rendered page tell
	the truth.

2024-09-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/afmtodit/afmtodit.tables: Update using the Unicode
	16.0.0 version of the "UnicodeData.txt" file.

2024-09-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/afmtodit/afmtodit.tables: Update with freshly
	changed "make-afmtodit-tables" script, adding ~192 mappings.

	Fixes <https://savannah.gnu.org/bugs/?65716> (2/2).  Thanks to
	Deri James for the report.

2024-09-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/afmtodit/make-afmtodit-tables: Alter maintainer-mode
	script to stop excluding code points from the Private Use Area
	in the Unicode Basic Multilingual Plane from glyph mappings for
	Adobe fonts (and workalikes).  Doing so expands coverage to ~192
	more glyphs, including groff's "braceex".

	Fixes <https://savannah.gnu.org/bugs/?65716> (1/2).  Thanks to
	Deri James for the report.

2024-09-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (interpolate_macro): Fix code style
	nits.  Reorder equality comparisons to avoid inadvertent lvalue
	assignment.  Rename local variable `warned` to `was_warned` and
	demote it from `int` to `bool`.  Assign to it using Boolean, not
	integer, literals.  Explicitly compare variable of pointer type
	to null pointer literal instead of letting it pun down to a
	Boolean.  Stop treating return value of `warning()` as
	significant.  If ever there was a function that was called only
	for its side effects, that's it.

2024-09-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (device_request): Add extensive new
	logic to subvert copy mode so as to interpret special character
	escape sequences.  We don't yet support _composite_ special
	character escape sequences.
	* src/roff/groff/tests/
	device-control-special-character-handling.sh: Update and expand
	test cases.  Comment out one new case that doesn't yet work.

	This change is in further service of the grueling march toward
	resolution of <https://savannah.gnu.org/bugs/?63074>.

2024-09-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp (main): Clarify verbose output.

2024-09-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/groff.cpp: Boolify variables controlling
	whether a command pipeline is constructed.
	(run_commands): Demote `no_pipe` argument from `int` to `bool`.
	(main): Rename `vflag` to `want_version_info` and demote it from
	`int` to `bool`.  Assign to it using Boolean, not integer,
	literals.
	* src/roff/groff/pipeline.c (run_pipeline):
	* src/roff/groff/pipeline.h (run_pipeline): Demote `no_pipe`
	argument from `int` to `bool`.
	* src/roff/groff/pipeline.c: Include "stdbool.h" header file.

2024-09-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	[gxditview]: Accept the `-v` option groff(1) may supply.

	* src/devices/xditview/xditview.c (Syntax): Report `-v` as an
	accepted synonym of `-version` and `--version` in usage message.
	(main): Refactor argument processing.  Accept `-v`.  Handle
	early-exit options {`--help`, `--version` and their synonyms}
	_before_ checking for an excess argument count, another error
	condition.

	* src/devices/xditview/gxditview.1.man (Synopsis): Document
	`-v` option.

2024-09-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (remove_macro, rename_macro)
	(alias_macro, chop_macro, stringdown_request, stringup_request)
	(substring_request, length_request): Check for arguments: if
	none are present, throw warning in category "missing" and skip
	the remainder of the input line.
	(do_string_case_transform): Add `assert()` since our callers
	now require that arguments be present.

2024-09-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (decode_string_args): Improve
	error diagnostic to disclose more context.

2024-09-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (close_stream): Handle being given a
	nonexistent stream to close.  Prevents null pointer dereference.
	Continues 6d32f2492e, 13 September.

2024-09-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (open_file): Fix unsafe-mode SEGV
	caused by null pointer dereference.  Problem introduced by me in
	commit 6d32f2492e, 13 September.  Also add assertion; null
	`FILE` stream pointers should not be getting stored in GNU
	troff's `stream_dictionary`.

2024-09-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (report_color): Report color space
	and channel assignments.

	* doc/groff.texi.in (Debugging):
	* man/groff.7.man (Request short reference):
	* man/groff_diff.7.man (New requests):
	* NEWS: Update documentation.

2024-09-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/color.h: Fix code style nit: drop unnecessary
	`#include`.

2024-09-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (report_composite_characters): Fix
	code style nit: eliminate unnecessary temporary variable.

2024-09-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Refactor.  `\X` reads its delimited argument in
	interpretation mode and the `device` request reads its argument
	in copy mode.  We want parity in special character handling for
	these formatter instructions, but one works with tokenized
	input and the other with tokens that happen to be a sequence of
	ordinary characters.  (In other words, in `\X'\[em]'` and
	`.device \[em]`, the escape sequence "knows" that it is dealing
	with a valid special character named "em", whereas the request
	merely handles '\', '[', 'e', 'm', and ']' in series.)  This
	change is in service of the grueling march toward resolution of
	<https://savannah.gnu.org/bugs/?63074>.

	* src/roff/troff/input.cpp
	(map_special_character_for_device_output): New function handles
	all of the potential special (including composite) character
	identifier rewriting formerly in...
	(encode_special_character_for_device_output): ...this function,
	which now simply calls the foregoing after extracting the
	special character identifier from the `charinfo` of the current
	token.

2024-09-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_device_extension): Make `\X`
	escape sequence begin the first page of the document if it
	hasn't begun already.  In the "grout" page description language,
	this puts the leading 'x' initialization commands on the output
	stream, which we guarantee to come first in any such document.
	Device extension commands 'x X' before that point are not
	well-defined, and further this change brings `\X` into parity
	with its sibling, the `device` request, which does so already.

2024-09-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Clean up streams on formatter exit.

	* src/roff/troff/input.cpp (close_all_streams): New function
	iterates `stream_dictionary` and closes each stream.
	(exit_troff): Call `close_all_streams()`.

2024-09-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Add `pstream` request.

	* src/roff/troff/input.cpp (print_streams): New request handler
	iterates through `stream_dictionary`, writing each entry.
	(init_input_requests): Wire up `pstream` request to new handler.

2024-09-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Make groff streams objects of new `grostream` class, so
	we can conveniently store more state in them.

	* src/roff/troff/input.cpp (class grostream): Declare.
	(grostream::grostream): Declare constructor.
	(grostream::~grostream): Declare (trivial) destructor.
	(print_streams): Report mode in which the stream was opened and
	name of file backing it.
	(open_file, close_stream, do_write_request)
	(write_macro_request): Migrate to expect an object of type
	`grostream` from a `stream_dictionary.lookup()` instead of a
	pointer to `FILE`.

2024-09-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (close_request): Move stream-closing
	logic (as opposed to request argument validation) into...
	(close_stream): ...its own new function.

2024-09-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Declare global `stream_dictionary`
	as type `object_dictionary` instead of `dictionary`, since we
	want the stored values to be class objects instead of a
	primitive data type.
	(open_file, close_request): Update member function calls
	appropriately; the former class uses return values for
	`lookup()` and `remove()`, the latter does not.
	(open_file): Clarify diagnostic when we try to reorient an
	existing stream name to a new file, but can't close the old file
	associated with the stream name.
	(close_request): Remove the stream from the dictionary only if,
	and after, we have successfully closed the `FILE` stream.

2024-09-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (class input_iterator): Trivially
	refactor.  Rename `eptr` member variable to `endptr`.
	(input_stack::get, input_stack::finish_get, input_stack::peek)
	(string_iterator::string_iterator, string_iterator::fill)
	(string_iterator::peek, temp_iterator::temp_iterator): Migrate.

2024-09-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Slightly refactor.  Move
	responsibility for skipping the rest of the input line...
	(open_file): ...from this internal helper function...
	(open_request, opena_request): ...to these handler functions,
	for better symmetry with other request handlers.

2024-09-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_open): The `write` request, an
	"unsafe mode" feature, has been broken for a week.  (As,
	possibly, have others that write to streams.)  Revert
	`static_cast` operators to C-style casts, which seem to be
	necessary (sometimes) with groff's bespoke, pre-STL `dictionary`
	class implementation.  Unfortunately, when static casts fail,
	they fail silently, happily handing back null pointers that you
	might not notice right away.  Fixes problem introduced by me in
	commit 3bb13e4752, 4 September.

2024-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (source_request)
	(source_quietly_request, pipe_source_request, open_request)
	(opena_request, close_request, macro_source_request)
	(macro_source_quietly_request, ps_bbox_request): Check for
	arguments: if none are present, throw warning in category
	"missing" and skip the remainder of the input line.

2024-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(do_open): Rename this...
	(open_file): ...to this.
	(open_request, opena_request): Update call sites.

2024-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename
	request-handling functions to append `_request` to their names.
	  `source`               -> `source_request`
	  `source_quietly`       -> `source_quietly_request`
	  `pipe_source`          -> `pipe_source_request`
	  `macro_source`         -> `macro_source_request`
	  `macro_source_quietly` -> `macro_source_quietly_request`
	(init_input_requests): Migrate to new names.
	(open_request, opena_request): Clarify error diagnostics.

2024-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/soelim/soelim.1.man (Description):
	* src/roff/groff/groff.1.man (groff-specific options, Usage)
	(Getting started): Hyperlink man page cross references on first
	occurrences.

	Fixes <https://savannah.gnu.org/bugs/?66103>.  Thanks to Helge
	Kreutzmann and the manpage-l10n project for the report.

2024-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/html/pre-html.cpp (html_system): Improve report of
	failing system(3) commands and fix code style nits.  Use
	standard constant symbol `STDOUT_FILENO` in favor of a "1"
	literal.  Parenthesize complex expressions.  Recast diagnostic
	message.  Stop misreporting the `int` return value of `system()`
	as the command's "(exit) status".  The integer _encodes_ the
	exit status in its lowest seven bits.  Distinguish the cases of
	the command exiting with a failing status, being signalled, and
	being stopped, using standard POSIX macros; see wait(2).

2024-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/html/pre-html.cpp (imageList::createPage)
	(imageList::createImage): Drop trailing newline from commands
	constructed for passage to system(3).  They (a) are unnecessary
	and (b) make diagnostics repellently ugly.

2024-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/html/pre-html.cpp: Improve diagnostic message
	handling.
	(html_system, imageList::createPage, imageList::createImage)
	(set_redirection, save_and_redirect, print_args [DEBUGGING]):
	Prefix output to standard error stream with name of program.
	(html_system [DEBUGGING], imageList::createPage [DEBUGGING])
	(imageList::createImage [DEBUGGING], print_args [DEBUGGING]):
	Prefix output to standard error stream with "debug:" message
	severity tag.
	(main): Assign to `program_name` global variable before emitting
	first diagnostic ([CAPTURE_MODE]), and convert that diagnostic
	to use it.

2024-09-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/html/pre-html.cpp (dump_args): "`#if 0` out"
	function with no call sites.

2024-09-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Trivially refactor; rename variables
	to better suggest their data types.
	  `suppress_start_page` -> `suppression_starting_page_number`
	(suppress_node::tprint):
	  `current_page` -> `page_number`

2024-09-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (indent, temporary_indent): Report
	amount of computed indentation when warning of negative value.

2024-09-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp
	(possibly_handle_first_page_transition): Boolify.

2024-09-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.h (class top_level_diversion): Rename
	`before_first_page` to `before_first_page_status` to emphasize
	its non-Boolean nature.
	* src/roff/troff/div.cpp
	(top_level_diversion::top_level_diversion): Migrate constructor.
	* src/roff/troff/div.cpp (top_level_diversion::output)
	(top_level_diversion::transparent_output)
	(top_level_diversion::copy_file)
	(top_level_diversion::space)
	(top_level_diversion::begin_page)
	(vertical_position_reg::get_value)
	(vertical_position_reg::get_string)
	(nl_reg::get_string):
	* src/roff/troff/env.cpp (environment::make_tag)
	(environment::do_break, title):
	* src/roff/troff/input.cpp
	(possibly_handle_first_page_transition, device_request)
	(copy_file, transparent_file): Explicitly compare to integer
	literal instead of punning to Boolean.

2024-09-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.h (class top_level_diversion): Boolify
	member variable `ejecting_page`, migrating trivial accessor and
	mutator.
	* src/roff/troff/div.cpp
	(top_level_diversion::top_level_diversion): Migrate constructor.
	(top_level_diversion::begin_page): Migrate.

2024-09-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.h (class top_level_diversion): Boolify and
	rename member variable: `have_next_page_number` ->
	`overriding_next_page_number`.
	* src/roff/troff/div.cpp (top_level_diversion::begin_page)
	(top_level_diversion::set_next_page_number)
	(top_level_diversion::get_next_page_number): Migrate.

2024-09-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.h (class diversion, class macro_diversion)
	(class top_level_diversion): Boolify trivial member function
	`is_diversion()`.

2024-09-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.h (class diversion, class macro_diversion)
	(class top_level_diversion): Boolify and rename `space()` member
	function argument, demoting `forced` from `int` to `bool`, and
	renaming it `forcing`, for symmetry with `appending` and
	`boxing`.
	* src/roff/troff/div.cpp (macro_diversion::space)
	(top_level_diversion::space, continue_page_eject)
	(save_vertical_space, output_saved_vertical_space):
	* src/roff/troff/input.cpp (exit_troff): Migrate.

2024-09-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.h (class diversion, class macro_diversion)
	(class top_level_diversion): Boolify `output()` member function
	argument, demoting `retain_size` from `int` to `bool`.
	* src/roff/troff/div.cpp (macro_diversion::output)
	(top_level_diversion::output): Boolify at definition sites.
	This variable seems to be coupled to `suppress_filling` in
	"env.cpp".

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

	* src/roff/troff/div.h (do_divert): Boolify function arguments.
	Comment formal argument names as a compromise with the
	Stroustrup-style C++ used in most of groff.
	* src/roff/troff/div.h (class diversion):
	* src/roff/troff/env.h (class environment): Update friend
	declarations.
	* src/roff/troff/div.h (class macro_diversion): Similarly
	boolify and rename constructor argument.
	* src/roff/troff/div.cpp (do_divert, divert, divert_append, box,
	box_append): Boolify function arguments.  Rename `append` to
	`appending`, to match the existing `boxing`.
	(macro_diversion::macro_diversion): Similarly boolify and rename
	constructor argument.

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

	* src/roff/troff/div.cpp (begin_page): Boolify local variable
	`got_arg`.

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

	* src/roff/troff/div.h (class diversion): Boolify member
	variables that cache values of Boolean member variables of
	`environment` class.  Mark them as possibly nilpotent; when I
	experimentally deleted each of them, no automated tests failed,
	and even Peter's fearfully complex mom(7) documents looked fine.
	Possibly a task for groff 1.25.

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

	* src/roff/troff/div.h (class diversion): Boolify and rename
	member variable `no_space_mode` to `is_in_no_space_mode`.
	* src/roff/troff/div.cpp (diversion::diversion): Use new name
	and construct with Boolean, not integer, literal.
	(macro_diversion::output, top_level_diversion::output)
	(top_level_diversion::copy_file, top_level_diversion::space)
	(begin_page, space_request, blank_line)
	(no_space_mode_reg::get_value, no_space_mode::get_string):
	Migrate to new name and assign to with Boolean, not integer,
	literal.

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

	* src/roff/troff/div.cpp (class diversion): Drop unused member
	variables `any_chars_added` and `needs_push`.

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

	* src/roff/troff/div.cpp (macro_diversion::macro_diversion):
	Boolify argument to `macro` object constructor, using Boolean
	instead of integer literal.  Continues commit 7c5b8e5d4a, 27
	August.

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

	* src/roff/troff/node.cpp (macro_diversion::macro_diversion)
	(page_number): Use C++ `static_cast` operator instead of C-style
	type cast.
	(top_level_diversion::find_next_trap)
	(top_level_diversion::add_trap): Parenthesize complex
	expressions.
	(page_number, vertical_position_traps): Zero-initialize
	stack-allocated integer.
	(macro_diversion::macro_diversion)
	(top_level_diversion::find_next_trap)
	(top_level_diversion::add_trap, page_number): Reorder equality
	comparisons to avoid inadvertent lvalue assignment.

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

	* src/roff/troff/node.cpp (troff_output_file::fill_color):
	Explicitly compare variable of pointer type to null pointer
	literal instead of letting it pun down to a Boolean.
	(glyph_node::add_self)
	(dbreak_node::merge_glyph_node):
	(kern_pair_node::merge_glyph_node):
	(kern_pair_node::add_discretionary_hyphen): Reorder equality
	comparisons to avoid inadvertent lvalue assignment.
	(kern_pair_node::merge_glyph_node): Chain assignments as is done
	in the rest of this file.

2024-09-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (print_env): Improve environment
	report.  Don't report two items of stale data about a completed
	line, and describe them more intelligibly.  Say "text length"
	rather than "total width"; the former is what is compared to the
	already reported "target text length".  Clarify "total number of
	spaces" as "number of adjustable spaces"; that's what's really
	counted.  Relocate report of "target text length" to more
	closely follow "text length" and "number of adjustable spaces"
	to make their relationship more obvious.

2024-09-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment_copy, space_size):
	Check for arguments: if none are present, throw warning in
	category "missing" and skip the remainder of the input line.

2024-09-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment_copy): Use C++
	`static_cast` operator instead of C-style type cast.  Explicitly
	compare variable of pointer type to null pointer constant
	instead of letting it pun down to a Boolean.

2024-09-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::output_line): Resize
	stack-allocated character buffer to use constant defined by
	libgroff for formatting unsigned `int`s as strings.  Use
	sprintf(3)'s 'u' conversion, not 'd', for output line number,
	which cannot be negative.  Explicitly discard return value of
	sprintf(3).

2024-09-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp
	(troff_output_file::start_device_extension): Call `flush_tbuf()`
	before any other function that may write to device-independent
	output.

2024-09-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp
	(troff_output_file::start_device_extension): Stop calling
	`do_motion()` in argumentless version, which is called only when
	writing HTML (specifically, when inlining images).  It seemed to
	accomplish nothing.  No tests fail and "pic.html", a document
	with many images, continues to render fine.  In
	device-independent output, a pair of absolute positioning
	commands ('H' and 'V') moves to a redundant place, but the HTML
	produced is identical (except for a date stamp in a comment).

2024-09-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/token.h (class token): Rename enumeration
	constant from `TOKEN_SPECIAL` to `TOKEN_SPECIAL_CHAR`.  Rename
	member function declaration from `is_special()` to
	`is_special_character()`.  Tokens can represent multiple types
	of formatter objects (at least three of which, "special
	characters", "special fonts", and "special nodes", have member
	functions named `is_special()`, and which have little to do with
	each other).
	(token::is_special): Rename this...
	(token::is_special_character): ...to this.

	* src/roff/troff/input.cpp (token::next, token:operator==)
	(token::description, token::get_char)
	(token::add_to_zero_width_node_list, token::process): Use new
	enumeration constant.
	(encode_character_for_device_output): Update `is_special()`
	call site.

2024-09-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	Migrate to "device extension [command]" terminology.

	* src/devices/grodvi/grodvi.1.man:
	* src/devices/gropdf/gropdf.1.man:
	* src/devices/grops/grops.1.man:
	* src/devices/grotty/grotty.1.man: Do it.

	* tmac/tests/an_MR-works.sh: Update test output.

2024-09-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor and reform terminology.  Call `\X`
	escape sequence and `device` request device _extension_
	instructions.  There is already, in groff, a device command
	'x u' that configures underlining of spaces (and which is
	implemented only by grotty(1)).  A dusty corner, to be sure, but
	we could support others in the future, and further, the new term
	indicates the fact that `\X` and `device` produce arguments only
	for 'x X' "sub"-commands--this has always been the case and for
	`\X` it was true even in Kernighan troff.

	* src/roff/troff/input.cpp (do_device_control): Rename this...
	(do_device_extension): ...to this.
	(do_device_extension, device_request): Migrate diagnostic
	messages.

	* src/roff/troff/troff.1.man (Options): Migrate terminology.

2024-09-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Rename `special_node` class to `device_extension_node`.

	* src/roff/troff/node.h (class special_node): Rename this...
	(class device_extension_node): ...to this.  Rename constructors.

	* src/roff/troff/node.cpp
	(device_extension_node::device_extension_node): Rename
	constructors.

	(special_node::is_same_as): Rename this...
	(device_extension_node::is_same_as): ...to this.

	(special_node::type): Rename this...
	(device_extension_node::type): ...to this.  Update return
	string.

	(special_node::ends_sentence): Rename this...
	(device_extension_node::ends_sentence): ...to this.

	(special_node::causes_tprint): Rename this...
	(device_extension_node::causes_tprint): ...to this.

	(special_node::is_tag): Rename this...
	(device_extension_node::is_tag): ...to this.

	(special_node::copy): Rename this...
	(device_extension_node::copy): ...to this.

	(special_node::tprint_start): Rename this...
	(device_extension_node::tprint_start): ...to this.

	(special_node::tprint_char): Rename this...
	(device_extension_node::tprint_char): ...to this.

	(special_node::tprint_end): Rename this...
	(device_extension_node::tprint_end): ...to this.

	(special_node::get_tfont): Rename this...
	(device_extension_node::get_tfont): ...to this.

	* src/roff/troff/env.cpp (configure_space_underlining)
	(environment::make_tag):
	* src/roff/troff/input.cpp (token::next, do_device_control)
	(device_request, device_macro_request): Update constructor
	calls.

	* src/roff/troff/input.cpp (special_node::tprint): Rename
	this...
	(device_extension_node::tprint): ...to this.

2024-09-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp (flush_output): Rename this...
	(flush_request): ...to this.  Also declare it `static` since it
	has no callers external to the translation unit.
	(init_div_requests): Update request initialization.

2024-09-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (class troff_output_file): Trivially
	refactor.  Rename member functions declarations.
	  `start_special` -> `start_device_extension`
	  `special_char` -> `write_device_extension_char`
	  `end_special` -> `end_device_extension`
	(troff_output_file::start_special): Rename this...
	(troff_output_file::start_device_extension): ...to this.
	(troff_output_file::special_char): Rename this...
	(troff_output_file::write_device_extension_char): ...to this.
	(troff_output_file::end_special): Rename this...
	(troff_output_file::end_device_extension): ...to this.
	(special_node::tprint_start, special_char::tprint_char)
	(special_node::tprint_end, suppress_node::put)
	(suppress_node::tprint): Update call sites.

2024-09-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (class troff_output_file): Declare new
	`flush` member function.
	(troff_output_file::flush): New member function calls
	`flush_tbuf()` and calls `real_output_file`'s own `flush` member
	function.

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

	* src/roff/troff/reg.cpp (dump_register): Report assigned format
	of register only if it is not string-valued.

	* doc/groff.texi.in (Debugging):
	* man/groff.7.man (Request short reference):
	* man/groff_diff.7.man (New requests):
	* NEWS: Update documentation.

2024-09-02  Sven Schober <sv3sch@gmail.com>

	[man]: Handle discrepant `pdf{images,totext}`.

	There are at least two different implementation variants for
	pdfimages and pdftotext out there: poppler's and
	xpdfreader.com's.

	* tmac/tests/an_UR-works.sh: Cope with minute syntax differences
	between these implementations in test case.

	Fixes <https://savannah.gnu.org/bugs/?66155> (1/2).

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

	* src/roff/troff/input.cpp (token::next)
	(map_composite_character, composite_glyph_name): Use new
	`errbuf` argument of libgroff's `valid_unicode_code_sequence()`
	to return information about how the input Unicode special
	character identifier was defective.

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

	* src/roff/troff/input.cpp (token::next)
	(map_composite_character, composite_glyph_name): Slightly
	refactor.  Introduce temporaries for brevity.

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

	* src/roff/troff/env.cpp (font_size::dump_size_table): Fix
	thinko: report scaling unit as 'z', not 's'.
	* src/roff/groff/tests/sizes-request-works.sh: Update test
	expectations.

	Continues commit f574a96f58, 3 September.

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

	* src/roff/nroff/nroff.sh: Update usage message, noting support
	for options -[aDIZ].

2024-09-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_open): Fix code style nits.
	Use C++ `static_cast` operator instead of C-style type casts.
	Emit error diagnostic if `fclose()` fails.

2024-09-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* Makefile.am: Revise and update internal documentation.

	Fixes <https://savannah.gnu.org/bugs/?64913>.  Thanks to Bjarni
	Ingi Gislason for the report.

2024-09-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (usage): Break lines in usage
	message.

2024-09-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (usage): De-document `-h` as synonym
	for `--help`.  That's not true for GNU troff.

2024-09-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor, renaming internal symbols matching
	`glyph_color` to `stroke_color`; the latter is what our
	documentation uses, and the glyph color is applied to things
	other than glyphs--the outlines of geometric figures.

	* src/roff/troff/env.h (class environment): Rename member
	variables and functions in declarations.
	  `glyph_color` -> `stroke_color`
	  `prev_glyph_color` -> `prev_stroke_color`
	  `get_glyph_color` -> `get_stroke_color`
	  `get_prev_glyph_color` -> `get_prev_stroke_color`
	  `set_glyph_color` -> `set_stroke_color`

	* src/roff/troff/env.cpp: Migrate.  Update member function
	definitions accordingly.
	(environment::environment): Update constructors.
	(environment::copy): Update back end of `evc` (_not_ a copy
	constructor).
	(glyph_color_change): Rename this...
	(stroke_color_change): ...to this.
	(title, environment::get_stroke_color_string): Update accesses
	to member variables.
	(init_env_requests): Wire up `gcolor` request to
	`stroke_color_change()`.  Wire up `.m` register to
	`get_stroke_color_string()`.

	* src/roff/troff/input.h: Migrate declaration.
	(do_glyph_color): Rename this...
	(do_stroke_color): ...to this.

	* src/roff/troff/input.cpp: Migrate.
	(do_stroke_color): Use new member function name
	`set_stroke_color()`.
	(token::next): Wire up `\m` escape sequence to
	`do_stroke_color()`.
	(read_drawing_command): Construct node using
	`get_stroke_color()`.

2024-09-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/reg.cpp (assign_register_format_request):
	Align wording of error diagnostic with warnings thrown by same
	function.

2024-09-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp (is_valid_term): Reject scaling
	units other than `f` in contexts where `f` is expected
	{dimensionless values in the unit interval expressing the
	magnitude of a color channel}.

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

2024-09-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp (is_valid_term): Accept `p` and `s`
	scaling units in expressions where `z` is accepted.  Also fix
	code style nit: parenthesize complex expressions.

	* doc/groff.texi.in (Using Fractional Type Sizes):
	* man/groff_diff.7.man (Fractional type sizes and new scaling
	units):
	* NEWS: Document this.

	* doc/groff.texi.in (Using Fractional Type Sizes): Add example.

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

2024-09-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (point_size, override_sizes): Ignore
	request in nroff mode, like `fam`.

2024-09-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (override_sizes): Fix regression
	introduced in commit 5f2704d64a, yesterday.  However, it was
	hard to tell whether the request works.
	(font_size::dump_size_table): New static member function reports
	the valid size table of the environment's currently selected
	font.
	(environment::print_env): Report the valid size table.

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

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

2024-09-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	Add tests to prevent recurrence of Savannah #66164.

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

	* src/roff/groff/groff.am (groff_TESTS): Run tests.

	Continues fixing <https://savannah.gnu.org/bugs/?66164>.  (We
	still need a regression test for the `sizes` request, but there
	is no straightforward means of introspecting that aspect of
	environment state at present.)

2024-09-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (pipe_output, system_request): Fix
	requests I broke in commit 5f2704d64a, yesterday.  Thanks to
	Deri James for the report.

	Begins fixing <https://savannah.gnu.org/bugs/?66164>.  (We need
	regression tests.)

2024-09-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Didja ever notice that `pnr` produces a lot of output,
	and it isn't sorted?  The `pnr` request now supports dumping
	only of registers specified as arguments.

	* src/roff/troff/reg.h (look_up_register): Add second argument,
	`suppress_creation`, with default `false` value, in declaration.
	* src/roff/troff/reg.cpp (look_up_register): Skip emission of
	warning and register definition on lookup of nonexistent
	register if `suppress_creation` is true.
	(dump_register): New function takes over the work, formerly in
	`dump_register_request()`, of writing to stderr.
	(dump_register_request): Handle arguments, treating each as a
	register identifier and dumping it.  Otherwise behave as before.

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

2024-09-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/reg.cpp (dump_register_request): Report the
	interpolation format of each register at a further tab stop.

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

2024-09-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/reg.cpp (dump_register_request): Fix code style
	nit.  Use C++ `reinterpret_cast` operator instead of C-style
	type cast.  (The use of the "dangerously omnipotent" casting
	operator is made necessary by groff's pre-template dictionary
	implementation.)

2024-09-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/reg.cpp: Trivially refactor.  Rename all
	functions implementing request handlers such that they end with
	"_request", a practice already fitfully adopted elsewhere in GNU
	troff.  The idea is to help contributing developers navigate the
	source code more easily.
	(define_register, alter_format, remove_reg, alias_reg)
	(rename_reg, print_registers): Rename these...
	(define_register_request, assign_register_format_request)
	(remove_register_request, alias_register_request)
	(rename_register_request, dump_register_request): ...to these.

2024-09-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/reg.cpp (define_register, alter_format)
	(remove_reg, alias_reg, rename_reg): Give warning category
	"missing" more exercise.  Handle omitted register arguments
	where we can communicate more information about where request
	parsing has gone wrong.
	* src/roff/troff/reg.cpp (define_register, alter_format)
	(alias_reg): Add assertions for paranoia's sake.

2024-09-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (associate_style_with_font_position):
	Clarify warning diagnostic.

2024-09-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (define_color, device_request):
	* src/roff/troff/node.cpp (translate_font, set_special_fonts)
	(zoom_font): Align diagnostic wording with similar messages.

	* src/roff/troff/input.cpp (define_color): Add an assertion for
	paranoia's sake.

2024-09-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (pipe_source, open_request)
	(opena_request, hyphenation_patterns_file_code, pipe_output)
	(system_request): Migrate wording of error diagnostics to
	describe, rather than name, the request at issue, because
	requests can be aliased and moreover the original names can then
	be removed.  This change might also help GNU troff be more
	self-documenting, though many requests remain a bit esoteric.

2024-09-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Update input token pointer appropriately when certain
	requests requiring arguments are invalidly invoked without them.

	* src/roff/troff/env.cpp (override_sizes):
	* src/roff/troff/input.cpp (while_request, pipe_output)
	(system_request): Check for arguments: if none are present,
	throw warning in category "missing" and skip the remainder of
	the input line.
	(pipe_output, system_request): Add some assertions for
	paranoia's sake.

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

2024-09-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: The `kern` request now interprets arguments with
	negative values as instructions to disable the corresponding
	feature, using the *roff integer-to-Boolean conversion idiom
	instead of the C/C++ one.  Thus, if you invoke this request with
	a register interpolation, the outcome agrees with an `if` test
	of the register's value.

	* src/roff/troff/node.cpp: Demote type of global
	`global_kern_mode` from `int` to `bool`.
	(set_kerning_mode): Assign value to `global_kern_mode` using
	*roff integer-to-Boolean conversion idiom.  When no argument is
	present, assign using Boolean, not integer, literal.
	(init_node_requests): Back `.kern` register with an object of
	class `readonly_boolean_register` instead of
	`readonly_register`.

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

2024-09-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Prevent nested use of `do` requests from causing an
	assertion failure.

	* src/roff/troff/input.cpp: Improve handling of nested
	selections of compatibility mode.  Use a global STL stack of
	`bool`, `want_att_compat_stack`, to manage them.  Drop global
	`int` `do_old_want_att_compat` with its less-useful-than-hoped
	"-1" value to signal an outermost "scope".
	(do_request): Drop dubious `assert()`ion.  Push the value of
	`want_att_compat` onto the stack before invoking/calling the
	named request/macro, and pop it afterwards.
	(class enclosing_want_att_compat_reg): Add new class to handle
	dynamic construction of `.cp` register value.  I based the
	approach on an idiom heavily used in "env.cpp", where read-only
	registers are not modeled as accessors of C++ globals, because
	they interpolate per-environment state.
	(enclosing_want_att_compat_reg::get_string): Member function of
	new class constructs `.cp` register value by peeking at the top
	of `want_att_compat_stack`.
	(init_input_requests): Wire up `.cp` register to an object of
	`enclosing_want_att_compat_reg` class instead of now-dead
	`do_old_want_att_compat` global.

	Fixes <https://savannah.gnu.org/bugs/?61100>.  Problem
	introduced by me when introducing `.cp` register in commit
	6a37bb5f00, 17 April 2020.  Thanks to Bjarni Ingi Gislason for
	suggesting the direction a minimal reproducer could take.

2024-09-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	Regression-test Savannah #61100.

	* src/roff/groff/tests/\
	double-do-request-does-not-raise-assertion.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2024-09-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Rename test scripts to better fit recent conventions.
	We now use underscores only for structuring, as with the
	various macro packages in the "tmac" directory.

	* src/roff/groff/tests/ab_works.sh:
	* src/roff/groff/tests/adjustment_works.sh:
	* src/roff/groff/tests/\
	use_point_size_escape_with_single_digit_arg.sh:
	* src/roff/groff/tests/break_zero-length_output_line_sanely.sh:
	* src/roff/groff/tests/\
	device_control_escapes_express_basic_latin.sh:
	* src/roff/groff/tests/\
	do_not_loop_infinitely_when_breaking_cjk.sh:
	* src/roff/groff/tests/dot-cp_register_works.sh:
	* src/roff/groff/tests/dot-nm_register_works.sh:
	* src/roff/groff/tests/dot-nn_register_works.sh:
	* src/roff/groff/tests/dot-trap_register_works.sh:
	* src/roff/groff/tests/output_driver_C_and_G_options_work.sh:
	* src/roff/groff/tests/evc_produces_no_output_if_invalid.sh:
	* src/roff/groff/tests/fp_should_not_traverse_directories.sh:
	* src/roff/groff/tests/handle_special_input_code_points.sh:
	* src/roff/groff/tests/smoke-test_html_device.sh:
	* src/roff/groff/tests/html_works_with_grn_and_eqn.sh:
	* src/roff/groff/tests/initialization_is_quiet.sh:
	* src/roff/groff/tests/on_latin1_device_oq_is_0x27.sh:
	* src/roff/groff/tests/localization_works.sh:
	* src/roff/groff/tests/msoquiet_works.sh:
	* src/roff/groff/tests/recognize_end_of_sentence.sh:
	* src/roff/groff/tests/soquiet_works.sh:
	* src/roff/groff/tests/string_case_xform_requests.sh:
	* src/roff/groff/tests/string_case_xform_errors.sh:
	* src/roff/groff/tests/string_case_xform_unicode_escape.sh:
	* src/roff/groff/tests/substring_works.sh: Rename these...

	* src/roff/groff/tests/ab-request-works.sh:
	* src/roff/groff/tests/adjustment-works.sh:
	* src/roff/groff/tests/\
	backslash-s-works-with-single-digit-argument.sh:
	* src/roff/groff/tests/break-zero-length-output-line-sanely.sh:
	* src/roff/groff/tests/\
	device-control-escapes-express-basic-latin.sh:
	* src/roff/groff/tests/\
	do-not-loop-infinitely-when-breaking-cjk.sh:
	* src/roff/groff/tests/dot-cp-register-works.sh:
	* src/roff/groff/tests/dot-nm-register-works.sh:
	* src/roff/groff/tests/dot-nn-register-works.sh:
	* src/roff/groff/tests/dot-trap-register-works.sh:
	* src/roff/groff/tests/driver-C-and-G-options-work.sh:
	* src/roff/groff/tests/\
	evc-request-produces-no-output-if-invalid.sh:
	* src/roff/groff/tests/\
	fp-request-does-not-traverse-directories.sh:
	* src/roff/groff/tests/handle-special-input-code-points.sh:
	* src/roff/groff/tests/html-device-smoke-test.sh:
	* src/roff/groff/tests/html-device-works-with-grn-and-eqn.sh:
	* src/roff/groff/tests/initialization-is-quiet.sh:
	* src/roff/groff/tests/latin1-device-maps-oq-to-0x27.sh:
	* src/roff/groff/tests/localization-works.sh:
	* src/roff/groff/tests/msoquiet-request-works.sh:
	* src/roff/groff/tests/recognize-end-of-sentence.sh:
	* src/roff/groff/tests/soquiet-request-works.sh:
	* src/roff/groff/tests/stringdown-and-stringup-requests-work.sh:
	* src/roff/groff/tests/\
	stringdown-request-rejects-request-names.sh:
	* src/roff/groff/tests/\
	stringup-request-transforms-non-basic-latin.sh:
	* src/roff/groff/tests/substring-request-works.sh: ...to these.

	* src/roff/groff/groff.am (groff_TESTS, groff_XFAIL_TESTS):
	Update macro assignments accordingly.

2024-09-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_request): Fix assertion failure.
	Validate presence of arguments before further operating.

	Fixes:

	$ echo '.do' | ./build/test-groff
	troff: ../src/roff/troff/input.cpp:9050: request_or_macro*
	lookup_request(symbol): Assertion `!nm.is_null()' failed.
	.../groff: error: troff: Aborted (core dumped)

2024-09-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (hyphenate): Explicitly compare
	variable of pointer type to null pointer constant instead of
	letting it pun down to a Boolean.

2024-09-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (family_change): Ignore `fam` request
	if in nroff mode.
	* src/roff/troff/node.cpp (embolden_font): Ignore `bd` request
	if in nroff mode.

2024-09-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (asciify_macro, unformat_macro):
	(warnscale_request, translate, translate_no_transparent)
	(translate_input): Check for mandatory arguments to each of
	these requests (`asciify`, `unformat`, `warnscale`, `tr`,
	`trnt`, and `trin`), and throw warning in category "missing" if
	they are lacking.

2024-09-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (title):
	* src/roff/troff/input.cpp (copy_file, vjustify [0])
	(transparent_file): Throw warning in category "missing" and
	ignore the request if given no arguments, instead of starting
	the document and producing device-independent output.

2024-09-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (has_arg): Improve and slightly
	optimize; return `false` immediately if the current token is a
	newline.  This is more responsive when running interactively,
	particularly with the new support for "peeking" ahead in the
	input stream by requests that read their arguments in copy mode
	{and in some other cases}.

2024-09-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp
	(encode_special_character_for_device_output): Fix off-by-one
	error in C-style string handling, which led to truncation of
	composite Unicode special character sequence in some cases.
	Fixes problem introduced by me in commit c8332c5c1a, 25 August.
	Thanks to Deri James for the report.

2024-08-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::choose_breakpoint): Fix
	code style nit: parenthesize complex expressions.

2024-08-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/\
	device-control-special-character-handling.sh:
	* src/roff/groff/tests/\
	device_control_escapes_express_basic_latin.sh: Revise test
	expectations.

	Continues fixing Savannah #63074.

2024-08-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Add test of diagnostics for attempts to write invalid
	things to device-independent output.  We don't generally write
	tests for invalid or incorrect input, but this particular area
	has been a sore and poorly understood point for a long time.

	* src/roff/groff/tests/unencodable-things-in-grout.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

	Continues fixing Savannah #63074.

2024-08-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp
	(encode_special_character_for_device_output): Demote diagnostics
	arising from non-encodable items from errors to warnings in
	category "char", since unlike most (all?) errors, GNU troff
	continues processing input on the control line or within the
	escape sequence argument.  Clarify language to make it clearer
	what is wrong with the rejected input.

	Continues fixing Savannah #63074.

2024-08-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp
	(encode_special_character_for_device_output): Improve detection
	of non-Unicode special character escape sequences.

2024-08-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Reject some nonsense in `\X` arguments.

	* src/roff/troff/input.cpp
	(encode_special_character_for_device_output): Reject tab,
	leader, and backspace characters in a `\X` device extension
	escape sequence argument.  Silently ignore hyphen indicator
	`\%`, dummy character `\&`, and zero-width break `\:` escape
	sequences in such arguments.

	Continues fixing Savannah #63074.

2024-08-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/unicode.cpp (valid_unicode_code_sequence):
	Tighten wording of error diagnostic.

2024-08-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (usage): Sync language with troff(1).

2024-08-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	Update with respect to Unicode 15.1.0.

	* src/libs/libgroff/uniuni.cpp:
	* src/utils/afmtodit/afmtodit.tables: Regenerate.

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

2024-08-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/make-uniuni: Fix code style nits.  Permit
	override via environment of `CPP` variable locating C
	preprocessor program.  Reduce `$0` to its "basename", and
	actually use, in the usage message, the variable set aside for
	that purpose.  Exit with status 2, not 1, on usage error.
	In generated C++ file:
	- Drop old-style Emacs file-local variable.
	- Use variable of type `size_t`, not `unsigned int`, to index
	  array.
	- Use libgroff's newfangled `array_length()` template function
	  to measure arrays.
	- Annotate why we retain a  C-style type cast.
	- Add editor aid comments.

2024-08-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/{fallbacks,tty}.tmac: Reorganize.  Move recently added
	fallbacks for "ascii" device from "fallbacks.tmac" to "tty.tmac"
	since they are particular to one output device.

2024-08-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Begin fixing Savannah #63074: support construction of
	arbitrary byte sequences in device control commands using groff
	special character sequence notation.

	* src/roff/troff/input.cpp
	(encode_special_character_for_device_output): Enhance.  When
	constructing the content of a device control escape sequence
	{and, in the future, that of a `device` request}, try harder to
	convert special characters into something meaningful.  If a
	special character identifier looks like something other than an
	attempt at a Unicode special character escape sequence already,
	try to convert it into one.  Otherwise, write any valid Unicode
	special character identifier {in groff notation: `\[u123ABC]`}
	to the macro being assembled {and thence the `special` node, and
	ultimately the `x X` command this node type produces}.
	* src/roff/groff/tests/\
	device-control-special-character-handling.sh: Update test
	expectations.  "\[u1F6C3]" is now correctly passed through, and
	"\[`a]" correctly converted to "\[u00E0]".  Shorten test cases a
	little.

2024-08-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp
	(encode_special_character_for_device_output): Require a
	non-empty special character escape sequence argument in _both_
	paths through the start of the function.

2024-08-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp: Trivially refactor.  Rename and
	boolify file-scoped variable `vertical_position_traps_flag` to
	`honor_vertical_position_traps`.  Initialize and assign to it
	using Boolean, not integer, literals.  Also parenthesize complex
	expressions.
	(macro_diversion::output, macro_diversion::space)
	(top_level_diversion::output, top_level_diversion::space)
	(top_level_diversion::begin_page, continue_page_eject)
	(vertical_position_traps, init_div_requests): Do it.

2024-08-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Boolify and rename member function of `node` class
	hierarchy to `did_space_merge()`.  Its former name,
	`merge_space()`, was ambiguous.  There is a difference between
	_testing_ a condition's truth value and _assigning_ one to it,
	and further with performing some sort of side effect.  {Without
	having read the foregoing, which did `merge_space()` mean?}
	Functional languages--including any language that distinguishes
	"pure" functions from those with side effects--are better at
	getting the programmer to consider these matters.

	* src/roff/troff/node.h
	(struct node)
	(class space_node)
	(class word_space_node)
	(class unbreakable_space_node):
	Rename `merge_space()` member function declarations to
	`did_space_merge()` and demote return type from `int` to `bool`.

	* src/roff/troff/node.cpp
	(node::did_space_merge)
	(space_node::did_space_merge)
	(word_space_node::did_space_merge)
	(unbreakable_space_node::did_space_merge):
	Rename `merge_space()` member function definition to
	`did_space_merge()` and demote return type from `int` to `bool`.

	* src/roff/troff/env.cpp (environment::space_newline)
	(environment::space): Update call sites.

2024-08-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Boolify and rename member function of `node` class
	hierarchy to `causes_tprint()`.  This function indicates whether
	the node requires certain formatter state (roughly, changes to
	the environment) to be flushed to output before the next node is
	written ("tprint"ed).

	* src/roff/troff/node.h
	(struct node)
	(class line_start_node)
	(class space_node)
	(class word_space_node)
	(class unbreakable_space_node)
	(class diverted_space_node)
	(class diverted_copy_file_node)
	(class extra_size_node)
	(class vertical_size_node)
	(class hmotion_node)
	(class space_char_hmotion_node)
	(class vmotion_node)
	(class hline_node)
	(class vline_node)
	(class dummy_node)
	(class transparent_dummy_node)
	(class zero_width_node)
	(class left_italic_corrected_node)
	(class overstrike_node)
	(class bracket_node)
	(class special_node)
	(class suppress_node)
	(class tag_node)
	(class draw_node):
	* src/roff/troff/node.cpp
	(class glyph_node)
	(class ligature_node)
	(class kern_pair_node)
	(class dbreak_node)
	(class hyphen_inhibitor_node)
	(class italic_corrected_node)
	(class break_char_node)
	(class composite_node):
	* src/roff/troff/input.cpp
	(class non_interpreted_char_node)
	(class token_node)
	(class non_interpreted_node):
	Rename `force_tprint()` member function declarations to
	`causes_tprint()` and demote return type from `int` to `bool`.

	* src/roff/troff/node.cpp
	(hyphen_inhibitor_node::causes_tprint)
	(node::causes_tprint)
	(space_node::causes_tprint)
	(special_node::causes_tprint)
	(tag_node::causes_tprint)
	(suppress_node::causes_tprint)
	(unbreakable_space_node::causes_tprint)
	(draw_node::causes_tprint)
	(extra_size_node::causes_tprint)
	(vertical_size_node::causes_tprint)
	(hmotion_node::causes_tprint)
	(space_char_hmotion_node::causes_tprint)
	(vmotion_node::causes_tprint)
	(hline_node::causes_tprint)
	(vline_node::causes_tprint)
	(dummy_node::causes_tprint)
	(transparent_dummy_node::causes_tprint)
	(zero_width_node::causes_tprint)
	(italic_corrected_node::causes_tprint)
	(left_italic_corrected_node::causes_tprint)
	(overstrike_node::causes_tprint)
	(bracket_node::causes_tprint)
	(composite_node::causes_tprint)
	(glyph_node::causes_tprint)
	(ligature_node::causes_tprint)
	(kern_pair_node::causes_tprint)
	(dbreak_node::causes_tprint)
	(break_char_node::causes_tprint)
	(line_start_node::causes_tprint)
	(word_space_node::causes_tprint)
	(diverted_space_node::causes_tprint)
	(diverted_copy_file_node::causes_tprint):
	* src/roff/troff/input.cpp
	(non_interpreted_char_node::causes_tprint)
	(token_node::causes_tprint)
	(non_interpreted_node::causes_tprint):
	Rename `force_tprint()` member function definition to
	`causes_tprint()` and demote return type from `int` to `bool`.

	* src/roff/troff/node.cpp
	(troff_output_file::really_print_line): Update call site.

2024-08-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Fix code style nits.
	(troff_output_file::put_char_width): Parenthesize complex
	expressions.  Memorization of the ~15-17-level C and C++
	operator precedence tables should be a matter of shame, not
	pride.
	(special_node::is_same_as): Use `static_cast` instead of C-style
	cast.

2024-08-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (class troff_output_file): Boolify
	final argument to `start_special` member function.
	(troff_output_file::start_special): Rename argument from
	`no_init_string` to `omit_command_prefix` and demote it from
	`int` to `bool`.
	(special_node::tprint_start): Update call site to use new name.

	* src/roff/troff/node.h (class special_node): Rename member
	variable from `no_init_string` to `lacks_command_prefix` and
	demote it from `int` to `bool`.
	* src/roff/troff/node.cpp (special_node::special_node): Update
	constructor initialization lists.
	(special_node::is_same_as): Update to use new name.
	(special_node::copy): Update constructor call.
	(special_node::tprint): Rename argument to `start_special` call
	on `troff_output_file` object: here is where the
	`lacks_command_prefix` property of the `special_node` becomes an
	instruction to the `troff_output_file` object to omit that
	prefix.

2024-08-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Boolify `troff_output_file` class.
	Demote member variables from `int` to `bool` and rename them.
	  `force_motion` -> `must_update_drawing_position`
	  `begun_page` -> `has_page_begun`
	(troff_output_file::really_print_line)
	(troff_output_file::do_motion)
	(troff_output_file::put_char_width)
	(troff_output_file::really_on)
	(troff_output_file::really_begin_page)
	(troff_output_file::really_copy_file)
	(troff_output_file::troff_output_file): Update names and assign
	Boolean, not integer, literals.

2024-08-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (class input_iterator)
	(input_iterator::input_iterator): Boolify.  Demote constructor
	argument, member variable `is_diversion`, and member functions
	`has_args`, `space_follows_arg`, `is_macro` `int` arguments or
	return types from `int` to `bool`.  Return Boolean, not integer,
	literals from these and from `set_location` and `next_file`
	member functions, the latter previously (partially) boolified.
	(class file_iterator): Boolify `seen_escape` member variable.
	Boolify and rename two others.
	  `popened` -> `was_popened`
	  `newline_flag` -> `seen_newline`
	Demote return type of `next_file` member function from `int` to
	`bool`.
	(file_iterator::file_iterator): Update initializer list of
	constructor accordingly.
	(file_iterator::close, file_iterator::next_file)
	(file_iterator::file, file_iterator::backtrace): ...and member
	function definitions to use new names and type literals.
	(class input_stack)
	(input_stack::space_follows_arg):
	Similarly boolify member function.
	(input_stack::pop_macro): Boolify local variable `is_macro`.
	(class string_iterator): Similarly demote type and rename member
	function.
	  `newline_flag` -> `seen_newline`
	(string_iterator::string_iterator): Update initializer list of
	constructor accordingly.  (And definition of another
	argumentless constructor.)
	(string_iterator::fill): ...and member function definition to
	use new name and type literal.
	(class string_iterator, string_iterator::is_diversion):
	Similarly boolify member function.
	(struct arg_list): Boolfy `space_follows` member variable.
	(arg_list::arg_list): ...and constructor.  Rename constructor
	argument from `s` to `b` to reflect its Boolean type.
	(class macro_iterator)
	(macro_iterator::space_follows_arg):
	(macro_iterator::macro_iterator)
	(macro_iterator::is_diversion): Similarly boolify member
	functions and use Boolean instead of integer literals.
	(macro_iterator::macro_iterator): Rename parameter from
	`init_args` to `want_arguments_initialized`.
	(macro_iterator::space_follows_arg): Parenthesize complex
	expression.

2024-08-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (class input_iterator): Boolify
	`is_file` member function.
	(class file_iterator): Boolify `is_file` member function and
	define in declaration...
	(file_iterator::is_file): ...instead of separately.

2024-08-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Demote `is_div` argument to `macro` constructor from
	`int` to `bool`.

	* src/roff/troff/request.h (class macro):
	* src/roff/troff/input.cpp (macro::macro): Do it.

2024-08-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Boolify return
	value and first argument of `get_location()` member functions.
	Use Boolean, not integer, literals in initializers and
	assignments.
	(class input_iterator, class file_iterator)
	(file_iterator::get_location, file_iterator::backtrace)
	(class input_stack, input_stack::get_location, macro::macro)
	(class string_iterator, string_iterator::get_location)
	(do_define_macro, get_file_line, lineno_reg::get_string)
	(writable_lineno_reg::get_value, filename_reg::get_string):
	Do it.

2024-08-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.h:
	* src/roff/troff/env.cpp (do_underline): Rename this...
	(configure_underlining): ...to this.

	* src/roff/troff/env.cpp (do_underline_special): Rename this...
	(configure_space_underlining): ...to this.  Now the argument is
	self-explanatory.

2024-08-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (main): Migrate `.T` register backing
	class from `readonly_text_register` to
	`readonly_boolean_register`.

2024-08-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (main): Trivially refactor.  Boolify
	and rename variables controlled by command-line options.  Use
	Boolean, not integer, literals in initializers and assignments.
	`iflag` -> `want_stdin_read_last`
	`tflag` -> `have_explicit_device_argument`
	`fflag` -> `have_explicit_default_family`
	`nflag` -> `have_explicit_first_page_number`
	`no_rc` -> `want_startup_macro_files_skipped`

2024-08-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (usage): If writing to the standard
	output stream (the user requested `--help`), include a paragraph
	descriptive of the program.
	* src/roff/troff/troff.1.man: Sync language with the foregoing.

2024-08-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/unicode.cpp (valid_unicode_code_sequence):
	Return a null pointer after `assert()` call, in the event
	someone compiles with `NDEBUG` defined.

2024-08-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.h: Trivially refactor `environment` class.
	Rename (private) member variables.
	`dummy` -> `is_dummy_env`
	`fill` -> `is_filling`
	`spreading` -> `is_spreading`
	`discarding` -> `is_discarding`
	* src/roff/troff/env.cpp (environment::add_char)
	(environment::add_node, environment::space_newline)
	(environment::space, environment::environment)
	(environment::copy, environment::get_fill, fill, no_fill)
	(environment::interrupt, environment::newline)
	(environment::output_line, environment::start_line)
	(environment::possibly_break_line)
	(environment::dump_troff_state, environment::do_break)
	(title, environment::print_env): Migrate to new names.

2024-08-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp
	(encode_special_character_for_device_output): New helper
	function takes over much of the tedium of
	`encode_character_for_device_output()`, for maintainability.
	(encode_char_for_device_output): Rename this...
	(encode_character_for_device_output): ...to this.  Use the new
	helper function when necessary.

2024-08-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_long_escape_parameters)
	(interpolate_arg, encode_char_for_device_output): Clarify error
	diagnostics.

2024-08-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/fallbacks.tmac: Spell fallbacks for Unicode special
	character escape sequences correctly, using four hexadecimal
	digits at minimum.  Problem introduced by me in commit
	81aa7b77c0, 10 October 2022.

2024-08-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/fallbacks.tmac: Spell fallbacks for Unicode special
	character escape sequences correctly, using uppercase
	hexadecimal digits.  Problem dates back to commit 48a13daf13, 24
	May 2012.

2024-08-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/unicode.h: Declare new constants `UNIBUFSZ` and
	`GLYPHBUFSZ` to help callers of `glyph_name_to_unicode()` and
	`unicode_to_glyph_name()` allocate sufficient memory to hold any
	returned special character identifiers.

2024-08-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Modify `valid_unicode_code_sequence()` function to
	take optional second parameter, a pointer to a character buffer
	in which an error message is stored if the character sequence in
	the first argument is invalid.  Declare new constant `ERRBUFSZ`
	to help any caller allocate sufficient memory to hold any such
	generated message.

	* src/include/unicode.h:
	* src/libs/libgroff/unicode.cpp (valid_unicode_code_sequence):
	Do it.  Also squawk about use of lowercase hexadecimal digits in
	Unicode special character identifiers, as these are invalid in
	groff.

2024-08-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (encode_char_for_device_output)
	(macro::append_str, do_suppress): Trivially refactor.  Compare
	`char` array elements to character literals rather than an
	integer literal with a C-style typecast to `char`.

	(macro_iterator::~macro_iterator, map_composite_character)
	(composite_glyph_name, charinfo::contains): Explicitly compare
	variable of pointer type to null pointer constant instead of
	letting it pun down to a Boolean.

2024-08-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Further refactor `charinfo` class.

	* src/roff/troff/charinfo.h (class charinfo): Rename enumeration
	constants.
	`BREAK_BEFORE`      -> `ALLOWS_BREAK_BEFORE`
	`BREAK_AFTER`       -> `ALLOWS_BREAK_AFTER`
	`TRANSPARENT`       -> `IS_TRANSPARENT_TO_END_OF_SENTENCE`
	`IGNORE_HCODES`     -> `IGNORES_SURROUNDING_HYPHENATION_CODES`
	`DONT_BREAK_BEFORE` -> `PROHIBITS_BREAK_BEFORE`
	`DONT_BREAK_AFTER`  -> `PROHIBITS_BREAK_AFTER`
	`INTER_CHAR_SPACE`  -> `IS_INTERWORD_SPACE`
	Rename member functions.
	`can_break_before()` -> `allows_break_before()`
	`can_break_after()` -> `allows_break_after()`
	`transparent()` -> `is_transparent_to_end_of_sentence()`
	`ignore_hcodes()` -> `ignores_surrounding_hyphenation_codes()`
	`prohibit_break_before()` -> `prohibits_break_before()`
	`prohibit_break_after()` -> `prohibits_break_after()`
	`inter_char_space()` -> `is_interword_space()`
	`numbered()` -> `is_numbered()`
	Demote the return types of the foregoing and `ends_sentence()`,
	`overlaps_vertically()`, `overlaps_horizontally()`,
	`first_time_not_found()`, `is_normal()`, `is_fallback()`, and
	`is_special()` from `int` to `bool`.  Update inline definitions.
	Parenthesize complex `return` expressions.
	* src/roff/troff/input.cpp (init_charset_table): Migrate to new
	enumeration constants.
	* src/roff/troff/node.cpp: Rename constants in `enum`
	`break_char_type` to match those in "charinfo.h".
	(troff_output_file::put_char_width, troff_output_file::put_char)
	(charinfo_node::ends_sentence, break_char_node::add_self)
	(make_glyph_node, node::add_char): Migrate to new enumeration
	constant and member function names.

2024-08-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Boolify `charinfo` class, renaming
	member functions and variables and demoting their (return) types
	from `int` to `bool`.  Use Boolean, not integer, literals in
	initializers and assignments.

	* src/roff/troff/charinfo.h:
	* src/roff/troff/input.cpp: Do it.
	`not_found` -> `is_not_found`
	`transparent_translate` -> `is_transparently_translatable`
	`translate_input` -> `translatable_as_input`
	`set_translation_input()` -> `make_translatable_as_input()`
	`get_translation_input()` -> `is_translatable_as_input()`

2024-08-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (charinfo_node::ends_sentence): Fix
	compiler warning.

	warning: control reaches end of non-void function
	[-Wreturn-type]

	Not the most penetrating exhibit of control flow analysis.

2024-08-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Check for correct and diagnostic-free behavior of
	`Rs`/`Re`-related macros such as `doc-reference-title-name`,
	`doc-city-name`, and `doc-date`.

	* tmac/tests/doc_Rs-works.sh: Do it.
	* tmac/tmac.am (tmac_TESTS): Run test.

2024-08-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/fallbacks.tmac: Define fallbacks for all special
	characters in "Accented characters" section of groff_char(7) for
	"ascii" output device.
	* tmac/tests/an_do-not-abbreviate-escape-using-TH-arguments.sh:
	Update test expectations.

2024-08-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* font/devascii/R.proto: Map `ad` (dieresis accent) special
	charcter as yet another alias of `"` on the ASCII output device.

2024-08-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (chop_macro): Clarify diagnostic.
	Say whether the argument being operated on is a "diversion" or a
	"macro or string", instead of the vague term "object", which is
	otherwise little-used in *roff discussions.

2024-08-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Boolify `macro` class, renaming
	member functions and variables and demoting their (return) types
	from `int` to `bool`.

	* src/roff/troff/request.h:
	* src/roff/troff/input.cpp: Do it.
	`empty_macro` -> `is_empty_macro`
	`is_a_diversion`
	`is_a_string`
	`empty()` -> `is_empty()`
	`is_diversion()`
	`is_string()`

	* src/roff/troff/input.cpp (macro::macro)
	(macro::clear_string_flag, macro::append, macro::is_empty): Use
	Boolean, not integer, literals in initializers and assignments.

2024-08-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (device_request): Don't write null
	characters to device control command commands (`x X` in
	device-independent output).  These can occur if one interpolates
	a diversion into the argument of a `device` request.

2024-08-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/pdf.tmac (pdfbookmark): Trivially refactor.  Rename
	`pdf:cleaned` string to `pdf:title` to reflect (1) its use in
	the emitted PDF device control command and (2) the fact that it
	is no longer sanitized by emitting it into a diversion and
	invoking `asciify` on that diversion.

2024-08-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/pdf.tmac (pdfclean): Drop unused macro.

2024-08-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* m4/groff.m4 (GROFF_WCOREFLAG): Include <stdlib.h> header file
	in test program, since it calls exit(3).  Thanks to Eli Schwartz
	for noting the problem.

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

2024-08-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (doc/groff-man-pages.pdf)
	(doc/groff-man-pages.utf8.txt): Run groff with "-K latin-1"
	option to avoid (harmless) error when formatting
	"groff_mmse.7".  Prompted by discussion with Deri in Savannah
	#66122.

	Fixes:

	troff:contrib/mm/groff_mmse.7:172: error: cannot translate
	character code 229 to special character 'oa' in
	device-independent output

2024-08-24  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Make compatible with ImageMagick (IM) < 7.0.

	Peter Schaffter discovered some problems with recent changes to
	gropdf and the `PDFPIC` macro: they were not fully compatible
	with ImageMagick 6.9, which he was using.  See <https://lists.
	gnu.org/archive/html/groff/2024-08/msg00044.html>.

	* src/devices/gropdf/gropdf.pl: One difference in IM 6 is that
	an alpha channel of all zeroes meant the image was opaque, but
	in 7 it is reversed and means the image is wholly transparent.

	This change is documented here:-

	<http://www.imagemagick.org/script/porting.php#alpha>

	"Alpha

	We support alpha now, previously opacity.  With alpha, a value
	of 0 means that the pixel does not have any coverage information
	and is transparent; i.e. there was no color contribution from
	any geometry because the geometry did not overlap this pixel.  A
	value of QuantumRange means that the pixel is opaque because the
	geometry completely overlapped the pixel.  As a consequence, in
	version 7, the PixelInfo structure member alpha has replaced the
	previous opacity member.  Another consequence is the alpha part
	of an sRGB value in hexadecimal notation is now reversed (e.g.
	#0000 is fully transparent)."

	This is now handled by gropdf.

	There was an undocumented (I thought it came as part of
	perlmagick--it doesn't) dependency on the module
	Image::ExifTool.  This is no longer used by gropdf, so not
	required.

	* tmac/pdfpic.tmac: Another issue was that identify(1) sometimes
	reports PDF sizes that do not match the page size--it seems to
	be attempting to report the size of the image embedded in the
	PDF.  pdfinfo(1) is thus now used first on files, which
	consistently reports the page size.  This imposes a slight time
	penalty since non-PDF files endure a (failed) pdfinfo run.

2024-08-24  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Handle preconv better.

	If preconv is used, it should also be run when generating
	forward references.

	* src/devices/gropdf/pdfmom.pl: Add preconv (if requested)
	to the pre-run that generates the `pdf:bm` strings.

2024-08-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* font/devps/ZDR: Regenerate.

2024-08-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* font/devps/ZD: Regenerate using updated dingbats.map.

	Fixes <https://savannah.gnu.org/bugs/?63018>.  Thanks to Deri
	James and Dave Kemper for (extensive) consultation.

2024-04-29  Deri James  <deri@chuzzlewit.myzen.co.uk>

	* font/devps/generate/dingbats.map: Update to map many more
	Unicode code points to Zapf Dingbats glyphs.

2024-08-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/afmtodit/afmtodit.pl: Improve information written to
	generated font description files in comments.  Name the AFM and
	map files used.  Report any options specified on the command
	line.  The idea is to make it easier for future (and current)
	maintainers to update such files because years pass between
	occurrences, and institutional memory is, if not lost, laborious
	to dredge up.  This practice might also assist users in
	producing groff description files for their own fonts.  Also
	write out a glyph's corresponding Unicode code point in the
	comment field only if one is defined.  Otherwise we get a
	comment marker followed by a tab and a newline, which Git marks
	in radioactive red.

	Begins addressing <https://savannah.gnu.org/bugs/?65697>.

2024-08-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/afmtodit/afmtodit.pl: Define `prog` scalar as only
	the "basename" of argv[0], making diagnostic and usage messages
	less garrulous; see Savannah #65110.  Add new `opt_w` scalar to
	separate it from existing `space_width` scalar so that we can
	report the options we were invoked with in a comment in the
	generated file.  Reorganize scalar representation of version
	information: new `groff_version`, which is populated at build
	time, new `short_version` which is `groff_version` stripped of
	any Git revision and partial hash information; new
	`version_stub` which holds the prefixed information identifying
	the program and project; new `output_version` which holds the
	stub and the short version; and existing `afmtodit_version`,
	which holds the stub and the (full) groff version.  Write
	`output_version` instead of `afmtodit_version` to the generated
	file.  Update call sites of `croak` and new `whine` subroutines
	to use `&` sigil and omit trailing newline.
	(croak): Assume responsibility for writing a newline at the end
	of the message.
	(whine): New subroutine throws a diagnostic marked "warning".
	Perl's `warn` output is ugly and not structured like other groff
	diagnostics.  Give it responsibility for emitting the name of
	the program.

2024-08-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::add_char): Declare local
	variable closer to point of use.  It's also a dead store, but
	demanded by our internal API.  (See `node::add_char()` in
	"node.cpp".)  Prompted by a report by Lukas Javorsky involving
	use of "SAST analyzers {combination of coverity, snyk, cppcheck,
	gcc, clang, shellcheck, unicontrol}".

	Also see <https://savannah.gnu.org/bugs/?66079>.

2024-08-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (get_delimited_name, do_if_request)
	(read_drawing_command, read_drawing_command_color_arguments):
	When complaining of mismatched or missing closing delimiter,
	report the identity of the delimiter we were expecting.
	* src/roff/troff/reg.cpp (alter_format): When complaining of
	invalid register format, list the valid ones.

2024-08-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Adjust and parallelize diagnostic
	message language.
	(get_char_for_escape_parameter): Say "argument", not
	"parameter".
	(do_zero_width_output): Identify the invalid token.
	(do_zero_width_output, charinfo_to_node_list): Characterize
	invalid token more precisely as part of the escape sequence's
	_argument_.

2024-08-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* NEWS: Add items for Deri's just-committed new features.

2024-06-22  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Add support for embedding bit-mapped images to a
	generated pdf.

	Currently gropdf supports the inclusion of pdf files as separate
	images, now many other image formats are supported. The pdf
	standard requires programs which process pdfs to handle embedded
	jpegs, and from version 1.5 jpeg2000 images are handled natively
	as well. (Current gropdf produces pdfs which conform to version
	1.7).

	The pdf standard supports a raw format with separate channels
	{RGB/CMYK/Grey} in 8/16/32 bit formats. This is used for other
	image formats. If there is a transparency channel it is
	converted to an 8-bit soft mask for the image.

	* src/devices/devpdf/gropdf.pl: add code to \X'pdf: pdfpic' to
	handle other image types, not just pdfs.

	* man/groff_tmac.5.man: document changes to PDFPIC macro.

	* src/devices/devpdf/gropdf.1.man: explain use of
	\X'pdf: pdfpic ...'

	* tmac/pdfpic.tmac: expand the PDFPIC macro to handle multiple
	image formats, not just embedding pdfs.

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

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* font/devcp1047/*: Recursively delete.
	* Makefile.am: Stop including the Automake file therein.
	* MANIFEST: De-document.
	* NEWS: Note withdrawal of "cp1047" device support.

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

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/cp1047.tmac: Delete.

	* tmac/tmac.am (TMACNORMALFILES): Stop shipping it.

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

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/nroff/nroff.sh: Drop support for "cp1047" output
	device.

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

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Drop support for "cp1047" output device.

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

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/doc.tmac: Drop support for "cp1047" output device.

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

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/eqnrc: Drop eqn(1) support for "cp1047" output device.

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

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/fallbacks.tmac:
	* tmac/troffrc:
	* tmac/tty.tmac: Drop "cp1047" output device support.

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

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* m4/groff.m4 (GROFF_EBCDIC, GROFF_OS390): Drop macros.
	* configure.ac: Stop using them.

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

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grops, grotty, libgroff, pic]: Drop EBCDIC support.

	* src/devices/grops/psrm.cpp:
	* src/devices/grotty/tty.cpp:
	* src/libs/libgroff/invalid.cpp:
	* src/preproc/pic/lex.cpp: Do it.

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

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.h: Drop input character definitions for
	CCSID (code page) 1047 (EBCDIC).

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

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Revise `\A` and `\B` escape
	sequences to no longer interpolate anything (not even "0" for
	"false") if they lexically don't even get as far as an opening
	delimiter; in such a case they are invalid.
	(do_name_test, do_expr_test): Do it.  Change return type from
	`bool` to a pointer to a constant `char`.  Return null pointer
	if there is no delimiter.  Otherwise return string instead of
	Boolean literals.
	(token::next): Handle null pointer returns from these functions.

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_overstrike, do_bracket)
	(do_device_control): Stop pushing a newline onto the input stack
	when encountering one; this character can no longer serve double
	duty as a delimiter and a formattable newline.
	(do_overstrike, do_bracket, do_name_test, do_expr_test)
	(do_zero_width_output, do_width, do_device_control): Similarly
	when finishing up with a delimited escape sequence with a
	malformed ending.

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix Savannah #66113 (misleading `\B` diagnostic).

	* src/roff/troff/input.cpp (do_expr_test): Advance the input
	token pointer at the end of the endless for loop, not the
	beginning, since `get_number_rigidly()` already left it at the
	next input character to be processed.  (Most parameterized
	escape sequence reading functions don't call an input reading
	function before entering this sort of loop, so they correctly
	advance the token pointer _first_.)

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix Savannah #63142 (newlines as delims).

	Withdraw support for newlines as escape sequence delimiters.
	Only a few (6) supported this, and the rationale behind it is
	unknown.  DWB 3.3 troff didn't behave this way in any case.

	* src/roff/troff/input.cpp (do_overstrike, do_bracket)
	(do_name_test, do_zero_width_output, do_width)
	(do_device_control): Do it.  As a bonus, check starting
	delimiters for these escape sequences (`\[obAZwX]`) for validity
	in general.
	(do_overstrike, do_bracket, do_zero_width_output): Avoid leaking
	memory when returning early; delete the `new` node we just
	allocated.
	(token:next): Be prepared for the `\b` and `\o` escape sequences
	to return a null pointer (if the sequence doesn't even validly
	get off the ground), as handlers for `\Z` and `\X` already are.

	* src/roff/groff/tests/\
	some_escapes_accept_newline_delimiters.sh: Delete.
	* src/roff/groff/groff.am (groff_TESTS): Drop test.

	* doc/groff.texi.in (Delimiters):
	* man/groff.7.man (Delimiters):
	* NEWS: De-document support for newlines as delimiters.

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

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::is_usable_as_delimiter):
	Generalize diagnostics.  Anything that's invalid as a "starting"
	delimiter is invalid as an ending one, too.  Also our
	terminology has been poorly paired; we say "closing" delimiter
	but not "opening" for its counterpart.  This fixes that.

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::is_usable_as_delimiter):
	Reject end-of-file as the starting delimiter for an escape
	sequence.

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (make_glyph_node): Don't throw a
	warning if `get_char_for_escape_parameter()` in "input.cpp"
	already threw an error for the same input token.  Also compare
	array elements of `const char` type to character, not integer,
	literals.

	Fixes <https://savannah.gnu.org/bugs/?46470>.  Thanks to Hanno
	Boeck for the report.

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Boolify and rename `compatible_flag`, demoting it from
	`int` to `bool` and calling it `want_att_compat`.  Initialize
	and assign to it using Boolean, not integer, literals.

	* src/roff/troff/input.cpp (read_escape_parameter)
	(read_increment_and_escape_parameter, get_copy, do_overstrike)
	(do_bracket, do_name_test, do_zero_width_output, token::next)
	(compatible, diagnose_invalid_identifier, do_request)
	(decode_args, do_define_string, define_nocomp_string)
	(do_define_macro, define_nocomp_macro, append_nocomp_macro)
	(read_size, get_delimited_name, read_title_parts)
	(do_device_control, do_if_request, main, init_input_requests)
	(lookup_request, charinfo_to_node_list): Do it.

	(class string_iterator): Boolify and rename
	`saved_compatible_flag` to `att_compat`.  Rename and retype
	member functions.

	(class input_iterator, class_string_iterator): Rename and retype
	member functions.
	`save_compatible_flag()` -> `set_att_compat()`
	`get_compatible_flag()` -> `get_att_compat()`
	The former now takes a `bool` argument instead of an `int`, and
	the latter returns a `bool` instead of an `int`.
	(input_stack::set_att_compat, input_stack::get_att_compat):
	Update implementations accordingly.
	(get_copy, token::next): Update call sites.

	(init_input_requests): Back the `.C` register with object of
	type `readonly_boolean_register` instead of `readonly_register`.

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Boolify and rename `ignoring`, demoting it from
	`int` to `bool` and calling it `want_input_ignored`.  Initialize
	and assign to it using Boolean, not integer, literals.

	* src/roff/troff/input.cpp (do_define_macro)
	(append_indirect_nocomp_macro, copy_mode_error): Do it.

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Boolify and rename `inhibit_errors`, demoting it from
	`int` to `bool` and calling it `want_errors_inhibited`.
	Initialize and assign to it using Boolean, not integer,
	literals.

	* src/roff/troff/input.cpp (do_expr_test, main, do_error): Do
	it.
	(do_expr_test): Similarly boolify and rename local variable
	`saved_inhibit_errors` -> `saved_want_errors_inhibited`.

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Boolify and rename `backtrace_flag`, demoting it from
	`int` to `bool` and calling it `want_backtraces`.  Initialize
	and assign to it using Boolean, not integer, literals.

	* src/roff/troff/input.cpp (main, do_error): Do it.

2024-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Boolify and rename `class_flag`, demoting it from `int`
	to `bool` and calling it `using_character_classes`.  Initialize
	and assign to it using Boolean, not integer, literals.

	* src/roff/troff/charinfo.h
	(charinfo::overlaps_horizontally, charinfo::overlaps_vertically)
	(charinfo::can_break_before, charinfo::can_break_after)
	(charinfo::ends_sentence, charinfo::transparent)
	(charinfo::ignore_hcodes)
	(charinfo::prohibit_break_before)
	(charinfo::prohibit_break_after)
	(charinfo::inter_char_space, charinfo::add_to_class):
	* src/roff/troff/input.cpp (get_flags): Do it.

2024-08-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.
	(do_zero_width): Rename this...
	(do_zero_width_output): ...to this.
	(token::next): Update call site.

2024-08-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_zero_width): Tweak `\Z`
	diagnostic output.

2024-08-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_drawing_command): Trivially
	refactor.  Boolify local variable `no_last_v`.  Rename local
	variable `err` to `had_error`.

2024-08-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_drawing_command): Demote
	diagnostic thrown on empty drawing command escape sequence
	argument list from error to warning in "missing" category.  I
	can imagine someone programmatically constructing a string to be
	passed to a `\D` escape sequence; such a string might be empty.

2024-08-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (read_drawing_command): Handle
	an invalid delimiter in a drawing command escape sequence `\D`
	the same as every other escape sequence that recognizes a
	restricted set of delimiters (`\h`, `\H`, `\l`, `\L`, `\N`,
	`\R`, `\s`, `\S`, `\v`, and `\x`): stop parsing immediately
	instead of consuming and discarding input until encountering a
	matching invalid delimiter, newline, or EOF.

2024-08-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename
	confusingly named functions that interpret *roff language input,
	not "nodes", a family of _groff_ class objects.
	(read_draw_node): Rename this...
	(read_drawing_command): ...to this.
	(read_color_draw_node): Rename this...
	(read_drawing_command_color_arguments): ...to this.

2024-08-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp (macro_diversion::macro_diversion):
	Handle member variables `diversion_trap` and
	`diversion_trap_post` in constructor's initializer list, for
	clarity and to ensure that they don't contain garbage.

2024-08-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/e.tmac (@M, $c): If the formatter is GNU troff,
	use value of its `.R` register instead of "10000" to indicate an
	arbitrary large integer.
	(EQ): Same, but in commented form; a formatter DoS attack is
	otherwise revealed.
	(TS): Similar; set line length to `.R` basic units minus 1n to
	avoid saturation warnings on output devices with a non-unit
	horizontal motion quantum.
	* tmac/html-end.tmac: Set page length to `.R` basic units minus
	1v to avoid saturation warnings on output devices with a
	non-unit vertical motion quantum (as the "html" device has).
	* tmac/man.ultrix (HB): Use value of `.R` register instead of
	"999" to indicate an arbitrary large integer.
	* tmac/psfig.tmac (F+):
	* tmac/s.tmac (cov*tl-au-print, ID, par@TL, par@AU, par@AI): Use
	value of `.R` register instead of "9999" to indicate an
	arbitrary large integer.

2024-08-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (init_input_requests): Initialize
	`.R` read-only register to `INT_MAX` instead of 10000.

	* doc/groff.texi.in (Built-in Registers):
	* man/groff.7.man (Read-only registers):
	* man/groff_diff.7.man (Altered registers): Document it.

	* doc/groff.texi.in (Manipulating Filling and Adjustment)
	(End-of-input Traps): Apply it to examples.

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

2024-08-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Support construction of read-only
	registers from integers.
	(class readonly_text_register): Declare constructor taking `int`
	argument.
	(readonly_text_register::readonly_text_register): Add it.
	(main): Use it to initialize `.T` register.
	(init_registers): Use it to initialize `.A` register.
	(init_input_requests): Use it to initialize `.g` and `.R`
	registers.

2024-08-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Slightly refactor.
	(do_overstrike): Rename local variable `on` to `osnode`.
	(do_bracket): Rename local variable `bn` to `bracketnode`.
	(do_expr_test): Demote return type from `int` to `bool`, and
	return Boolean, not integer, literals.
	(do_zero_width): Move declaration and initialization of `n`
	local unaccountably far from its point of use to prepare for
	shoveling of most of this function's body into a `for` loop,
	required by forthcoming fix for Savannah #63142.

2024-08-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: When throwing a warning diagnostic about a mismatched
	escape sequence delimiter, say what what we were expecting and
	what we got instead.

	* src/roff/troff/input.cpp (do_overstrike, do_bracket)
	(do_name_test, do_zero_width, do_width, do_device_control)
	(read_delimited_number, get_line_arg, do_register)
	(do_expr_test):
	* src/roff/troff/reg.cpp (inline_define_register [0]): Do it.

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

2024-08-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_name_test): Fix buglet in
	handling of newline as delimiter for the `\A`, `\w`, and `\Z`
	escape sequences.  An invalid C++ conditional resulted
	in a newline being interpreted both as the delimiter and as an
	input token, spuriously putting a space on the output.  Drop
	subsequent tautologous conditional: `tok != start_token` will
	always evaluate true because `tok.is_eof()` is true and
	`start_token` cannot be an EOF.

	Before:

	$ printf 'foo\A\naz\nbar\n' | groff -a
	<beginning of page>
	foo1 bar

	After:

	$ printf 'foo\A\naz\nbar\n' | ./build/test-groff -a
	<beginning of page>
	foo1bar

	* src/roff/groff/tests/\
	some_escapes_accept_newline_delimiters.sh: Update test
	expectations.

2024-08-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (interpolate_register): Add assertion
	to blow up on null pointer dereference.

2024-08-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix code style nits.

	* src/roff/troff/input.cpp (length_request)
	(interpolate_number_format, do_register): Use `static_cast`
	instead of C-style cast on dictionary values.
	(do_overstrike, do_bracket, do_zero_width, token::next)
	(length_request, interpolate_number_format, do_register):
	Explicitly compare variable of pointer type to null pointer
	constant instead of letting it pun down to a Boolean.
	(do_register, token::next): Reorder equality comparison to avoid
	inadvertent lvalue assignment.
	(do_error): Add parentheses to complex expression.

2024-08-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Slightly refactor; boolify a static function.

	* src/roff/troff/input.cpp (get_line_arg): Demote return type
	from `int` to `bool`.  Return Boolean, not integer, literals.

2024-08-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/reg.cpp (define_register): Warn when garbage
	encountered in numeric expression argument to `nr` request.

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

2024-08-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `get_number()` to
	`read_measurement()`.  Part of the idea here is to use the verb
	"read" to suggest that the function advances the token pointer
	through the input stream (and it does).  Another part is to
	reduce confusion, since the class `charinfo` has an unrelated
	member function `get_number()`.

	* src/roff/troff/token.h (get_number):
	* src/roff/troff/number.cpp (get_number): Rename this...
	* src/roff/troff/token.h (read_measurement):
	* src/roff/troff/number.cpp (read_measurement): ...to this.

	* src/roff/troff/number.cpp (read_measurement): Update
	self-reference in assertion message.

	* src/roff/troff/env.cpp (point_size):
	* src/roff/troff/input.cpp (get_color_element)
	(read_delimited_number, get_line_arg, read_size, do_register)
	(do_if_request, evaluate_expression):
	* src/roff/troff/node.cpp (embolden_font)
	(configure_track_kerning, constantly_space_font):
	* src/roff/troff/reg.cpp (define_register)
	(inline_define_register [0]): Update call sites.

2024-08-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/groff.texi.in (Page Location Traps): Correct erroneous
	claim; the `.t` register does not interpolate the maximum
	representable integer in a diversion when there is no pending
	diversion trap if the output device does not have a vertical
	resolution of "1" ("ps" does; "utf8" doesn't).

	Problem introduced by me in commit 18697e757c, 22 November 2020.
	Thanks to Dave Kemper for the discussion in Savannah #63587.

2024-08-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp (is_valid_term): When reading an
	overlong integer literal, save the value corresponding to the
	longest valid digit sequence, and use that if overflow occurs.
	(scale): Demote "numeric overflow" errors to "integer value
	saturated" warnings in category "range".

	* src/roff/troff/hvunits.h (vunits::to_units)
	(class vunits: operator +, operator -, operator *):
	(hunits::to_units)
	(class hunits: operator +, operator -, operator *):
	* src/roff/troff/number.cpp (vunits::vunits, hunits::hunits):
	Impose saturating arithmetic on overflowing operations.  Demote
	overflow from error, throwing warning in "range" category if
	overflow would occur, and describe integer result as "saturated"
	rather than "wrapped".

	* src/roff/groff/tests/arithmetic-works.sh: Enable warnings in
	"range" category.  Update test expectations.  Drop check of
	operation that is no longer meaningful with refactored
	arithmetic parsing.

	* doc/groff.texi.in (Numeric Expressions):
	* man/groff.7.man (Numeric expressions):
	* NEWS: Document it.

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

2024-08-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp (get_vunits, get_hunts, get_number)
	(get_integer): Clarify diagnostic when integer arithmetic wraps.

2024-08-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix code style nits.

	* src/roff/troff/reg.cpp (number_value_to_ascii): Add
	parentheses to complex expressions.
	(number_value_to_ascii): Assign character, not integer, literal
	to element of array of `char` type.
	(inline_define_register [0], define_register, set_register)
	(look_up_register, alter_format): Use `static_cast` instead of
	C-style cast on dictionary values.
	(inline_define_register [0], define_register, set_register)
	(look_up_register, alter_format): Reorder equality comparisons
	to avoid inadvertent lvalue assignment.

2024-08-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Clear array memory when allocating it from the heap.
	Prompted by Lukas Javorsky's static-analysis-driven report in
	Savannah #66081.

	* src/roff/troff/env.cpp (override_sizes, tab_stops::to_string)
	(add_hyphenation_exceptions, hyphen_trie::insert_hyphenation):
	* src/roff/troff/input.cpp (read_long_escape_parameters)
	(token::next, do_get_long_name, get_delimited_name, pipe_source)
	(read_string, pipe_output, open_macro_package)
	(do_register_assignment, do_string_assignment, copy_mode_error):
	Do it.

2024-08-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix code style nits.

	* src/roff/troff/env.cpp (override_sizes): Add parentheses to
	complex expressions.
	(add_hyphenation_exceptions): Reorder equality comparisons to
	avoid inadvertent lvalue assignment.
	(add_hyphenation_exceptions, hyphen_trie::insert_hyphenation):
	Use `static_cast` instead of C-style cast on dictionary values.

	* src/roff/troff/env.cpp (add_hyphenation_exceptions)
	(hyphen_trie::insert_hyphenation):
	* src/roff/troff/input.cpp (read_two_char_escape_parameter)
	(do_get_long_name): Assign character, not integer, literal to
	element of array of `char` type.

	* src/roff/troff/input.cpp (read_long_escape_parameters): Demote
	local variable `have_char` from `int` to `bool` and assign to it
	with Boolean, not integer, literals.

	* src/roff/troff/input.cpp (do_get_long_name): Explcitly
	express size of array element type in argument to `memcpy()`.

2024-08-14  Lukas Javorsky <ljavorsk@redhat.com>

	* src/roff/troff/env.cpp (override_sizes): Zero out
	heap-allocated memory prior to use.  If `strtok()` returns a
	null pointer, we break early from the `for` loop before
	populating it.  The only other case where we break out of the
	loop is when `lower` is 0, and we do so only after adding this 0
	to `sizes`.  Since this memory is then passed to
	`font_size::init_size_table()`, which uses a zero integer to
	detect the end of the list, we could then access uninitialized
	memory.  [The user is not required to supply a zero argument to
	the `sizes` request.  I also revised the patch to use memset(3)
	instead of (an empty) value initializer, which is a C++03
	feature.  --GBR]

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

2024-08-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (override_sizes): Refer to size range
	as "invalid", not "bad", in warning diagnostic.

2024-08-14  Lukas Javorsky <ljavorsk@redhat.com>

	* src/roff/troff/input.cpp (token::add_to_zero_width_node_list):
	Initialize stack-allocated variable that is not populated by all
	paths through this function.

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

2024-08-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Slightly refactor: boolify.

	* src/roff/troff/node.h (struct hyphen_list): Demote `hyphen`
	member from `unsigned char` to `bool` and rename it to
	`is_hyphen'.
	(hyphen_list::hyphen_list): Migrate struct initializer list to
	new name and Boolean literal.
	* src/roff/troff/env.cpp (hyphenate): Update assignments to use
	new name and Boolean, not integer, literals.
	* src/roff/troff/node.cpp (glyph_node::add_self)
	(composite_node::add_self): Update comparisons to use new name.

	* src/roff/troff/node.h (struct hyphen_list): Boolify. Demote
	`breakable` member from `unsigned char` to `bool` and rename it
	to `is_breakable'.
	(hyphen_list::hyphen_list): Migrate struct initializer list to
	new name and Boolean literal.
	* src/roff/troff/env.cpp (environment::hyphenate_line):
	* src/roff/troff/node.cpp (break_char_node::add_self): Update
	comparisons.

	* src/roff/troff/node.cpp (break_char_node::add_self): Demote
	`have_space_node` local variable from `int` to `bool`.

	* src/roff/troff/node.h (struct node, class hmotion_node):
	Boolify.  Demote member function `set_unformat_flag()` and
	member variable `unformat` from `int` to `bool`.  These could
	use renaming, but `make_unformattable()` and `is_unformattable`
	would be terribly misleading.
	* src/roff/troff/node.cpp (node::set_unformat_flag)
	(word_space_node::set_unformat_flag)
	(vertical_size_node::set_unformat_flag)
	(hmotion_node::set_unformat_flag): Demote return type and use
	Boolean literals for assignments and return values.
	(word_space_node::word_space_node): Use Boolean literal in
	constructor's initializer list.
	(word_space_node::word_space_node): Update data type in
	constructor's argument list.

	* src/roff/troff/node.h (class hmotion_node): Demote `was_tab`
	member from `unsigned char` to `bool`.  Use Boolean literals for
	it in constructors' initializer lists.

	* src/roff/troff/node.h (struct node): Demote `is_inner`
	argument from `int` to `bool` and assign to it using Boolean,
	not integer, literals.

2024-08-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/token.h (token:ch): Return character instead
	of integer literal for this inline function of `(unsigned) char`
	type.

2024-08-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Boolify remaining `token` class member functions that
	need it.

	* src/roff/troff/token.h (class token): Demote declarations of
	`operator==`, `operator!=`, `add_to_zero_width_node_list`.
	* src/roff/troff/input.cpp (token::operator==)
	(token::operator!=, token::add_to_zero_width_node_list): Do it.

2024-08-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Throw diagnostic in event of a diversion's contents
	overflowing its maximum vertical position.  We can't do anything
	sensible in this case, so make it a fatal error.  (It's also
	more likely that your host environment will exhaust memory
	available to the `troff` process before encountering this
	problem.)

	* src/roff/troff/div.cpp: New constant symbol
	`DIVERSION_LENGTH_MAX` defines the maximum permissible vertical
	size of a diversion in basic units.  Presently, it is `INT_MAX`.
	(macro_diversion::distance_to_next_trap): When there is no
	diversion trap, or its position has already been passed, report
	the distance to `DIVERSION_LENGTH_MAX` (rather than `INT_MAX`)
	divided by the vertical resolution.
	(macro_diversion::output): Check for overflow when incrementing
	vertical position upon writing out a line, and emit fatal error
	diagnostic if it occurs.

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

2024-08-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/e.tmac (n1, n2): Invoke the renamed `po` request
	directly, not our wrapper for it.

	Fixes a latent issue with saturating arithmetic.

2024-08-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp
	(macro_diversion::distance_to_next_trap): Return a value
	quantized to the vertical resolution of the output device.  Add
	an `assert()` for a paranoia's sake, since there is an integer
	arithmetic land mine here.

2024-08-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/arithmetic-works.sh: Add more test cases.

2024-08-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (troff_output_file::flush_tbuf): Add
	assertion: the type size should be positive.

2024-08-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/symbol.h (class symbol): Boolify `is_null()` and
	`is_empty()` member functions.

2024-08-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Rename `WARN_TOTAL` symbol to `WARN_MAX` for
	consistency with other GNU troff enumerated types.

	* src/roff/troff/troff.h:
	* src/roff/troff/input.cpp: Do it.

	* src/roff/troff/input.cpp (warn_request): Clarify warning
	diagnostic.

2024-08-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp
	(top_level_diversion::transparent_output, continue_page_eject)
	(top_level_diversion::set_diversion_trap)
	(top_level_diversion::clear_diversion_trap):
	* src/roff/troff/input.cpp (transparent_translate)
	(get_delimited_name, do_source, pipe_source, pipe_output,
	transparent_file, charinfo_to_node_list):
	* src/roff/troff/node.cpp (troff_output_file::really_copy_file):
	* src/roff/troff/reg.cpp (reg::increment, reg::decrement)
	(reg::set_increment, reg::alter_format, reg::set_value): Clarify
	error diagnostics, and stop using contractions in wording.

2024-08-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp
	(top_level_diversion::transparent_output):
	* src/roff/troff/input.cpp (transparent_translate): Drop
	`GROFF_ENABLE_TRANSPARENCY_WARNINGS` environment variable
	kludge.  The underlying problems are better understood now and
	giving the user tools to fix them is on the horizon.

2024-08-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Drop Autoconf-guarded inclusion of
	<unistd.h>.  Jugding by the groff 1.16 change log this appears
	to have to do with the use of wait(2)-related macros, but
	dropping it doesn't break a glibc-based build, and our
	"src/include/nonposix.h" header has the same guarded inclusion,
	so we should still get it on unusual systems.  If a build breaks
	due to this change, we should document the specific symbol(s) we
	need and/or rely on gnulib for them.

2024-08-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Replace club with scalpel when including standard C
	library header files.

	* src/roff/troff/troff.h: Drop standard C library header file
	inclusions altogether.  This exhibited an old style of writing C
	{and C++?} where your multi-translation unit program would have
	an overarching header file, included by all your *.c files, and
	into which you stuffed all of your libc header file dependencies
	without documenting which symbols you actually needed or where.
	This tended to lead to excessive inclusion, and that tendency
	bore out here.  On a glibc-based system, GNU troff doesn't need
	4 of the 6 headers formerly #included here at all.  And we now
	use gnulib to help us with portability, which was not the case
	in 1989.

	* src/roff/troff/env.cpp:
	* src/roff/troff/input.cpp:
	* src/roff/troff/node.cpp: Include <errno.h> and annotate why.
	* src/roff/troff/reg.cpp: Include <assert.h> and annotate why.

2024-08-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_string_case_transform): Use
	libgroff's `cmupper()` and `cmlower()` functions instead of
	going directly to the standard C library's `to{upp,low}er()`.

2024-08-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/troff.h: Slightly refactor; boolify and rename
	some global `int`s.
	- `suppress_output_flag` -> `want_output_suppressed`
	- `color_flag` -> `want_color_output`
	- `is_html` -> `is_writing_html`
	* src/roff/troff/env.cpp (environment::newline)
	(environment::make_tag, environment::construct_state)
	(environment::construct_format_state)
	(environment::construct_new_line_state):
	* src/roff/troff/input.cpp ([top level], main):
	* src/roff/troff/mtsm.cpp (statem:add_tag_ta, mtsm::push_state)
	(mtsm::pop_state, mtsm::flush, mtsm:changed):
	* src/roff/troff/node.cpp (suppress_node::tprint)
	(space_char_hmotion_node::tprint)
	(unbreakable_space_node::tprint): Migrate `is_html`.
	* src/roff/troff/input.cpp ([top level], activate_color, main):
	(init_input_requests):
	* src/roff/troff/node.cpp (troff_output_file::fill_color)
	(troff_output_file::glyph_color): Migrate `color_flag`.
	* src/roff/troff/input.cpp (init_input_requests): Use
	`readonly_boolean_register` class to expose `want_color_output`
	to documents, not `readonly_register`.
	* src/roff/troff/input.cpp ([top level], main):
	* src/roff/troff/node.cpp (init_output): Migrate
	`suppress_output_flag`.

2024-08-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (hyphenation_patterns_file_code):
	Throw error warning of future withdrawal.

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

2024-08-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tty.tmac: Revise fallback character for `\[em]` on UTF-8
	device to make it more like a true em dash, taking up two
	character cells.

2024-08-09  Dave Kemper <saint.snit@gmail.com>

	* tmac/andoc.tmac: Annotate "unnecessary" control lines.

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

2024-08-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/troffrc: Define macro `troffrc*trap` to throw a
	diagnostic message complaining of a text line in a startup file.
	Make it the blank line and leading space macro.
	* tmac/troffrc-end: Clear blank line and leading space macros.
	Delete `troffrc*trap`.

	Inspired by an Arch Linux blunder <https://gitlab.archlinux.org/
	archlinux/packaging/packages/groff/-/commit/
	db8623565d8e14d4c9c5c3a67e1c8647c34e3d48>.  I've made similar
	ones myself.

2024-08-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (input_stack::get)
	(process_input_stack): Trivially refactor.  Rename global
	`old_have_formattable_input` to
	`have_formattable_input_on_interrupted_line`.  Yes, this
	identifier is as long as your arm, but it has a highly
	specialized purpose and needs to be intelligible in context.

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

	* tmac/doc-old.tmac: Migrate from font name "C" to "CR", fixing
	warnings.

	  troff:.../doc-old.tmac:...: warning: cannot select font 'C'

2024-08-08  Bjarni Ingi Gislason <bjarniig@simnet.is>

	* tmac/doc-old.tmac: Drop spurious dot in control line.

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

2024-08-08  Dave Kemper <saint.snit@gmail.com>

	* tmac/tty.tmac: Revise fallback character for • (bullet) to
	asterisk, affecting "ascii" and "latin1" output devices.

	Fixes <https://savannah.gnu.org/bugs/?56015>.  Thanks to Jeff
	Conrad for the report.

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

	* tmac/tty.tmac: Revise fallback characters for ± and ∓ to
	separate plus and minus signs with a slash, and to use actual
	minus sign glyphs(!).

	Prompted by discussion with Alex Colomar, Vincent Lefevre, and
	Dave Kemper; see <https://lists.gnu.org/archive/html/groff/
	2024-08/msg00016.html>.

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

	[troff]: Implement new `phcode` request.

	* src/roff/troff/input.cpp (report_hyphenation_codes): Add.
	(init_input_requests): Wire up `phcode` request name to
	`report_hyphenation_codes()`.

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

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

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

	* src/roff/troff/input.cpp (set_hyphenation_codes): Handle the
	common case (copying the existing hyphenation code of one
	character to another) first.  Support clearing a character's
	hyphenation code by copying that of a character that lacks one.
	Reorganize for clarity, and add comments.

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

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

	* src/roff/troff/env.cpp (hyphenate): Slightly refactor.
	Reorder equality comparison to avoid inadvertent lvalue
	assignment.  `memset()` the stack-allocated character array
	`hbuf` with null terminators as a paranoid hedge.  Rename `buf`
	to `bufp`, since it is a pointer and moreover used as a cursor
	into the word that is a candidate for hyphenation.  Pointers and
	arrays are _not_ synonymous in C/C++; see Chapter 4, _Expert C
	Programming: Deep C Secrets_, by van der Linden (1994).  Add
	assertions for further paranoia.  Use `static_cast` instead of
	C-style cast on dictionary values.  `memset()` the
	stack-allocated integer array `word` with zeroes.

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

	[troff]: Fix code style nits.

	* src/roff/troff/input.cpp (temp_iterator::temp_iterator):
	Explicitly cast return value of `memcpy()` to `void`.
	(make_temp_iterator): Reorder comparison with null pointer to
	avoid inadvertent lvalue assignment.

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

	[troff]: Fix Savannah #66052 (2/2).

	* src/roff/troff/input.cpp (temp_iterator::temp_iterator):
	Prevent potential heap overreads.  Ensure that temporary
	iterators are null-terminated when constructing them.

	Fixes <https://savannah.gnu.org/bugs/?66052> (2/2).  Thanks to
	Lukas Javorsky for identifying the problem using "SAST analyzers
	{combination of coverity, snyk, cppcheck, gcc, clang,
	shellcheck, unicontrol}".

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

	[troff]: Fix Savannah #66052 (1/2).

	* src/roff/troff/env.cpp (hyphenate): Fix potential one-byte
	stack overwrite if attempting to hyphenate a 256-letter sequence
	within a word.  Reserve space for null terminator in `hbuf`
	character array.  Initially, this isn't necessary because the
	array is simply walked to normalize hyphenation codes by their
	equivalence classes.  However, when we subsequently look up the
	{possibly partial} word in the exception dictionaries, `hbuf`
	{or a pointer into it} needs to be treatable as a C string, thus
	null-terminated.  Respell already correct expression later in
	the code to reinforce similarity.

	Fixes <https://savannah.gnu.org/bugs/?66052> (1/2).  Thanks to
	Lukas Javorsky for identifying the problem using "SAST analyzers
	{combination of coverity, snyk, cppcheck, gcc, clang,
	shellcheck, unicontrol}".

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

	* src/roff/troff/node.cpp (set_font_specific_special_fonts):
	Adjust diagnostic message for clarity (and relative brevity).

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

	* tmac/{en,it}.tmac: Load "latin1.tmac".
	* tmac/latin5.tmac: Add case mapping for dotless I.

	Continues commit 0629380a9d, 3 August.  Thanks to Dave Kemper
	for the discussion.

2024-08-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	[groff]: Drop tests of "cp1047" output device.

	* src/roff/groff/tests/ab_works.sh:
	* src/roff/groff/tests/backslash-X-works.sh:
	* src/roff/groff/tests/\
	  backslash-exclamation-early-does-not-fail.sh:
	* src/roff/groff/tests/cf-request-early-does-not-fail.sh:
	* src/roff/groff/tests/device-request-works.sh:
	* src/roff/groff/tests/output-request-works.sh: Do it.

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

2024-08-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/ps.tmac: Drop `\[S ,]` and `\[s ,]` fallback character
	definitions and hyphenation code assignments.

	* NEWS: Document this.

	Thanks to Werner Lemberg for noting the issue in <https://lists.
	gnu.org/archive/html/groff/2024-08/msg00001.html>.

2024-08-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	tmac/*: Refactor hyphenation code declarations.

	Move `hcode` invocations from language-specific macro files
	{those that define a "groff locale", such as "english" or
	"german"} to the macro files that support 8-bit character
	encodings, because in the formatter, hyphenation codes are
	global, not environment-specific like other hyphenation data.
	{That design decision is worth reconsidering in the future,
	but feels less urgent than adding UTF-8 input support to the
	formatter, which may obviate some encoding-related issues.}

	* tmac/LOCALIZATION: Relieve groff locale contributor of
	hyphenation code definition duty.
	* tmac/de.tmac: Move Latin-1 hyphenation code definitions from
	here...
	* tmac/latin1.tmac: ...to here.  Reorganize and cover _every_
	letter glyph in ISO 8859-1, including Icelandic letters that
	German hyphenation patterns don't require.
	* tmac/ru.tmac: Move KOI8-R hyphenation code definitions from
	here...
	* tmac/koi8-r.tmac: ...to here.
	* tmac/latin2.tmac: Define Latin-2 hyphenation codes.
	* tmac/latin5.tmac: Define Latin-5 hyphenation codes.  Include
	the notorious special case for the Turkish capital dotted I, and
	annotate it for migration in the event we ever get a "tr.tmac"
	file, because this is a language-specific case mapping, not one
	strictly implied by the character encoding.
	* tmac/latin9.tmac: Define Latin-9 (ISO 8859-15) hyphenation
	codes.

	Fixes <https://savannah.gnu.org/bugs/?59397>.  Thanks to Werner
	Lemberg for the discussion in <https://lists.gnu.org/archive/
	html/groff/2024-08/msg00001.html>.

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

	* src/roff/troff/input.cpp (set_hyphenation_codes): Accept a
	special character as a source for hyphenation code assignment.

	* doc/groff.texi.in (Manipulating Hyphenation) <hcode>:
	* man/groff_diff.7.man (New requests) <hcode>: Document loosened
	restriction.

	Fixes <https://savannah.gnu.org/bugs/?66054>.  Thanks to Carsten
	Kunze for the report and Dave Kemper for a test case that
	clarified matters.

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

	Regression-test Savannah #66054.

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

2024-08-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (set_hyphenation_code): Do more input
	validation of `hcode` request arguments.  Handle case where an
	argument is an escape sequence (but not a special character)
	ourselves instead of delegating it to `token::get_char()`.
	Throw errors (and stop processing arguments) when {1} the
	destination character is a numeral; {2} the destination
	character is a (non-special-character) escape sequence; {3} the
	source character is a numeral; or {4} the source character is a
	{non-special-character} escape sequence.

	* doc/groff.texi.in (Manipulating Hyphenation) <hcode>:
	* man/groff_diff.7.man (New requests) <hcode>: Document that the
	request aborts processing its arguments upon encountering an
	invalid one.

	Continues <https://savannah.gnu.org/bugs/?66040>.  Thanks to
	Dave Kemper for further discussion.

2024-08-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/groff.texi.in (Manipulating Hyphenation) <hcode>:
	* man/groff_diff.7.man (New requests) <hcode>: Remove claim that
	ran out ahead of ongoing code changes.  A special character that
	has already been assigned a hyphenation code is not _yet_ a
	valid source for another character's hyphenation code.

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

	* tmac/an.tmac (HP): The `mS` extension register has changed its
	meaning (commit f680c55d38, 13 June) such that it is no longer a
	reliable indicator of whether the deprecation warning for this
	macro should be suppressed, so stop suppressing a deprecation
	warning based on its value.  In fact, stop issuing the
	deprecation warning altogether.  (See <https://
	lists.gnu.org/archive/html/bug-ncurses/2024-04/msg00027.html>.)

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

	* src/roff/troff/div.cpp (page_length):
	* src/roff/troff/env.cpp (line_length, title_length): Tweak
	diagnostic to say "computed" rather than "invalid", because
	while the value we're complaining about _is_ invalid, it is also
	a numeric expression that may have traveled a great distance
	through the alimentary canal of GNU troff's arithmetic
	evaluator, and bear little resemblance to what the user typed in
	a source document.  Among other things, we no longer have any
	idea what scaling units were supplied, but can report
	measurements only in basic units.

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

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

	* doc/groff.texi.in (Manipulating Hyphenation): Fix incorrect
	claim and expand discussion.  A special character _can_ be an
	argument to the `hcode` request, and this has been true for over
	20 years (for example, in "tmac/ps.tmac").  Problem dates back
	to commit bd66717ef7, 16 April 2001.

	* man/groff.7.man (Request short reference):
	* man/groff_diff.7.man (New requests): Sync language with our
	Texinfo manual, and clarify.

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

	* src/roff/troff/input.cpp (set_hyphenation_code): Restore
	diagnostic message when attempting to assign the hyphenation
	code of a special character to another character (special or
	ordinary).  Also initialize local variable much closer to where
	we test its value, for readability.

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

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

	* src/roff/troff/number.cpp (get_vunits, get_hunits, get_number)
	(get_integer): Align assertion error messages with function
	names.

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

	* src/roff/troff/number.cpp (is_valid_expression_start): Fix
	missing space in diagnostic message.

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

	* src/roff/troff/number.cpp (vunits::vunits, hunits::hunits):
	Migrate to C23 checked arithmetic macros.  Throw error if
	addition overflows.

	Fixes <https://savannah.gnu.org/bugs/?64301>.  (For real this
	time, fingers crossed.)

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

	* src/roff/groff/tests/arithmetic-works.sh: Add more tests.

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

	* src/roff/troff/number.cpp (vunits::vunits, hunits::hunits):
	Move common subexpression to a temporary variable to prepare for
	reuse in C23 checked artihmetic macros.

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

	[troff]: Enforce minimum page length.

	* src/roff/troff/div.cpp (page_length): Clamp `pl` request
	argument to the output device's vertical resolution (similarly
	to the way `ll` and `lt` behave).

	* doc/groff.texi.in (Page Layout):
	* NEWS: Document this.

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

	* src/roff/troff/env.cpp (line_length, title_length): Drop use
	of needless temporary variable `minimum_length`.  Use global
	variable `hresolution` instead of static class member variable
	`font::hor`.  Clarify wording of warning diagnostic message when
	{title} line length invalid.

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

	* src/utils/grog/grog.pl (interpret_line): Fix logic error; set
	Boolean scalar `have_seen_first_macro_call` _after_ testing it,
	not before, avoiding its tautological truth.
	(infer_man_or_ms_package): Drop `TH` from list of "unique"
	man(7) macro names.  It isn't; most full-service macro packages
	use it to manage tbl(1) headings, and we already have special
	logic for handling it as the first call in a page anyway (where
	it is overwhelmingly idiomatic of a man(7) document).

	Fixes <https://savannah.gnu.org/bugs/?66006>.  Thanks to Morten
	Bo Johansen for the report.

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

	Regression-test Savannah #66006.

	* src/utils/grog/tests/avoid-man-fakeout.sh: Do it.
	* src/utils/grog/grog.am (grog_TESTS): Run test.

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

	* src/roff/troff/input.cpp (is_char_usable_as_delimiter): Reject
	`|`.

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

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

	Add test of *roff arithmetic.

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

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

	[troff]: Prevent traps on overflowing integer arithmetic.

	* bootstrap.conf: Add "stdckdint" to `gnulib_modules`.
	* src/roff/troff/number.cpp: Include `config.h` and
	`stdckdint.h` headers.
	(get_number, get_integer, is_valid_expression): Use `ckd_add()`,
	`ckd_sub()`, and `ckd_mul()` instead of primitive operations,
	and throw error diagnostic if arithmetic wraps.
	(is_valid_expression): Remove manual detection of overflow.
	(get_vunits, get_hunits): Use `ckd_add()` (with temporary
	variable, annotating why) instead of primitive operation, and
	throw error diagnostic if arithmetic wraps.
	(is_valid_term): When parsing integer literals, remove manual
	detection of overflow, relying on `ckd_mul()` and `ckd_add()` to
	indicate it.  When an overflowing literal is encountered, skip
	excess digits.  This is a behavior change, albeit an esoteric
	one; evaluation of a numeric term no longer aborts in this
	scenario.  When applying the *roff `|` boundary-relative motion
	operator, remove manual detection of overflow, relying on
	`ckd_sub()` to indicate it, and store result to temporary
	variable in case it overflows and must be discarded.  Otherwise,
	copy temporary to the storage for the term being interpreted.
	When negating a term, remove manual detection of negation of
	`INT_MIN` (guaranteed to overflow in a two's complement
	representation), relying on `ckd_mul()` to indicate it.

	* src/roff/troff/hvunits.h: Include `config.h` and `stdckdint.h`
	headers.
	(vunits operator -, hunits operator -): Use `ckd_sub()` instead
	of primitive operation, and throw error diagnostic if arithmetic
	wraps.
	(vunits::to_units, hunits::to_units): Use `ckd_mul()` instead of
	primitive operation, and throw error diagnostic if arithmetic
	wraps.
	(vunits operator +, hunits operator +): Use `ckd_add()` instead
	of primitive operation, and throw error diagnostic if arithmetic
	wraps.
	(vunits operator *, hunits operator *): Use `ckd_mul()` instead
	of primitive operation, and throw error diagnostic if arithmetic
	wraps.

	Fixes <https://savannah.gnu.org/bugs/?64301>.  You had to
	compile GNU troff with the (GCC) compiler option `-ftrapv` for
	arithmetic to trap and cause a core dump.

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

	* src/roff/troff/number.cpp (is_valid_term): Trivially refactor
	implementation of boundary-relative ("absolute" [sic]) motion
	operator.  Rename `tem` to `position`, since it is the
	horizontal or vertical drawing location to be altered.
	Parenthesize expressions for clarity.

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

	[troff]: Refactor `has_arg()` to optionally work in copy mode.

	* src/roff/troff/token.h (has_arg): Add Boolean parameter,
	defaulting to `false`, indicating that "peeking" ahead in the
	input stream is desired.  This is for use by requests that need
	to read their argument(s) in copy mode.
	* src/roff/troff/input.cpp (has_arg): Implement, moving code
	duplicated in `device_request` and `output_request`.
	(device_request, output_request): Drop duplicated code in favor
	of calling `has_arg()` with `true` argument.

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

	* src/roff/troff/input.cpp (device_request): Honor a `device`
	request even if it precedes any formatted output, as we do the
	`\X` escape sequence.

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

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

	* src/roff/troff/input.cpp (get_long_name): Call
	`do_get_long_name()` with null character literal for parameter
	of `char` type, rather than punning an integral zero.
	(do_get_long_name): Rename parameter from `end` to `end_char`.

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

	* bootstrap: Resync with gnulib upstream.  Thanks to Dave Kemper
	for the report and Collin Funk for the suggested fix.

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

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

	* src/roff/troff/number.cpp (is_valid_term): Trivially refactor;
	simplify tautologus Boolean expression.

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

	* src/roff/troff/input.cpp (token::description): Revise
	diagnostic when reporting unexpected character code > 128 in
	input.  Report only its code in decimal and Unicode-style
	hexadecimal instead of trying to write it literally.

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

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

	* doc/pic.ms: Reduce vertical spacing in displays only on
	typesetters.  To that end:
	(SS): Define new macro for starting a "small display".
	(SE): ...and a macro for ending one.
	Migrate use of `DS`/`DE` macros with `ps` and `vs` requests to
	the new macros.

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

	* tmac/groff_mdoc.7.man: Manipulate type size and vertical
	spacing only in troff mode.

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

	* src/roff/troff/number.cpp (is_valid_term): Boolify.  Rename
	`negative` to `is_negative` and demote it and `do_next` from
	`int` to `bool`.  Assign to them with Boolean, not integer,
	literals.

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

	* src/roff/troff/number.cpp (is_valid_expression, get_hunits)
	(get_number, get_integer, is_valid_term): Trivially refactor.
	Replace `v` as the general name for any numeric quantity
	{possibly arising from copy-and-paste operations from a
	`vunits`-handling original} with one more suggestive of its
	type: `h`, `u`, or `i` for horizontal, general, or integral
	units respectively.

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

	* src/roff/troff/hvunits.h: Boolify.
	(vunits:operator <, vunits::operator >, vunits::operator <=)
	(vunits:operator >= vunits::operator ==, vunits::operator !=)
	(hunits:operator <, hunits::operator >, hunits::operator <=)
	(hunits:operator >= hunits::operator ==, hunits::operator !=):
	Return `bool` instead of `int`.

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

	* tmac/an-ext.tmac (DS, DE): Drop (empty) macro definitions,
	introduced in groff 1.20 (January 2009).
	* NEWS: Document this.  Technically, it's an interface change.
	Any man page calling these macros (without defining them itself)
	will prompt warnings if GNU troff is given the `-wmac` option
	{or equivalent}.

2024-03-19  Alexis Hildebrandt <afh@surryhill.net>

	[grohtml]: Migrate from psselect(1) to ps2ps(1).

	* src/preproc/html/pre-html.cpp (imageList::createPage): Do it.
	* src/devices/grohtml/grohtml.1.man (Dependencies): Document
	the changed runtime requirement.
	* m4/groff.m4 (GROFF_CHECK_GROHTML_PROGRAMS):
	* src/roff/groff/tests/html_works_with_grn_and_eqn.sh:
	* src/roff/groff/tests/smoke-test_html_device.sh: Check for
	existence of `ps2ps` command instead of `psselect`.

	* ANNOUNCE:
	* NEWS:
	* README:
	* README.MinGW: Document change in dependencies.

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

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

	* src/libs/libgroff/searchpath.cpp (is_directory): New function
	uses stat(2) to check file name argument to see if it's a
	directory, and returns a Boolean.
	(search_path::open_file):
	(search_path::open_file_cautious): Use `is_directory()` before
	attempting to `fopen()` a file specification; fail and set
	`errno` to `EISDIR` if it's a directory so that the caller
	reports a useful diagnostic.

	* bootstrap.conf: Add gnulib `stat` module, because the story of
	POSIX and non-POSIX systems alike trying and failing to sensibly
	implement the fundamental Unix file system model is a sorry tale
	of indifference and self-owns by rock star programmers.
	{Seriously, read the "sys/stat.h" and "stat" sections of the
	gnulib manual.}

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

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

	* tmac/an-ext.tmac: Fix incomplete changes to support `YS` with
	an argument to reuse indentation of previous synopsis.  (An
	insufficiently aggressive test case is a dangerous thing.)
	Revise meaning of `mS` register from "are we in a synopsis?" to
	"are we reusing the previous synopsis's indentation?"
	(SY): Save hyphenation and adjustment modes and disable
	automatic hyphenation if we have any arguments.
	(YS): Set `mS` register if we have any arguments, otherwise
	clear it.

	* tmac/tests/an_HY-register-works.sh: Drop test cases on
	"nested" synopses.  These are now ill-formed and no longer
	supported.  See "NEWS" file.

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

	* tmac/tests/an-ext_SY-and-YS-work.sh: Test new behavior of `YS`
	when given an argument.

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

	* src/preproc/eqn/main.cpp (main):
	* src/roff/troff/input.cpp (process_startup_file): Throw error
	diagnostic when a startup file cannot be opened for some reason
	other than its nonexistence.

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

	* src/preproc/grn/main.cpp (conv):
	* src/preproc/html/pre-html.cpp (get_resolution)
	(get_image_generator):
	* src/roff/troff/env.cpp (hyphen_trie::read_patterns_file):
	* src/roff/troff/input.cpp (process_macro_package_argument):
	When failing to open a file, say why in error diagnostic.

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

	* src/preproc/eqn/main.cpp (main):
	* src/roff/troff/env.cpp (hyphen_trie::read_patterns_file):
	* src/roff/troff/input.cpp (next_file, do_open, close_request)
	(open_macro_package, process_macro_package_argument)
	(do_macro_source, process_input_file): Parallelize (and shorten)
	wording of diagnostic messages.

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

	* src/libs/libgroff/font.cpp (text_file::~text_file)
	(font::extend_ch, font::load, font::load_desc):
	* src/libs/libgroff/searchpath.cpp
	(search_path::open_file_cautious):
	* src/roff/troff/env.cpp (hyphen_trie::read_patterns_file):
	Reorder comparisons with null pointers to avoid inadvertent
	lvalue assignment.

	* src/libs/libgroff/font.cpp (text_file::next_line, scale_round)
	(font::get_width, font::alloc_ch_index, font::load_desc): Do the
	same for comparisons to integral zeroes.

	* src/libs/libgroff/font.cpp (glyph_to_unicode): Add parentheses
	to complex expression.

	* src/libs/libgroff/searchpath.cpp (search_path::search_path)
	(search_path::open_file, search_path::open_file_cautious)
	* src/preproc/eqn/main.cpp (main):
	* src/roff/troff/input.cpp (file_iterator::set_location)
	(next_file, do_open, close_request, do_write_request)
	(write_macro_request, transparent_file, open_macro_package)
	(process_macro_package_argument, process_startup_file)
	(do_macro_source, process_input_file): Explicitly compare
	variable of pointer type to null pointer constant instead of
	letting it pun down to a Boolean.

	* src/roff/troff/input.cpp (writable_lineno_reg::set_value): Use
	explicit void cast when ignoring function's return value.

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

	* src/libs/libgroff/font.cpp (font::load, font::load_desc):
	Reduce cleverness of assignment nested inside conditional--a
	favorite of C obscurantists and an especially gratuitous case
	since it was preceded by a declarator without an initializer.
	This aligns `font::load()` with another overloaded version of
	itself and with `font::scan_papersize()`.

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

	* src/roff/troff/input.cpp (file_iterator::set_location): Stop
	initializing the output.  Preprocessing empty documents could
	lead to baffling results.  In groff 1.22.4 and before, you'd get
	a blank document from some output drivers despite no evident
	reason from the preprocessed input that this should be the case.
	In groff 1.23.0, this happened for fewer output drivers but
	still generated a mysterious diagnostic.

	  fatal error: 'V' command invalid before first 'p' command

	It turns out to be unnecessary to initialize `the_output` upon
	encountering an `lf` request.  The spurious output aspect of the
	problem dates back to commit e092fba4517, 6 February 2000
	{"groff pre-1.16"}.

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

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

	* src/roff/troff/env.cpp (number_lines): Clarify diagnostics;
	output line numbers cannot be negative, but input line numbers
	can, in both AT&T/DWB troff and GNU troff.

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

	[troff]: Boolify `set_location()` member function and those of
	its derived classes.

	* src/roff/troff/input.cpp (class input_iterator)
	(class file_iterator, class input_stack)
	(file_iterator::set_location):
	(input_stack::set_location): Demote return type from `int` to
	`bool`.
	(file_iterator::set_location, input_stack::set_location): Return
	Boolean instead of integer literals.

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

	* src/preproc/soelim/soelim.cpp (do_file): Stop "normalizing"
	an input file name of "-" to "stdin".  The other preprocessors
	don't do that.

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

	* src/roff/nroff/nroff.sh: Tweak shell pattern for clarity.

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

	Update gnulib to stable/2024-07.

	Point to 0ba13435a9362bec0ff5fd0830907b9fac723e41.

2024-03-16  Alejandro Colomar <alx@kernel.org>

	* src/devices/grolbp/lbp.cpp (main): Fix range check after
	`strtol()`.  In case INT_MAX==LONG_MAX, we need to check for
	ERANGE to reject high values.  The test 'n > INT_MAX' would
	never be true.

	Fixes <https://savannah.gnu.org/bugs/?65451> (6/6).

2024-03-16  Alejandro Colomar <alx@kernel.org>

	* src/utils/indxbib/indxbib.cpp (check_integer_arg): Collapse
	related tests.

	Fixes <https://savannah.gnu.org/bugs/?65452> (4/4).

2024-03-16  Alejandro Colomar <alx@kernel.org>

	* src/utils/indxbib/indxbib.cpp (check_integer_arg): Remove dead
	code.  The tests (LONG_MAX > INT_MAX && n > INT_MAX) and (n >
	INT_MAX) are equivalent.

	Fixes <https://savannah.gnu.org/bugs/?65452> (3/4).

2024-03-16  Alejandro Colomar <alx@kernel.org>

	* src/utils/indxbib/indxbib.cpp (check_integer_arg): Clear
	`errno` before calling `strtol()`.  Otherwise, `errno` may hold
	`ERANGE` from before.  See strtol(3).

	Fixes <https://savannah.gnu.org/bugs/?65452> (2/4).

2024-03-16  Alejandro Colomar <alx@kernel.org>

	* src/utils/indxbib/indxbib.cpp (check_integer_arg): Don't
	`else` after [[noreturn]].

	Fixes <https://savannah.gnu.org/bugs/?65452> (1/4).

2024-03-16  Alejandro Colomar <alx@kernel.org>

	[libgroff,libbib,indxbib]: Add, use `ceil_prime()`.

	* src/include/lib.h:
	* src/libs/libgroff/prime.cpp (ceil_prime): Add function to get
	the lowest prime not less than n.  While at it, fix the logic,
	which was incorrect in the open-coded call sites, since for an
	input of 1, it produced 3, but the first prime is 2.  A recent
	commit started rejecting 1 earlier, so this bug was now
	impossible to trigger, but remained there.

	Also, since this is a library function, let's behave well for an
	input of 0, which is mathematically fine, and return also the
	first prime, 2.

	* src/libs/libbib/index.cpp
	(index_search_item::read_common_words_file):
	* src/utils/indxbib/indxbib.cpp (main): And use it where the
	same logic was being open-coded.

	Fixes <https://savannah.gnu.org/bugs/?65451> (5/6).

2024-03-16  Alejandro Colomar <alx@kernel.org>

	* src/devices/grolbp/lbp.cpp (main): Remove bogus (and
	redundant) check.  `str == end` can only happen if strtol(3)
	returns 0.

	Fixes <https://savannah.gnu.org/bugs/?65451> (4/6).

2024-03-16  Alejandro Colomar <alx@kernel.org>

	* src/devices/grodvi/dvi.cpp
	(dvi_font::handle_unknown_font_command):
	* src/devices/grolbp/lbp.cpp (main):
	* src/devices/grolj4/lj4.cpp
	(lj4_font::handle_unknown_font_command, main):
	* src/devices/grops/ps.cpp (ps_printer::do_mdef)
	(ps_printer::do_import):
	* src/devices/grops/psrm.cpp (read_uint_arg):
	* src/libs/libgroff/font.cpp (font::load):
	* src/preproc/eqn/lex.cpp (do_space):
	* src/preproc/pic/tex.cpp (tpic_output::command):
	* src/preproc/refer/command.cpp (check_args):
	* src/preproc/refer/ref.cpp (reference::compute_sort_key):
	* src/preproc/refer/refer.cpp (main):
	* src/utils/indxbib/indxbib.cpp (check_integer_arg):
	* src/utils/lkbib/lkbib.cpp (main):
	* src/utils/lookbib/lookbib.cpp (main):
	* src/utils/tfmtodit/tfmtodit.cpp (main): Remove redundant checks
	after strtol(3).  `str == end` can only happen if strtol(3)
	returns 0.

	Fixes <https://savannah.gnu.org/bugs/?65451> (3/6).

2024-03-16  Alejandro Colomar <alx@kernel.org>

	* src/libs/libgroff/curtime.cpp (current_time): Remove dead
	code.  strtol(3) can only report ERANGE, if the base is valid
	{and it is}.

	Fixes <https://savannah.gnu.org/bugs/?65451> (2/6).

2024-03-16  Alejandro Colomar <alx@kernel.org>

	* src/libs/libgroff/curtime.cpp (current_time): Remove redundant
	checks.  ERANGE can only happen if strtol(3) returns either
	LONG_MIN or LONG_MAX.

	Fixes <https://savannah.gnu.org/bugs/?65451> (1/6).

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

	[nroff]: Support argument clustering.

	* src/roff/nroff/nroff.sh: Support argument clustering by
	iterating over the argument list and declustering options that
	can be clustered (`-abCEikpRStUzZ`).

	* src/roff/nroff/tests/verbose_option_works.sh: Test it.

	* NEWS: Document it.

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

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

	* src/roff/nroff/nroff.sh: Support groff `-a`, `-D`, `-I`, and
	`-Z` options.

	* src/roff/nroff/nroff.1.man:
	* NEWS: Document it.

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

	* src/roff/nroff/nroff.sh: Describe program briefly when invoked
	with `--help` option.

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

	* src/roff/nroff/nroff.sh: Define `prog` variable as only the
	"basename" of argv[0], making diagnostic and usage messages less
	garrulous.  See Savannah #65110.

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

	* src/roff/troff/node.cpp (class composite_node): Declare
	`dump_node()` member function.
	(composite_node::dump_node): Implement.

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

	* doc/groff.texi.in (Groff Options):
	* man/groff.7.man (Syntax reference conventions):
	* src/roff/troff/troff.1.man (Options): Document restriction on
	file names used as request arguments: no spaces, tabs, or line
	feeds.

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

	* src/devices/grotty/tests/basic_latin_glyphs_map_correctly.sh:
	* src/roff/groff/tests/smoke-test_html_device.sh: Revise tests
	to better handle non-glibc environments.  For example, Bionic
	libc offers no "locale" command to query the locale's character
	set from the shell.  When that is the case, skip the test and
	describe the failure more accurately.  Fixes test failures on
	Termux.

2024-05-14  Dave Kemper <saint.snit@gmail.com>

	* tmac/e.tmac: Add debugging advice for developers.

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

2024-07-09  Bjarni Ingi Gislason <bjarniig@rhi.hi.is>

	[docs]: Fix doubled word typos.

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

2024-07-09  Dave Kemper <saint.snit@gmail.com>

	[docs]: Revise "input file" usage.

	Change the term "input file" to "input" in groff documentation
	in cases where the referenced input need not come from a file.

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

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

	Actually use the detected Netpbm option for quieting output in
	the pre-grohtml(1) preprocessor.

	* m4/groff.m4 (GROFF_PNMTOOLS_CAN_BE_QUIET): Set up an
	Autoheader template for the C/C++ preprocessor symbol
	`PNMTOOLS_QUIET`.  Report the detected option (if any) as the
	result of this configuration test.  Get the expansion into the
	"config.h" file with `AC_DEFINE_UNQUOTED`.
	* src/preproc/html/pre-html.cpp (imageList::createImage): Use
	the preprocessor symbol instead of a "-quiet" string literal.

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

	Search for and use pamcut(1), not pnmcut(1).  Per upstream, the
	former was introduced 23 years ago and the latter withdrawn 15
	years ago.  And we just got the memo!

	* m4/groff.m4 (GROFF_CHECK_GROHTML_PROGRAMS):
	* src/preproc/html/pre-html.cpp (imageList::createImage): Do it.

	* src/roff/groff/tests/html_works_with_grn_and_eqn.sh:
	* src/roff/groff/tests/smoke-test_html_device.sh: Update tests.

	* NEWS:
	* README.MinGW:
	* src/devices/grohtml/grohtml.1.man (Dependencies): Document it.

	Fixes <https://savannah.gnu.org/bugs/?65960>.  Thanks to Bjarni
	Ingi Gislason for the report.

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

	* src/roff/troff/input.cpp: Slightly refactor.
	(pipe_output): Reduce cleverness of assignment nested inside
	conditional--a favorite of C obscurantists and an especially
	gratuitous case since it was immediately preceded by a
	declarator without an initializer.  This aligns the logic with
	`system_request`.
	(pipe_output, system_request): Reorder comparisons to avoid
	inadvertent lvalue assignment.

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

	* doc/groff.texi.in (while):
	* man/groff_diff.7.man (New requests) <while>: Point out that
	the `slimit` register can be used to _lower_ the formatter's
	internal stack size limit as well.

	Fixes <https://savannah.gnu.org/bugs/?65962>.  Thanks to Bjarni
	Ingi Gislason for the report and Dave Kemper for the suggestion.

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

	* tmac/an-ext.tmac (SY): Drop unnecessary `do` request.

2024-06-28  Dave Kemper <saint.snit@gmail.com>

	* doc/groff.texi.in: Drop relict macro call in example.

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

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

	* src/utils/grog/grog.pl: Trivially refactor.  Relocate
	declaration of huge list `request` closer to its point of use.

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

	* src/utils/grog/grog.pl: Trivially refactor.  Rename scalar
	`have_any_valid_arguments` to `have_any_valid_operands`,
	reflecting its more specific purpose.  Rename subroutine
	`process_input` to `read_input`; it transforms its input only
	for internal purposes (to draw inferences), without output.
	Rename subroutine `do_line` to `interpret_line`.  "Do" is an
	overused term in software development, too often meaning
	"whatever the programmer had in mind at the time but failed to
	document anywhere".

2024-06-22  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf] Fix invalid pdf when using certain sizes of
	dashed ellipse in pic.

	* src/devices/gropdf/gropdf.pl: For short dashes on flat part
	of ellipse some v. small numbers written in form n.nnnE-n which
	is invalid for pdfs. Also rather than split each arc always into
	4 pieces, split into number of quadrants described between start
	and end angle. If arc describes a straight line, use line segment
	rather than bezier curve. (grops does this as well)

	Fixes <https://savannah.gnu.org/bugs/?65901>.  Thanks to Morten
	Bo Johansen for reporting this issue.

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

	* src/roff/troff/env.cpp (environment::possibly_break_line):
	Trivially refactor.  Explicitly handle adjustment modes that had
	been handled by falling completely through a `switch` statement.
	Throw assertion if an unhandled case is encountered.

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

	[mdoc]: Recognize new POSIX.1-2024 standard.

	* tmac/mdoc/doc-syms: Do it.
	* tmac/groff_mdoc.7.man (Standards): Document it.

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

	[grog]: Fix Savannah #65902 (detect use of chem(1)).

	* src/utils/grog/grog.pl: Take `cstart` and `cend` tokens out of
	`preprocessor_for_macro` hash.  They don't work with the
	existing logic.  Also drop tokens used by preprocessors that
	don't have corresponding groff(1) options and therefore don't
	influence the output grog(1) can emit.
	(do_line): Add bespoke handling for `cstart` and `cend`.  Not
	only are they the only AT&T troff preprocessor tokens that are
	longer than two characters, but their names collide in those
	first two characters with the names of troff requests.

	Fixes Savannah #65902.  Thanks to Morten Bo Johansen for the
	report.  Problem introduced by me in commit 53a9964497, 31 July
	2021.

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

	[grog]: Regression-test Savannah #65902.

	* src/utils/grog/tests/detect-chem.sh: Do it.
	* src/utils/grog/grog.am (grog_TESTS): Run test.

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

	* src/roff/troff/mtsm.cpp (mtsm::inherit): Fix failing test.

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

	Fix Savannah #65894.  Refactor troff's "mini-troff state
	machine" to use STL stack implementation instead of a bespoke
	one, fixing a double-free error.

	* src/roff/troff/mtsm.h: Include C++ standard library "stack"
	header.
	(struct stack): Drop.
	(class mtsm): Declare `stack` data member as a standard stack of
	`statem` objects instead of a pointer to local `stack` type.

	* src/roff/troff/mtsm.h (statem::merge, statem::update):
	* src/roff/troff/mtsm.cpp (statem::merge, statem::update): Take
	references instead of pointers to some `statem` arguments (those
	that will be accessed via the `stack` data member).

	* src/roff/troff/mtsm.cpp (stack::stack, stack::~stack): Drop.
	(mtsm::mtsm): Drop initializer of `sp` data member.
	(mtsm::~mtsm): Drop (conditional) deletion of `sp`.
	(mtsm::push_state, mtsm::pop_state, mtsm::inherit): Use STL
	`stack`'s `push()`, `empty()`, and `pop()` instead of primitive
	operations.
	(statem::update): Access data members of `mtsm` class via
	references instead of pointers (using `.` instead of `->`
	operator).
	(statem::merge): Drop null pointer test of reference, which
	can't be null.

	Fixes <https://savannah.gnu.org/bugs/?65894>.  This was a latent
	bug exposed by commit 0951ff53e4, 10 August (a change to the
	man(7) macro package; such things should _never_ cause the
	formatter to crash).

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

	Add regression test for latent bug: surprising "grout" produced
	when using "html" output device and a memory management bug is
	fixed.

	* src/roff/groff/tests/html-does-not-fumble-tagged-paragraph.sh:
	Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

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

	* src/utils/grog/grog.pl (do_line): Recognize new `pline`
	request forthcoming in groff 1.24 release.

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

	* tmac/trans.tmac: For mm package, alias new string name
	`Abstract` instead of old (and internal!) one, `cov*abs-name`.

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

	* src/roff/troff/input.cpp (token::next, interpolate_arg):
	Tighten up null-terminated string traversal.

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

	[docs]: Fix Savannah #65837.

	* doc/groff.texi: Fix erroneous documentation of input backspace
	handling.
	(Requests and Macros): Add footnote directing reader to "Page
	Motions" node for discussion of backspace.
	(Identifiers): Drop 0x08 from list of invalid input characters.
	(Manipulating Filling and Adjustment): Add concept index entry
	for "word space".  Define "word space" as terminology.
	(Page Motions): Describe semantics of input backspace character,
	motivate its existence, and discourage its use.

	* man/groff.7.man (Identifiers):
	* man/roff.7.man (Requests and macros): Sync.

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

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

	[ms]: Fix Savannah #64005 (again).

	* tmac/s.tmac (bp): Fix thinko swapping the normal and no-break
	control characters.

	Fixes <https://savannah.gnu.org/bugs/?64005>.  Thanks to Deri
	James for catching this misbehavior.

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

	[ms]: Further regression-test Savannah #64005.

	* tmac/tests/s_honor-page-break-in-text.sh: Do it.
	* tmac/tmac.am (tmac_TESTS): Run test.

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

	* tmac/doc.tmac: Drop nilpotent junk from end of file.

	Fixes <https://savannah.gnu.org/bugs/?65701>.  Thanks to Bjarni
	Ingi Gislason for the report.

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

	* m4/groff.m4 (GROFF_WCOREFLAG): Use `AC_LANG_PROGRAM` more
	idiomatically; stop explicitly defining `main()`.  Reportedly
	resolves implicit function declaration warnings from Clang.

	Fixes <https://savannah.gnu.org/bugs/?65762>.  Thanks to Eli
	Schwartz for the report.

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

	* src/roff/troff/input.cpp (interpolate_arg): Stop embedding
	unprintable input characters in messages diagnosing invalid
	syntax.

	See
	<https://lists.gnu.org/archive/html/groff/2024-05/msg00057.html>
	and follow-ups.

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

	* src/roff/troff/node.cpp (glyph_node::dump_node):
	(node::dump_node): Favor `fputs()` over `fprintf()` when the
	output string doesn't require formatting.

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

	* src/roff/troff/node.cpp (dbreak_node::dump_node): Drop
	extraneous space from output.

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

	[gropdf] Deal better with invalid destination names.

	Bookmark destinations (supplied by -T to .pdfbookmark)
	are "Name Objects" in pdf terms, as such they are limited
	to characters in the range 33 (!) to 126 (~). Characters
	outside this range must be coded as a # followed by the
	2 digit hex number. So a space character should be '#20'.

	Gropdf produces pdfs which conform to this rule, but the
	pdf parser (used to import pdfs for pdfpic) expects only
	valid syntax. To convert pdfmark input to a pdf object
	gropdf used this inbuilt parser.

	The .TH macro in an.tmac passes its first parameter as a
	bookmark destination. Normally this is fine, since the
	convention is that this will be the name of the program
	the man page is documenting. The problem in this case
	is the line:-

	.TH "Pamaltsat User Manual" 0 "14 September 2018"
	    "netpbm documentation"

	The first parameter contains spaces, which yields invalid
	syntax when parsed as "/Dest /Pamaltsat User Manual(0)".

	* src/devices/gropdf/gropdf: Don't use internal parser
	on "user" supplied input, be a bit more careful.

	Fixes:-

	https://savannah.gnu.org/bugs/?65788

	Thanks to Bjarni for the report.

2024-05-14  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf] Problem if mixed fonts have different lenIV.

	* src/devices/gropdf/gropdf: Restore default value (4) for
	each font in case custom value used by previous font. Slight
	change to pattern matches.

2024-05-14  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf] \X'pdf: xrev' has issues.

	* src/devices/gropdf/gropdf: Fails if point size not = 10, in
	a number of ways.

	* src/devices/gropdf/gropdf.1.man: Clarify exact operation of
	'xrev'.

2024-05-14  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf] Passing just "\" as a bookmark problem.

	* src/devices/gropdf/gropdf: it ends up as a pdf string "(\)",
	which is treated as an escaped bracket and the string is not
	terminated! Solution is to embed the "\" in octal notation,
	i.e. (\134).

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

	* tmac/an.tmac (EE): Define macro with `de1` request, not `de`.

	Fixes <https://savannah.gnu.org/bugs/?65729>.  Thanks to Bjarni
	Ingi Gislason for the report.  Problem introduced by me in
	commit 15f8188656, 21 February 2022.

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

	[tmac]: Perform actual string comparisons.

	* tmac/fallbacks.tmac:
	* tmac/troffrc-end: Bracket comparands to formatted output
	comparison operator with `\?` escape sequences to perform a more
	elementary string comparison on them (cf. a comparison of
	_formatted text_).  This way they continue to perform their
	function even if the default font family has no coverage of
	Basic Latin (not a bizarre choice when considering potential
	rendering of documents using Devanagari or East Asian
	languages).  Unfortunately this means of comparing strings,
	while long documented in the GNU troff Manual, is neither
	idiomatic for *roff macro programmers nor portable to AT&T
	troff.  (The *roff language historically _lacks_ a string
	comparison operator.)  Each macro package will have to decide
	for itself whether it wants to have portability at the expense
	of requiring Basic Latin coverage (possibly switching fonts
	before and after a formatted output comparison for the sole
	purpose of obtaining it).  These two files are unconditionally
	loaded by the stock `troffrc`, and therefore must be dealt with
	in any case.

	Fixes <https://savannah.gnu.org/bugs/?64155>.  Thanks to Dave
	Kemper for the report, and to him, Peter Schaffter, and Deri
	James for the discussion.

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

	Begin withdrawing support for CCSID (code page) 1047 (EBCDIC).

	* tmac/X.tmac:
	* tmac/Xps.tmac:
	* tmac/dvi.tmac:
	* tmac/html.tmac:
	* tmac/ps.tmac: Stop loading "latin1.tmac" or "cp1047.tmac"
	depending on the special character `\[char97]` matching "a".

	* tmac/troffrc: Simplify logic; map special character
	`\[char160]` to `\~` unconditionally.

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

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

	* src/roff/troff/node.cpp (class dbreak_node): Add `dump_node`
	member function, overriding virtual function in `node` base
	class.
	(dbreak_node::dump_node): Disclose more information, namely the
	contents of any defined glyph nodes within.

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

	* src/roff/troff/node.cpp (glyph_node::dump_node)
	(node::dump_node, node::dump_node_list): Tweak output format.

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

	* tmac/doc.tmac (doc-empty-line):
	* tmac/mdoc/doc-common (doc-header, doc-break-body-text)
	(doc-footer, doc-end-macro): Define macros with `de1` instead of
	`de` so the macro package doesn't throw warnings when used in
	compatibility mode.

	Fixes <https://savannah.gnu.org/bugs/?65717>.  Thanks to Bjarni
	Ingi Gislason for the report.

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

	* src/roff/troff/env.cpp (environment::get_prev_char)
	(environment::width_registers, distribute_space)
	(environment::start_field): Slightly refactor.  Explicitly
	compare variable of pointer type to null pointer constant
	instead of letting it pun down to a Boolean.

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

	* src/roff/troff/node.cpp: Trivially refactor.  Rename member
	function argument indicating the diversion level to be used when
	constructing a `node` struct from "pop" (a word that suggests
	action, or a Boolean indicator, to me) to "divlevel", as is
	already used in the constructors in "node.h".
	(charinfo_node::charinfo_node, glyph_node::glyph_node)
	(ligature_node::ligature_node, kern_pair_node::kern_pair_node)
	(dbreak_node::dbreak_node)
	(italic_corrected_node::italic_corrected_node)
	(break_char_node::break_char_node)
	(extra_size_node::extra_size_node)
	(vertical_size_node::vertical_size_node)
	(vmotion_node::vmotion_node, hline_node::hline_node)
	(vline_node::vline_node, zero_width_node::zero_width_node)
	(overstrike_node::overstrike_node, bracket_node::bracket_node)
	(space_node::space_node)
	(diverted_space_node::diverted_space_node)
	(diverted_copy_file_node::diverted_copy_file_node)
	(space_char_hmotion_node::space_char_hmotion_node)
	(special_node::special_node)
	(suppress_node::suppress_node, tag_node::tag_node)
	(composite_node::composite_node)
	(word_space_node::word_space_node)
	(unbreakable_space_node::unbreakable_space_node)
	(draw_node::draw_node)
	(left_italic_corrected_node::left_italic_corrected_node): Do it.

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

	* src/roff/troff/env.cpp (print_nodes_from_input_line): Fix
	elementary mistake in request implementation.  It is essential
	that requests call `skip_line()` when they are done interpreting
	arguments--even if there are none, to prevent the newline at the
	end of the input line from being interpreted as text (and
	causing a line or word break, depending on filling enablement).

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

	* tmac/an-ext.tmac (YS): Clear `mS` register unconditionally.

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

	* tmac/tests/an-ext_SY-and-YS-work.sh: Add test case exercising
	correct suspension of automatic hyphenation.  Thanks to Alex
	Colomar for the report and a reproducer.

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

	* src/roff/troff/env.h (class environment): Rename member
	function.
	* src/roff/troff/env.cpp (environment::get_using_line_tabs):
	Rename this...
	(environment::is_using_line_tabs): ...to this.
	(init_env_requests): Update reference.

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

	* src/roff/troff/env.cpp (environment::print_env): Fix typo in
	environment report.

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

	* src/roff/troff/input.cpp (do_if_request): Boolify.  Demote
	`result` from `int` to `bool`.  Assign Boolean literals to it.

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

	* tmac/an.tmac (TH): Reset `mE` and `mS` registers from
	"an-ext.tmac" to zero upon beginning a new document.

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

	[man]: Revise and expand `SY` and `YS` macro behavior, largely
	to accommodate C library function synopses.  `SY` no longer puts
	vertical space on the output, and initially breaks the output
	line _only_ if it is encountered repeatedly without a preceding
	`YS` call.  The computed indentation of synopsis lines after the
	first now also includes the width of anything on the line
	_before_ the synopsis, so that you can precede the `SY` call
	with, for instance, the C language data type used for the return
	value in a function prototype.  The `SY` macro now accepts an
	optional second argument.  This second argument is typeset in
	bold, replaces the fixed-width space that is appended to the
	synopsis keyword in `SY`'s single-argument form, and is used in
	computation of the indentation of non-initial synopsis lines.

	...unless overridden.  You can now reuse the indentation amount
	computed in a previous synopsis.  To do this, give any argument
	to the `YS` macro call "closing" the synopsis whose indentation
	you want to reuse.  When you're done with such a grouped
	synopsis, simply leave the argument off the final `YS` call.

	Finally, the `SY` macro is now effectively a no-op if it is
	called with no arguments; no text is discarded.

	* tmac/an-ext.tmac (SY, YS): Do it.

	* NEWS:
	* tmac/groff_man.7.man.in: Document it.

	* tmac/tests/an-ext_SY-and-YS-work.sh: Update test expectations.

	* contrib/chem/chem.1.man:
	* contrib/eqn2graph/eqn2graph.1.man:
	* contrib/gdiffmk/gdiffmk.1.man:
	* contrib/glilypond/glilypond.1.man:
	* contrib/gperl/gperl.1.man:
	* contrib/gpinyin/gpinyin.1.man:
	* contrib/grap2graph/grap2graph.1.man:
	* contrib/mm/groff_mm.7.man:
	* contrib/mm/groff_mmse.7.man:
	* contrib/mm/mmroff.1.man:
	* contrib/mom/groff_mom.7.man:
	* contrib/pdfmark/pdfroff.1.man:
	* contrib/pic2graph/pic2graph.1.man:
	* src/devices/grodvi/grodvi.1.man:
	* src/devices/grohtml/grohtml.1.man:
	* src/devices/grolbp/grolbp.1.man:
	* src/devices/grolj4/grolj4.1.man:
	* src/devices/gropdf/gropdf.1.man:
	* src/devices/gropdf/pdfmom.1.man:
	* src/devices/grops/grops.1.man:
	* src/devices/grotty/grotty.1.man:
	* src/devices/xditview/gxditview.1.man:
	* src/preproc/eqn/eqn.1.man:
	* src/preproc/grn/grn.1.man:
	* src/preproc/pic/pic.1.man:
	* src/preproc/preconv/preconv.1.man:
	* src/preproc/refer/refer.1.man:
	* src/preproc/soelim/soelim.1.man:
	* src/preproc/tbl/tbl.1.man:
	* src/roff/groff/groff.1.man:
	* src/roff/nroff/nroff.1.man:
	* src/roff/troff/troff.1.man:
	* src/utils/addftinfo/addftinfo.1.man:
	* src/utils/afmtodit/afmtodit.1.man:
	* src/utils/grog/grog.1.man:
	* src/utils/hpftodit/hpftodit.1.man:
	* src/utils/indxbib/indxbib.1.man:
	* src/utils/lkbib/lkbib.1.man:
	* src/utils/lookbib/lookbib.1.man:
	* src/utils/pfbtops/pfbtops.1.man:
	* src/utils/tfmtodit/tfmtodit.1.man:
	* src/utils/xtotroff/xtotroff.1.man:
	* tmac/groff_man.7.man.in:
	* tmac/groff_me.7.man:
	* tmac/groff_ms.7.man: Migrate synopses to new idiom, using `YS`
	to terminate each synopsized item, and `P` to vertically
	separate item(s) where appropriate.

	Thanks to Alex Colomar and Lennart Jablonka for feedback and to
	Peter Chubb for his suggestion of `bsearch()` as an exemplar.

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

	[troff]: Trivially refactor.  Rename node and node list dumping
	member function prefixes from "debug_" to "dump_", to reflect
	the fact that they're not just for (source-level) debugging
	anymore.

	* src/roff/troff/node.h (struct node): Rename.
	- `debug_node` -> `dump_node`
	- `debug_node_list` -> `dump_node_list`
	* src/roff/troff/node.cpp (glyph_node::debug_node)
	(node::debug_node)
	(node::debug_node_list): Rename these...
	(glyph_node::dump_node)
	(node::dump_node):
	(node::dump_node_list): ...to these.
	* src/roff/troff/env.cpp (environment::add_char)
	(environment::dump_node_list):
	* src/roff/troff/node.cpp (node::dump_node_list): Update call
	sites.

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

	* src/roff/troff/node.cpp (node::debug_node): Report list of
	pending output nodes in forward order, likely corresponding to
	user intuition.  (Internally, the formatter stores the nodes in
	LIFO order, for the convenience of appending to a singly-linked
	list.)

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

	[troff]: Add new request `pline` to dump list of nodes in the
	pending output line.

	* src/roff/troff/env.h (class environment): Declare new
	`dump_node_list` member function.
	* src/roff/troff/env.cpp (environment::dump_node_list): New
	function calls `debug_node_list()`.
	(print_node_list): New function dumps list of nodes
	in the environment's pending output line.
	(init_env_requests): Wire up `pline` request to
	`print_node_list()`.

	* doc/groff.texi (Manipulating Filling and Adjustment)
	(Debugging):
	* man/groff.7.man (Request short reference, Debugging):
	* man/groff_diff.7.man (New requests, Debugging):
	* NEWS: Document it.

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

	* src/roff/troff/div.cpp (page_number):
	* src/roff/troff/env.cpp (environment::add_node)
	(environment::construct_state):
	* src/roff/troff/input.cpp (psbb_locator::psbb_locator)
	(psbb_locator::parse_bounding_box, psbb_locator::get_line)
	(psbb_locator::context_args, psbb_locator::get_header_comment)
	(psbb_locator::skip_to_trailer): Use idiomatic C++98 null
	pointer constant literal.

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

	* src/roff/troff/env.cpp (environment::print_env): Revise
	report.  Recast for comprehensibility and to use terminology
	from our man pages and our Texinfo manual.  In nroff mode, stop
	reporting type size and font family parameters; the formatter
	ignores the relevant requests and escape sequences in that mode.
	Report the previous and current resolved font names alongside
	the existing mounting position selections.

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

	* src/roff/troff/env.cpp (environment::print_env): Stop
	reporting the value of the "discarding" flag as a property of
	the *roff environment.  There's no corresponding concept in CSTR
	#54 or groff's documentation.  It is an internal
	implementation detail having to do with the disposal of trailing
	spaces on input lines (and not even in general at that; as far
	as I can tell it applies only when the `\p` escape sequence is
	also used).  Move the report of its value from here...
	(environment::dump_troff_state): ...to here, a member function
	that is only reachable if the `DEBUGGING` preprocessor symbol is
	defined and if one is using a debugger on an unstripped troff
	executable.

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

	* src/roff/troff/env.cpp (environment::possibly_break_line):
	(environment::print_env): Explicitly compare variable of pointer
	type to null pointer constant instead of letting it pun down to
	a Boolean.
	(environment::print_env): Similarly for testing value of
	function returning pointer.

2024-04-30  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf] Re-arrange pattern matches.

	* src/devices/gropdf/gropdf.pl: Correct order of pattern
	match.

	Fixes https://savannah.gnu.org/bugs/?65585 (again!)

2024-04-30  Christof Meerwald <cmeerw@cmeerw.org>

	* src/devices/gropdf/gropdf.pl: Call PDFDate with the output of
	`time` rather than one of the processed versions.
	(PDFDate): Accept an epoch-seconds argument rather than a
	reference to a list as returned by `gmtime` or `localtime`.
	Calculate the relationship between local time and UT more
	carefully.  Remove incorrect sign character before minutes
	field.

	Problem introduced in commit d7bbfb04ea, 9 July.

2024-04-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp
	(pending_output_line::pending_output_line)
	(environment::add_node, environment::get_prev_char)
	(environment::extract_output_line, environment::output_line)
	(environment::choose_breakpoint, node_list_reverse)
	(distribute_space, environment::construct_state)
	(environment::construct_format_state)
	(environment::construct_new_line_state)
	(environment::make_tab_node): Rename function parameters and
	local variables from `n` to `nd` (or `nod` in one case when `nd`
	was already in use) when they are of `node *` type; the file
	also uses `n` for integers, which is confusing.

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

	* src/roff/troff/env.cpp (select_font): Fix code style nit.
	Compare constant character to null character literal, not an
	integral zero.

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

	* src/roff/troff/env.cpp (environment::add_char)
	(environment::add_node, environment::add_hyphen_indicator)
	(environment::add_italic_correction, environment::space_newline)
	(environment::space, environment::get_input_line_position)
	(environment::set_input_line_position)
	(environment::get_prev_char, environment::get_text_length)
	(environment::extract_output_line, environment::newline)
	(environment::possibly_break_line, environment::do_break)
	(environment::is_empty, environment::wrap_up_tab)
	(environment::handle_tab, environment::wrap_up_field)
	(environment::handle_tab, environment::wrap_up_field): Fix code
	style nit.  Perform explicit comparisons of `current_tab` (an
	enumerated type) against `TAB_NONE` instead of punning down to a
	Boolean.

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

	* src/roff/troff/env.cpp (environment::add_italic_correction):
	Fix code style nit; explicitly compare variable of pointer type
	to null pointer constant instead of letting it pun down to a
	Boolean.
	(environment::output) [WIDOW_CONTROL]: Same, in de-configured
	code.

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

	[troff]: Trivially refactor.  Rename member functions and
	variables such that it is easier to tell Boolean objects (or
	even an imperative verb/noun action) from a countable quantity.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp (environment::get_centered_line_count)
	(environment::environment, environment::copy, center)
	(right_justify, environment::newline)
	(environment::possibly_break_line)
	(environment::dump_troff_state, environment::construct_state)
	(environment::construct_format_state, environment::print_env)
	(init_env_requests): Rename `center_lines` to
	`centered_line_count`.  Rename `get_center_lines()` to
	`get_centered_line_count()`.
	* src/roff/troff/env.cpp (environment::print_env): Perform
	integer comparison, not Boolean test, for clarity and to ensure
	consistency with *roff integer-to-Boolean conversion idiom.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp
	(environment::get_right_aligned_line_count)
	(environment::environment, environment::copy, center)
	(right_justify, environment::newline)
	(environment::possibly_break_line)
	(environment::dump_troff_state, environment::construct_state)
	(environment::construct_format_state, environment::print_env)
	(init_env_requests): Rename `right_justify_lines` to
	`right_aligned_line_count`.  Rename `get_right_justify_lines()`
	to `get_right_aligned_line_count()`.
	* src/roff/troff/env.cpp (environment::print_env): Perform
	integer comparison, not Boolean, test, for clarity and to ensure
	consistency with *roff integer-to-Boolean conversion idiom.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp (environment::environment)
	(environment::copy, do_underline) (environment::newline)
	(environment::print_env): Rename `underline_lines` to
	`underlined_line_count`.
	* src/roff/troff/env.cpp (environment::print_env): Perform
	integer comparison, not Boolean, test, for clarity and to ensure
	consistency with *roff integer-to-Boolean conversion idiom.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp (environment::environment)
	(environment::copy, environment::distance_to_next_tab)
	(line_tabs_request, environment::print_env, init_env_requests):
	Rename `line_tabs` to `using_line_tabs`.
	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp (environment::get_line_tabs): Rename
	this...
	(environment::get_using_line_tabs): ...to this.

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

	[troff]: Demote parameter of global `do_underline` function from
	`int` to `bool`.

	* src/roff/troff/env.h: Do it.
	* src/roff/troff/env.cpp (do_underline): Do it.  Rename paramter
	from `underline_spaces` to `want_spaces_underlined`.

	* src/roff/troff/env.h (class environment): Update friend
	access.

	* src/roff/troff/env.cpp (continuous_underline, underline): Call
	it with Boolean, not integer, literals.

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

	[troff]: Boolify `suppress_push` global variable, and declare it
	in a header file.

	* src/roff/troff/env.cpp: Move `extern` declaration from here...
	* src/roff/troff/input.h: ...to here.

	* src/roff/troff/input.cpp: Demote it from `int` to `bool` and
	assign Boolean, not integer, literals to it.

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

	[troff]: Boolify `translate_space_to_dummy` global variable.

	* src/roff/troff/env.h:
	* src/roff/troff/env.cpp: Do it.

2024-04-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Boolify more `environment` class member variables,
	member function parameters, and local variables.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp (class pending_output_line)
	(pending_output_line::output, environment::output)
	(environment:output_title): Rename `no_fill` to
	`suppress_filling` and demote it from `int` to `bool`.

	* src/roff/troff/env.h (class environment) [WIDOW_CONTROL]:
	* src/roff/troff/env.cpp (class pending_output_line)
	[WIDOW_CONTROL]: Update prototype of `environment::output`
	friend declaration.

	* src/roff/troff/env.cpp (class pending_output_line)
	(pending_output_line::pending_output_line): Demote parameter
	`nf` from `int` to `bool`.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp (class pending_output_line)
	(environment::output, environment::newline)
	(environment::output_line, environment::possibly_break_line):
	(environment::construct_format_state, environment::do_break):
	Demote `was_centered` from `int` to `bool`.
	(environment::newline): Assign Boolean literals to variables of
	type `bool`.
	(class pending_output_line) [WIDOW_CONTROL]: Update prototype of
	`environment::output` friend declaration.

	* src/roff/troff/env.cpp (class pending_output_line)
	(pending_output_line::pending_output_line)
	(pending_output_line::output, environment::mark_last_line)
	[WIDOW_CONTROL]: Rename `last_line` to `is_last_line` and demote
	it from `int` to `bool`.

	* src/roff/troff/env.cpp (class pending_output_line)
	(pending_output_line::output): Demote member function's return
	type from `int` to `bool`.  Return Boolean, not integer,
	literals from functions returning `bool`.

	* src/roff/troff/env.cpp (class pending_output_line)
	(pending_output_line::output): Demote parameter `ce` from `int`
	to `bool`.

	* src/roff/troff/env.h (class environment) [WIDOW_CONTROL]:
	* src/roff/troff/env.cpp (environment::output)
	(environment::output_pending_lines, widow_control_request)
	(environment::output, environment::environment)
	(environment::copy, environment::print_env) [WIDOW_CONTROL]:
	- Rename `widow_control` to `want_widow_control` and demote it
	  from `int` to `bool`.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp (environment::space_newline)
	(environment::space, environment::environment)
	(environment::copy, environment::print_env):
	- Rename member variable `spread_flag` to `spreading` and demote
	  it from `int` to `bool`.
	- Assign Boolean literals to it.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp (environment::hyphenate_line)
	(environment::possibly_break_line):
	- Rename parameter `start_here` to `must_break_here` and demote
	  it from `int` to `bool`.

	* src/roff/troff/env.cpp (environment::possibly_break_line):
	* src/roff/troff/input.cpp (process_input_stack):
	- Pass Boolean, not integer, literals to it.

	* src/roff/troff/env.h (class environment): Demote `fill` member
	variable from `int` to `bool`.
	* src/roff/troff/env.cpp (environment::environment, fill)
	(no_fill): Assign Boolean literals to it.

	* src/roff/troff/env.h (class environment): Rename member
	variable `interrupted` to `line_interrupted` and demote it from
	`int` to `bool`.
	* src/roff/troff/env.cpp (environment::add_char)
	(environment::add_node, environment::add_italic_correction)
	(environment::space, environment::set_font):
	(environment::set_family, environment::set_size):
	(environment::set_char_height, environment::set_char_slant):
	(environment::set_glyph_color, environment::set_fill_color):
	(environment::set_glyph_color, environment::set_fill_color):
	(environment::environment, environment::copy):
	(environment::interrupt, environment::newline): Assign Boolean
	literals to it.

	* src/roff/troff/env.cpp (environment::choose_breakpoint):
	Demote local variable `best_bp_fits` from `int` to `bool`.
	Assign Boolean literals to it.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp (environment::possibly_break_line):
	Rename parameter `forced` to `must_adjust` and demote it from
	`int` to `bool`.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp (environment::handle_tab): Demote
	parameter `is_leader` from `int` to `bool`.  Assign Boolean
	literal to it.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp
	(environment::construct_state): Rename parameter `only_eol` to
	`has_only_eol` and demote it from `int` to `bool`.
	* src/roff/troff/env.cpp (environment::add_char):
	(environment::add_node):
	* src/roff/troff/input.cpp (input_stack::push): Assign Boolean
	literals to it.

	* src/roff/troff/env.h (class environment): Demote member
	variables `seen_space`, `seen_eol`, `suppress_next_eol`, and
	`seen_break` from `int` to `bool`.
	* src/roff/troff/env.cpp (environment::environment)
	(environment_switch, no_fill, environment::newline)
	(environment::construct_state)
	(environment::construct_format_state)
	(environment::construct_new_line_state,  environment::do_break):
	Assign Boolean literals to them.  Simplify conditional
	expressions.

	* src/roff/troff/env.h (class environment): Demote member
	variable `underline_spaces` from `int` to `bool`.
	* src/roff/troff/env.cpp (environment::environment)
	(environment::copy, do_underline, environment::newline): Assign
	Boolean literals to it.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp
	(environment::add_char, environment::add_node)
	(environment::space_newline, environment::space)
	(environment::environment, environment::copy)
	(environment::newline, environment::possibly_break_line)
	(environment::wrap_up_tab, environment::start_field)
	(environment::wrap_up_field, environment::print_env): Rename
	parameter `current_field` to `has_current_field` and demote it
	from `int` to `bool`.
	* src/roff/troff/env.cpp (environment::add_char):
	(environment::add_node):
	* src/roff/troff/input.cpp (input_stack::push): Assign Boolean
	literals to it.

	* src/roff/troff/env.h (class environment): Demote member
	variable `composite` from `int` to `bool`.
	* src/roff/troff/env.cpp (environment::environment)
	(environment::copy):
	* src/roff/troff/env.h (environment::set_composite): Assign
	Boolean literals to it.
	* src/roff/troff/env.h (environment::is_composite): Return a
	`bool`, not an `int`.

	* src/roff/troff/env.cpp (temporary_indent): Rename local
	variable `err` to `is_valid`, invert its sense, and demote it
	from `int` to `bool`.  Assign Boolean literals to it.

	* src/roff/troff/env.h (class environment): Demote member
	variable `dummy` from `int` to `bool`.
	* src/roff/troff/env.cpp (environment::environment): Assign
	Boolean literals to it.
	* src/roff/troff/env.h (environment::is_dummy): Return a
	`bool`, not an `int`.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp (environment::is_empty): Return a
	`bool`, not an `int`.

	* src/roff/troff/env.cpp (hyphen_trie::read_patterns_file):
	Rename local variables.
	- final_pattern     -> is_final_pattern
	- final_hyphenation -> is_final_hyphenation
	- traditional       -> is_traditional
	Demote these and `have_patterns`, `have_hyphenation`, and
	`have_keyword` from `int` to `bool`.  Assign Boolean literals to
	them.

	* src/roff/troff/env.h (class environment): Demote member
	variable `tab_precedes_field` from `int` to `bool`.
	* src/roff/troff/env.cpp (environment::wrap_up_tab): Assign
	Boolean literal to it.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp (environment::add_tab): Rename
	parameter `repeated` to `is_repeated` and demote it from `int`
	to `bool`.

	* src/roff/troff/env.cpp (environment::hyphenate_line): Demote
	local variable `inhibit` from `int` to `bool`.

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

	* src/roff/troff/env.cpp (tab_stops::to_string)
	(environment::wrap_up_tab, environment::handle_tab):
	* src/roff/troff/input.cpp (process_input_stack, read_size)
	(token::process, main)
	* src/roff/troff/node.cpp (font_info::get_tfont)
	(kern_pair_node::ends_sentence, node_list_ends_sentence)
	(node::split, unbreakable_space_node::nbreaks):
	* src/roff/troff/reg.cpp (number_value_to_ascii):
	Replace `assert(0)` calls with communicative predicates.

	* src/roff/troff/number.cpp (get_vunits, get_hunits, get_number)
	(get_integer, is_valid_expression, is_valid_term): Align
	language of assertion failures with others in use.

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

	* src/roff/troff/env.cpp (environment::print_env): Fix glitch in
	report of line number multiple when line numbering enabled.

	Problem introduced in commit b022f38dfa, 2 September 2006.

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

	* src/roff/troff/env.cpp (environment::dump_troff_state): Tweak
	debugging function's output to report Boolean value more
	idiomatically.

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

	[troff]: Boolify some `environment` class member variables.

	* src/roff/troff/env.h (class environment): Demote type of
	member variables `have_temporary_indent` and `discarding` from
	`int` to `bool`.
	* src/roff/troff/env.cpp (environment::environment)
	(environment::copy, indent, temporary_indent)
	(environment::start_line, environment:possibly_break_line)
	(environment::do_break): Use Boolean instead of integer literals
	to initialize or update aforementioned member variables.

2024-04-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an-ext.tmac (mQ): Remove `mU` string once unneeded.

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

	[gropdf] ignore 'Cspace' as input

	* src/devices/gropdf/gropdf.pl: As grops does.

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

	[gropdf] use nospace mode if font does not contain
	/space glyph.

	Gropdf always had two modes, depending on whether the font
	defined /space or not (using space could make the pdf
	slightly more compact). Some fonts which don't have /space
	do have a glyph named /u0020 and the code used that as a
	space, however I'm not convinced of the robustness of this
	so, now, if a font has no /space then nospace mode is used.

	* src/devices/gropdf/gropdf.pl: Always use nospace mode if
	font has no /space glyph.

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

	[gropdf] Can't handle DecodeParams in Deflate filter.

	If gropdf called with -d (debug) the pdf is produced with
	objects uncompressed, if object does not use default deflate
	parameters Zlib does not decompress properly, so the
	decompressed object is invalid. This affects when using a
	pdf imported with 'pdfpic' which contains a png image.

	This only affects imported pdfs when using the -d flag,
	because otherwise it is just passed through with no
	decompress.

	* src/devices/gropdf/gropdf.pl: Don't decompress if object has
	a DecodeParams dictionary.

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

	* tmac/tmac.am ($(M4CHECK)): Ensure directory exists to house
	the stamp file before attempting to create the latter.

2024-04-17  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf] Handle both types in one document.

	The different format of font described in previous commit fails
	if document contains fonts of both formats. The reason is
	because the regexes included the /o flag (compile once) for
	speed, but if the format changed (from RD to -|) in a different
	font, parsing failed.

	Now the regexes are compiled once for each font.

	* src/devices/gropdf/gropdf.pl: Use qr// to compile regexes once
	per font.

2024-04-17  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf] Improve font parsing.

	The usual (for fontforge converted ttf fonts) is to use the RD,
	ND and NP operators within charstring definitions, however these
	are just named in the private subrs dictionary so could be
	assigned any name.

	A debian .pfb version of a google .ttf font (which has not
	passed through fontforge) used -| |- and | as the 3 equivalent.
	In addition it used a different lenIV value for the eexec
	encryption (4) and the charstring encryption (0) (didn't know
	you could do that).

	* src/devices/gropdf/gropdf.pl: Make RD, ND and NP variables set
	from parsing the private subrs. Honour lenIV=0 when encrypting
	charstrings.

2024-04-16  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf] Problem with '(' and '\' (\[rs])

	Both these tokens have meaning for roff AND pdf strings. In
	pdfs unbalanced parentheses have to be escaped (with '\') and
	a single '\' has to be similarly escaped, '\\'. It is gropdf's
	responsibility to ensure pdf strings are valid, no matter what
	the input.

	If '\(ul' is passed then the UTF-16 character becomes '_'.
	If '\[rs](ul' is passed (i.e. '\(ul' is intended to become the
	UTF-16 string) \[rs] becomes '\' leaving '\(ul', which
	becomes '_', not what is intended. If the unbalanced '(' is
	escaped first, '\[rs]\(ul' which could become '\\_' when the '\'
	is escaped, yielding '\_'. The code which escapes parenthesis
	checks it is not already preceded by '\' since adding another
	would give you '\\(' which is not what you want. The correct
	output should be '\\\(ul' to achieve the correct pdf string.

	This fixes the above issue (I hope).

	* src/devices/gropdf/gropdf.pl: Change pattern matches

2024-04-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an-ext.tmac <mV, mQ>: Trivially refactor.  Rename string
	used to store URI hyperlink from `m1` to `mU`.

2024-04-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Fix computation of bookmark level.  If this
	register's value is specified on the command line, don't clobber
	it.  Adjust logic for assigning tag to the bookmark to the
	{possibly adjusted} base level accordingly.  Based on a patch by
	Deri James.

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

	[troff]: Retire "el" warning category.

	It's much too hard to perform this analysis without the risk of
	throwing this warning spuriously.  Paul Eggert reported a
	real-world use of `ie`/`el` requests nested without the use of
	brace escape sequences in his zic(8) man page that is
	structurally equivalent to the following (with indentation added
	for clarity).

	.ie \nA .tm register A is truthy
	.el .ie t .tm in typesetter mode
	.    el   .tm in terminal mode

	Without brace escape sequences, the `skip_branch()` function
	that discards input corresponding to control flow branches not
	taken does not reliably keep track of the nesting level.  So why
	not just make `skip_branch()` more sophisticated to handle this
	case?  Because it doesn't generalize.  What if the input changes
	the control character, or uses the no-break control character?
	What if the input has renamed the `ie` request or invokes it
	through a macro?

	* src/roff/troff/input.cpp: Drop this warning category from the
	`warning_table` global.
	(else_request): Stop throwing it.
	* src/roff/troff/troff.h: Comment out its value in the
	`warning_type` enum.

	* doc/groff.texi.in (if-else, Warnings):
	* src/roff/troff/troff.1.man (Warnings): De-document "el" troff
	warning category.

	Fixes <https://savannah.gnu.org/bugs/?65474>.  Thanks to Paul
	Eggert for the report.

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

	* src/roff/troff/input.cpp (skip_branch): Handle control flow
	branches consisting only of a newline correctly when skipping
	them--actually skip them, as AT&T troff does.  A newline after
	the `el` request, or after the conditional expression of an
	`if`, `ie`, or `while` request, is not "nothing"; if the branch
	is taken, it puts a newline on the output, and if it is not
	taken, it should neither affect output nor be _syntactically_
	ignored on the pretense that the next input line was actually
	part of the branch.

	Fixes <https://savannah.gnu.org/bugs/?45502>.  Problem likely
	goes back to groff's origin.  (You could always avoid it with
	brace escape sequences, which might explain why it seemed to
	cause little consternation.)  Thanks to Carsten Kunze for the
	report and to Dave Kemper for the code review.

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

	[groff]: Regression-test Savannah #45502.

	* src/roff/groff/tests/degenerate-control-flow-works.sh: Do it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

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

	* src/roff/troff/input.cpp: Trivially refactor.  Rename
	functions to use more idiomatic computer science terminology.
	(begin_alternative): Rename this...
	(take_branch): ...to this.
	(skip_alternative): Rename this...
	(skip_branch): ...to this.
	(do_if_request, else_request): Update call sites.

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

	* src/roff/troff/input.cpp: Refactor.  Replace bespoke class
	`bool_stack` with STL `stack<bool>`.  Migrate global
	`if_else_stack` to use it.
	(process_input_stack): Migrate `trap_bol_stack` to use it.
	(process_input_stack, else_request): Migrate member function
	calls.
	- `is_empty()` -> `empty()`
	- `pop()` -> `top()`, `pop()`

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

	* src/roff/troff/input.cpp: Slightly refactor.  Reconstruct
	class `int_stack` as `bool_stack` since all we require are
	Boolean values.

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

	* src/roff/troff/input.cpp: Slightly refactor.  Boolify.  Demote
	and rename global `while_break_flag` to `want_loop_break`.
	(do_if_request): Demote return type from `int` to `bool`.
	Demote and rename local `invert` to `want_test_sense_inverted`.
	(while_request): Demote and rename local `escaped` to
	`is_char_escaped`.

2024-04-12  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Correct and improve linear search introduced in commit
	cd9fde325f, 4th March.

	* tmac/pdf.tmac: Add mark counter, `pdf:bm.nk`.
	(pdfbookmark, pdf*href-M): ...and use it.
	(pdf:lookup): Add string `pdf:lookup-value` to record the `.val`
	attribute of a PDF bookmark, distinctly from its `.tag`.
	(pdfnote, pdfbookmark, pdf*href-M, pdf*href): Use `\A` escape
	sequence to validate *roff strings as (parts of) identifiers
	{seen in Keith Marshall's "pdfmark.tmac"}.
	(pdf*href-M, pdf*href, pdfbookmark): Stop using old `pdf:look`
	method of bookmark tag lookup.  Drop conditionals on presence of
	mom(7) `PRINTSTYLE` macro to select its use.
	(pdfbookmark): Drop logic for cleaning bookmark tag of material
	invalid in *roff identifiers, since the foregoing ensure that
	we no longer use such in their construction.
	(pdfmarksuspend, pdfmarkrestart): Drop management of mark
	suspension state; "pdf.tmac" now subsumes this function.

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

2024-04-12  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Support UTF-16-encoded PDF bookmarks.

	* src/utils/afmtodit/afmtodit.pl: Generate comment field holding
	the UTF-16 code for each groff character.

	* font/devps/AB:
	* font/devps/ABI:
	* font/devps/AI:
	* font/devps/AR:
	* font/devps/BMB:
	* font/devps/BMBI:
	* font/devps/BMI:
	* font/devps/BMR:
	* font/devps/CB:
	* font/devps/CBI:
	* font/devps/CI:
	* font/devps/CR:
	* font/devps/HB:
	* font/devps/HBI:
	* font/devps/HI:
	* font/devps/HNB:
	* font/devps/HNBI:
	* font/devps/HNI:
	* font/devps/HNR:
	* font/devps/HR:
	* font/devps/NB:
	* font/devps/NBI:
	* font/devps/NI:
	* font/devps/NR:
	* font/devps/PB:
	* font/devps/PBI:
	* font/devps/PI:
	* font/devps/PR:
	* font/devps/S:
	* font/devps/TB:
	* font/devps/TBI:
	* font/devps/TI:
	* font/devps/TR:
	* font/devps/ZCMI: Regenerate with updated aftmtodit.pl.

	* man/groff_font.5.man: Document use of comment field to hold
	UTF-16 code.

	* src/devices/gropdf/gropdf.pl (LoadFont): Extract UTF-16 code
	from font comment field (rather than a new field).
	(ParsePDFValue): Validate input more strictly.
	(do_x): Manage state more strictly; don't suspend a mark
	{hotspot} when one is not active, and don't restart it when one
	is not suspended.

2024-03-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/grog/grog.pl (do_line): Recognize new requests in
	forthcoming groff 1.24 release.  Update lists of characteristic
	package macros: for mm, add list management macros (except for
	`LI`, made ambiguous by groff_www(7)), unnumbered header macro,
	and `EPIC`; for man(7), drop `MT` (it is also an mm macro) and
	add `MR`, from groff 1.23.0 and plan9port.  Also discard closing
	brace escape sequence as not a legitimate macro name.

2024-03-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Simplify `Ql` macro behavior.

	* tmac/mdoc/doc-ditroff (Ql): Rip out most of the logic
	{counting and measuring arguments}, replacing it with a save and
	restore of the font family to temporarily use the Courier
	family.  The new behavior is: when formatting for terminals,
	`Ql`'s arguments are quoted; when formatting for typesetters,
	its arguments are set in Courier.  In practice, it does not seem
	difficult to distinguish even single characters in Courier from
	those in Times.  (If it is, an _explicit_ quoting macro like
	`Sq` or `Dq` should be used.)
	* tmac/groff_mdoc.7.man (Enclosure and Quoting Macros) <Ql>:
	* NEWS: Document this.

	See, e.g., <https://savannah.gnu.org/bugs/?61276>.

2024-03-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/mdoc/doc-ditroff (Dl): Refactor.  Instead of using the
	"literal" (`Li` macro) font, save the family, switch to Courier,
	emit the arguments, then restore the family.

2024-03-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Refactor.

	* tmac/doc.tmac: Move `Dl` macro definition from here...
	* tmac/mdoc/doc-ditroff:
	* tmac/mdoc/doc-nroff: ...to these files to prepare for changes
	to the "ditroff" version.

2024-03-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/mdoc/doc-ditroff: Align typesetting font defaults with
	terminal font defaults.  Change `Cm`, `Fl`, and `Li` to use bold
	instead of roman.

2024-03-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/doc.tmac: Add new string "array",
	`doc-display-fam-stack`, to maintain a stack of font family
	changes.
	(Bd): If the `-literal` argument is given, push the current font
	family onto the stack and select family `C`.
	(Ed): If we're ending a display of type "literal", pop the
	saved font family from its stack.
	(doc-save-global-vars, doc-restore-global-vars): Add this new
	string.

2024-03-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Change default font used for many macros when formatting
	for typesetters (cf. terminals).

	* tmac/mdoc/doc-ditroff: Stop switching to Courier family when
	setting arguments to the macros `Ar`, `Cm`, `Er`, `Fa`, `Fd`,
	`Fl`, `Fn`, `Ft`, `Ic`, `Li`, and `Nm`.

	Only you can prevent aneurysms; see discussion starting at
	<https://lists.gnu.org/archive/html/groff/2024-03/msg00152.html>
	and bear in mind that you can use the mdoc.local file to
	customize the font used to render nearly any mdoc(7) macro.
	This mechanism has been in place since 1992.

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

2024-03-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Add support for `MF` rendering option in parallel with
	groff man(7), and working much like the `HF` string.

	* tmac/doc.tmac (initialization): If the user specifies no `MF`
	string definition, define it as `I`.
	* tmac/mdoc/doc-ditroff:
	* tmac/mdoc/doc-nroff: Default `doc-page-identifier-font` and
	`doc-Xr-font` to use the value of the `MF` string.

	* NEWS:
	* tmac/groff_mdoc.7.man (Options): Document it.

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

2024-03-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/mdoc/doc-common ([initialization], Dt, Os, doc-header,
	doc-footer, doc-reset-titles, Rd):
	* tmac/mdoc/doc-ditroff:
	* tmac/mdoc/doc-nroff: Rename string `doc-page-topic` to
	`doc-page-identifier` and `doc-page-topic-font` to
	`doc-topic-identifier-font`, following terminological reform in
	groff_mdoc(7) (and groff_man(7)).

2024-03-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/main.cpp (main): Fix missing space in
	diagnostic message.

2024-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/{ja,ru,zh}.tmac: Add heuristic checks for glyph coverage
	of characteristic code points for these languages' scripts.
	Throw the warning only once for each language.  The formatter
	will merrily spew "special character ... not defined" error
	diagnostics for each non-covered glyph encountered; this leads
	people to complain that "groff doesn't support Unicode".  (This
	additional warning diagnostic might not help much; the error
	diagnostics already refer to characters in these scripts _by
	their Unicode code points_, which should be a clue, but too
	often isn't.)  And this one will slip through even if someone
	runs groff (or troff) with the `-E` option.  If you want to
	typeset Unicode, you have to use a font that covers Unicode.
	groff can't force one onto your system.  (We could do more to
	help the user configure one for use with groff, though; see
	Savannah #60930.)
	* src/roff/groff/tests/initialization_is_quiet.sh: Update test;
	check the "utf8" output device, not the "ps" default (which
	might not have been the configured default anyway), and which
	will lack glyph coverage for Chinese and Japanese (as the base
	14 fonts of Adobe PostScript lacked it).

2024-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (an-reset-paragraph-spacing, RS, RE): Trivially
	refactor.  Rename structurally named sets of registers emulating
	arrays (more precisely in this instance, stacks) to separate the
	index from the rest of the name with a `!` character, as is done
	in groff ms(7) and some other packages.  This makes the names
	more readable and less resembling of typos in the unfortunate
	event a troff(1) diagnostic message discloses their names to a
	hapless human reader.

2024-03-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (an-reset-paragraph-spacing): Assign
	`an-saved-margin1` the value of the `BP`, not the `IN` register.
	It makes no practical difference (because this is the
	"outermost" inset level), but the status quo ante made the
	inset register pushing and popping logic harder to reason about.
	Continues commit 5d2e49f818, 9 August.

2024-03-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/doc.tmac (Ar): Don't reset the selected font to its
	previous value when formatting `doc-str-Ar-default`; the latter
	string already takes care of this.

	* tmac/groff_mdoc.7.man (Arguments) <Ar>: Add a case of an
	interstitial ellipsis in an argument list, to demonstrate that
	the typeface gets reset correctly after the ellipsis.

	Fixes a post-1.23.0 regression.  Thanks to Lennart Jablonka for
	the report.  Problem introduced by me in commit df1fc139af, 3
	September.

2024-03-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/mdoc/doc-common: Trivially refactor.  Rename
	`doc-need-titles-reset` register to `doc-end-previous-document`,
	reflecting its newly narrowed purpose.

2024-03-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/mdoc/doc-common (doc-reset-titles): New macro pulls
	several string assignment operations to here...
	(doc-end-macro): ...from here, because they're needed more
	generally.
	(Dd): Call the new macro unconditionally.

	Fixes <https://savannah.gnu.org/bugs/?65480>.  Problem
	introduced by me in the 1.23.0 development cycle; I didn't
	bother to bisect it down to an individual commit because I know
	I churned parts of the macro package pretty vigorously to get
	batch rendering of mixed man(7) and mdoc(7) documents working
	correctly.  (And as we can see, I didn't _quite_ succeed.)

2024-03-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Regression-test Savannah #65480.

	* tmac/tests/doc_reset-data-between-documents.sh: Do it.
	* tmac/tmac.am (tmac_TESTS): Run test.

2024-03-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/doc.tmac (Xr): Fix copy-and-paste error that made all man
	page hyperlinks "internal".  Continues commit 4c59005ba0, 16
	March.

2024-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (an*scan-string-for-backslash): Choose an escape
	character that is much less likely than the at sign to be
	specified in a man(7) document's page footer.

	Fixes <https://savannah.gnu.org/bugs/?65469>.  Thanks to Thomas
	Dickey for the report.

2024-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/an_inner-footer-abbreviation-works.sh: Add
	regression test case for Savannah #65469.

2024-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Improve diagnostic message format (5/4).

	* tmac/doc.tmac (Bd, Ta, An):
	* tmac/mdoc/doc-syms (doc-St-usage): Use new `doc-report-usage`
	macro instead of hand-crafting diagnostic message with `tm`
	request.

	* tmac/doc.tmac (Bl): Drop unneccessary argumentless `tm` request.
	(doc-Bl-usage): Use three single-line `doc-report-usage`
	requests instead of writing a six-line diagnostic.  Both are
	regrettable--`Bl` is just crazily complex.
	(doc-defunct-macro): Use new `doc` string to construct bespoke
	diagnostic complaining of defunct macro usage.

	* tmac/doc.tmac (Bk):
	* tmac/mdoc/doc-common (LP, PP, pp, SH):
	* tmac/mdoc/doc-syms (At, Dx, Fx, Nx, St, Lb): Use new
	`doc-warn` macro instead of hand-crafting diagnostic message
	with `tm` request.

	Continues fixing <https://savannah.gnu.org/bugs/?52463>, which I
	should have known would not stay dead for long.  (And which I
	won't be surprised to see scrabble forth from the grave again.)

2024-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/doc.tmac (Xr): When formatting PDF, automatically attempt
	lookups of `Xr` destinations as internal bookmark tags.  If
	lookup succeeds, link to the within-document destination rather
	than an "external" URL like "man:foobar(1)".

	For example, this enables "outbound" links from the
	groff_mdoc(7) page to the other ~60 documents collected in
	"groff-man-pages.pdf".

2024-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/mdoc/doc-common (Os): When formatting PDF, automatically
	give each `Os` call a named PDF bookmark tag that can be used in
	links (inside the guts of the `Xr` macro).

	For example, this enables "inbound" links to the groff_mdoc(7)
	page in "groff-man-pages.pdf".

2024-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	[pdf,man,mdoc]: Refactor a recent feature.

	The "pdfhref pipe" feature recently added used in-band signaling
	to indicate that a PDF mark hotspot should be left open by the
	`pdhref` hyperlink management macro.  I'm uneasy with this
	because it forecloses the possibility of using the chosen
	in-band signal content as link text.  (Compounding the risk of
	user frustration is that there's no documentation of any of
	this.)  Replace it by adding a new `-S` flag to the `pdfhref`
	macro, indicating the caller's desire to manage closing of the
	hotspot themselves, as "tmac/an.tmac" does already.

	See <https://savannah.gnu.org/bugs/?61434#comment5>.

	* tmac/pdf.tmac (pdfhref): Initialize `pdf:href-S` register to
	zero (false).
	(pdf:href.opt-S): Define new alias for `pdf:href.flag`, so the
	{complex, Unix command-emulating} `pdfhref` argument management
	system treats it as a Boolean parameter.
	(pdf*href): Rename `pdf:href.pipe` register to
	`pdf:href.leave-mark-open`.  Throw error and don't honor "-S"
	parameter if the user has also specified a link text appendment
	with the "-A" option.  (If we're not closing the hotspot, we
	don't know where the appendment will go.)  Stop treating link
	text (the `PDFHREF.DESC` string) specially if it is "|".

	* tmac/an.tmac (an*end-hyperlink, MR):
	* tmac/doc.tmac (doc-begin-hyperlink-pdf): Migrate to new API.

2024-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/pdf.tmac (pdf*href): Fix derpy syntax error, introduced
	by me in commit cd9fde325f, 4 March.  Exposed by a pending
	change.

2024-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: When formatting PDF, attempt lookups of `MR` destinations
	as internal bookmark tags.  If lookup succeeds, link to the
	within-document destination rather than an "external" URL like
	"man:foobar(1)".

	* doc/GMPfront.t.in: Drop `END` dummy macro and redefinition of
	`MR` macro, moving the logic from here...
	* tmac/an.tmac (MR): ...to here, and trivially refactoring to
	rename variables for intelligibility.  Also simplify, using the
	"dangling open mark" incantation of the `pdfhref` macro that
	Deri innovated, since the existing logic unconditionally writes
	the link text subsequently.

2024-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: When formatting PDF, automatically give each `TH` call a
	named PDF bookmark tag that can be used in links (inside the
	guts of the `MR` macro).

	* doc/GMPfront.t.in (reload-man [appendment]): Move logic for
	declaring a named ("tagged") bookmark from here...
	* tmac/an.tmac (an*bookmark*pdf): ...to here.

2024-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/pdf.tmac (pdf*href): Fix problem with hotspot placement
	when there is no link text (illustrated by the "See also"
	section of pic(1) when rendered to PDF).  It is apparently
	necessary to flush the output buffer immediately after
	constructing certain device control nodes ("pdf: markstart" and
	"pdf: markend" in this case).  Deri understands this stuff
	better than I do; the misapprehensions I exhibited in Savannah
	#65052 might be related.  If that's the case, then the issue is
	maintaining synchrony between the formatter's idea of the
	drawing position and the output driver's.

2024-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Fix Savannah #64267.

	* tmac/an.tmac (an-reset-paragraph-spacing): Restore spacing
	{that is, cancel no-space mode} to handle a "belated" `PD` call
	immediately after a paragraphing macro (`P`, `HP`, or `IP` with
	no marker argument).

	Fixes <https://savannah.gnu.org/bugs/?64267>.  Thanks to Alex
	Colomar for the report.

2024-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Regression-test Savannah #64267.

	* tmac/tests/an_PD-restores-spacing.sh: Do it.
	* tmac/tmac.am (tmac_TESTS): Run test.

2024-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Fix Savannah #65464.

	* tmac/an.tmac (an*end-hyperlink): Unformat the diversion before
	emitting it.  This way adjustment of spaces will take place in
	the context where it's actually formatted, and be more
	appropriate to the line.

	* tmac/tests/an_adjust-link-text-correctly.sh: Update test
	expectations.  The only change here was to adjustment parity.

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

2024-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Fix Savannah #65462.

	* tmac/an.tmac (TP): Save the existing adjustment mode before
	disabling adjustment in the diversion used to format the
	paragraph tag.
	(an*TP-trap): Restore the saved adjustment mode after closing
	the diversion, instead of using the configured default
	adjustment mode.

	Fixes <https://savannah.gnu.org/bugs/?65462>.  Thanks to Russ
	Allbery for the report.

2024-03-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Regression-test Savannah #65462.

	* tmac/tests/\
	an_adjustment-mode-preserved-after-paragraph-tag.sh: Do it.
	* tmac/tmac.am (tmac_TESTS): Run test.

2024-03-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/indxbib/indxbib.cpp: Validate `-h` option arguments
	more carefully.
	(main): Insist on an argument value of at least 2, since a hash
	table of size 1 is pointless.
	(check_integer_arg): Try to be more robust in the face of
	C/C++'s notoriously lax integer sizing practices.  We might
	consider gnulib's "xstrtol" module.  Promote `-h` argument
	validation errors to `fatal()`.  Only perform a comparison
	against INT_MAX if LONG_MAX is larger than INT_MAX in the first
	place.  Report the supported range in range diagnostics.  Use
	C++- instead of C-style type cast of result.

	Mitigates, but arguably does not fix,
	https://savannah.gnu.org/bugs/?65452>.  Thanks to Alex Colomar
	for the report.

2024-03-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Improve diagnostic message format (4/4).

	* tmac/doc.tmac (doc-report-usage): Add internal macro for
	reporting usage error diagnostics.  Arrange message per GNU
	Coding Standards, including report of input filename.

	* tmac/doc.tmac (doc-generic-macro, Cd, Fd, In, Nm, Tn, Ns, Ap)
	(Bf, Ek, El, doc-Xr-usage, doc-column-list, Dl, D1, Vt, Ft, Fa)
	(Fn, Fo, Rs, Re, %A, %B, %C, %D, %I, %J, %N, %O, %P, %Q, %R, %T)
	(%U, %V, An, Rv, Ex, doc-Mt-usage, doc-Lk-usage):
	* tmac/mdoc/doc-common (Sh, Ss):
	* tmac/mdoc/doc-ditroff (Ql):
	* tmac/mdoc/doc-nroff (Ql):
	* tmac/mdoc/doc-syms (Lb): Use it.

	Fixes <https://savannah.gnu.org/bugs/?52463> (at long last).

2024-03-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Improve diagnostic message format (3/4).

	* tmac/doc.tmac (doc-warn): Add internal macro for reporting
	warning diagnostics.  Arrange message per GNU Coding Standards,
	including report of input filename.

	* tmac/doc.tmac (doc-generic-macro, Pf, Bf, Ef, Bk, Ek, Bd)
	(doc-do-Bd-args, Ed, Bl, doc-do-Bl-args, It, doc-end-list, Re)
	(doc-print-reference, em):
	* tmac/mdoc/doc-common (Dd, Dt, Os, doc-check-depth): Use it.

2024-03-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Improve diagnostic message format (2/4).

	* tmac/doc.tmac (doc-err): Add internal macro for reporting
	error diagnostics.  Arrange message per GNU Coding Standards,
	including report of input filename.
	(It, doc-fo-func-args, Fo, Fc, %V, Lk, doc-defunct-macro): Use
	it.

2024-03-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Improve diagnostic message format (1/4).

	* tmac/doc.tmac: Add new `doc` string recording the name the
	macro package self-reports.  Use it when issuing diagnostics
	about rendering parameters (register and string settings) that
	can't be honored.

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

	* src/roff/troff/input.cpp: Trivially refactor.
	(encode_char_for_troff_output): Rename this...
	(encode_char_for_device_output): ...to this.
	(do_device_control): Update call site.

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

	* src/roff/troff/input.cpp: Refactor.  Pull delimiter character
	validator into its own function operating on a character, rather
	than on an object of the token class.
	(is_char_usable_as_delimiter): New function compares `char`
	parameter to list of valid delimiters.
	(token::is_usable_as_delimiter): Refactor to call the foregoing.

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

	* src/roff/troff/input.cpp (is_usable_as_delimiter): Fix code
	style nit, using C++-style type cast instead of C-style cast.

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

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

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

	* tmac/pspic.tmac (PSPIC): Prepare for alteration of `\X` device
	control escape sequence to read its argument in copy mode; use
	nested backslashes instead of `\E`, which cannot meaningfully
	persist into the device-independent output.  (The *roff escape
	character is not only undefined but meaningless in that file
	format.)

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

	* src/roff/troff/node.cpp (ascii_output_file::outc)
	(ascii_output_file::outs, put_string, troff_output_file::put)
	(ascii_output_file::really_transparent_char)
	(ascii_output_file::really_print_line): Guard uses of standard C
	library `putc()` and `fputc()` functions with a null pointer
	check.  They could fail if the output stream has been
	invalidated.  Problem present from groff's birth and apparently
	exposed by man-db man's use of AppArmor.  See
	<https://bugs.launchpad.net/ubuntu/+source/lintian/+bug/2055402>
	and follow-up discussion there.

	Fixes <https://savannah.gnu.org/bugs/?65427>.  Thanks to an
	anonymous submitter for the report.

2024-03-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/pdf.tmac (pdf*href): Fix (harmless?) `ie`/`if` thinko.

2024-03-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[pdf]: Implement linear bookmark tag search.

	* tmac/pdf.tmac (pdf:lookup): Given an argument, search defined
	bookmark tags for a match and return one (if found) in the
	string `pdf:lookup-result`, which is defined but empty if there
	is no match.  Previously (and, for mom(7), still--see below),
	lookups were O(1) because strings named `pdf:look($TAG_NAME)`
	were defined.  The speed was great but unfortunately, in
	practical use, tags often got *roff escape sequences stuck into
	them, which drew diagnostic messages from the formatter and
	could defeat the matches.
	(pdfbookmark, pdf*href-M): Use the new mechanism to record a
	bookmark tag if `PRINTSTYLE` (a mom(7) macro) is _not_ defined,
	so as to not regress documents using that package.  Store the
	tag text in the string `pdf:bm\\n[pdf:bm.nr].tag`; every PDF
	bookmark in a groff document gets a serial number already.
	(pdf*href): Use the new mechanism to call `pdf:lookup` and
	locate a match for the desired tag.

	* doc/GMPfront.t.in (an*cln): Delete this macro.  It iterated
	through a string, scrubbing it of `\%` escape sequences.  Much
	more exotic things could be placed in bookmark tags; we were
	fortunate that man page cross references tend to stick to ASCII,
	plus `\%` to suppress hyphenation.  But that's suitable only for
	man page references; if we want taggable (sub)section headings,
	like groff_mmse(7)'s "Se också", we need strings, not just valid
	groff identifiers.
	(an*bookmark): Populate `an*page-ref-nm` without cleaning it
	first.

2024-03-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/GMPfront.t.in: Resync `MR` replacement with its
	counterpart in "an.tmac".

2024-03-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/pdf.tmac (pdf*href): Fix excess escaping.

2024-03-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/pdf.tmac (pdfclean): Fix missing closing brace escape
	sequence.  Appears to have done no damage; possibly the end of
	the macro definition reset the formatter's state.  Or maybe we
	simply got lucky with diversions with the documents in our tree.

2024-03-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Improve encoding of *roff string contents when
	interpolated into device control escape sequences.

	* src/roff/troff/input.cpp (encode_char_for_troff_output):
	Discard several escape sequences from `\X` contents when
	interpolated: `\%`, `\:`, `\&`, `\)`.  Interpolate the escape
	character into device-independent output as `\` no matter what
	the *roff escape character is defined to be.

	* src/roff/groff/tests/\
	device-control-special-character-handling.sh: Update test
	expectations.  Comment out some tests that depended on a
	reverted commit of a half-baked idea.  (See Savannah #64484.)

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

	* tmac/an.tmac: Add experimental feature to support increasing
	the base level of PDF bookmarks.  Define register
	`an*bookmark-base-level`, initialized to zero.
	(PT): Add 1 to it when producing document bookmark.
	(SH): Add 2 to it when producing section heading bookmark.
	(SS): Add 3 to it when producing subsection heading bookmark.

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

	[man]: Accept `MR` calls with only one argument.

	* tmac/an.tmac (MR): If only one argument is present, do not
	hyperlink it, but do set it with (potential) italic corrections.
	Prompted by a similar change Deri James applied in
	doc/GMPfront.t.in, and for consistency with the way we've long
	handled the analogous `Xr` macro in mdoc(7).
	* tmac/groff_man.7.man.in (Hyperlink macros) <MR>: Update macro
	synopsis and description.

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

	* tmac/pdf.tmac: Add internal flag register
	`pdf*is-mark-suspended`.
	(pdfmarksuspend, pdfmarkrestart): Use it to avoid sending
	PDFMark restart commands when they haven't been suspended.

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

	* tmac/an.tmac (PT): Be consistently paranoid.  The idea of a
	"page ref string" (like "ls(1)") with leading space in it
	strikes me as dubious, but for the time being we accept it; do
	so consistently.

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

	* tmac/an.tmac (SH): Fix code style nit.

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

	* tmac/doc.tmac (Xr): Support the crazy old menagerie of Mac OS
	X/macOS man page URL formats as groff man(7) does.

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

	* tmac/an.tmac (MR): Fix "format 4" URLs to include the section
	number again in parentheses after the identifier.

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

	* tmac/doc.tmac (Xr): Fix dead store to string.

2024-03-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* NEWS:
	* doc/groff.texi.in:
	* man/groff.7.man:
	* man/groff_diff.7.man: Document new `hydefault` feature.

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

2024-03-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tmac]: Migrate localization packages to `hydefault` request.

	* tmac/cs.tmac:
	* tmac/de.tmac:
	* tmac/en.tmac:
	* tmac/es.tmac:
	* tmac/fr.tmac:
	* tmac/it.tmac:
	* tmac/ru.tmac:
	* tmac/sv.tmac: Set the hyphenation mode default appropriately
	per the hyphenation patterns and the value of the trap-awareness
	bit.

	* tmac/ja.tmac:
	* tmac/zh.tmac: Set the hyphenation mode default to zero.

2024-03-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (hyphenate_request): If given no
	argument, set hyphenation mode to the configured default.

2024-03-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Add new `hydefault` request.

	* src/roff/troff/env.cpp (set_hyphenation_mode_default): New
	function sets the environment's default hyphenation mode.
	(init_env_requests): Wire up `hydefault` to foregoing function.
	* src/roff/troff/env.h (class environment): Declare foregoing
	function as a friend, permitting mutator access.

2024-03-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (init_env_requests): Set up `hla`
	request and `.hla` register here, since they're
	environment-specific...
	(init_hyphenation_pattern_requests): ...instead of here.

2024-03-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (init_hyphen_requests): Rename this...
	(init_hyphenation_pattern_requests): ...to this.
	* src/roff/troff/input.cpp (main): Update call site.
	* src/roff/troff/request.h: Update declaration.

2024-03-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Add `.hydefault` read-only register storing the
	environment's default hyphenation mode.

	* src/roff/troff/env.h (class environment): Add private member
	variable `hyphenation_mode_default` and declare public member
	function (accessor) `get_hyphenation_mode_default`.
	* src/roff/troff/env.cpp (environment::get_hyphenation_mode):
	Implement.
	(environment::environment): Initialize new member variable in
	ordinary and copy constructors.
	(environment::copy): Copy new member variable.
	(environment::print_env): Report environment's hyphenation mode
	default.
	(init_env_requests): Wire up hyphenation mode default value to
	`.hydefault` troff register.
	(class hyphenation_default_mode_reg): Add class.
	(hyphenation_default_mode_reg::get_string): Implement.

2024-03-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp:
	* src/roff/troff/env.h:
	(environment::get_adjust_mode):
	(environment::get_hyphenation_mode): Migrate report of these
	quantities to use "unsigned int" type instead of a signed type;
	this is more consistent with their internal storage, more
	appropriate given their use as bit vectors, and more
	future-proof in the event their meaningful values ever carry
	them close to the sign bit (let's hope not).

2024-03-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Add support for read-only numeric
	registers backed by unsigned integer values.  Define new type
	alias `UNSIGNED_FUNCP`.  Define new C++ prepreprocessor macro
	`init_unsigned_env_reg`, paralleling `init_int_env_reg`.
	(class unsigned_env_reg): Add new class; just like `int_env_reg`
	except it's for use with "unsigned int" member variables.
	(unsigned_env_reg::unsigned_env_reg)
	(unsigned_env_reg::get_value)
	(unsigned_env_reg::get_string): Implement.

2024-03-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp (environment::print_env): Report
	environment's numeric hyphenation mode, not just its meaning.

2024-03-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor (hyphenation flags->mode).

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp (class environment):
	- Rename `hyphenation_flags` to `hyphenation_mode`.
	- Rename `get_hyphenation_flags` to `get_hyphenation_mode`.

	* src/roff/troff/env.cpp (environment::get_hyphenation_flags):
	Rename this...
	(environment::get_hyphenation_mode): ...to this.

	(environment::get_hyphenation_mode):
	(environment::environment):
	(environment::copy):
	(no_hyphenate):
	(environment::hyphenate_line):
	(environment::print_env):
	(init_env_requests): Update member function and variable
	references.

2024-03-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: `mso` request no longer rewrites its argument to search
	for a file other than that named in the argument.

	* src/roff/troff/input.cpp (do_macro_source): Drop logic that
	attempts to open a macro file named "tmac.s" if "s.tmac" was
	specified in the argument and not found, or vice versa.

	* NEWS:
	* doc/groff.texi.in (I/O):
	* man/groff_diff.7.man (New requests): Document it.

	See
	<https://lists.gnu.org/archive/html/groff/2024-02/msg00086.html>
	and follow-ups.

2024-02-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Implement hyperlink support.

	* tmac/doc.tmac: Recognize `U` register as man(7) does to enable
	hyperlinking, defaulting on.
	(doc-begin-hyperlink-ascii):
	(doc-begin-hyperlink-cp1047):
	(doc-begin-hyperlink-latin1):
	(doc-begin-hyperlink-utf8):
	(doc-begin-hyperlink-html):
	(doc-begin-hyperlink-pdf):
	(doc-end-hyperlink-ascii):
	(doc-end-hyperlink-cp1047):
	(doc-end-hyperlink-latin1):
	(doc-end-hyperlink-utf8):
	(doc-end-hyperlink-html):
	(doc-end-hyperlink-pdf): New macros produce appropriate device
	control commands to start and stop hyperlinking of formatted
	text.
	(doc-begin-hyperlink-nop, doc-end-hyperlink-nop): New do-nothing
	macros handle user-driven hyperlink disablement for devices
	lacking hyperlink support.  Create aliases for the "X100",
	"X100-12", "X75", "X75-12", "dvi", "lbp", "lj4", and "ps"
	devices corresponding to these.
	(doc-Xr-usage, doc-Mt-usage, doc-Lk-usage): New macros eliminate
	repeated logic to emit usage messages.
	(Xr): Heavily rewrite to support production of hyperlinked
	argument text.  In mdoc, there appears to be no mechanism to
	inject macro calls later in the argument stream.  To correctly
	place a `doc*end-hyperlink` call, we must parse (optional)
	arguments ourselves until we have seen enough to know we've
	reached the end of the link text (an inline macro call,
	punctuation, or the end of the input line).  Throw usage
	diagnostic in more cases of bad input.
	(Mt): Include "mailto:" schema in generated hyperlink but not in
	visible link text.
	(Mt, Lk): Call device-appropriate `doc-{begin,end}-hyperlink`
	macros.
	(Lk): Hyperlink argument only if it is a "string" (mdoc parlance
	for formattable text as opposed to a macro name or punctuation).
	Format link text as groff man(7) does, not like mandoc(1) does,
	with its "link-text: <url>" presentation.
	* tmac/mdoc.local: Add commented code illustrating how to
	disable hyperlinking.

	* tmac/tests/doc_Lk-respects-sentence-ending-punctuation.sh:
	* tmac/tests/doc_Lk-works.sh:
	* tmac/tests/doc_Mt-works.sh:
	* tmac/tests/doc_Xr-works.sh:
	* tmac/tests/doc_heading-font-remapping-works.sh: Update test
	expectations and check output when hyperlink output enabled and
	disabled.

	* NEWS:
	* tmac/groff_mdoc.7.man (Options): Document it.

2024-02-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/doc_Xr-works.sh: Add checks of inline `Pf` and `Ns`
	call behavior after `Xr`.

2024-02-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/doc_heading-font-remapping-works.sh: Dump output of
	test case in plain text in addition to device-independent *roff
	format.

2024-02-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Rename a test.

	* tmac/tests/doc_Lk-respect-sentence-ending-punctuation.sh:
	Rename this...
	* tmac/tests/doc_Lk-respects-sentence-ending-punctuation.sh:
	...to this.
	* tmac/tmac.am (tmac_TESTS): Update.

2024-02-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/doc_Xr-works.sh: Unit-test `Xr` macro.
	* tmac/tmac.am (tmac_TESTS): Run test.

2024-02-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (an*end-hyperlink): Fix bug: when no link text
	was supplied, the fallback link text (the hyperlink itself) was
	not appearing in PDF output.  This bug was masked by another:
	the "no link text supplied" branch was never being taken because
	the wrong diversion dimension register was being tested.  Test
	register `dl` instead of `dn` and annotate the reasoning.  Emit
	the trailing text in two places in the logic, since the
	`pdfhref` macro takes over this function with its `-A` parameter
	{which we now use}, but wasn't designed to accommodate the use
	case where we start the mark with one call and close it with
	another, which we use for the "no link text supplied" case.

2024-02-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/an_UR-works.sh: Add tests of PDF output, using
	pdftotext(1) (from poppler-utils) to scrape the text from PDF.

2024-02-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/pdf.tmac (pdfbookmark): Validate bookmark level argument;
	complain if it is not a numeric expression and treat it as "1".

2024-02-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (an*end-hyperlink): Trivially refactor.  Store
	the first argument in a string named `an*trailing-text` (and use
	it) to clarify later logic.  Delete the string when done.

2024-02-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Trivially refactor.

	* tmac/an.tmac: Revise mechanism for detecting new page headings
	that should get a top-level bookmark.
	(an-end, (initialization)): Make new string
	`an*previous-page-ref-string` empty.
	(TH, PT): Drop `an*was-TH-bookmark-emitted` register.
	(PT): Compare `an*page-ref-string` to
	`an*previous-page-ref-string`; emit a bookmark if they differ.

2024-02-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Trivially refactor (DRY).

	* tmac/mdoc/doc-ditroff:
	* tmac/mdoc/doc-nroff: Move string definitions that are
	identical from here...
	* tmac/mdoc/doc-common: ...to here.

2024-02-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/mdoc/doc-nroff (ua): Define string as `ha` special
	character, not "^".  This is (probably) a matter only of
	pedantic correctness, as this definition takes place only in the
	"else" block of a conditional testing for the "utf8" output
	device, and no other supported nroff-mode device renders "^"
	surprisingly to ASCII nostalgics.

2024-02-20  Lennart Jablonka <humm@ljabl.com>

	* src/preproc/eqn/main.cpp: This file includes header
	<stdlib.h>.  As part of the C++ standard library, <stdlib.h>
	provides a bunch of stuff, including `atexit()`, in the global
	name space; it need not provide that stuff in the `std` name
	space.

	See <https://eel.is/c++draft/support.c.headers.other>.

2024-02-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/psrm.cpp
	(resource_manager::read_download_file): Stop interpreting spaces
	as token delimiters, so that PostScript font files with spaces
	in their names can be handled (read and embedded in the
	generated PostScript).
	* src/devices/grops/grops.1.man (Usage): Update documentation.

	* NEWS: Add item reporting this user-visible change.

	Fixes <https://savannah.gnu.org/bugs/?65246>.  Thanks to Deri
	James for the report.

2024-02-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[output drivers]: Reset line number at end of input.

	* src/devices/grodvi/dvi.cpp (dvi_printer::~dvi_printer):
	* src/devices/grohtml/post-html.cpp
	(html_printer::~html_printer):
	* src/devices/grolbp/lbp.cpp (lbp_printer::~lbp_printer):
	* src/devices/grolj4/lj4.cpp (lj4_printer::~lj4_printer):
	* src/devices/grops/ps.cpp (ps_printer::~ps_printer):
	* src/devices/grotty/tty.cpp (tty_printer::~tty_printer): Clear
	line number when tearing down output writer so that diagnostic
	messages aren't emitted with a misleading (and nonexistent) line
	number (the number of lines in the device-independent output
	file plus one).  The PostScript driver in particular does large
	amounts of processing at this point (like resolving PostScript
	resources).  The problem is more theoretical for other output
	drivers, but done for consistency.

2024-02-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/string.cpp (string::string): When
	constructing a new string from a pointer to char, if the
	pointed-to-string doesn't exactly fit the storage reserved for
	it, populate the storage with null bytes before copying, to
	avoid reads of garbage heap memory.

2024-02-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/psrm.cpp (resource::resource): Spell "file
	name" thus in diagnostic message.  It's English, not C.

2024-02-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/psrm.cpp (resource_manager::output_prolog):
	Report underlying system error when `putenv()` fails.

	* src/devices/grops/psrm.cpp (resource_manager::output_prolog):
	(resource_manager::supply_resource)
	(resource_manager::read_download_file): Parallelize wording of
	diagnostic messages.

2024-02-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/ps.cpp: Promote type definition to global
	scope and deanonymize it as `proc_table_t` so we can use it with
	`array_length` template.

	* src/devices/grops/psrm.cpp: Promote `comment_info` type
	definition to global scope so we can use it with `array_length`
	template.

	* src/devices/grops/ps.cpp (ps_printer::special):
	* src/devices/grops/psrm.cpp: Slightly refactor; migrate from
	`sizeof` and division operators to groff's `array_length`
	template function.
	(resource_manager::read_resource_arg, parse_extensions)
	(resource_manager::process_file)
	(resource_manager::print_extensions_comment): Switch types of
	loop indices iterating over these objects from `int`s of various
	signedness to `size_t`.
	(resource_manager::process_file)
	(resource_manager::read_download_file): Use `sizeof` operator
	idiomatically; it is an operator, not a function, and should be
	followed by parentheses only when making it operate on a type
	cast to get the size of a non-lvalue.

2024-02-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/pdf.tmac (pdfbookmark): Drop unused register storing
	computed length of `pdf:clean` string, `pdf:clean:len`.

2024-02-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (do_define_string, length_request):
	Drop redundant diagnostic message on invalid string identifiers.

2024-02-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	[pdf]: Regression-test Savannah #65320.

	* tmac/tests/pdf_bookmark-starting-with-control-char-works.sh:
	Do it.
	* tmac/tmac.am (tmac_TESTS): Run test.
	(tmac_XFAIL_TESTS): Mark as an expected failure since resolution
	of this bug is blocked by resolution of Savannah #65322.

2024-02-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Implement `.it`, `.itc`, and `.itm` registers.  These
	read-only (and, in the case of `.itm`, string-valued as well)
	registers report the number of lines remaining in a pending
	input trap, a Boolean indication of whether that pending input
	trap honors output line continuation (cf. the `it` and `itc`
	requests), and the name of the macro associated with the pending
	input trap, respectively.

	* src/roff/troff/env.h (class environment): Declare new member
	functions to retrieve these data.
	* src/roff/troff/env.cpp
	(environment::get_input_trap_line_count)
	(environment::get_input_trap_respects_continuation)
	(environment::get_input_trap_macro): Implement them.
	(environment::environment): Update constructors to initialize
	`input_trap_count` to "-1", as a hint that no input trap has
	ever been sprung in the environment.  (After one has, the count
	remains at zero and the name of the macro associated with the
	last trap that was sprung remains in `.itm`, until a new input
	trap is planted or explicitly cleared.)
	(environment::copy): Set the input trap line count to "-1".
	(do_input_trap): Update `it`/`itc` request handler.  Reset the
	input trap line count to "-1" and null out the associated macro
	name.  If the `it` or `itc` requests are given no arguments,
	this is the situation that persists.  Recast diagnostic message
	when attempting to set a nonpositive input line count.
	(init_env_requests): Hook up the new register names to accessor
	functions.

	* doc/groff.texi.in (Input Line Traps):
	* man/groff.7.man (Read-only registers):
	* man/groff_diff.7.man (New registers): Document them.

	* NEWS: Add item.

2024-02-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: The `color`, `cp`, `linetabs`, and `vpt` requests now
	interpret arguments with negative values as instructions to
	disable the corresponding feature, using the *roff
	integer-to-Boolean conversion idiom instead of the C/C++ one.
	Thus, if you invoke these requests with a register
	interpolation, the outcome agrees with an `if` test of the
	register's value.

	* src/roff/troff/div.cpp (vertical_position_traps):
	* src/roff/troff/env.cpp (widow_control_request) [WIDOW_CONTROL]
	(line_tabs_request):
	* src/roff/troff/input.cpp (activate_color, compatible): Do it.

	* doc/groff.texi.in (Tabs and Fields, Colors)
	(Vertical Position Traps, Compatibility Mode):
	* man/groff.7.man (Syntax reference conventions)
	(Request short reference):
	* man/groff_diff.7.man (New requests): Document it.

	* NEWS: Add item.

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

2024-02-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	Update default search path for URW fonts; Fedora 39 has come up
	with a new place for them.

	* font/devpdf/Foundry.in: Do it (at run time).
	* m4/groff.m4 (GROFF_URW_FONTS_CHECK): Do it (at build time).

	Thanks to T. Kurt Bond for the report to the groff mailing list.
	<https://lists.gnu.org/archive/html/groff/2024-02/msg00018.html>

2024-02-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	Put version number on cover page of our Texinfo manual.

	* doc/groff.texi: Rename this...
	* doc/groff.texi.in: ...to this.
	* doc/doc.am (EXTRA_DIST): Add "doc/groff.texi.in".
	(MAINTAINERCLEANFILES): Add "doc/groff.texi".
	(doc/groff.texi): Add rule for constructing "groff.texi" from
	"groff.texi.in", using `DOC_SED` macro of course.
	(doc/groff.info): Update dependency and construction to use the
	now-generated "groff.texi" (so look for it in the build
	directory).
	(maintainer-clean-local): Delete "doc/groff.texi".

	* doc/groff.texi.in: Replace "1.23.0+Git" with "@VERSION@".

2024-02-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	Put version number on cover page of collected man pages.

	* doc/GMPfront.t: Rename this...
	* doc/GMPfront.t.in: ...to this.
	* doc/GMPfront.t.in: Add `@VERSION@` token.  Set it in 10-point
	italics.  Reduce subsequent vertical spacing.  This looks better
	to my eye with the added material, but Deri's eye is better.
	* doc/doc.am (DOCFILES_NOINST): Update to reflect rename.
	(DOC_GMP_COVER_PAGE): Add new macro to house the generated
	file's name, "doc/GMPfront.t".
	($(DOC_GMP_COVER_PAGE)): New target creates this file from its
	*.in.  Use existing `DOC_SEC` make(1) macro to perform version
	substitution.
	(doc/groff-man-pages.pdf): Migrate dependency and construction
	to now-generated `$(DOC_GMP_COVER_PAGE)` file.
	(MOSTLYCLEANFILES): Add `$(DOC_GMP_COVER_PAGE)`.

2024-02-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (doc/groff-man-pages.pdf): Add dependency on
	"pdfmom".

2024-02-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp
	(non_interpreted_char_node::non_interpreted_char_node): Rename
	parameter from `n` to `cc`; it is of `unsigned char` type, and
	GNU troff's code uses `n` as a pointer to `node` type
	ubiquitously.  It also uses `c` for an `unsigned char` type
	pretty reliably, but that is already a private member variable
	for this class.

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

	* tmac/an.tmac (TH): Set up end macro unconditionally here...
	(an-set-up-continuous-rendering): ...instead of here.

	* tmac/tests/an_TP-works.sh: Add test case for the specimen of
	ill-formed input that the foregoing remedies (ending input with
	a pending input line trap and continuous rendering disabled).

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

	* src/roff/troff/env.cpp (print_hyphenation_exceptions): Flush
	the standard error stream once the list is written.

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

	[man]: Back away from color management concerns.

	Hyperlink colors in PDF were showing a tendency to get "stuck
	on" when they shouldn't, and the extra difficulty of managing
	nested traps (`TP` followed by `UR`, for example) is proving
	tricky to sort out.  On top of that, the man(7) package
	historically has no cognizance of color issues and it doesn't
	seem like a good time to start, particularly if we only do it
	for the 'pdf' output device.

	* tmac/an.tmac (an-input-trap): Set stroke color to default
	after springing `TP`'s supporting trap.
	(an*begin-hyperlink, MR): Stop saving the stroke color.
	(an*end-hyperlink, MR): Stop restoring the saved stroke color.
	Set it to the default instead after formatting the link text.

2024-02-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Fix Savannah #61434.

	* tmac/an.tmac: Support `UR`/`UE` and `MT`/`ME` hyperlinks as
	paragraph tags.
	(an*begin-hyperlink): Kick away the guard that prevented
	attempts to do so, now that support has been refactored in
	underneath it.

	* tmac/groff_man.7.man.in (Hyperlink macros): De-document lack
	of support for this.  Retain caveat that if the output device
	lacks hyperlink support, the hyperlink is typeset as part of the
	paragraph body rather than the tag.  I could not see any way to
	achieve the alternative given the way this package uses traps
	and diversions.  We might make a virtue of necessity by noting
	that paragraph tags could be lengthy, and URLs often will be,
	and it will be hella ugly to have the tag break.  Furthermore,
	if we implement automated generation of link anchors based on
	`TP` paragraph tags, not having their destination URLs in the
	tag text means we don't have to scrape them out later.

	* tmac/tests/an_link-macros-work-in-paragraph-tags.sh: Update
	test expectations.

	* NEWS: Add item.

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

2024-02-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Refactor.  Give `TP` its own trap.
	(an*TP-trap): New macro takes over some of the former functions
	of `an-input-trap` and `an-write-paragraph-tag`, ending the
	paragraph tag diversion, restoring the adjustment mode and line
	length, and calling `an-write-paragraph-tag`...
	(an-write-paragraph-tag): ...which now deals only with
	formatting the tag.
	(an-input-trap): Ensure that `an*TP-trap` is sprung when input
	line traps overlap...
	(an-end): ...and when an ill-formed document ends with an input
	trap pending.

2024-02-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Refactor.
	(TH, an-write-paragraph-tag, an-input-trap, TP): Replace
	register `an*is-in-paragraph-tag-diversion` with
	`an*have-paragraph-tag` changing its meaning to indicate whether
	we have collected a paragraph tag in a diversion that we need to
	output.
	(TP): Detect nesting of `TP` or `TQ` by testing name of current
	diversion instead of `an*is-in-paragraph-tag-diversion`
	register.

2024-02-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (TP): Don't set up an input trap if we're bailing
	out of the macro due to invalid nesting.

2024-02-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Refactor to distinguish visible hyperlinks from
	those that are sent only to device control commands.
	(an*begin-hyperlink): Rename existing string `an*hyperlink` to
	`an*visible-hyperlink`, which is the argument passed in via `UR`
	and `MT` calls.  Redefine `an*hyperlink` as the same argument,
	but with the `an*prefix` that its caller may specify.  (This
	feature is used to get the "mailto:" URI scheme into links but
	not clutter the page text with them.)
	(an*end-hyperlink): Use `an*hyperlink` in device control
	commands instead of the catenation of `an*prefix` and
	`an*hyperlink`.  When there is no link text, use
	`an*visible-hyperlink` for it.  Remove both of these strings
	when done with them.

2024-02-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Fix code style
	nit.  Use `sizeof` operator instead of `strlen()` to compute
	length of string literal at compile time.  Prompted by warning
	from Clang 17.

2024-02-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (an-end): Call `an-input-trap`.  If a document
	ends with an input trap pending, this ensures that any text on
	the applicable input line will be emitted, better accommodating
	ill-formed documents.

2024-02-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/an_TP-works.sh: Add unit test.
	* tmac/tmac.am (tmac_TESTS): Run test.

2024-02-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grotty/tty.cpp (tty_printer::special): Improve
	diagnostic message when handling unsupported device control
	command: report name of unrecognized tag.

2024-02-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/an_MT-works.sh:
	* tmac/tests/an_adjust-link-text-correctly.sh: Add more checks
	to test cases.

	* tmac/tests/an_MT-works.sh: Also stop worrying about the exact
	placement of adjustment spaces in this test.

2024-02-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Refactor.
	(an*begin-hyperlink): Before changing the stroke color to
	typeset the link text, save it in new string
	`an*saved-stroke-color` (as `MR` already does).
	(an*end-hyperlink): After setting hyperlinked text, restore the
	stroke color using the string we created for the purpose, not
	the mysterious internal "pdf.tmac" string `pdf:curcol`.  Delete
	string afterward.

2024-02-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Trivially refactor (an-write-paragraph-tag):
	Rename `an-env-paragraph-tag` to `an*temporary-env`.
	(an*end-hyperlink, MR): Use idiomatic delimiter in device
	control escape sequences.

2024-02-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor; rename and boolify.

	* src/roff/troff/env.h (class environment): Demote member
	function `do_input_trap`'s parameter type from `int` to `bool`.

	* src/roff/troff/env.h (class environment):
	* src/roff/troff/env.cpp (class environment): Demote member
	variable `continued_input_trap` from `int` to `bool`.

	* src/roff/troff/env.cpp (class environment): Initialize member
	variable `continued_input_trap` with Boolean, not integer,
	literals.

	* src/roff/troff/env.cpp (do_input_trap): Demote argument from
	`int` to `bool` in definition...
	* src/roff/troff/env.h (class environment): ...and friend
	function declaration.

	* src/roff/troff/env.cpp (do_input_trap): ...and rename it from
	`continued` to `respect_continuation`.  Assign to
	`continued_input_trap` using Boolean literals.
	(input_trap, input_trap_continued): Call `do_input_trap` with
	Boolean literals.

2024-01-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/GMPfront.t: Save and restore the type size.  The effective
	base paragraph indentation was too large.  Since it is in ens,
	it turns out it was being calculated (as of the first man page
	rendered) based on the type size this cover sheet left it at,
	which was 16 points--a bit too big.

2024-01-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am ($(DOC_GNU_EPS)): Create "doc" destination
	directory before trying to create a file in it.  This bug has
	been latent (for out-of-tree builds) for ages, but has seemingly
	seldom or never arisen.  It seems that even in parallel builds,
	one of the many other "doc" targets that _did_ use the `MKDIR_P`
	make(1) macro nearly always won the race.  (In my experience, in
	builds from Git, the generated forms of our Texinfo manual could
	be relied upon to do this because they were near the root of the
	dependency tree; other groff targets tend not to depend on
	them.)  Anyway, fixed now.

2024-01-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (DOCFILES_INST): Ship "GMPfront.t" in the
	distribution archive.

2024-01-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (an*begin-hyperlink): Stop shutting off hyperlink
	support permanently if we hit one unsupported instance of `MT`
	or `UR` nested inside `TP`.

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

2024-01-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/GMPfront.t: Support non-internal man page cross
	references.  Port over contemporary implementation of `MR` from
	"an.tmac" to its local replacement in this file.  Also remove
	conditionals on the `.T` string matching "pdf".  Instead test
	this register once at the beginning of the file and skip it with
	the `nx` request if it doesn't match.  This lowers the
	complexity and average indentation level of the file.

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

2024-01-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/GMPfront.t: Bikeshed the collected man pages.  Retitle to
	"groff Collected Reference Pages".  Spell "groff" in full
	lowercase.  Favor requests over escape sequences.  Simplify
	means of setting page number.

2024-01-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (doc/groff-man-pages.pdf): Register dependency on
	"doc/GMPfront.t".

2024-01-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (MR): Support hyperlinked man page cross
	references in PDF.

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

2024-01-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp (table::add_entry): Recast recently
	added diagnostic message.

2024-01-26  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Changes to satisfy Savannah #65231.

	Alter build of groff-man-pages.pdf to use the new pdfmom,
	so that all forward references (i.e. reference to groff_font(5)
	in addftinfo(1) page) are handled properly. Also pass bookmark
	names as text strings.

	* doc/doc.am: Use pdfmom.
	* tmac/an.tmac: Pass parameters to .pdfbookmark as a string.

	New pdfmom, can now be used with all macros.

	Previously only useful for producing documents with
	mom.

	* src/devices/gropdf/pdfmom.pl: New --roff flag allows
	other macros (e.g. -ms) to be given on the command line.

	* src/devices/gropdf/pdfmom.1.man: Document the new facility.

	Front Cover for groff-man-pages.pdf

	Feel free to alter "artwork" at will (perhaps add maintainer
	information.

	* doc/GMPfront.t: Only used during build, not required as part
	of installation.

	Remove artifacts from using stringhex.

	Introduced in commit #e62b188aacb, betraying its origin
	from my deri-gropdf-ng branch which uses .stringhex.

	* src/devices/gropdf/gropdf.pl: minor fixes

	Fixes <https://savannah.gnu.org/bugs/?64060> (pdfmom needs
	`--help` option).

2024-01-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grog]: Fix Savannah #65227.

	* src/utils/grog/grog.pl (process_arguments): Match a 'C' only
	in a groff option cluster when deciding to enable compatibility
	mode, not any 'C' anywhere in any option.

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

2024-01-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Fix Savannah #65225.

	* src/preproc/tbl/table.cpp (table::add_entry): Fix regression
	in repeated glyph tbl(1) feature (`\R`), rendering it
	inoperative.  Problem introduced by me in commit 4f4b79b8aa, 26
	April 2022.  Restore logic to handle this table entry type.
	Also throw new error diagnostic if the repeated glyph token
	appears with no argument.  Also improve code style by reusing
	variable with already-computed entry string length instead of
	calculating it again.

	Fixes <https://savannah.gnu.org/bugs/?65225>.  Thanks to the
	anonymous submitter for a reproducing case and a correct
	suggestion of the offending commit.

2024-01-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Regression-test Savannah #65225.

	* src/preproc/tbl/tests/repeated-character-entry-works.sh: Do
	it.
	* src/preproc/tbl/tbl.am (tbl_TESTS): Run test.

2024-01-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Refactor diversion management.

	* tmac/an.tmac (TH, an-write-paragraph-tag, an-input-trap, TP):
	Rename `an-is-in-diversion` register to
	`an*is-in-paragraph-tag-diversion`.
	(an-write-paragraph-tag, TP): Rename `an-div` diversion to
	`an*paragraph-tag`.
	(an*begin-hyperlink, an*end-hyperlink): Rename
	`an*link-text-div` to `an*link-text`.
	(an-write-paragraph-tag, an*end-hyperlink): Delete diversions
	after using them.
	(an*end-hyperlink): Revise emission of link text diversion.
	(TP): Throw warning if macro is nested with itself or `TQ`.
	(an*begin-hyperlink): Throw warning if hyperlink already inside
	diversion.
	(TH): Initialize `an*is-in-link-text-diversion` register.
	(an*begin-hyperlink): Set `an*is-in-link-text-diversion`
	register.  Use the register for its intended purpose.  If a
	nested diversion is attempted, clear `an*do-hyperlink` register.
	(an*end-hyperlink): Clear `an*is-in-link-text-diversion`
	register rather than deleting it.

2024-01-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (MT, ME, UR, UE): Throw warnings on bad nesting.

2024-01-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (an*begin-hyperlink): Repair damage I introduced
	in commit 6f12a82806, 27 January.

2024-01-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/doc.tmac (Mt): Give macro a real implementation instead
	of wrapping `Pa`.  Among other benefits, this means that it
	recognizes a `doc-Mt-font` string for styling of the argument,
	instead of using the styling applied to `Pa`.

	* tmac/mdoc/doc-ditroff (doc-Mt-font):
	* tmac/mdoc/doc-nroff (doc-Mt-font): Define new strings.  Set
	email addresses in roman by default.

	* NEWS: Report change in font styling.

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

2024-01-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac:
	* tmac/doc.tmac: Slightly refactor.  Make the
	`an*is-output-html` and `doc-is-output-html` registers the
	{nearly} sole determinant (within each package) of behavior
	tailored for HTML output.  Annotate why we use each instead of
	testing `.T` string.

	* tmac/an.tmac (an*end-hyperlink, MR): Apply exceptions to the
	above rule when explicitly issuing device control escape
	sequences to embed HTML elements; only grohtml(1) can interpret
	these, not grops(1) when executed by pre-grohtml(1).

2024-01-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/doc_Lk-works.sh: Add unit test.
	* tmac/tmac.am (tmac_TESTS): Run test.

2024-01-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/doc.tmac (Mt, Lk): Validate arguments.

2024-01-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/doc_Mt-works.sh: Test "direct" `Mt` call.

2024-01-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Specialize `an*bookmark` macro by output device.
	(an*bookmark): Move former operation, conditional on 'pdf'
	output device, from here...
	(an*bookmark*pdf): ...to here.
	(an*bookmark): Make into a wrapper calling the device-specific
	macro.
	(an*bookmark*ascii, an*bookmark*cp1047, an*bookmark*dvi)
	(an*bookmark*html, an*bookmark*latin1, an*bookmark*lbp)
	(an*bookmark*lj4, an*bookmark*ps, an*bookmark*utf8): Define as
	empty strings.

2024-01-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Trivially refactor.
	(an*bookmark, an*header, an*footer, an*begin-hyperlink)
	(an*end-hyperlink, (initialization)): Retire `an*is-output-pdf`
	register (and interpolation-time checks of its value) in favor
	of (load-time) use of output comparison operator to check
	built-in `.T` string against value "pdf".

2024-01-26  Deri James  <deri@chuzzlewit.myzen.co.uk>

	Our documentation groff_man.7 documents that these requests are
	for hyperlinks. The .pdfhref W command expects the hotspot text
	to be passed as a parameter, but these pairs of requests enclose
	the required text. To solve this conundrum if the given
	hyperlink text to the .pdfhref request is the single pipe
	character "|" then mark all following text sent for output as
	the hotspot, terminate the hotspot on receipt of \X'pdf:
	markend' escape. This new facility is only available using -T
	pdf, not using -T ps and the pdfmark macros. Note the advice in
	the gropdf man page to use \X'pdf: marksuspend' and \X'pdf:
	markrestart' to protect any headers and footers becoming part of
	the hotspot in case the hyperlinked text crosses a page
	boundary.

	* tmac/an.tmac: add code to use .pdfhref W for these hyperlinks
	and protect against crossing page boundaries.

	* tmac/pdf.tmac: if the given text for a hyperlink consists of
	a single pipe character "|", start the hotspot and only
	terminate when \X'pdf: markend' is received.  Update hyperlink
	text color from RGB 0.35/0/0.6 to 0/0.35/0.6 (magenta-ish to
	cyan-ish).

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

2024-01-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor (trap Booleans).

	* src/roff/troff/div.h:
	* src/roff/troff/input.cpp: Rename trap-related flags and
	boolify them.  Assign to them using Boolean literals.
	- `trap_sprung_flag` -> `was_trap_sprung`
	- `postpone_traps_flag` -> `are_traps_postponed`

	* src/roff/troff/div.cpp (space_request):
	* src/roff/troff/env.cpp (pending_output_line::output)
	(environment::output)
	(environment::output_title)
	* src/roff/troff/input.cpp (process_input_stack, spring_trap)
	(postpone_traps, unpostpone_traps):
	Update variable access sites.

	* src/roff/troff/div.h:
	* src/roff/troff/input.cpp: Demote return type of
	`unpostpone_traps()` from `int` to `bool`.
	(unpostpone_traps): Return Boolean, not integer, literals.

2024-01-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/groff.texi: Resolve warnings thrown by Texinfo 7.1.

	Fixes <https://savannah.gnu.org/bugs/?64889>.  Thanks to Bjarni
	Ingi Gislason for the report.

2024-01-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Fix underspecified `getenv()` prototype.

	* src/libs/libgroff/getopt.c: Do it.  Seen when building groff
	  on a non-glibc-based system (clang 17 complains).

2024-01-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (doc/webpage.ms): Register dependency on
	"tmac/pspic.tmac".

2024-01-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (map_composite_character): Stop
	throwing diagnostic message when `composite` request invoked
	with only one argument.  This has long worked just fine to
	delete a composite character mapping.  That is something a
	{rare} user might conceivably want to do.

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

2024-01-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Implement new `pcomposite` request.

	* src/roff/troff/input.cpp (report_composite_characters): Add.
	(init_input_requests): Wire up `pcomposite` request name to
	`report_composite_characters()`.

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

2024-01-17  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (report_color): Flush standard error
	stream after dumping defined colors.  Trivially refactor to
	generalize and eliminate use of pointless temporary.  Continues
	commit e080a78c91, 5 January.

2024-01-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (encode_char_for_troff_output):
	Trivially refactor to make clearer what gets silently discarded
	from (and not encoded for) device control commands.

2024-01-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Re-fix Savannah #62471 (vrules in nroff and no-space
	modes).

	* src/preproc/tbl/table.cpp (do_top): Compensate harder for
	non-intersected vertical rules occurring at the top of a table
	in nroff mode.  The previous strategy would fail if no-space
	mode was on and the drawing position was at the top of a page,
	provoking an error from grotty ("output above first line
	discarded").  Restore spacing before issuing `sp` request.

	Continues fixing Savannah #62471, and commit 6ccdab9d64, 29
	December.

2024-01-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Add another test case.

	* src/preproc/tbl/tests/\
	do-not-overdraw-page-top-in-nroff-mode.sh: Add an eleventh test
	case, prompted by ascii(7) from Linux man-pages, where a table
	with a vertical rule got coincidentally rendered at the very top
	of a page (which can only happen in continuous rendering mode,
	where the page boundaries are invisible) while no-space mode was
	on (due to the table immediately following a paragraphing
	macro).

2024-01-14  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Retain plain ASCII labels when possible.

	* src/devices/gropdf/gropdf.pl: Do not use hexed label unless
	necessary.  Restores the ability for some PDF viewers to accept
	"#label" as suffix to the file name.

2024-01-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/\
	device-control-special-character-handling.sh: Add unit test for
	this feature.  We want to be able to consistently pass (some)
	special character escape sequences to device control commands,
	and we want the `device` request and `\X` escape sequences to
	behave consistently with each other.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2024-01-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (encode_char_for_troff_output):
	Qualify `c` argument as `const`.  Reorder comparisons to avoid
	inadvertent lvalue assignment.  (Yes--suspenders _and_ a belt.)

2024-01-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix code style nits.

	* src/roff/troff/input.cpp (device_request)
	(device_macro_request, output_request): Declare functions
	`static` since they do not require external linkage.

2024-01-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Add unit test for `\X` (device control) escape
	sequence.

	* src/roff/groff/tests/backslash-X-works.sh: Add test.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

2024-01-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Add unit test for `device` request.

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

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

2024-01-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/div.cpp (top_level_diversion::output)
	(top_level_diversion::transparent_output)
	(top_level_diversion::copy_file): Clarify diagnostic messages.

2024-01-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/div.cpp (top_level_diversion::begin_page):
	Demote return type from `int` to `bool`.  Return Boolean instead
	of integer literals.

	* src/roff/troff/div.h (class top_level_diversion): Update
	declaration.

2024-01-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Enhance new tests.

	* src/roff/groff/tests/\
	backslash-exclamation-early-does-not-fail.sh:
	* src/roff/groff/tests/output-request-early-does-not-fail.sh:
	Check that escape/request parameters don't get emitted before
	the output leader, and that they do show up in the output.

2024-01-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Add tests of early usage of formatter features that
	throw fatal errors when called "too early", but for which this
	error handling appears to be dead code.  Further test the
	`output` request in furtherance of Savannah #64959.

	* src/roff/groff/tests/\
	backslash-exclamation-early-does-not-fail.sh:
	* src/roff/groff/tests/cf-request-early-does-not-fail.sh:
	* src/roff/groff/tests/output-request-works.sh: Add tests.

	* src/roff/groff/groff.am (groff_TESTS): Run tests.

2024-01-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Revise diagnostics.

	* src/roff/troff/div.cpp (top_level_diversion::output)
	(top_level_diversion::transparent_output)
	(top_level_diversion::copy_file): Recast diagnostic messages to
	be distinguishable and provide more information about what the
	problem is.  Make the proffered advice agnostic with respect to
	choice of control character and request renaming.

2024-01-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/input.cpp (encode_char): Rename this...
	(encode_char_for_troff_output): ...to this.

	(do_special): Update call site.

2024-01-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Restore diagnostic from groff 1.22.4.

	* src/roff/troff/input.cpp (encode_char): Add `else` to `if`
	statement checking the output device for the
	"use_charnames_in_special" directive (used only by grohtml(1)).
	This way we once again throw a diagnostic upon the following
	input, invalid with any other output device.

		printf '\\X@pdf: \\[u1234]@\n' | groff

	Problem introduced by me in commit eb695ab2b5, 30 October 2021.

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

	* font/devpdf/Foundry.in: More BMI, BMR mapping swap; swap the
	file name pairs "URWBookmanL-LighItal" and "URWBookmanL-Ligh";
	and "b018032l.pfb" and "018012l.pfb" as well.

2024-01-07  Deri James  <deri@chuzzlewit.myzen.co.uk>

	* src/devices/gropdf/gropdf.pl (do_x): Comment out line causing
	incorrect table of contents relocation.

	Thanks to Peter Schaffter for the report.

2024-01-07  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Fix inclusion of PDF v1.7 files.

	PDF 1.5 introduced the object type ObjStm, which can contain a
	bunch of objects in its own compressed stream, but there is a
	restriction that an object with its own stream cannot be
	included into the ObjStm (i.e., no streams within streams).
	Gropdf has supported this for some years, but it has come to
	light that some PDFs have a "skeleton" object that contains the
	stream, while the rest of the object is held in an ObjStm.

	* src/devices/gropdf/gropdf.pl (LoadPDF, ObjMerge): If a
	skeleton object exists at the top level and in an ObjStm stream,
	merge the two objects.

2024-01-07  Deri James  <deri@chuzzlewit.myzen.co.uk>

	* src/devices/gropdf/gropdf.pl (subs_call): Fix bad fix for
	Savannah #65112.

	{Problem introduced by me in commit 6e45bb0bc6, 4 January, when
	I manually merged Deri's patch that wouldn't merge
	automatically, and I misread the magic constant "16" as "6".  My
	fault, but this is also one reason symbolic constants with
	human-readable names are usually preferred to numeric literals.
	-- GBR}

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

	[troff]: Fix Savannah #64592 (default color name).

	* src/libs/libgroff/color.cpp: Explicitly name the default color
	"default", instead of permitting it to have a null name.

	* doc/groff.texi (Colors):
	* man/groff.7.man (Read-only registers):
	* NEWS: Document it.

	Fixes <https://savannah.gnu.org/bugs/?64592>.  Thanks to Deri
	James, Dave Kemper, and Peter Schaffter for the discussion.

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

	[troff]: Implement new `pcolor` request.

	* src/roff/troff/input.cpp (report_color): Add.
	(init_input_requests): Wire up `pcolor` request name to
	`report_color()`.

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

2024-01-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/input.cpp
	(class non_interpreted_char_node)
	(class token_node)
	(class non_interpreted_node):
	Rename `same()` member function to `is_same_as()`.  Demote
	`is_same_as()` and `is_tag()` member function from `int` to
	`bool`.

	(non_interpreted_char_node::same):
	(token_node::same):
	(non_interpreted_node::same): Rename these...
	(non_interpreted_char_node::is_same_as):
	(token_node::is_same_as):
	(non_interpreted_node::is_same_as): ...to these.  Demote return
	type from `int` to `bool`.

	(non_interpreted_char_node::is_tag):
	(operator==):
	Demote return type from `int` to `bool`.

	(operator==):
	Return Boolean instead of integer literal.  Rename local
	variable `are_same` to `same` for brevity and demote it from
	`int` to `bool`.

	* src/roff/troff/node.cpp
	(class glyph_node)
	(class ligature_node)
	(class kern_pair_node)
	(class dbreak_node)
	(class hyphen_inhibitor_node):
	(class italic_corrected_node):
	(class break_char_node):
	(class composite_node):
	Rename `same()` member function to `is_same_as()`.  Demote
	`is_same_as()` and `is_tag()` member function from `int` to
	`bool`.

	(hyphen_inhibitor_node::same):
	(special_node::same):
	(suppress_node::same):
	(tag_node::same):
	(draw_node::same):
	(extra_size_node::same):
	(vertical_size_node::same):
	(hmotion_node::same):
	(space_char_hmotion_node::same):
	(vmotion_node::same):
	(hline_node::same):
	(vline_node::same):
	(dummy_node::same):
	(transparent_dummy_node::same):
	(zero_width_node::same):
	(italic_corrected_node::same):
	(left_italic_corrected_node::same):
	(overstrike_node::same):
	(bracket_node::same):
	(composite_node::same):
	(glyph_node::same):
	(ligature_node::same):
	(kern_pair_node::same):
	(dbreak_node::same):
	(break_char_node::same):
	(line_start_node::same):
	(space_node::same):
	(word_space_node::same):
	(unbreakable_space_node::same):
	(diverted_space_node::same):
	(diverted_copy_file_node::same):
	Rename these...
	(hyphen_inhibitor_node::is_same_as):
	(special_node::is_same_as):
	(suppress_node::is_same_as):
	(tag_node::is_same_as):
	(draw_node::is_same_as):
	(extra_size_node::is_same_as):
	(vertical_size_node::is_same_as):
	(hmotion_node::is_same_as):
	(space_char_hmotion_node::is_same_as):
	(vmotion_node::is_same_as):
	(hline_node::is_same_as):
	(vline_node::is_same_as):
	(dummy_node::is_same_as):
	(transparent_dummy_node::is_same_as):
	(zero_width_node::is_same_as):
	(italic_corrected_node::is_same_as):
	(left_italic_corrected_node::is_same_as):
	(overstrike_node::is_same_as):
	(bracket_node::is_same_as):
	(composite_node::is_same_as):
	(glyph_node::is_same_as):
	(ligature_node::is_same_as):
	(kern_pair_node::is_same_as):
	(dbreak_node::is_same_as):
	(break_char_node::is_same_as):
	(line_start_node::is_same_as):
	(space_node::is_same_as):
	(word_space_node::is_same_as):
	(unbreakable_space_node::is_same_as):
	(diverted_space_node::is_same_as):
	(diverted_copy_file_node::is_same_as):
	...to these.  Demote return type from `int` to `bool`.

	(hyphen_inhibitor_node::is_tag):
	(node::is_tag):
	(space_node::is_tag):
	(special_node::is_tag):
	(tag_node::is_tag):
	(suppress_node::is_tag):
	(unbreakable_space_node::is_tag):
	(draw_node::is_tag):
	(extra_size_node::is_tag):
	(hmotion_node::is_tag):
	(space_char_hmotion_node::is_tag):
	(vmotion_node::is_tag):
	(hline_node::is_tag):
	(vline_node::is_tag):
	(dummy_node::is_tag):
	(transparent_dummy_node::is_tag):
	(zero_width_node::is_tag):
	(italic_corrected_node::is_tag):
	(left_italic_corrected_node::is_tag):
	(overstrike_node::is_tag):
	(bracket_node::is_tag):
	(glyph_node::is_tag):
	(ligature_node::is_tag):
	(kern_pair_node::is_tag):
	(dbreak_node::is_tag):
	(break_char_node::is_tag):
	(line_start_node::is_tag):
	(word_space_node::is_tag):
	(diverted_space_node::is_tag):
	(diverted_copy_file_node::is_tag):
	Demote return type from `int` to `bool`.

	(hyphen_inhibitor_node::is_tag):
	(node::is_tag):
	(space_node::is_tag):
	(special_node::is_tag):
	(tag_node::is_tag):
	(unbreakable_space_node::is_tag):
	(draw_node::is_tag):
	(vertical_size_node::is_tag):
	(hmotion_node::is_tag):
	(space_char_hmotion_node::is_tag):
	(vmotion_node::is_tag):
	(hline_node::is_tag):
	(vline_node::is_tag):
	(dummy_node::is_same_as):
	(dummy_node::is_tag):
	(transparent_dummy_node::is_same_as):
	(zero_width_node::is_tag):
	(italic_corrected_node::is_tag):
	(left_italic_corrected_node::is_tag):
	(overstrike_node::is_tag):
	(bracket_node::is_tag):
	(glyph_node::is_tag):
	(ligature_node::is_tag):
	(kern_pair_node::is_tag):
	(dbreak_node::is_tag):
	(break_char_node::is_tag):
	(line_start_node::is_same_as):
	(line_start_node::is_tag):
	(word_space_node::is_tag):
	(diverted_space_node::is_tag):
	(diverted_copy_file_node::is_tag):
	(same_node, same_node_list):
	Return Boolean instead of integer literal.

	(make_glyph_node, same_node): Make explicit comparisons of
	pointer types to null pointer literals.

	* src/roff/troff/node.h (struct node): Demote member variable
	`is_special` from `int` to `bool`.  Demote pure virtual member
	function `is_tag`'s return type from `int` to `bool`.  Rename
	pure virtual member function from `same` to `is_same_as` and
	demote its return type from `int` to `bool`.
	(node::node): Use Boolean instead of integer literal in
	overloaded `is_special` initializers.
	(class line_start_node):
	(class space_node):
	(class word_space_node):
	(class unbreakable_space_node):
	(class diverted_space_node):
	(class diverted_copy_file_node):
	(class extra_size_node):
	(class vertical_size_node):
	(class hmotion_node):
	(class space_char_hmotion_node):
	(class vmotion_node):
	(class hline_node):
	(class vline_node):
	(class dummy_node):
	(class transparent_dummy_node):
	(class zero_width_node):
	(class left_italic_corrected_node):
	(class overstrike_node):
	(class bracket_node):
	(class special_node):
	(class suppress_node):
	(class tag_node):
	(class draw_node):
	Rename member function `same` to
	`is_same_as`.  Demote member functions `is_same_as` and `is_tag`
	from `int` to `bool`.

	* src/roff/troff/request.h (class macro): Demote friend function
	`operator==` from `int` to `bool`.

2024-01-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (make_glyph_node): Trivially refactor;
	Boolify local variable.

2024-01-04  Deri James  <deri@chuzzlewit.myzen.co.uk>

	font/devpdf/Foundry.in: Fix Savannah #65115.

	* font/devpdf/Foundry.in: Fix BMI, BMR mapping swap.

	Fixes <https://savannah.gnu.org/bugs/?65115>.  Thanks to Bjarni
	Ingi Gislason for the report.

2024-01-04  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Fix Savannah #65112.

	* src/devices/gropdf/gropdf.pl (subs_call): Type 1 fonts have a
	section of numbered subroutines which can be called from the
	actual glyph definition; I have seen over 1000 in some large
	fonts.  So, when you are subsetting you need to subset (and
	renumber) any relevant subroutines used by the glyph you are
	subsetting.

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

2024-01-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/grog/grog.pl: Trivially refactor; simplify code.

2024-01-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/glyphuni.cpp: Slightly refactor.
	(glyph_to_unicode_init::glyph_to_unicode_init): Use
	`array_length()` (our std::size for C++98) and `size_t` as type
	for loop index.

2024-01-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libgroff/glyphuni.cpp: Trivially refactor.
	(struct glyph_to_unicode): Rename this...
	(struct glyph_to_unicode_map): ...to this.  We already have a
	_function_ called `glyph_to_unicode` in the code base and
	apparently it's not a name space conflict (despite groff making
	little use of any but the default name space), but it's
	definitely confusing when searching the code.

2024-01-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff, troff]: Refactor.

	* src/include/unicode.h: Rename function `check_unicode_name` to
	`valid_unicode_code_sequence` and update comments to better
	explain what it actually does.  The validity of "u1234_5678" in
	addition to "u1234" was undocumented and not even implied.
	* src/libs/libgroff/unicode.cpp (check_unicode_name): Rename
	this...
	(valid_unicode_code_sequence): ...to this.

	* src/libs/libgroff/font.cpp (glyph_to_unicode)
	* src/roff/troff/input.cpp (token::next)
	(map_composite_character, composite_glyph_name): Update call
	sites.  Make comparisons to null pointers explicit.

2024-01-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	[gropdf]: Fix Savannah #65111.  Add "notice" diagnostic level
	for debugging.

	* src/devices/gropdf/gropdf.pl (Notice): Add new subroutine.  It
	emits a diagnostic message only if debugging ("gropdf -d").
	(Warn): Prefix diagnostic with severity level here...
	(Msg): ...instead of here.
	(LoadFont): Demote diagnostic about fonts lacking space glyphs
	from warning to notice.

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

2024-01-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/gropdf/gropdf.pl: Report only "basename" of
	program name in diagnostic messages.

	Fixes <https://savannah.gnu.org/bugs/?65110>.  Thanks to Dave
	Kemper for the code review.

2024-01-03  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Add `pdfpagenumbering` macro.

	* tmac/pdf.tmac: Do it.
	* src/devices/gropdf/gropdf.1.man: Document it.

2024-01-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	Increment Perl dependency from 5.6.1.  gropdf requires 5.8.

	* m4/groff.m4 (GROFF_PERL): Do it.
	* INSTALL.extra:
	* doc/webpage.ms: Document it.

2024-01-03  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Add font subsetting and Type 1 font parser.

	* src/devices/gropdf/gropdf.pl: There are two main areas of
	change.  The first is rectifying my design mistake in the
	original gropdf. It used the "t" command from groff as the
	primary command as a series of input characters which would be
	converted to postscript glyphs, all other text commands (for
	example "c") were converted back to their input character and
	treated as a single character "t" command.  I was focussed on
	the groff font rather than the postscript font.

	While thinking about font subsetting it became clear it made
	more sense to convert all input to postscript glyph names
	immediately, and use them as the "common currency" rather than
	focus on words.  This particularly makes sense when dealing with
	non-latin input which has been processed with preconv.  It is
	also makes it much more natural when dealing with font
	subsetting.  Previously this was not necessary because the whole
	font was embedded by gropdf.

	The second major change is the addition of a type 1 font parser
	and code to generate a font which only contains the glyphs
	required by the document being processed.  This is the area
	which needs the most testing.  I have tested with dozens of
	fonts that this parser is robust enough, but there are thousands
	of fonts out there.  It seems to be happy with fonts produced by
	fontforge, which is promising.

2024-01-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/tbl.1.man (roff interface): Fix incorrect
	claim regarding `#T` register.

2024-01-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man,mdoc]: Increase default line length to 80n on terminals.
	The resolution of tbl(1) bugs such as Savannah #63749, #63640,
	and #62471 enables us to discard a decades-old convention of
	using 78n for the default line length when formatting for
	terminals; this was because tbl(1) would sometimes overset
	lines, with ugly consequences.  (I _assume_ this was the reason;
	no one ever seems to have gone on record about it--it was
	seemingly yet another case of Unix folklore that "everybody
	knew".)  Overset lines are still possible; tbl(1) will warn if
	so.  They can also overset if the document disables filling; the
	author is expected to know what they are doing in that case.

	* tmac/an.tmac:
	* tmac/doc-old.tmac:
	* tmac/mdoc/doc-nroff: Do it.

	* tmac/groff_man.7.man.in:
	* tmac/groff_mdoc.7.man: Update documentation and annotations.

	* tmac/tests/an-ext_SY-and-YS-work.sh:
	* tmac/tests/an_HY-register-works.sh:
	* tmac/tests/an_LL-init-sanely.sh:
	* tmac/tests/an_UE-breaks-before-long-URIs.sh:
	* tmac/tests/an_adjust-link-text-correctly.sh:
	* tmac/tests/an_do-not-abbreviate-escape-using-TH-arguments.sh:
	* tmac/tests/an_title-abbreviation-works.sh:
	* tmac/tests/andoc_flush-between-packages.sh:
	* tmac/tests/doc_indents-correctly.sh:
	* tmac/tests/doc_smoke-test.sh: Update test output expectations.

	* NEWS: Document it.

2024-01-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/mdoc/doc-nroff (doc-setup-page-layout): Port nroff-mode
	horizontal rule width compensation from "an.tmac" (29 December)
	to mdoc.

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

	[tmac]: Update tests to more recent script conventions, and to
	share more information.

	* tmac/tests/an_LL-init-sanely.sh: Rename variable from
	`EXAMPLE` to `input`.  Write the test output to the standard
	output stream.  Report the horizontal motion quantum (`.H`
	register) and the line length in ens (character cells) as well
	for comprehensibility by *roff non-experts.

	* tmac/tests/an_do-not-abbreviate-escape-using-TH-arguments.sh:
	Write the test output to the standard output stream.

	* tmac/tests/an_title-abbreviation-works.sh: Rename variables to
	use lowercase instead of uppercase.  Define and use `wail()`
	function instead of repeating logic in failure cases.  Write the
	test output to the standard output stream.  Report test progress
	and outcomes to standard error stream.

	* tmac/tests/andoc_flush-between-packages.sh: Rename variable
	from `FAIL` to `fail`.  Define and use `wail()` function instead
	of repeating logic in failure cases.

	* tmac/tests/doc_indents-correctly.sh: Define and use `wail()`
	function instead of repeating logic in failure cases.  Report
	test progress to standard error stream.  Drop redundant `exit`.

	* tmac/tests/doc_smoke-test.sh: Drop redundant variable
	initialization.

2023-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Fix Savannah #62471 (hrules in nroff mode).

	This fixes the last problem I know of that keeps man pages from
	freely using the full width of the terminal.  (You can still
	cause lines to overrun manually, of course.)

	* src/preproc/tbl/table.h (class table): Define new enumeration
	constant, `HAS_DATA_HRULE`, to keep track of whether a table
	uses a horizontal rule as a data row.
	* src/preproc/tbl/main.cpp (process_data): Set it when
	encountering appropriate input.
	* src/preproc/tbl/table.cpp (table::compute_overall_width):
	Check for it if the table is not already boxed, and emit output
	to reduce the line length by one in nroff mode.

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

2023-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Regression-test Savannah #62471.

	* src/preproc/tbl/tests/horizontal-rules-not-drawn-too-long.sh:
	Do it.
	* src/preproc/tbl/tbl.am (tbl_TESTS): Run test.

2023-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp (table::compute_overall_width):
	Document the nroff-mode workarounds we do in *roff comments in
	the generated output.

2023-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (an-end): Horizontal rules in nroff mode _always_
	overdraw by one character cell; this is how grotty detects
	intersections with vertical rules at boundaries (see Savannah
	#62471).  Unfortunately it has unhappy consequences when drawing
	a rule that extends to the right margin.  Compensate by drawing
	the rule between consecutively rendered man pages nominally one
	en shorter than the line length, which turns out to be exactly
	the line length.

2023-12-29  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Fix Savannah #65092 (rounded corners in hdtbl's
	"color_boxes.roff" example).

	The \X'ps: exec ...' for setlinejoin and setlinecap (which
	hdtbl.tmac emits as one command) is documented as separate
	commands in gropdf(1).

	* src/devices/gropdf/gropdf.pl (do_x): Allow both setlinecap and
	setlinejoin to be combined in one command.

	Fixes <https://savannah.gnu.org/bugs/?64958>.  Thanks to Bjarni
	Ingi Gislason for the report.

2023-12-10  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Fix arc drawing when `-l` option used.

	* src/devices/gropdf/gropdf.pl (PlotArcSegement): When landscape
	flag `-l` is given, coordinates for arcs need rotation.

2023-11-24  Deri James  <deri@chuzzlewit.myzen.co.uk>

	[gropdf]: Fix processing of catenated dit files (-Z).

	Normally it is safe to pass concatenated dit files to gropdf,
	typically this would be a separate source file which produces a
	custom cover and a different source for the body (different
	macro set?). Problem occurs if one of the dits uses the same
	fontno for a different font. Normally troff allocates TR to #5,
	but if one of the dits has been run with the flag "U-T" then
	U-TR is allocated to #5.

	* src/devices/gropdf/gropdf.pl (LoadFont): Check if "x font #
	name" has the same number AND name as a previously registered
	font, otherwise reload the font.

2023-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grotty/tty.cpp (tty_printer::end_page): Add
	`assert()` to check invariant.

2023-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/tests/check-horizontal-line-length.sh: Tweak
	shell style and have test issue groff output to the standard
	output stream.

2023-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (charinfo::contains): Add
	sure-to-fail `assert()` to member function taking a `charinfo`
	pointer and a `bool`.  It has been marked "TODO" and
	unconditionally returning false for 13 years.  We should find
	out if it blows up in real-world use.

2023-12-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/table.cpp (table::add_entry): Recast
	diagnostic when user attempts to put a text block in a table
	cell classified as numeric, and demote it from error to warning
	since the program falls back to left alignment.

2023-12-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Add another explicit mechanism for disabling automatic
	hyphenation; accept an `hla` request without arguments for this
	purpose.

	* src/roff/troff/env.cpp (select_hyphenation_language): Do it.

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

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

	Fixes https://savannah.gnu.org/bugs/?64958>.

2023-12-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/groff/tests/dot-trap_register_works.sh: Fix thinko.
	The test was spuriously always passing.  Fortunately, the test
	continues to pass when corrected.  Problem introduced by me with
	new `.trap` register feature in commit 4c2cd5e076, 26 July.

2023-12-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix code style nits.

	* src/roff/troff/input.cpp (do_open, open_request)
	(opena_request, close_request): Demote `int` arguments to
	`bool`.  Declare functions `static` since they do not require
	external linkage.

2023-12-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Revise diagnostics when opening and closing streams.

	* src/roff/troff/input.cpp (do_open, close_request): Do it.
	Recast.  Check `fclose()` for failure and report the system's
	error description upon failure.

2023-12-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[docs]: Revise explanation of `fl` request.

	This has been an annoying lacuna of groff documentation forever.

	* doc/groff.texi (Debugging):
	* man/groff.7.man (Request short reference): Do it.

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

2023-12-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	Support pic(1) pictures when formatting HTML and using
	"fallback" pic macros.

	* tmac/pic.tmac (PS): Call `HTML-IMAGE` at end of macro
	definition.
	* tmac/pic.tmac (PF): Call `HTML-IMAGE-END` at end of macro
	definition.  (`PE` and `PY` call `PF`, and so are also handled.)

	Fixes https://savannah.gnu.org/bugs/?65047> (2/2).  Thanks to
	Hans Bezemer and Dave Kemper for the report.

2023-12-23  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (EE): Fix latent logic error; use `if` for
	conditional without an "else".  Since there was no subsequent
	`el` request, but the formatter was "primed" to expect one,
	this could conceal an `el` usage error in a man page document or
	otherwise behave strangely.

2023-12-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/env.cpp (environment::do_break)
	(do_break_request): Boolify parameter and rename it to
	`want_adjustment`.  In the future, adjustment might not only
	"spread", but "squeeze" as well.
	(break_request): Rename this...
	(break_without_adjustment): ...to this, and declare it `static`.
	Pass Boolean literal to `do_break_request`.
	(break_spread_request): Rename this...
	(break_with_adjustment): ...to this, and declare it `static`.
	Pass Boolean literal to `do_break_request`.
	(init_env_requests): Update "call" sites of renamed functions.
	* src/roff/troff/env.cpp (class environment): Demote
	`do_break`'s parameter from `int` to `bool`, and drop parameter
	names from prototype, in keeping with the Stroustrup-style C++
	used in most of groff.

2023-12-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (nop_request, do_if_request)
	(if_else_request, if_request, else_request, while_request)
	(while_break_request, while_continue_request): Define functions
	as `static`; they require no visibility outside this translation
	unit.

2023-12-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (if_else_request, if_request): Throw
	warning in category `missing` if given no arguments.

2023-12-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	Manage config.h more consistently.

	* src/roff/troff/env.cpp: Ensure that we include config.h (if
	necessary) _before_ C standard library header math.h.

	* src/devices/xditview/Dvi.c:
	* src/devices/xditview/draw.c:
	* src/devices/xditview/font.c:
	* src/devices/xditview/lex.c:
	* src/devices/xditview/page.c:
	* src/devices/xditview/parse.c:
	* src/libs/libbib/map.c:
	* src/libs/libgroff/change_lf.cpp:
	* src/libs/libgroff/cmap.cpp:
	* src/libs/libgroff/cset.cpp:
	* src/libs/libgroff/fmod.c:
	* src/libs/libgroff/geometry.cpp:
	* src/libs/libgroff/getcwd.c:
	* src/libs/libgroff/localcharset.c:
	* src/libs/libgroff/prime.cpp:
	* src/libs/libgroff/ptable.cpp:
	* src/libs/libgroff/quotearg.c:
	* src/libs/libgroff/spawnvp.c:
	* src/libs/libxutil/DviChar.c:
	* src/libs/libxutil/XFontName.c:
	* src/libs/libxutil/xmalloc.c:
	* src/preproc/eqn/eqn.ypp:
	* src/preproc/grn/hdb.cpp:
	* src/preproc/grn/hpoint.cpp:
	* src/roff/troff/env.cpp:
	* src/utils/indxbib/signal.c: Bracket inclusion of config.h with
	preprocessor test of `HAVE_CONFIG_H` where absent.  Use
	angle bracket rather than double-quote notation for the
	preprocessor file inclusion.  See
	<https://savannah.gnu.org/bugs/?60035>.

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

	* src/roff/troff/env.cpp (do_hyphenation_patterns_file):
	Rename...
	(read_hyphenation_patterns_from_file): ...to this.
	(hyphenation_patterns_file, hyphenation_patterns_file_append):
	Update call sites.
	(hyphenation_patterns_file): Rename...
	(load_hyphenation_patterns_from_file): ...to this.
	(hyphenation_patterns_file_append): ...and this...
	(append_hyphenation_patterns_from_file): ... to this.
	(init_hyphen_requests): Update call sites.

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

	* src/roff/troff/env.cpp (select_hyphenation_language): Demote
	missing argument diagnostic from error to warning.
	(add_hyphenation_exceptions, hyphenation_patterns_file)
	(hyphenation_patterns_file_append): Throw warning in category
	`missing` if given no arguments.

2023-12-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Drop unused function parameter.

	* src/include/lib.h: Drop `want_unlink` parameter from
	`xtmpfile` declaration.
	* src/libs/libgroff/tmpfile.cpp (xtmpfile): Drop same from
	definition, along with useless (always true) conditional test.

2023-12-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (select_underline_font)
	(set_font_specific_special_fonts): Tweak diagnostic messages.

2023-12-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (set_special_fonts): Revert part of
	commit 44db6efc01, 3 November.  Stop throwing diagnostic and
	ignoring request if given no arguments; that's how you clear the
	global list of fonts designated as special by request (contrast
	with those that declare themselves as special in their
	description files).

2023-12-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix Savannah #64957 (`device`, `output` broken).

	The GNU troff(1) internal function `has_arg()` has a side effect
	of advancing the token pointer (a sort of cursor into the input
	stream).  So when I changed `device_request()` and
	`output_request()` to use `has_arg()` in commit 429723c3ec (10
	November), the first character of the argument got stripped,
	making it unintelligible to the output driver.

	* src/roff/troff/input.cpp (device_request, output_request):
	Drop call of `has_arg()` in favor of `input_stack::peek()`.
	Manually discard space characters until reaching something else;
	if that is a newline or EOF, throw warning diagnostic as before.
	Otherwise, proceed with request processing.

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

2023-12-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/groff.texi: Fix typos.

	Fixes <https://savannah.gnu.org/bugs/?64954>.  Thanks to Bjarni
	Ingi Gislason for the report.

2023-11-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Improve font-related diagnostics.

	* src/roff/troff/node.cpp (mount_font_at_position)
	(associate_style_with_font_position, select_underline_font)
	(define_font_specific_character, remove_font_specific_character)
	(configure_track_kerning, constantly_space_font): Throw warning
	in category `missing` if given no arguments.

	(set_font_specific_special_fonts, set_special_fonts): Demote
	diagnostic when given no arguments to warning in category
	`missing`.

	(mount_font_at_position, associate_style_with_font_position):
	Report invalid font mounting position in error diagostic.

	(associate_style_with_font_position): Throw warning in category
	`missing` if given only one argument.

2023-11-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Improve `hcode` request validation.

	* src/roff/troff/input.cpp (set_hyphenation_codes): Throw
	warning diagnostic if no arguments supplied.  Throw error
	diagnostic if there are an odd number of arguments.  Check
	second arguments of pairs for nonsense.

2023-11-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (hyphenation_code): Rename to...
	(set_hyphenation_codes): ...this.
	(init_input_requests): Update call site.

	(set_hyphenation_codes): Declare as `static`; this function
	doesn't need external visibility.

2023-11-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (composite_request): Rename to...
	(map_composite_character): ...this.
	(init_input_requests): Update call site.

	(map_composite_character): Declare as `static`; this function
	doesn't need external visibility.

2023-11-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (composite_request): Throw warning
	diagnostic if either argument is absent; stop relying upon
	`get_name()` to do so, which is a slight abuse since we
	don't regard the arguments to this request as "identifiers"
	{how they're described in its diagnostic messages}.  Instead
	test retrieved symbol for nullity and throw a more contextful
	message.

2023-11-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (char_flags): Rename to...
	(set_character_flags): ...this.
	(init_input_requests): Update call site.

	(set_character_flags): Declare as `static`; this function
	doesn't need external visibility.  Throw warning diagnositc when
	no character arguments are present.

2023-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/groff.texi (Miscellaneous): Clarify behavior of `mc`.

	Fixes <https://savannah.gnu.org/bugs/?64891>.  Thanks to Bjarni
	Ingi Gislason for the report.

2023-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/html/pre-html.cpp (makeTempFiles): Stop explicitly
	specifying parameters redundantly with their default values.

2023-11-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libgroff]: Trivially refactor `xtmpfile`.

	* src/include/lib.h:
	* src/libs/libgroff/tmpfile.cpp (xtmpfile): Boolify `int`
	parameter and rename it from `do_unlink` to `want_unlink`.

	* src/libs/libgroff/tmpfile.cpp (xtmpfile): Make null pointer
	comparison explicit. Recast diagnostic to identify what
	operation failed instead of cryptically uttering only the name
	of a standard C library function.

2023-11-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Don't enforce tag separation on `IP`.

	The marker argument to the `IP` macro is often very short, such
	as a bullet or list enumerator (and in fact we encourage this
	practice in our style advice, promoting `TP` instead for
	definition lists and similar).  We therefore don't want to
	enforce the `TS` tag separation for them.  `.IP \[bu] 2n` is a
	perfectly cromulent usage pattern.

	* tmac/an.tmac: Add new Boolean-valued register,
	`an*enforce-tag-separation`, to control this aspect of state.
	Initialize it true.
	(an-write-paragraph-tag): Multiply `TS` by this register to
	apply enforcement (or not).
	(IP): Temporarily clear register while setting paragraph tag.

	* tmac/groff_man.7.man.in (Paragraphing macros, Options):
	* NEWS: Update documentation.

2023-11-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[build]: In source files that #include <assert.h>, ensure that
	we #include <config.h> first (with a `HAVE_CONFIG_H` inclusion
	guard).  This should prevent build failures on AIX with Clang++.

	* src/devices/grodvi/dvi.cpp:
	* src/devices/grolbp/lbp.cpp:
	* src/devices/grolj4/lj4.cpp:
	* src/include/itable.h:
	* src/include/ptable.h:
	* src/include/stringclass.h:
	* src/libs/libbib/linear.cpp:
	* src/libs/libbib/search.cpp:
	* src/libs/libdriver/printer.cpp:
	* src/libs/libgroff/color.cpp:
	* src/libs/libgroff/font.cpp:
	* src/libs/libgroff/fontfile.cpp:
	* src/libs/libgroff/nametoindex.cpp:
	* src/libs/libgroff/relocate.cpp:
	* src/libs/libgroff/searchpath.cpp:
	* src/preproc/eqn/box.cpp:
	* src/preproc/eqn/delim.cpp:
	* src/preproc/eqn/pile.cpp:
	* src/preproc/eqn/script.cpp:
	* src/preproc/html/pre-html.cpp:
	* src/preproc/pic/pic.h:
	* src/preproc/preconv/preconv.cpp:
	* src/preproc/soelim/soelim.cpp:
	* src/roff/groff/groff.cpp:
	* src/roff/troff/troff.h:
	* src/utils/hpftodit/hpftodit.cpp:
	* src/utils/indxbib/indxbib.cpp:
	* src/utils/lkbib/lkbib.cpp:
	* src/utils/lookbib/lookbib.cpp:
	* src/utils/tfmtodit/tfmtodit.cpp: Do it.

	Fixes <https://savannah.gnu.org/bugs/?64910>.  Also see
	<https://savannah.gnu.org/bugs/?61315>.  Thanks to Mike Fulton
	for the report.

2023-11-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp: Rename some enumeration constants.
	- `BAD` -> `INVALID`
	- `ABSOLUTE` -> `ASSIGN`

2023-11-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Boolify numeric expression-reading functions.

	* src/roff/troff/hvunits.h (get_vunits, get_hunits):
	* src/roff/troff/token.h (get_number_rigidly, get_number)
	(get_integer):
	* src/roff/troff/number.cpp (get_vunits, get_hunits)
	(get_number_rigidly, get_number, get_integer): Do it.

2023-11-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/number.cpp (is_valid_expression): Boolify and
	rename local variable from `overflow` to `had_overflow`.

2023-11-09  Paul Eggert  <eggert@cs.ucla.edu>

	[libbib]: Fix bogus size diagnostic.

	* src/libs/libbib/index.cpp (index_search_item::check_header):
	Fix size calculation typo that generated bogus diagnostic
	"lookbib: error: corrupt header in index file".

	{Fixes <https://savannah.gnu.org/bugs/?64879>.  Problem
	introduced by me in commit 4fad0459bb, 2022-01-05.
	-- GBR, 2023-11-10}

2023-11-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (device_request, output_request):
	Throw warning diagnostic if no arguments given.

2023-11-06  Pim <pimh@kth.se>

	* src/preproc/eqn/lex.cpp: Update internal macro definitions
	used to construct tilde and under-tilde ("utilde") accents to
	set them in the roman face, like other accent marks in eqn.
	* src/preproc/eqn/eqn.1.man (New primitives): Update example.

	Fixes <https://savannah.gnu.org/bugs/?64860>.  Thanks to Damian
	McGuckin for reporting this problem on the groff mailing list.
	<https://lists.gnu.org/archive/html/groff/2023-06/msg00143.html>

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

	* src/roff/troff/node.cpp (embolden_font): Do nothing if in
	nroff mode.

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

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

	* src/roff/troff/input.cpp: Mark `suppression_level`,
	`have_formattable_input`, `old_have_formattable_input`, and
	`want_unsafe_requests` as `static` to give them internal
	visibility only.

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

	[troff]: Make `in_nroff_mode` visible to other translation
	units, in preparation for Savannah #64866 fix.  Boolify it and
	rename it from `nroff_mode`.  Relocate definition alongside
	other externally visible symbols.

	* src/roff/troff/troff.h: Declare it.
	* src/roff/troff/input.cpp: Do it.
	(nroff_request, troff_request, do_if_request, do_error): Update
	references.

2023-11-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (set_font_specific_special_fonts):
	Declare automatic variable closer to its first point of use.

2023-11-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor dictionary implementation.

	* src/roff/troff/dictionary.h (class dictionary_iterator):
	(class object_dictionary_iterator):
	(object_dictionary_iterator::get): Demote return type of `get()`
	from `int` to `bool`.
	(class object_dictionary): Demote return type of `alias()` from
	`int` to `bool`.
	(class object): Rename member variable `rcount` to `refcount`.
	* src/roff/troff/dictionary.cpp (is_good_size):
	(dictionary_iterator::get):
	(object_dictionary::alias): Demote return type from `int` to
	`bool`.  Update return value literals.
	(object::object):
	(object::add_reference):
	(object::remove_reference): Rename member variable `rcount` to
	`refcount`.

2023-11-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Implement new `phw` request.

	* src/roff/troff/env.cpp (print_hyphenation_exceptions): Add.
	(init_hyphen_requests): Wire up `phw` request name to
	`print_hyphenation_exceptions()`.

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

	Inspired by a debugging process (that ultimately involved
	input character encoding confusion) on the groff mailing list,
	raised by Walter Alejandro Iglesias.  See
	<https://lists.gnu.org/archive/html/groff/2023-09/\
	msg00032.html> and
	<https://lists.gnu.org/archive/html/groff/2023-10/\
	msg00008.html> and follow-ups.  It my opinion it should have
	been easier to ask the formatter where it thought a hyphenation
	exception's hyphenation points were.

2023-11-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/reg.cpp (alter_format): Slightly refactor.
	Push more diagnostic work to `tok.description()`, since it is
	capable of describing any token.

2023-11-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/groff.texi (Setting Registers, Strings):
	* man/groff.7.man (Request short reference): Fix errors; the
	`rm` and `rr` requests take an arbitrary number of arguments.
	Ossanna nroff and DWB nroff both behave this way.  Nor did CSTR
	#54, in its 1976 or 1992 revisions, document this.  Problem
	appears to date back "forever", to the oldest revisions of these
	files in our Git repository.

2023-11-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Drop parameter names from prototypes,
	in keeping with the Stroustrup-style C++ used in most of groff.

2023-11-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Clarify diagnostic and trivially
	refactor.
	(hyphen_word): Rename this...
	(add_hyphenation_exceptions): ...to this.
	(init_hyphen_requests): Update call site.

	(add_hyphenation_exceptions): Make error diagnostic more
	helpful.

2023-11-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/env.cpp: Add diagnostic and trivially refactor.
	(set_hyphenation_language): Rename this...
	(select_hyphenation_language): ...to this.
	(init_hyphen_requests): Update call site.

	(select_hyphenation_language): Throw more helpful diagnostic
	when not given an argument; promote "missing identifier" warning
	to a context-rich error.

2023-11-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/groff.texi (Line Continuation): Drop concept index entry
	regarding use of `\R` escape sequence after `\c` on an input
	line.  There is no longer anything special to say; `\R` works as
	otherwise documented.  Formerly (pre-1.23.0), our Texinfo manual
	suggested that nothing on an input line after `\c` was
	interpreted, which was false.  Nothing after it is _formatted_.

	Fixes <https://savannah.gnu.org/bugs/?64844>.  Thanks to Bjarni
	Ingi Gislason for the report.

2023-11-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (set_font_specific_special_fonts)
	(set_special_fonts): Throw error when invoked with insufficient
	arguments.

2023-11-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/groff.texi: Add numerous @anchor commands to aid
	resolution of hyperlinks into this manual based on the node
	names used in groff 1.22.4 (and for several years previous, as
	the document saw little change for a while).  Some node names, I
	did not add anchors for; they correspond either to material that
	we've dropped altogether from our Texinfo manual (mainly a
	somewhat stale duplicate of groff_man(7), which no GNU Info
	partisan would read anyway) or were empty stubs anyway.  An HTTP
	404 response is therefore honest in such cases.

	Fixes <https://savannah.gnu.org/bugs/?64758>.  Thanks to Ingo
	Schwarze for the report, Gavin Smith for proposing a
	resolution technique, and Thérèse Godefroy for assistance
	cleaning up our Texinfo manual's hyperlinks on the GNU web site.

2023-10-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac (TH):
	* tmac/mdoc/doc-common (doc-set-up-titles): Update default
	footer trap location to leave a half-inch margin below the
	footer, not 1/2 inch minus one vee.
	* tmac/an.tmac (PT):
	* tmac/mdoc/doc-common (doc-header): Adjust vertical spacing at
	page top to leave a half-inch above the header, and 1 inch
	distance from the page top to the top of the running text.

	* tmac/groff_man.7.man.in (Options) <-rFT>:
	* tmac/groff_mdoc.7.man (Options) <-rFT>: Document new default.

	* tmac/tests/an_P-register-works.sh:
	* tmac/tests/andoc_P-register-works.sh:
	* tmac/tests/doc_P-register-works.sh: Update test expectations.

	* NEWS: Add item.

2023-10-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/refer.tmac (ref*add-J, ref*add-D, ref*add-E, ref*add-G)
	(ref*add-B, ref*add-O, ref*add-A, ref*add-V, ref*add-N)
	(ref*add-dflt): Fix thinko in `ie` predicates.  The true
	branches of the conditionals were never taken because the
	condition was consistently misspelled, testing for the existence
	of, for example, a register named "ef*spec!J:\\$1" (where `\\$1`
	_would_ be interpolated, but not improve chances of success).
	Fix by using the `d` conditional expression operator as
	obviously intended.  This enables some refer(1) formatting
	customization that was unfortunately inoperative.  Problem
	appears to date back to commit 3bab8e6fe5, 2011-01-28.

	Fixes <https://savannah.gnu.org/bugs/?64779>.  Thanks to an
	anonymous bug submitter for the report and the patch.

2023-10-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/mdoc/doc-ditroff (doc-Ev-font):
	* tmac/mdoc/doc-nroff (doc-Ev-font): Change typeface for
	environment variable identifiers from (Courier) roman to italic,
	for consistency with man(7).

2023-10-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* font/devps/generate/Makefile (zapfdr.afm): Fix typo in
	dependency name.  Problem introduced by me in commit 2566b64e0b,
	13 March 2022, which claimed "[s]hould not cause regressions
	because the Make targets invoked are never called during a build
	{they are isolates that you have to manually name on the command
	line}."  Thus was fortune's hostage seized.  Apparently
	OpenSUSE uses this Makefile as part of its "ghostscript-fonts-
	grops" package build.  (Fair enough--we _do_ install it.)

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

	* src/roff/troff/input.cpp (while_break_request)
	(while_continue_request): Clarify diagnostic messages.

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

	[troff]: Trivially refactor.  Rename and boolify some file-local
	functions.

	* src/roff/troff/input.cpp (get_delim_number): Rename this...
	(read_delimited_number): ...to this, and boolify it.  The idea
	behind "read" instead of "get" is that the latter more strongly
	implies (to me) that the value being "got" is returned by the
	function.  But for `read_delimited_number`, the number is stored
	{after possible unit conversion} in one of the function
	parameters.
	(get_delim_name): Rename this...
	(get_delimited_name): ...to this.
	(token::next): Update call sites.

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

	[troff]: Trivially refactor.  Rename local `start` variables to
	`start_token` for better code readability.

	* src/roff/troff/input.cpp (do_overstrike, do_bracket)
	(do_name_test, do_expr_test, do_zero_width, get_delim_number)
	(get_line_arg, get_delim_name, do_register, do_width)
	(do_special, read_draw_node):
	* src/roff/troff/reg.cpp (inline_define_register): Do it.

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

	[troff]: Trivially refactor.  Rename Boolean-valued member
	function to read like a logical predicate.

	* src/roff/troff/token.h (token::usable_as_delimiter): Rename...
	(token::is_usable_as_delimiter): ...declaration to this.
	* src/roff/troff/input.cpp (token::usable_as_delimiter):
	(token::is_usable_as_delimiter): ...same for implementation.

	* src/roff/troff/env.cpp (number_lines):
	* src/roff/troff/input.cpp (do_expr_test, get_delim_number)
	(get_line_arg, read_size, do_register, do_if_request)
	(read_draw_node):
	* src/roff/troff/node.cpp (has_font, embolden_font): Update call
	sites.

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

	* src/roff/troff/input.cpp (token::next, device_macro_request):
	Recast language of one of groff's more notorious diagnostics,
	eliminating the much-abused word "transparently".  Also name the
	offending token.  It is difficult to overstate how unhelpful
	diagnostic messages are when they know precisely what is wrong
	but refuse to tell the user.

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

	* src/roff/troff/input.cpp (token::next): Tweak language of
	diagnostic message when encountering unsupported escape
	sequence.
	* doc/groff.texi (Using Escape Sequences): Update example
	accordingly.

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

	* src/roff/troff/env.cpp (font_change): Trivially refactor,
	renaming this function...
	(select_font): ...to this.  Doing so aligns with other use of
	the term "select" in groff font documentation.  Further, when
	formatting for typesetters, fonts can be "changed" in a
	different sense by altering height, slant, (constancy of)
	spacing, and magnification.  Also mark function as "static"; it
	needs no visibility outside this translation unit.

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

	[troff]: Throw error diagnostic on attempt to select a font
	named "DESC".  That will never work.

	* src/roff/troff/env.cpp (font_change):
	* src/roff/troff/input.cpp (token::next): Do it.

2023-09-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Add bespoke handling of `lbp` device.

	* tmac/an.tmac (EX): Refactor, using new register
	`an*unmap-fonts` to keep track of whether we're remapping fonts
	instead of switching families.  Like TeX DVI, the LBP output
	device lacks a (complete) monospaced font family.  In EX/EE
	examples on that device, remap the bold-italic face to italics.
	(EE): Revert remappings and remove `an*unmap-fonts` register.

	Prompted by discussion with pandoc developers at
	<https://github.com/jgm/pandoc/issues/9020>.

2023-09-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn]: Make synopsis, usage message more helpful.

	* src/preproc/eqn/eqn.1.man (Synopsis): Use descriptive phrases
	as metasyntactic variables.
	* src/preproc/eqn/main.cpp (usage): Sync with the foregoing.

2023-09-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/pic/troff.cpp (strsame): Add utility function for
	comparing two C strings for identical content, handling null
	pointer arguments as `strcmp()` does not.
	(troff_output::set_location): Refactor; write the two-argument
	form of the `lf` request if the current and last seen file names
	_don't_ match.  Problem introduced by me in commit 705be31107,
	29 July.  Also fix heap memory leak when repeatedly updating
	`troff_output::last_filename` member variable.

	Fixes <https://savannah.gnu.org/bugs/?64628>.  Thanks to Bjarni
	Ingi Gislason for the report.

2023-09-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[pic]: Save and restore stroke and fill colors when entering and
	leaving, respectively, preprocessed regions.

	* src/preproc/pic/troff.cpp: Define C/C++ preprocessor macros to
	house names of *roff strings storing this information.
	(troff_output::start_picture): Save stroke and fill colors.
	(troff_output::finish_picture): Restore stroke and fill colors.

	Fixes <https://savannah.gnu.org/bugs/?64624>.  Thanks to Dave
	Kemper for the report and testing this code change.

2023-09-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (doc/meintro_fr.ps): Depend on tbl, resolving race
	in sufficiently parallelized builds.  Overlooked in commit
	92349ae223, 2022-05-30.

	Fixes <https://savannah.gnu.org/bugs/?64695>.  Thanks to
	Alexander Kanavin for the report.

2023-09-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (doc/webpage.ps, doc/webpage.html): Update and
	parallelize target dependencies.  Resolve race by requiring
	"grn" and "soelim" to be built first.  Also add dependency on
	`$(TMAC_PACKAGE_MS)`.

	Fixes <https://savannah.gnu.org/bugs/?64681>.  Thanks to
	Alexander Kanavin for the report.

2023-09-15  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (charinfo_to_node_list): Trivially
	refactor.  Rename `old_escape_char` to `previous_escape_char`.

2023-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `ascii_output_flag` to
	`want_abstract_output`.

	* src/roff/troff/input.cpp (main, init_registers):
	* src/roff/troff/node.cpp (init_output):
	* src/roff/troff/troff.h: Do it.

2023-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename
	`unsafe_flag` to `want_unsafe_requests`.
	(pipe_source, open_request, opena_request, pipe_output):
	(system_request, main, init_input_requests): Do it.
	(init_input_requests): Migrate from `readonly_register` to
	`readonly_boolean_register`.

2023-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Add class for Boolean-valued read-only registers.
	Their values have been stored variously in `readonly_register`,
	which has full `int` range, and in normal string registers, as
	with `.A`.

	* src/roff/troff/reg.h (class readonly_boolean_register): Add.
	* src/roff/troff/input.cpp
	(readonly_boolean_register::readonly_boolean_register)
	(readonly_boolean_register::get_string): Define.

2023-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename some
	functions and recast diagnostic messages.
	(open_mac_file):
	(process_macro_file): Rename these...
	(open_macro_package):
	(process_macro_package_argument): ...to these.

	As our documentation now makes more clear, "macro packages" are
	a subset of "macro files", and have additional rules regarding
	their handling (where they are sought and how their names are
	rewritten).

2023-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp: Trivially refactor.  Rename
	`begin_level` to `suppression_level`.
	(do_suppress, init_input_requests): Do it.

2023-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (input_stack::get, token::next)
	(process_input_stack, do_width, do_suppress, do_if_request)
	(charinfo_to_node_list, read_color_draw_node): Trivially
	refactor.  Rename symbols and demote their types from `int` to
	`bool`.
	- `have_input` -> `have_formattable_input`
	- `old_have_input` -> `old_have_formattable_input`

2023-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `debug_state` symbol to
	`want_html_debugging` and demote its type from `int` to `bool`.

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

	* src/roff/troff/input.cpp (input_stack::finish_get)
	(input_stack::push, process_input_stack, main)
	(charinfo::get_flags, charinfo::contains): Do it.

	* src/roff/troff/node.cpp: Drop unused declaration.

2023-09-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.  Rename `break_flag` symbol to
	`want_break` and demote its type from `int` to `bool`.

	* src/roff/troff/env.h:
	* src/roff/troff/input.cpp: Do it (declarations).

	* src/roff/troff/div.cpp (begin_page, space_request)
	(flush_output):
	* src/roff/troff/env.cpp (fill, no_fill, center, right_justify)
	(indent, temporary_indent, do_break_request):
	* src/roff/troff/input.cpp (process_input_stack)
	(macro_iterator::macro_iterator, copy_file, transparent_file):
	Do it.

2023-09-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/doc.tmac (doc-str-Ar-default): Use unbreakable space
	between "file" and ellipsis.

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

	* tmac/groff_me.7.man: Fix error in summary of "safe" groff
	requests; `ce`, `rj`, and `ul` count (productive) _input_
	lines, not output lines.

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

	[libgroff]: Explicitly construct `default_color`.

	Without explicit construction, link-time optimization feels free
	to send this object into the twilight zone, subtly changing the
	semantics of the current and previous stroke and fill colors,
	making their registers interpolate "default" instead of empty
	strings.

	* src/libs/libgroff/color.cpp: Construct `default_color` with
	empty string instead of leaving uninitalized.  Problem appears
	to date back to commit ea5a42d080, 2002-01-24.

	Fixes <https://savannah.gnu.org/bugs/?64421>.  Thanks to Günther
	Noack for the report, a good reproducer, identification of
	`-flto=auto` as the free variable in our experiments, and
	artifact production beyond the call of duty; Peter Schaffter for
	ruling out macro programming goofs; and Deri James for shrewd
	pointers in the right direction (twice!).

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

	[groff]: Regression-test Savannah #64421.

	* src/roff/groff/tests/detect-evil-link-time-optimizer.sh: Do
	it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

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

	* tmac/e.tmac (np, bu): Throw diagnostic if given arguments; we
	document these as being "like" `ip`, but they aren't with
	respect to argument handling.
	(sk): Genericize existing diagnostic to use `\$0` to report its
	own name.

2023-09-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[ms]: Doug McIlroy pointed out a hazard of the Berkeley DD
	display distance feature when footnotes end with displays; offer
	advice.

	* doc/ms.ms: Document caveat with display usage in footnotes.

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

2023-09-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/doc.tmac (doc-str-Ar-default, Ar): Stop setting ellipsis
	in italics.
	* tmac/groff_mdoc.7.man (Arguments): De-document apology for
	former behavior.

2023-09-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grotty/tests/osc8_works.sh: Port test to newer
	conventions.

2023-09-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[grog]: Drop `--ligatures`, `--run` support.

	Simulate the former (which was specific to the "pdf" output
	device) with the option sequence "-P -U -P y", and the latter by
	using the command substitution feature of your shell; see
	section "Examples" of groff(1).

	* src/utils/grog/grog.pl: Do it.
	* src/utils/grog/grog.1.man: De-document them.

	* NEWS: Add item.

2023-09-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tmac]: Drop AT&T troff font aliases/remappings.  Now that we
	have working diagnostics for font selection problems, users will
	be made aware of portability issues and can address them where
	they feel appropriate; in a document, in the "troffrc" file, or
	by modifying these files.

	* tmac/X.tmac:
	* tmac/dvi.tmac:
	* tmac/html.tmac:
	* tmac/lbp.tmac:
	* tmac/lj4.tmac:
	* tmac/ps.tmac: Do it.

	* NEWS: Add item.

2023-08-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/localization-works.sh: Test hyphenation modes for
	Spanish and Russian.

2023-08-31  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/es.tmac: Correct hyphenation mode used when suppressing
	hyphenation before traps.  A "base" mode of 1 should map to 2,
	not to 6, as (possibly) copied-and-pasted from "fr.tmac".

2023-08-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tmac]: Improve robustness of mm translations.

	* tmac/cs.tmac (\*[locale]-qrf):
	* tmac/de.tmac (\*[locale]-qrf):
	* tmac/es.tmac (\*[locale]-qrf):
	* tmac/fr.tmac (\*[locale]-qrf):
	* tmac/it.tmac (\*[locale]-qrf):
	* tmac/ru.tmac (\*[locale]-qrf):
	* tmac/sv.tmac (\*[locale]-qrf): Define string contents using
	`\E` instead of `\\`, for better robustness.  See our Texinfo
	manual, node/section "Copy mode".

2023-08-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tmac]: Rename test file for consistency.

	* tmac/tests/doc_synopsis_is_not_adjusted.sh: Rename this...
	* tmac/tests/doc_synopsis-is-not-adjusted.sh: ...to this.

	* tmac/tmac.am (tmac_TESTS): Reflect rename.

2023-08-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	[libdriver, grohtml]: Revise diagnostics.

	* src/devices/grohtml/post-html.cpp
	(html_printer::set_number_reg):
	* src/libs/libdriver/printer.cpp (printer::set_numbered_char):
	Use wording consistent with our documentation if \N'xxx' fails.

2023-08-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/lib.h (array_size): Rename to...
	(array_length): ...this.

	* src/preproc/eqn/box.cpp (set_param, reset_param, get_param)
	(init_param_table, free_param_table): Migrate call sites.

	Thanks to Alex Colomar for the discussion.

2023-08-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	* Makefile.am (EXTRA_DIST): Ship ancient groff ChangeLog files
	split off from ChangeLog.115 (.old, .111, .112, .113, .114).

2023-08-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (translate_font): Validate arguments.

2023-08-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor; add utility function.

	* src/roff/troff/node.cpp (is_nonnegative_integer): New function
	tests C-style string for validity as such; promoted from open
	code because I just spotted a second place we can use it.

2023-08-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor; demote `int`-returning functions to
	Boolean-returning ones and rename.
	- check_font -> is_font_name
	- check_style -> is_abstract_style

	* src/roff/troff/node.h:
	* src/roff/troff/node.cpp: Do it.

	* src/roff/troff/env.cpp (is_family_valid):
	* src/roff/troff/input.cpp (do_if_request): Update call sites.

2023-08-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/main.cpp (main): Trivially refactor; demote
	`int` `load_startup_file` to Boolean `want_startup_file`.

2023-08-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn]: Implement "reset" keyword.

	* src/preproc/eqn/box.cpp: Use `static` storage class for
	parametric defaults, moving them to file scope from global.
	Rename `param_table` array of structs to `default_param_table`.
	Use the length of this array for iteration since it is known at
	compile time.  Convert `param_table` to a null pointer.
	(set_param): Update diagnostic message text.
	(reset_param): New function restores a rendering parameter in
	`param_table` to its corresponding value in
	`default_param_table`.
	(get_param): New function accesses `param_table` entries via a C
	string rather than integer lvalues.  Use `assert()` to dump
	core if the parameter name is not recognized; this function is
	never called by the parser, but only by static logic.  Add
	`fatal()` under this same circumstance, in case anyone
	`#define`s `NDEBUG`.
	(init_param_table): New function populates the (mutable)
	`param_table` from the (immutable) `default_param_table` using
	heap storage.
	(free_param_table): New function avoids memory leak by freeing
	the heap storage allocated for `param_table`.
	* src/preproc/eqn/eqn.h: Drop external declaration of `nroff`.
	* src/preproc/eqn/eqn.ypp: Add new token `RESET`.
	* src/preproc/eqn/lex.cpp: Map C string "reset" to token `RESET`
	in untagged struct `token_table`.
	(do_reset): Handle new keyword; if argument valid, call
	`reset_param()` with it.
	(yylex): Hook up token `RESET` to `do_reset()`.
	* src/preproc/eqn/box.h: Declare `reset_param()`, `get_param()`,
	`init_param_table()`, and `free_param_table()`.
	* src/preproc/eqn/main.cpp (main): Call `init_param_table()`
	when starting up.  Register `free_param_table()` with
	`std::atexit()`.
	* src/preproc/eqn/pbox.h: Drop external declarations of
	rendering parameters.
	* src/preproc/eqn/delim.cpp (build_extensible)
	(define_extensible_string, delim_box::compute_metrics):
	* src/preproc/eqn/lex.cpp (yylex):
	* src/preproc/eqn/limit.cpp (limit_box::compute_metrics):
	* src/preproc/eqn/list.cpp (compute_spacing):
	* src/preproc/eqn/other.cpp (accent_box::compute_metrics)
	(overline_char_box::overline_char_box):
	(overline_box::compute_metrics, overline_box::output):
	(underline_char_box::underline_char_box):
	(underline_box::compute_metrics, underline_box::output):
	(fat_box::compute_metrics, fat_box::output):
	(vcenter_box::compute_metrics):
	* src/preproc/eqn/over.cpp (over_box::compute_metrics):
	(over_box::output):
	* src/preproc/eqn/pile.cpp (pile_box::compute_metrics):
	(matrix_box::compute_metrics, matrix_box::output):
	* src/preproc/eqn/script.cpp (script_box::compute_metrics):
	* src/preproc/eqn/sqrt.cpp (sqrt_box::compute_metrics): Migrate
	from lvalue access to `get_param()` for parameter retrieval.

	* src/preproc/eqn/eqn.1.man (Customization): Document it.

	* src/preproc/eqn/tests/parameters-can-be-set-and-reset.sh: Test
	it.
	* src/preproc/eqn/eqn.am (eqn_TESTS): Run test.

	* NEWS: Add item.

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

2023-08-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/box.cpp (set_param): Migrate iteration style
	to use new `array_size()` instead of null pointer guards at the
	end of an array of structs.

2023-08-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	[src]: Add template function for obtaining the length of an
	array.

	* src/include/lib.h (array_size) [__cplusplus]: Do it.

2023-08-22  Dave Kemper <saint.snit@gmail.com>

	* doc/pic.ms: Document `PY` macro, new to groff 1.23.0.

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

2023-08-22  Dave Kemper <saint.snit@gmail.com>

	* tmac/pic.tmac (PY): Call `PF` rather than duplicating its
	{three bytes of} code.  This is almost too trivial to DRY, but
	{1} the new form is a cue to the human reader that .PY is meant
	to be an alias of .PF; and {2} .PE was already defined as a
	variant of .PF with an explicit call to it, so this makes the
	.PY definition conform to that precedent.

2023-08-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/an.tmac: Stop setting `an*can-hyperlink` if formatting
	for PDF; we don't yet have support for this implemented, leading
	to vanishing text when the `U` register is true and, for
	instance, `UR`/`UE` are called with no link text.

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

2023-08-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (PROCESSEDFILES_DEPS_HTML): Depend on
	tmac/html{,-end}.tmac.
	(PROCESSEDFILES_DEPS_PDF): Depend on tmac/pdf.tmac.
	(PROCESSEDFILES_DEPS_PS): Depend on tmac/ps.tmac.
	(PROCESSEDFILES_DEPS_TXT): Depend on tmac/tty.tmac.

2023-08-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/devices/grops/ps.cpp (ps_printer::define_encoding):
	* src/devices/grops/psrm.cpp (resource_manager::output_prolog)
	(resource_manager::supply_resource): Report more intelligible
	diagnostics when libgroff's `font::open_file()` returns a null
	pointer without setting `errno`.  The only way this can happen
	is if it rejected the file name for containing a slash, thus
	attempting directory traversal (recall Savannah #61424).  Also
	fix code style nits: explicitly `#include` errno.h C standard
	library header, align style of null pointer checks, and stop
	explicitly setting `errno` to zero before (indirectly) calling
	`fopen()`; we inspect `errno`'s value only under a documented
	error condition (a null stream pointer).  See errno(3).

	* NEWS: Add item; we should have mentioned this (and produced
	these better diagnostics) when 1.23.0 was released.
	Distributors may find this change desirable to backport.

	Fixes <https://savannah.gnu.org/bugs/?64577>.  Thanks to Phil
	Chadwick for the report and Deri James for swiftly finding a
	correct workaround that suited the reporter.

2023-08-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (class tfont_spec): Stop declaring
	copy constructor.  The implicitly defined one suffices.
	Resolves "-Wdeprecated-copy" warning from GCC.

	Fixes <https://savannah.gnu.org/bugs/?57515>.  Thanks to Bjarni
	Ingi Gislason for the report.

2023-08-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* configure.ac: Include paper format in configuration report.

	* m4/groff.m4 (GROFF_PAGE): Slightly refactor, and help users to
	figure out how the "configure" script decided upon the paper
	format it did by supplementing the `AC_MSG_RESULT` message.  If
	not falling back to the "letter" default or honoring a
	command-line setting (e.g., "./configure PAGE=a4"), report which
	file or command was used to infer the paper locale.  Apply DRY
	principle by using shell variables more.

	Prompted by discussion with Damian McGuckin on the groff list.
	<https://lists.gnu.org/archive/html/groff/2023-07/msg00072.html>

2023-08-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	Our "Makefile.am" defines an `RM` macro if make(1) itself does
	not, and our Automake files employ it extensively; sweep up the
	stragglers.

	* font/devpdf/devpdf.am (mostlyclean_devpdf_extra)
	(uninstall_devpdf):
	* src/devices/xditview/xditview.am (uninstall_xditview):
	* src/libs/libgroff/libgroff.am (install_charset_data):
	* src/roff/nroff/nroff.am (nroff):
	* src/utils/indxbib/indxbib.am (install_indxbib):
	(uninstall_indxbib): Do it.

2023-08-12  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/utils/indxbib/indxbib.am (install_indxbib): Use `$(LN_S)`,
	not `ln -s`.

2023-08-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn]: Trivially refactor.

	* src/preproc/eqn/main.cpp (input_char_description): Migrate to
	`const`-qualified object to size an array of length computed at
	compile time and avoid repeating lengthy expression.

2023-08-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Add new `TS` register to configure required separation
	between a (`IP`, `TP`) paragraph's tag and its body, and change
	the default amount used for this purpose from 1n to 2n.  Retire
	private register `an-tag-separation` in favor of `TS`.

	* tmac/an.tmac: Assign `TS` value of 2n if not already defined.
	(TH): Stop setting the default here.
	(an-write-paragraph-tag): Use it.

	Fixes <https://savannah.gnu.org/bugs/?64539>.  Thanks to Alex
	Colomar for the report.

2023-08-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man,mdoc]: Change base paragraph indentation to 5n.  This
	corresponds to the amount used by historical man(7) and mdoc(7)
	implementations going back to Unix Version 7 and 4.3BSD-Reno,
	respectively.

	* tmac/an.tmac: Introduce new interface register, `BP`, to
	control the base paragraph indentation amount.  Formerly, `IN`
	determined it, the default relative inset amount, and the
	default amount of additional indentation used by `IP`, `TP`, and
	the deprecated `HP`.
	(an-reset-margin-and-inset-level, SH, SS): Use it.

	* tmac/doc.tmac: Introduce `BP` register, replacing `IN`.
	* tmac/mdoc/doc-common (Sh): Use it.

	* src/preproc/tbl/tests/save-and-restore-tab-stops.sh:
	* tmac/tests/an-ext_SY-and-YS-work.sh:
	* tmac/tests/an_TH-repairs-hy-damage.sh:
	* tmac/tests/an_UE-breaks-before-long-URIs.sh:
	* tmac/tests/an_adjust-link-text-correctly.sh:
	* tmac/tests/an_link-macros-work-in-paragraph-tags.sh:
	* tmac/tests/an_use-input-traps-correctly.sh:
	* tmac/tests/andoc_flush-between-packages.sh:
	* tmac/tests/doc_Mt-works.sh:
	* tmac/tests/doc_indents-correctly.sh:
	* tmac/tests/doc_synopsis_is_not_adjusted.sh: Update amount of
	indentation expected in output.

	* tmac/groff_man.7.man.in:
	* tmac/groff_mdoc.7.man: Document it.

	Fixes <https://savannah.gnu.org/bugs/?64018>.  Thanks to
	Thorsten Glaser and Ingo Schwarze for the discussion.

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

	[troff]: Add paranoia to `token::description()`.

	* src/roff/troff/input.cpp (token::description): Clear static
	buffer on entry to function to avoid another problem like
	Savannah #62813.

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

	[troff]: Trivially refactor (`define_color`).

	* src/roff/troff/input.cpp (define_color): Throw more helpful
	diagnostics when this 3-5-argument-taking request is not given
	enough of them.  Rename internal variable `style` to
	`color_space` to make it less opaque.

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

	[troff]: Trivially refactor.

	* src/roff/troff/input.cpp (input_char_description): Migrate to
	`const`-qualified object to size an array of length computed at
	compile time and avoid repeating lengthy expression.

2023-08-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	* man/groff_diff.7.man: Drop displayed examples.  Man pages'
	honor as references, not tutorials, has been vigorously
	championed on the groff mailing list.  Accordingly, drop
	displayed examples from this page; all are available in groff's
	Texinfo manual.
	* NEWS: Add item in case people wonder where they've gone.

2023-08-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Fix staggering of text block entries.

	* src/preproc/tbl/table.cpp: Add C preprocessor macro storing a
	"text block staggering macro" name.
	(block_entry::position_vertically): If staggering, call it in
	generated output with a negative half-vee motion.
	(block_entry::position_vertically, left_block_entry::print)
	(right_block_entry::print, center_block_entry::print)
	(alphabetic_block_entry::print): If staggering, call it in
	generated output with a positive half-vee motion.
	(table::init_output): Write out its definition in generated
	output.  It wraps the `sp` request.  If we're in a diversion,
	use the `\!` technique to recursively call ourselves and bubble
	up the spacing request a diversion level (spacing requests of
	anything other than 1v are ignored in diversions).  Otherwise,
	invoke the request.

	Fixes <https://savannah.gnu.org/bugs/?64454> a.k.a. Debian
	#1038391.  Thanks to наб for the report and a good test case.

2023-08-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Regression-test Debian #1038391.

	* src/preproc/tbl/tests/\
	align-staggered-text-blocks-correctly.sh: Do it.
	* src/preproc/tbl/tbl.am (tbl_TESTS): Run test.

2023-08-04  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Deprecate `SB` macro.  It is a SunOS 4.0 (1988) extension
	that in most contexts, does nothing you can't achieve with `SM`
	and `B` together (in either order).

	Study of the SunOS 4 man page corpus suggests a reason for its
	introduction of this macro: use of `SB` immediately after `TP`
	was common (610 out of 2,111 occurrences).  The problem with
	`TP` and the mechanism suggested above is that input traps in
	troff normally ignore the `\c` escape sequence, the use of which
	would be necessary to get the desired effect.  In groff since
	1.22.4, the man(7) `TP` macro uses GNU troff's `itc` request,
	which _does_ respect `\c`.  (mandoc(1) 1.14.2 and later behave
	compatibly with groff man >= 1.22.4.)  Solaris 11 switched to
	groff as its man page formatter, so there is no reason for newly
	written or currently maintained man pages to employ `SB`.

	* tmac/an.tmac (SB): Throw deprecation warning.

	* tmac/groff_man.7.man.in (Description): Move macro from table
	to deprecation list.
	(Font style macros): Move description from here...
	(Deprecated features): ...to here.
	(Portability): Drop mention, since we don't encourage people to
	use it at all.

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

2023-08-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (zoom_font): Validate arguments more.
	Invalid inputs could have bizarre consequences.

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

2023-08-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	Drop tmac/fixmacros.sed.  We hadn't ever actually installed it;
	it was provided only in our distribution archives, as far back
	as our history indicates.

	* tmac/fixmacros.sed: Delete.
	* tmac/tmac.am (EXTRA_DIST): Stop shipping it.
	* PROBLEMS: Recast and update relevant item description.  This
	is the only place the file was documented.

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

	* tmac/doc.tmac (doc-parse-args): Set ellipses in roman.

	Thanks to Lennart Jablonka for reminding me of this issue on the
	linux-man mailing list.

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

	* src/libs/libgroff/fontfile.cpp: Update `#include`s.
	(font::open_file): Do more parameter validation.  Don't
	construct a file name for opening from components that are null
	pointers.  Also `assert()` this since it should be an invariant.
	Migrate from `sprintf()` to `snprintf()`; we have the size of
	the destination buffer handy.

	Fixes <https://savannah.gnu.org/bugs/?64485>.  Thanks to Bjarni
	Ingi Gislason for the report.

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

	* src/preproc/pic/troff.cpp (troff_output::set_location): Do
	more parameter validation.  Generate the two-argument form of
	the `lf` request only if the C string holding the new file name
	to write isn't a null pointer.  Also `assert()` this since it
	should be an invariant.

	Fixes <https://savannah.gnu.org/bugs/?64488>.  Thanks to Bjarni
	Ingi Gislason for the report.

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

	[gxditview]: Add accelerators for "Print" action.

	An apparent bug in a support library affects some users; it
	disables gxditview's pop-up menu.  (The menu pops up, but no
	item can be selected.)  Also, "Print" was the only action for
	which no keyboard accelerator was defined.  "p" (unmodified) is
	already bound to `PreviousPage()`; bind "p" with any of the
	modifiers Shift, Ctrl, Alt, or Meta to `Print()`.

	* src/devices/xditview/GXditview.ad: Do it.
	* src/devices/xditview/gxditview.1.man: Document it.

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

	* tmac/es.tmac: Scream the entire word "BIBLIOGRAPHÍA", instead
	of dying off to a murmur at the last two letters.

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

	[troff]: Add new `.trap` built-in register.

	* src/roff/troff/div.h (class diversion, class macro_diversion,
	class top_level_diversion): Declare new member function
	`get_next_trap_name`.
	* src/roff/troff/div.cpp (macro_diversion::get_next_trap_name):
	New member function returns name of diversion trap if any, and
	if its position is greater than the vertical drawing position,
	otherwise an empty string.
	(top_level_diversion::get_next_trap_name): New member function
	returns the name of the next vertical position trap, if any,
	otherwise an empty string.
	(class next_trap_name_reg): New class has one member, a
	`get_string()` function.
	(next_trap_name_reg::get_string): New function.
	(init_div_requests): Add `.trap` to the register dictionary and
	wire it up to `next_trap_name_reg`.

	* doc/groff.texi (Page Location Traps):
	* man/groff.7.man (Read-only registers):
	* man/groff_diff.7.man (New registers): Document it.

	* src/roff/groff/tests/dot-trap_register_works.sh: Test it.
	* src/roff/groff/groff.am (groff_TESTS): Run test.

	* NEWS: Add item.

	Fixes <https://savannah.gnu.org/bugs/?64212>.  Thanks to Dave
	Kemper for feedback.

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

	* src/roff/troff/node.cpp (unbreakable_space_node::tprint):
	Write word marker ('w' command) to output.
	* NEWS: Add item.

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

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

	* tmac/papersize.tmac: Set register `#R_MARGIN` for mom(7)'s
	benefit, not `R_MARGIN`, which it neither tests nor interpolates
	as a register.  Continues commit bed42a77cb, 2022-11-16.

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

	* tmac/papersize.tmac: If the `paper` string is defined when
	this macro file is loaded, set the `O` (mm page offset register)
	independently of the `W` (mm line length ["width"] register).

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

	[docs]: Revise material in our Texinfo manual.

	* doc/groff.texi (Manipulating Filling and Adjustment): Document
	a CSTR #54 erratum; the arguments to the `ss` request are in
	12ths of the selected font's `spacewidth` parameter, not 36ths
	of an em.  Drop false claim of rounding of `.ss` and `.sss`
	register values on terminal devices.  (Rounding of any resulting
	adjustment quantities might still occur, but this is part of the
	usual application of motion quanta and not particular to the
	`ss` request.)  Characterize "undiscardable space" as
	"horizontal motion" to help the reader acquire this essential
	distinction between horizontal spaces and motions.
	(Manipulating Spacing): Clarify behavior.  Distinguish `sp`
	request from `\v` escape sequence and cross reference the
	latter.  Recast to squeeze presentation of `ss` request onto one
	U.S. letter page when typeset.  Drop (commented-out) trivial
	example of `ls` usage in favor of new example illustrating some
	macros using `vs` instead, for pedagogical purposes and to eat
	up a lot of dead space on the page caused by a later lengthy
	example.  (Knuth-Plass for the...uh...win.)
	(Page Control): Stop (arguably) mis-applying the term "widow",
	in favor of less metaphorical language.  Extend Woolf example to
	narrow the seas of vertical space produced by TeX's formatting
	of the page it occupies.  (Our blanched discourse can use the
	purple prose.)
	(Page Motion): Fix straggling use of "escape" as a noun; we
	prefer "escape sequence".

	* man/groff.7.man (Request short reference) <ss>: Sync.

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

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

	* src/roff/troff/env.cpp (environment::print_env): Fix error in
	report.  The units of {minimum inter-word, additional
	inter-sentence} space size are 12ths of the font's "spacewidth"
	parameter, not 36ths of an em.

	Consider the following input.
	  .\" groff -T ps -Z
	  .nf
	  foo bar1
	  .ss 12
	  foo bar2 \" cases 1 and 2 are the same
	  foo\h'1m/3u'bar3 \" wider than 1 & 2
	  foo\h'1m/36u*12u'bar4 \" slightly narrower than case 3
	  .ss 11
	  foo bar5 \" narrower than case 1 (as expected)
	  foo\h'1m/36u*11u'bar6 \" between cases (1,2) and 4

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

	* tmac/papersize.tmac: If not already defined, set `PO` register
	to one inch to integrate with ms(7), man(7), and mdoc(7).

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

	[ms]: Improve documentation of pic(1) usage.

	* tmac/groff_ms.7.man
	(Tables, figures, equations, and references): Document the
	mandatory arguments to `PS`.  Explain that pic(1) will supply
	them.  (This is documentation of the _package's_ interface.)

	* doc/groff.texi: As above, and add example of pic(1) input.
	Also tighten wording.

	* doc/ms.ms: As above, and supply pic output corresponding to
	example (if typesetting).  Add a keep.

	* doc/doc.am (doc/ms.ps): Preprocess with pic; call groff with
	`-p` option when generating document.

	* src/utils/grog/tests/smoke-test.sh: Drop a test case; we no
	longer have an ms(7) document in the tree that uses tbl and eqn
	but not pic.

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

	[tbl]: Fix post-1.23.0 regression.

	* src/preproc/tbl/main.cpp (process_format): Fix thinkos
	introduced in commit ba420961c3, 19 May, which caused the first
	character after [PpVv] column modifiers to be ignored.  Problem
	visible in typeset renderings of our "ms.ms" document, where
	some table entries were getting rendered at a type size of 1p.

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

	[ms]: Fix Savannah #64438.

	* tmac/s.tmac (@PS): Stop treating excess arguments as
	erroneous, foregoing preparation for pic(1) output.  Fixes
	regression from groff 1.22.4.

	Fixes <https://savannah.gnu.org/bugs/?64438>.  Thanks to Doug
	McIlroy for the report, Dave Kemper for root-cause analysis, and
	Deri James for usability feedback.

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

	* arch/djgpp/config.site:
	* arch/misc/shdeps.sh:
	* bootstrap:
	* font/devdvi/generate/CompileFonts:
	* font/devps/generate/afmname:
	* font/devps/generate/make-zapfdr:
	* font/util/make-Rproto:
	* gendef.sh:
	* m4/groff.m4:
	* mdate.pl:
	* src/devices/grops/grops.1.man:
	* src/devices/xditview/ad2c:
	* src/libs/libgroff/config.charset:
	* src/libs/libgroff/make-uniuni:
	* src/preproc/eqn/neqn.sh:
	* src/roff/nroff/nroff.sh:
	* src/utils/afmtodit/make-afmtodit-tables:
	* test-groff.in:
	* tmac/hyphenex.pl: Stop endorsing shebang line space myth.
	Fixes <https://savannah.gnu.org/bugs/?64058>.

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

	* m4/groff.m4 (GROFF_PROG_YACC): Behave more like `AC_PROG_YACC`
	where useful, seeking "bison" first.  Drop comment claiming that
	"Bison-generated parsers have problems with C++ compilers other
	than g++", which dates back to groff 1.10, 26 November 1995.
	Let us optimistically assume that GNU Bison (and C++ compilers)
	have improved since then.

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

	* src/roff/groff/groff.cpp (main): Update copyright notice and
	warranty disclaimer.  Bump year.  Lead with declaration as free
	software (join us now); specify GPL version and user's option to
	upgrade to later version.  Use a warranty disclaimer inspired by
	GNU Bison.  Drop mention of "COPYING" file, which is not
	installed by groff's "install" make(1) target and not sufficient
	information to aid users of groff packages prepared by
	distributors (which neverless are legally bound to provide
	licensing information via some means, and do so with high
	reliability).  After almost 35 years, we can have some hope that
	people have heard of the GNU GPL and can locate a copy of it
	without great difficulty.  Also drop use of term "subprogram".

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

	* tmac/man.local: Stop disabling hyperlinks on non-HTML output
	devices.  less(1) version 566 and later are in wide distribution
	now and will be more so by the time of the next groff release.

	* tmac/tests/an_UE-breaks-before-long-URIs.sh: Force hyperlinks
	off with `-rU0` to preserve test validity.

	* NEWS: Add item.

	Thanks to Colin Watson for pioneering these changes in Debian's
	groff 1.23.0-1 package.

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

	* src/preproc/html/pushback.cpp (pushBackBuffer::isString):
	Partially revert commit 411b42f4ec, 2 June.  This member
	function needs a signed type to iterate backwards for internal
	validation purposes, so use `ptrdiff_t` instead of `size_t`.
	Fixes post-1.23.0 problem with pre-grohtml infinitely looping on
	complex documents like groff_char(7).  Mea culpa.

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

	[eqn]: Clarify diagnostic message.

	* src/preproc/eqn/lex.cpp (do_delim): Do it.

	Thanks to Doug McIlroy for the report <https://lists.gnu.org/\
	archive/html/groff/2023-06/msg00158.html>.

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

	[troff]: Add unit tests for drawing commands.

	* src/roff/groff/tests/draw-arc.sh:
	* src/roff/groff/tests/draw-circle.sh:
	* src/roff/groff/tests/draw-ellipse.sh:
	* src/roff/groff/tests/draw-filled-circle.sh:
	* src/roff/groff/tests/draw-filled-ellipse.sh:
	* src/roff/groff/tests/draw-filled-polygon.sh:
	* src/roff/groff/tests/draw-line.sh:
	* src/roff/groff/tests/draw-polygon.sh:
	* src/roff/groff/tests/draw-spline.sh:
	* src/roff/groff/tests/set-stroke-thickness.sh: Do it.

	* src/roff/groff/groff.am (groff_TESTS): Run tests.

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

	[man, mdoc]: Parameterize page offset.

	* tmac/mdoc/doc-ditroff (doc-setup-page-layout):
	* tmac/mdoc/doc-nroff (doc-setup-page-layout):  Stop forcing the
	page offset to the device defaults, redundantly.

	* tmac/an.tmac:
	* tmac/mdoc/doc-ditroff (doc-setup-page-layout):
	* tmac/mdoc/doc-nroff (doc-setup-page-layout):  Honor `PO`
	register if set at startup.

	* tmac/groff_man.7.man.in (Options):
	* tmac/groff_mdoc.7.man (Options): Document it.

	* NEWS: Add item.

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

	Slightly refactor.

	[grodvi, grops, xditview, libbib, libgroff, eqn, pre-grohtml,
	preconv, refer, troff, tfmtodit]: Store return value of
	`strlen()` in a `size_t` (or `ptrdiff_t` if we're performing
	subtraction on it) instead of an `int`.  Change temporaries
	{loop indices and similar} to use the same types.

	* src/devices/grodvi/dvi.cpp (dvi_printer::do_special):
	* src/devices/grops/ps.cpp (ps_output::comment_arg):
	(ps_output::put_string, ps_output::put_number):
	(ps_output::put_float, ps_output::put_color):
	* src/devices/grops/ps.cpp (class ps_output) <put_string, col>:
	<max_line_length>:
	* src/devices/xditview/Dvi.c (ClassInitialize):
	* src/include/symbol.h (class symbol) <block_size>:
	* src/libs/libbib/index.cpp (index_search_item::munge_filename):
	(index_search_item::search_item):
	* src/libs/libgroff/fontfile.cpp (font::open_file):
	* src/libs/libgroff/string.cpp (string::operator=):
	(string::operator+):
	* src/libs/libgroff/symbol.cpp (symbol::symbol):
	(symbol::block_size):
	* src/preproc/eqn/delim.cpp (define_extensible_string):
	* src/preproc/html/pre-html.cpp (char_buffer::can_see):
	* src/preproc/html/pushback.cpp (pushBackBuffer::isString):
	* src/preproc/preconv/preconv.cpp (emacs2mime):
	* src/preproc/refer/label.ypp (format_expr::evaluate):
	* src/roff/troff/input.cpp (make_temp_iterator, pipe_source):
	* src/utils/tfmtodit/tfmtodit.cpp (main): Do it.

	* src/preproc/html/pushback.cpp (pushBackBuffer::isString): Drop
	`while` loop that is now tautologically true due to comparison
	of unsigned types.

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

	* src/roff/troff/env.cpp (font_change): Trivially refactor.
	Simplify conditionals.

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

	[eqn]: Trivially refactor.  Rename `check_tabs` member functions
	to `diagnose_tab_stop_usage`, to be more expressive and to
	prepare for the diagnosis of leaders in the input as well.

	* src/preproc/eqn/box.cpp (box::check_tabs):
	(box_list::list_check_tabs):
	(pointer_box::check_tabs):
	(tab_box::check_tabs):
	* src/preproc/eqn/box.h (box::check_tabs):
	(box_list::list_check_tabs):
	(list_box::check_tabs):
	(pile_box::check_tabs):
	(matrix_box::check_tabs):
	(pointer_box::check_tabs):
	(tab_box::check_tabs):
	* src/preproc/eqn/delim.cpp (delim_box::check_tabs):
	* src/preproc/eqn/limit.cpp (limit_box::check_tabs):
	* src/preproc/eqn/list.cpp (list_box::check_tabs):
	* src/preproc/eqn/other.cpp (accent_box::check_tabs):
	(uaccent_box::check_tabs):
	* src/preproc/eqn/over.cpp (over_box::check_tabs):
	* src/preproc/eqn/pile.cpp (pile_box::check_tabs):
	(matrix_box::check_tabs):
	* src/preproc/eqn/script.cpp (script_box::check_tabs):
	* src/preproc/eqn/sqrt.cpp (sqrt_box::check_tabs):
	Rename these...
	* src/preproc/eqn/box.cpp (box::check_tabs):
	(box::diagnose_tab_stop_usage):
	(box_list::list_diagnose_tab_stop_usage):
	(pointer_box::list_diagnose_tab_stop_usage):
	(tab_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/box.h (box::diagnose_tab_stop_usage):
	(box_list::list_diagnose_tab_stop_usage):
	(list_box::diagnose_tab_stop_usage):
	(pile_box::diagnose_tab_stop_usage):
	(matrix_box::diagnose_tab_stop_usage):
	(pointer_box::diagnose_tab_stop_usage):
	(tab_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/delim.cpp
	(delim_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/limit.cpp
	(limit_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/list.cpp (list_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/other.cpp
	(accent_box::diagnose_tab_stop_usage):
	(uaccent_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/over.cpp (over_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/pile.cpp (pile_box::diagnose_tab_stop_usage):
	(matrix_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/script.cpp
	(script_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/sqrt.cpp (sqrt_box::diagnose_tab_stop_usage):
	...to these.

	* src/preproc/eqn/box.cpp (box::top_level)
	(box_list::list_diagnose_tab_stop_usage):
	(pointer_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/delim.cpp
	(delim_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/limit.cpp
	(limit_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/list.cpp (list_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/other.cpp
	(accent_box::diagnose_tab_stop_usage):
	(uaccent_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/over.cpp (over_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/pile.cpp (pile_box::diagnose_tab_stop_usage):
	(matrix_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/script.cpp
	(script_box::diagnose_tab_stop_usage):
	* src/preproc/eqn/sqrt.cpp (sqrt_box::diagnose_tab_stop_usage):
	Update call sites.

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

	[eqn]: Trivially refactor.  Boolify `tab_box` member variable
	`disabled`.

	* src/preproc/eqn/box.cpp (tab_box::tab_box)
	(tab_box::check_tabs):
	* src/preproc/eqn/box.h (class tab_box): Do it.

	* src/preproc/eqn/box.cpp (tab_box::check_tabs): Also recast
	diagnostic message to clarify what "level" we're talking about:
	it's lexical.  Which, sadly, probably won't help any but
	CS/SWeng people...

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

	* src/roff/troff/env.h (read_hyphen_file): Drop relic prototype
	for undeclared function.  Should have been disposed of on
	1992-09-21, per ChangeLog.old (né ChangeLog.115).

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

	* src/roff/troff/input.cpp (do_error): Describe vertical page
	locations in output warning diagnostics in terms of lines on
	nroff devices.
	* doc/groff.texi (Debugging) <warnscale>:
	* man/groff.7.man (Request short reference) <warnscale>:
	Document this change.
	* NEWS: Add item.

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

	[tbl]: Refactor handling of type size and vertical spacing.

	* src/preproc/tbl/table.h (struct inc_number): Rename this...
	(struct size_expression): ...to this, and change its member
	types.  The `inc` `short` becomes a `relativity` enum
	because it only ever takes 3 values.  The `val` short becomes an
	`int`, undoing what I suspect to be premature optimization.
	* src/preproc/tbl/main.cpp (entry_modifier::entry_modifier)
	(entry_format::debug_print, process_format):
	* src/preproc/tbl/table.cpp (set_modifier, set_inline_modifier)
	(restore_inline_modifier): Update to reflect new types and
	enum literals.

2023-05-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/main.cpp (process_format): Check for EOF after
	eating spaces and tabs when processing [pPvVwW] column
	modifiers, and emit an appropriate error diagnostic.  This was
	already being done for [fFmM].

2023-05-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/tbl/main.cpp (process_format): Accept (and
	discard) space and tab characters after [pPvV] in a column
	descriptor, as is already done for [fFmMwW].  Modify [wW] to use
	the same loop style as the others, for consistency.

2023-05-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/box.cpp (half_space_box::output)
	(full_space_box::output, thick_space_box::output)
	(half_space_box::output): Add assertions to catch unexpected
	flow of control.

2023-05-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn]: Implement tunable "half_space" and "full_space"
	parameters.  They default to the same widths as "thin_space" and
	"thick_space", respectively, but control the widths of the '^'
	and '~' input tokens.

	* src/preproc/eqn/box.cpp: Add globals `half_space`,
	`full_space`.
	(struct S): Recognize "half_space" and "full_space" as
	parameters to the "set" primitive, and map them to the globals.
	(half_space_box::output): Format the half space width.
	(full_space_box::output): Format the full space width.
	(full_space_box::output, thick_space_box::output): Drop
	workaround for Firefox 1.5 MathML bug (November 2005).  Emit
	"&ThickSpace;" entity instead of "&ensp;".

	* src/preproc/eqn/eqn.1.man (Customization): Document feature.

	* NEWS: Add item.

	Fixes <https://savannah.gnu.org/bugs/?64216>.  Thanks to Doug
	McIlroy for the report and Damian McGuckin for the discussion.

2023-05-19  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn]: Add `thick_space` and `thin_space` classes.

	* src/preproc/eqn/box.cpp:
	* src/preproc/eqn/box.h: Do it.

2023-05-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn]: Trivially refactor.  Rename "space_box" class to
	"full_space_box" for clarity and to prepare for adding distinct
	thin and thick space box classes.

	* src/preproc/eqn/box.cpp (space_box::space_box)
	(space_box::output, space_box::debug_print):
	* src/preproc/eqn/box.h (class space_box): Rename these...
	* src/preproc/eqn/box.cpp (full_space_box::full_space_box)
	(full_space_box::output, full_space_box::debug_print):
	* src/preproc/eqn/box.h (class full_space_box): ...to these.
	* src/preproc/eqn/eqn.ypp (simple): Construct item using new
	type name.

2023-05-18  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/hvunits.h: Boolify.
	(class vunits, class hunits, vunits::is_zero, hunits::is_zero):
	Do it.

2023-05-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp: Rename request-handling functions to
	better describe their operation.
	(font_translate, font_position, style, underline_font)
	(define_font_special_character, remove_font_special_character)
	(font_special_request, special_request, font_zoom_request)
	(bold_font, track_kern, constant_space, ligature, kern_request)
	(set_soft_hyphen_char): Rename these...
	(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)
	(set_soft_hyphen_character): ...to these.

2023-05-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/node.cpp (font_translate, font_position, style)
	(underline_font, define_font_special_character)
	(remove_font_special_character, font_special_request)
	(special_request, font_zoom_request, bold_font, track_kern)
	(constant_space, ligature, kern_request, set_soft_hyphen_char):
	Declare functions as `static`.

2023-05-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix Savannah #64166.

	* src/roff/troff/node.cpp (bold_font): Add `WARN_MISSING`
	diagnostic if request given no arguments; it does nothing, and
	the behavior of this request is sufficiently complex that it's
	worth saying so.  Stop throwing font lookup error if second
	argument cannot be resolved as a font name; it might be an
	emboldening amount instead.

2023-05-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/s.tmac (PE): Turn on no-space mode after a pic(1)
	display, when not flying back with `PF`.  Continues fix for
	Savannah #62688.

2023-05-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/input.cpp (token::~token, token::operator=):
	Drop workaround for bug in compiler (SGI C++) that dates back to
	groff 1.07 (March 1993).  But don't go back to using the ternary
	operator.

2023-05-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Fix Savannah #64104.

	* src/roff/troff/input.cpp (set_escape_char): Rename this...
	(assign_escape_character): ...to this.  Don't permit the escape
	character to be set to the same thing as the control or no-break
	control characters.
	* doc/groff.texi (Using Escape Sequences): Document
	restrictions.

	* src/roff/troff/env.h (class environment): Slightly refactor.
	Rename fields `control_char` and `no_break_control_char` to
	`control_character` and `no_break_control_character`,
	respectively, and make them private.  Add public getters and
	setters for them.
	(get_control_character): New public member function returns
	`unsigned char`.
	(set_control_character): New public member function takes an
	`unsigned char` and returns a `bool`.
	(get_no_break_control_character):
	(set_no_break_control_character): Similar.
	* src/roff/troff/env.cpp (environment::environment): Update
	constructors to use new field names and initialize them in their
	new order of declaration.
	(environment::copy): Similar.  (Not to be confused with a copy
	constructor, this member function implements the operation of a
	valid `evc` GNU troff request.)
	(environment::get_control_character):
	(environment::set_control_character):
	(environment::get_no_break_control_character):
	(environment::set_no_break_control_character): Implement.

	* src/roff/troff/env.cpp: Drop handling of `cc` and `c2`
	requests.
	(control_char, no_break_control_char): Drop implementations.
	(init_env_requests): Drop `init_request` calls for them.

	* src/roff/troff/input.cpp: Resurrect handling of `cc` and `c2`
	requests here, with more error handling.
	(assign_escape_character, process_input_stack): Use the new
	getters defined above in environment object since the relevant
	fields are now private.
	(assign_control_character): New function assumes the former
	responsibilities of `env.cpp::control_char()` and rejects the
	request if the desired character is already the escape or
	no-break control character.
	(assign_no_break_control_character): New function assumes the
	former responsibilities of `env.cpp::no_break_control_char()`
	and rejects the request if the desired character is already the
	escape or control character.
	(process_input_stack): Reorder comparisons to avoid inadvertent
	lvalue assignment.  Add parentheses to assignment with complex
	RHS.
	(init_input_requests): Attach `cc` and `c2` requests to new
	functions above.
	* doc/groff.texi (Control Characters): Document restrictions.

2023-05-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Don't quote a character with itself in diagnostics.

	* src/roff/troff/input.cpp (token::description)
	(input_char_description): When quoting the ' character in
	diagnostics, use double-quotes, not apostrophes.

2023-05-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/input.cpp (top level, warnscale_request, main,
	do_error): Rename global `warn_scaling_indicator` to
	`warn_scaling_unit`, to align with our documentation.

2023-05-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Revise output warning diagnostic format.

	* src/roff/troff/input.cpp (do_error): For the `OUTPUT_WARNING`
	value of the `error_type` enum, spell out the words "page" and
	"diversion" instead of abbreviating them, and place the
	diversion information (if present) in parentheses.

2023-05-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Trivially refactor.

	* src/roff/troff/reg.cpp (set_number_reg): Rename to...
	(set_register): ...this.
	* src/roff/troff/reg.h: Update extern reference.
	* src/roff/troff/div.cpp (mark):
	* src/roff/troff/input.cpp (length_request, do_register)
	(token::add_to_zero_width_node_list, do_register_assignment)
	(init_registers): Update call sites.

	* src/roff/troff/div.cpp (interpolate_number_reg): Rename to...
	(interpolate_register): ...this.
	(get_copy, token::next, length_request, read_title_parts):
	Update call sites.
	* src/roff/troff/token.h: Update extern reference.  Explicitly
	declare as `extern`.

	* src/roff/troff/reg.cpp (define_number_reg): Rename to...
	(define_register): ...this.
	(init_reg_requests): Update call site.
	(set_number_reg): Rename to...
	(set_register): ...this.
	(print_number_regs): Rename to...
	(print_registers): ...this.

	* src/roff/troff/reg.cpp (lookup_number_reg): Rename to...
	(look_up_register): ...this.
	* src/roff/troff/input.cpp (interpolate_register): Update call
	site.
	* src/roff/troff/reg.h: Update extern reference.  Explicitly
	declare as `extern`.

2023-04-30  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn]: Improve tests of line number accuracy.

	* src/preproc/eqn/tests/\
	diagnostics-report-correct-line-numbers.sh: Add cases to check
	behavior of valid input, not just error cases.  Also add some
	unexecuted test cases for future use.

2023-04-29  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/include/lf.h (interpret_lf_args):
	* src/libs/libgroff/lf.cpp (interpret_lf_args): Boolify.

2023-04-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Fix Savannah #64122.

	* src/preproc/tbl/table.cpp (table::init_output): Specify
	scaling unit when using `hym` and `hys` requests.  Continues
	commit cee547e883, 30 January 2021.

	Thanks to Frederic Chartier and Peter Schaffter for the report.

2023-04-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Regression-test Savannah #64122.

	* src/preproc/tbl/tests/\
	save-and-restore-hyphenation-parameters.sh: Update input and add
	check.

2023-04-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Drop `POPEN_MISSING` preprocessor macro.

	3 source files test this macro but nothing appears to define it.
	It dates back to (at least) 1994.  I suspect this of being
	bitrot.  Reasons include: (1) We test for a declaration of
	`popen` in our "configure.ac" file; (2) our gxditview command
	uses `popen` _without_ #ifdef-guarding it (perhaps the
	assumption was that any system that supported X11 also had a
	working `popen`); (3) our "nonposix.h" header file defines a
	macro aliasing `popen` to `_popen`, which is its typical name on
	Windows systems, and is the most likely build host candidate for
	which support might have been missing as late as 1994.
	Microsoft end-of-lifed MS-DOS in 2000.  If someone wants to
	start up a FreeDOS port, talk to us.  Maybe even that has a
	functional `popen()`.  Here's hopin'.

	* src/roff/troff/input.cpp ([global], file_iterator::close)
	(pipe_source, pipe_output, init_input_requests):
	* src/roff/troff/node.cpp (class real_output_file)
	(output_file::real_output_file, output_file::~real_output_file):
	* src/roff/troff/node.h: Do it.

2023-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn]: Implement new "gifont" primitive.

	* src/preproc/eqn/eqn.ypp: Add token "GFONT" (to supplement
	"GIFONT", already renamed from "GFONT".
	* src/preproc/eqn/lex.cpp (struct token_table): Map "gifont" and
	"gfont" inputs to "GIFONT" and "GFONT" tokens.
	(do_gfont, do_gifont): Employ parallel implementations,
	differing only in diagnostic message text.
	(yylex): Handle token "GFONT" by calling `do_gfont()`.

	* src/preproc/eqn/eqn.1.man (New primitives, Fonts, Options)
	(Bugs): Document it.
	* NEWS: Add item.

	Fixes <https://savannah.gnu.org/bugs/?63967>.  Thanks to Damian
	McGuckin, Doug McIlroy, and Ralph Corderoy for support and
	suggestions.

2023-04-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/lex.cpp (do_include, do_undef, do_gsize)
	(do_gifont, do_grfont, do_gbfont, do_space, do_chartype)
	(do_set): Recast diagnostic messages to use terminology
	established in man page, and use more idiomatic English in
	phrasing.  Distinguish which argument has the problem when
	lexical analysis of "chartype" and "set" commands fails.

2023-04-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/lex.cpp (do_include, ignore_definition)
	(do_definition, do_undef, do_gsize, do_gifont, do_grfont)
	(do_gbfont, do_sprintf, do_ifdef, do_chartype, do_set): Recast
	diagnostic messages to characterize input as "invalid" rather
	than "bad".

2023-04-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	[eqn]: Trivially refactor, renaming various globals from
	containing "gfont" to "gifont", to make it clearer that they
	deal with the italic font used by equations.

	* src/preproc/eqn/box.cpp (gfont): Rename global char pointer
	from this...
	(gifont): ...to this.
	* src/preproc/eqn/box.cpp (get_gfont, set_gfont):
	* src/preproc/eqn/box.h (get_gfont, set_gfont):
	* src/preproc/eqn/lex.cpp (do_gfont): Rename functions from
	these...
	* src/preproc/eqn/box.cpp (get_gifont, set_gifont):
	* src/preproc/eqn/box.h (gifont, get_gifont, set_gifont):
	* src/preproc/eqn/lex.cpp (do_gifont): ...to these.
	* src/preproc/eqn/box.cpp (get_gifont, set_gifont): Update
	global `gfont` access sites.
	* src/preproc/eqn/box.cpp (box::top_level):
	* src/preproc/eqn/eqn.ypp (simple):
	* src/preproc/eqn/lex.cpp (do_gifont, yylex):
	* src/preproc/eqn/main.cpp (main): Update call sites.
	* src/preproc/eqn/eqn.ypp:
	* src/preproc/eqn/lex.cpp (token_table, yylex): Rename "GFONT"
	token type to "GIFONT".

2023-04-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/preproc/eqn/main.cpp (main): Prefix generated *roff
	diagnostics with name of input file (the document).  Use
	`tmc`/`tm1` to coalesce multi-line diagnostic onto one line of
	output to stderr.  Tighten wording.  Continues the long process
	of fixing Savannah #52463.

2023-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (temp_iterator::temp_iterator):
	Skip allocation of zero-length arrays.  Resolves "-Walloc-zero"
	warning from GCC.

	Fixes <https://savannah.gnu.org/bugs/?62398>.  Thanks to Bjarni
	Ingi Gislason for the report.

2023-04-02  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (token::description): Revise
	construction of description of printable ordinary input
	characters (U+0021 through U+007E).  This is to facilitate
	better diagnostics from the `rchar` request in the future.  See
	Savannah #63985.

2023-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/roff/troff/input.cpp (chop_macro)
	(do_string_case_transform, substring_request, asciify_macro):
	(unformat_macro, write_macro_request): When diagnosing
	impossible operations on request names, report the name of the
	request they were attempted upon.
	* src/roff/groff/tests/string_case_xform_errors.sh: Update test
	expectations.

2023-04-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[troff]: Make futile aliasing an error.

	* src/roff/troff/input.cpp (alias_macro): Promote diagnostic
	when attempting to alias a nonexistent macro/string/diversion
	from warning to error; this aligns with the handling of the
	requests `chop`, `stringup`, `stringdown`, `substring`,
	`asciify`, `unformat`, and `writem` when they are regarded as
	impossible.  Further, attempting to alias a nonexistent object
	does not create an empty one, unlike interpolating it; try ".als
	baz qux", then ".pm".
	* src/roff/troff/reg.cpp (alias_reg): Promote diagnostic when
	attempting to alias a nonexistent register from warning to
	error.  Attempting to alias a nonexistent register does not
	create an empty one, unlike interpolating it; try ".aln q r",
	then ".pnr".

2023-03-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Trivially refactor.  Rename variables and functions to
	use the term "rule" rather than "line".  The value of the term
	"rule" is that it is not confusable with "lines" of (text) input
	or output.

	* src/preproc/tbl/main.cpp (struct format) <vline>:
	(format::format) <vline>:
	(format::add_rows) <old_vline, vline>:
	(format::~format) <vline>:
	(struct input_entry_format) <vline, vline_count>:
	(input_entry_format::input_entry_format) <vline, vline_count>:
	(input_entry_format::debug_print) <vline, vline_count>:
	(process_format) <vline_count>:
	(process_data) ([anonymous] enum) <SINGLE_HLINE, DOUBLE_HLINE>:
	* src/preproc/tbl/table.cpp:
	* src/preproc/tbl/table.h (enum format_type) <FORMAT_HLINE,
	FORMAT_DOUBLE_HLINE>
	(class table) <vline, vline_spanned, ([anonymous] enum)
	<HAS_TOP_VLINE, HAS_TOP_HLINE>, add_single_hline,
	add_double_hline, add_vlines, print_single_hline,
	print_double_hline: Rename these...

	* src/preproc/tbl/main.cpp (struct format) <vrule>:
	(format::format) <vrule>:
	(format::add_rows) <old_vrule, vrule>:
	(format::~format) <vrule>:
	(struct input_entry_format) <vrule, vrule_count>:
	(input_entry_format::input_entry_format) <vrule, vrule_count>:
	(input_entry_format::debug_print) <vrule, vrule_count>:
	(process_format) <vrule_count>:
	(process_data) ([anonymous] enum) <SINGLE_HRULE, DOUBLE_HRULE>:
	* src/preproc/tbl/table.cpp:
	* src/preproc/tbl/table.h (enum format_type) <FORMAT_HRULE,
	FORMAT_DOUBLE_HRULE>
	(class table) <vrule, vrule_spanned, ([anonymous] enum)
	<HAS_TOP_VRULE, HAS_TOP_HRULE>, add_single_hrule,
	add_double_hrule, add_vrules, print_single_hrule,
	print_double_hrule: ...to these.

2023-02-25  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tbl]: Fix Savannah #63838.

	* src/preproc/tbl/table.cpp (table::add_entry): Throw error
	diagnostic if table entry ends in the zero-motion escape
	sequence `\z`.  This is nonsense and provokes baffling
	diagnostics from the formatter.  Stick user's nose directly into
	the problem.

	Fixes <https://savannah.gnu.org/bugs/?63838>.  Thanks to the
	mandoc(1) project for documenting the issue in a regression
	test.

2023-04-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	[build]: Improve portability to non-GNU, non-LLVM compilers.

	* bootstrap.conf (gnulib_modules): Add "attribute".
	* src/libs/libgroff/getopt.c:
	* src/libs/libgroff/new.cpp: Include gnulib's "attribute.h"
	header file.
	* src/libs/libgroff/getopt.c (_getopt_initialize):
	* src/libs/libgroff/new.cpp (operator delete): Replace GNU C
	unused attribute syntax with gnulib's "MAYBE_UNUSED".

	Thanks to Bruno Haible for the report and suggested remedy.

2023-03-16  G. Branden Robinson <g.branden.robinson@gmail.com>

	* src/libs/libxutil/XFontName.c (utoa): Rename function from
	this...
	(xu_utoa): ...to this, to avoid name collision when using
	"newlib" portability library.
	(XFormatFontName): Update call site.
	* PROBLEMS: Drop item.

	Fixes <https://savannah.gnu.org/bugs/?63831>.  Thanks to Brian
	Inglis for the report.

2023-05-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Preserve user-selected font family.

	* tmac/an.tmac: When initializing, save the currently selected
	font family as `an*body-family` instead of forcing 'T' (Times,
	which is the formatter's default, even on nroff-mode devices
	that can't switch families).  This change makes the formatter's
	`-f` option work on man(7) documents again (important for
	Japanese man pages, but there is now once again nothing stopping
	you from viewing man pages in Palatino or Helvetica on the 'ps'
	and 'pdf' devices where these families are available).  It also
	reopens an avenue for rogue pages to affect the rendering of
	unrelated documents later in batch rendering, but there are many
	other, and worse, ways for rogue pages to do damage.  Problem
	introduced by me in commit e0e16d8e65, 15 March 2022.

	Fixes <https://savannah.gnu.org/bugs/?64130>.  Thanks to Deri
	James for the report.

2023-05-01  G. Branden Robinson <g.branden.robinson@gmail.com>

	[man]: Stop `HP` producing excess vertical space.

	* tmac/an.tmac (HP): Fix thinko/typo when expanding macro as
	string to call `an-deprecation-warn`.
	* tmac/an-ext.tmac (SY): Put 1v of vertical space on the output
	if we are starting a (non-nested) synopsis.

	Thanks to Alex Colomar for the report.  Problem introduced by me
	in commit aea1dfb11b, 6 March 2022.

2023-04-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[ms]: Default vertical spacing to 120% of type size, not 2
	points larger.

	* tmac/s.tmac (par@load-init, par@init): Do it.
	* NEWS: Add item.

2023-04-26  G. Branden Robinson <g.branden.robinson@gmail.com>

	[pdfpic]: Refactor.

	* tmac/pdfpic.tmac: Migrate gathering of image dimensions from
	`sy` and a temporary file to `pso`.
	(pdfpic@cleanup): Drop `pdfpic*temporary-file` string.
	(pdfpic@get-image-dimensions): Remove redirection.  Invoke
	`pso`, not `sy`.
	(PDFPIC): Stop constructing `pdfpic*temporary-file` string.
	Stop testing `systat` register.  Stop sourcing and deleting
	temporary file.

2023-04-21  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/pdfpic.tmac: Refactor to make comprehensible some
	woefully undocumented cleverness and improve efficiency.
	(PDFPIC): Break out flaming-hoop-leaping "clever" bit of `sy`
	usage into its own macro, calling from here and relocating its
	requests from here...
	(pdfpic@get-image-dimensions): ...to here.  When using `sy`
	request to collect and munge output of pdfinfo(1), (a) disable
	the escape character while defining the macro; (b) construct the
	command in a roff string, appending to it in discrete, hopefully
	comprehensible chunks; (c) disable the escape character during
	macro interpretation wherever possible (most of it); (d) retain
	doubled backslashes so that they survive subsequent string
	interpolation; (e) stop using grep(1) in the pipeline when
	sed(1) is perfectly capable of performing its own input
	filtering; (f) invoke sed with '-n' option and emit output only
	upon a successful substitution; (g) replace unportable(!) POSIX
	BRE character class '[:digit:]' in substitution match text with
	'[0-9]'; and most importantly (h) replace multi-line sed 's'
	replacement text (see below for the reason we can't use it) with
	single roff control line employing the groff extension escape
	sequence `\R` to assign multiple registers.  Annotate
	portability and escaping challenges.  Tested on GNU/Linux, macOS
	12, and (with simulated pdfinfo(1) output) Solaris 11.

	There is a problem with trying to embed true newlines into the
	arguments of a `sy` request.  The C++ function that GNU troff
	uses to assemble the command string (character by character)
	_does not recognize C/C++ string literal escape sequences_.
	This means that you _cannot_ embed "\n" in `sy`'s arguments and
	have it survive, as a newline character, into the command string
	passed to the standard C library's system(3) function.  ("A\nB"
	gets encoded as 'A', '\\', 'n', 'B', not 'A', '\n', 'B'.)
	Unfortunately, this appears to be AT&T troff-compatible
	behavior.  But it means that you _cannot_ portably construct
	multi-line replacement text for sed's 's' command.  (Other sed
	commands like 'a', 'c', and 'i' will be similarly affected.)
	See Savannah #64071.

	* PROBLEMS: Drop item.

	Fixes <https://savannah.gnu.org/bugs/?64061>.  Thanks to Bruno
	Haible for the report, and to him and Ralph Corderoy for the
	discussion of portable and efficient sed constructs.

2023-04-27  G. Branden Robinson <g.branden.robinson@gmail.com>

	[pdfpic]: Clean up better.

	* tmac/pdfpic.tmac (PDFPIC): Call `pdfpic@cleanup` before
	returning when falling back to `PSPIC` for non-PDF documents.

2023-04-05  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tty.tmac: Add angle bracket fallbacks.

	Thanks to Mike Fulton for the report, and to Ralph Corderoy and
	Dave Kemper for the discussion.

2023-03-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tests]: Add Spanish language support (5/5).

	* src/roff/groff/tests/localization_works.sh:
	* tmac/tests/e_ld-works.sh: Test it.

	Fixes <https://savannah.gnu.org/bugs/?63921>.  Thanks to Eloi
	Montañés.

2023-03-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[docs]: Add Spanish language support (4/5).

	* doc/groff.texi (Manipulating Hyphenation):
	* doc/ms.ms (Language and localization):
	* man/groff_tmac.5.man (Localization files): Document it.

	* NEWS: Add item.

2023-03-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tmac]: Add Spanish language support (3/5).

	* tmac/hyphen.es:
	* tmac/es.tmac: Update editor aids.

2023-03-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tmac]: Add Spanish language support (2/5).

	* tmac/es.tmac: Spell weekday and month names in lowercase;
	every style authority I could find online mandates this, and it
	meshes with my half-remembered formal instruction in the
	language.  Fix groff composite special character escape
	sequences to place the base character first.  Replace one
	Unicode special character escape sequence with a composite
	special character escape sequence, for consistency.

2023-03-13  Eloi Montañés <em@ilsrv.com>

	[tmac]: Add Spanish language support (1/5).

	* tmac/hyphen.es: Add hyphenation patterns (encoded in Latin-9).
	* tmac/es.tmac: Add groff locale for Spanish.
	* tmac/tmac.am (TMACNORMALFILES): Ship new files.
	* doc/groff.texi (Manipulating Hyphenation): Add file/package
	  index entry for "es.tmac".
	* LICENSES: Update for CTAN Spanish hyphenation patterns.

2023-03-09  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tests]: Add Russian language support (7/7).

	* src/roff/groff/tests/localization_works.sh:
	* tmac/tests/e_ld-works.sh: Test it.

	Fixes <https://savannah.gnu.org/bugs/?63076>.  Thanks to Nikita
	Ivanov.

2023-03-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[docs]: Add Russian language support (6/7).

	* doc/groff.texi (Input Encodings, Manipulating Hyphenation):
	* doc/ms.ms (Language and localization):
	* man/groff_tmac.5.man (Localization packages, Input encodings):
	Document support for KOI8-R encoding and Russian language.

2023-03-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tmac]: Add Russian language support (5/7).

	* tmac/tmac.am (TMACNORMALFILES): Ship new Russian language
	support files.

2023-03-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tmac]: Add Russian language support (4/7).

	* tmac/koi8-ru.tmac: Rename this file...
	* tmac/koi8-r.tmac: ...to this.  There _is_ a "KOI8-RU"
	encoding, which appears to subsume KOI8-B and KOI8-U (by
	replacing more box drawing characters), but this file does not
	remap their values to applicable Unicode code points.
	* tmac/ru.tmac: Load the encoding file under its new name.

2023-03-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	[tmac]: Add Russian language support (3/7).

	* tmac/hyphen.ru:
	* tmac/ru.tmac: Update editor aids so these files can be edited
	more intelligibly using GNU Emacs.  Annotate apparent problem
	with Vim's KOI8-R support.

2023-03-08  G. Branden Robinson <g.branden.robinson@gmail.com>

	Add Russian language support (2/7).

	LICENSES: Update for CTAN Russian hyphenation patterns.

2023-03-08  Nikita Ivanov <nikita.vyach.ivanov@gmail.com>

	[tmac]: Add Russian language support (1/7).

	* tmac/hyphen.ru: Add hyphenation patterns (encoded in KOI8-R).
	* tmac/koi8-ru.tmac: Add character encoding support.
	* tmac/ru.tmac: Add groff locale for Russian.

2023-04-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/s.tmac (@EQ): Trivially refactor.  Shift valid
	pseudo-enumeration type values from 0..2 to 1..3 so that they
	more idiomatically test for truth values in roff (where zero and
	negative values are false).  Simplify a conditional accordingly.

2023-04-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	[ms]: Fix Savannah #64013.

	* tmac/s.tmac (@EQ): Revise argument handling.  If there is only
	one argument and it is not a recognized alignment, warn and
	treat it as an equation label.  If there are two arguments but
	the first is not a recognized alignment, throw a warning
	diagnostic (but still use default alignment with the second
	argument as label).  An explicitly empty first argument is
	synonymous with "C".

	Fixes <https://savannah.gnu.org/bugs/?64013>.

2023-04-07  G. Branden Robinson <g.branden.robinson@gmail.com>

	[ms]: Regression-test Savannah #64013.

	* tmac/tests/s_EQ-handles-empty-first-arg.sh: Do it.
	* tmac/tmac.am (tmac_TESTS): Run test.

2023-04-05  G. Branden Robinson <g.branden.robinson@gmail.com>

	[ms]: Fix Savannah #64005.

	* tmac/s.tmac (@break-page, bp): Define alias for `bp` request
	and wrapper for `bp` to (if needed) temporarily disable no-space
	mode, so that a document's `bp` requests are honored even if
	no-space mode is on, as can happen after displays.  Fixes a
	regression from groff 1.22.4 and historical ms implementations
	introduced by me on 6 July when resolving Savannah #62688.

	Fixes <https://savannah.gnu.org/bugs/?64005>.  Thanks to Michał
	Kruszewski for reporting the problem and Dave Kemper for
	identifying the cause.

2023-04-05  G. Branden Robinson <g.branden.robinson@gmail.com>

	[ms]: Regression-test Savannah #64005.

	* tmac/tests/s_honor-page-break-after-display.sh: Do it.
	* tmac/tmac.am (tmac_TESTS): Run test.

2023-03-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/mdoc/doc-common (Sh): Restore hyphenation configured with
	`HY` register upon entry to any new section.  Disable adjustment
	and hyphenation when in the "Synopsis" section.

	Fixes <https://savannah.gnu.org/bugs/?63957>.  Thanks to Alex
	Colomar for reporting an issue that brought this one to light.

2023-03-24  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Regression-test Savannah #63957.

	* tmac/tests/doc_synopsis_is_not_adjusted.sh: Do it.
	* tmac/tmac.am (tmac_TESTS): Run test.

2023-03-14  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tmac.am (tmac/stamp-wrap): Stop prepending groff's man(7)
	package wrapper ("-man") on hosts with a system man package with
	a request to source itself; this was search-and-replace damage
	from resolving Savannah #60789.  The wrapper still worked, but
	reported any errors inside the wrapped macro package many times
	until the process ran out of file descriptors.  Problem
	introduced by me in commit fdac25937f, 2021-07-05.

	Fixes <https://savannah.gnu.org/bugs/?63924>.

2023-05-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	* tmac/tests/an-ext_SY-and-YS-work.sh: Add test.
	* tmac/tmac.am (tmac_TESTS): Run test.

2023-04-28  G. Branden Robinson <g.branden.robinson@gmail.com>

	[build]: Skip an Autoconf check if not necessary.

	* m4/groff.m4 (GROFF_PNMTOPS_NOSETPAGE): Skip check if no
	"pnmtops" command was found.

2023-04-06  G. Branden Robinson <g.branden.robinson@gmail.com>

	[doc]: Abstract document dependencies on the mom package.

	* doc/doc.am (doc/automake.pdf): Replace dependency with new
	macro `TMAC_PACKAGE_MOM`.

	Aligns with <https://savannah.gnu.org/bugs/?62541> (4/4).

2023-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	[doc]: Add document dependencies on the ms package.

	* tmac/tmac.am (TMAC_PACKAGE_MS): Define new macro comprising
	the files of the ms package.
	* doc/doc.am (doc/ms.ps, doc/webpage.ps, doc/pic.html)
	(doc/pic.ps): Add dependency on new macro.

	Fixes <https://savannah.gnu.org/bugs/?62541> (2/4).

2023-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	[doc]: Add document dependencies on the "me" package.

	* tmac/tmac.am (TMAC_PACKAGE_ME): Define new macro comprising
	the files of the "me" package.
	* doc/doc.am (doc/grnexmpl.ps, doc/meintro.ps)
	(doc/meintro_fr.ps, doc/meref.ps): Add dependency on new macro.

	Fixes <https://savannah.gnu.org/bugs/?62541> (1/4).

2023-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	[build]: Install PDF documents better.  Ship only one copy of
	"automake.pdf", and install it and the new "groff-man-pages.pdf"
	in the "pdf/" subdirectory of the destination "doc" directory.

	* doc/doc.am (PROCESSEDDOCFILES): Drop
	"$(PROCESSEDDOCFILES_PDF)" from macro definition.
	(nodist_docpdfdoc_DATA) [USE_GROPDF]: Use it here instead,
	replacing a literal "doc/automake.pdf".
	(mostlyclean-doc) [USE_GROPDF]: Clean these same files.

2023-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	[build]: Ship groff.dvi (our Texinfo manual in DVI format).

	* doc/doc.am (install-dvi-local, uninstall-dvi): Add targets.
	(uninstall-local): Depend on "uninstall-dvi".

2023-04-03  G. Branden Robinson <g.branden.robinson@gmail.com>

	[build]: Resume shipping pic.html.

	* m4/groff.m4 (GROFF_CHECK_GROHTML_PROGRAMS)
	(GROFF_GROHTML_PROGRAM_NOTICE, GROFF_PNMTOOLS_CAN_BE_QUIET):
	Rename "make_htmldoc" to "use_grohtml" as expected by
	"configure.ac".  Also stop `AC_SUBST`ing it; we don't need
	"@use_grohtml@" in our Makefiles since an `AM_CONDITIONAL` in
	configure.ac already does an equivalent thing.  Continues commit
	aa5787c1eb by me from 20 May.
	(PROCESSEDDOCFILES): Drop "$(PROCESSEDDOCFILES_HTML)" from macro
	definition; annotate why.

2023-03-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	m4/groff.m4 (GROFF_TMAC): Eliminate garbage leading space from
	contents of `tmac_wrap` shell variable.

2023-03-13  G. Branden Robinson <g.branden.robinson@gmail.com>

	[build]: Clarify output of `GROFF_TMAC` Autoconf test.

	* configure.ac: Correct characterization of the list of macro
	packages reported.  It is not the list of macro packages
	receiving a "g" prefix, but the list of macro packages reciving
	a wrapper macro file in groff's macro directory, each of which
	sources the corresponding system (likely AT&T-descended troff)
	macro package.  Fixes wording I introduced in commit 4d30dd7424,
	31 May.
	* m4/groff.m4 (GROFF_TMAC): Clarify first "checking" message:
	we are looking for a file name prefix on existing system macro
	packages (like "tmac.").  This has nothing to do with the prefix
	applied to groff commands, or the "g" prefixed to groff
	implementations of the man, mm, and ms packages.  Tighten
	wording of second "checking" message.  Consistently say "(none)"
	instead of "none" or "none found".

	Fixes <https://savannah.gnu.org/bugs/?63900>.

2023-03-11  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (install-txt): Look for "groff.txt" in the source
	and build directories in sequence; it could be in either place
	depending on whether the build is from the Git repository or
	from a distribution archive.  Annotate this.  Fixes
	"install-doc" target when building from Git repository.  Problem
	introduced by me in commit 691fc70108, 22 February.  Thanks to
	Nikita Ivanov for the report.
	(install-pdf-local, install-html-local): Similar.

	Also fixes <https://savannah.gnu.org/bugs/?64059>, later
	reported anonymously.

2023-03-10  G. Branden Robinson <g.branden.robinson@gmail.com>

	* doc/doc.am (maintainer-clean-local): Remove temporary "*.t2d"
	and "*.t2p" directories created by texi2dvi.

2023-04-20  Bruno Haible <bruno@clisp.org>

	[build]: Fix gxditview linking on AIX.

	* m4/groff.m4 (GROFF_X11): Add macro dependency on
	`AC_CANONICAL_HOST`.  Introduce new variable `X_AW_DEPS`, empty
	on most hosts.  If we otherwise have Athena widget library
	support, and the host is AIX, force linkage against Xpm and Xext
	libraries to reflect modern Athena dependencies, which AIX's
	linker doesn't figure out on its own.  `AC_SUBST` this variable,
	exposing it to Automake files.
	* src/devices/xditview/xditview.am (gxditview_LDADD): Use it.

	{A similar change might also be useful for HP-UX, another Unix
	System V descendant; see
	<http://hpux.connect.org.uk/hppd/cgi-bin/wwwtar?/hpux/Gnu/\
	groff-1.23.0/groff-1.23.0-src-11.31.tar.gz+groff-1.23.0/\
	HPUX.Install+text>.  --GBR, 2023-07-10}

2023-04-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* bootstrap.conf (gnulib_modules): Add "sys_wait" module.  MinGW
	does not provide "sys/wait.h", which we require in
	src/preproc/html/pre-html.cpp since commit 11137209ed, 27 June.

2023-04-20  G. Branden Robinson <g.branden.robinson@gmail.com>

	* Makefile.am: Initialize (as empty) Automake variables that we
	don't use but which gnulib modules expect to be defined.
	(AUTOMAKE_OPTIONS, SUBDIRS, noinst_HEADERS, noinst_LTLIBRARIES)
	(pkgdata_DATA, MOSTLYCLEANDIRS, AM_CFLAGS): Do it.

	Thanks to Bruno Haible for the advice.

2023-04-22  G. Branden Robinson <g.branden.robinson@gmail.com>

	[mdoc]: Regression-test Savannah #57665, but for mdoc.

	* tmac/tests/doc_TS-do-not-keep-tables-when-cR-set.sh: Do it.
	* tmac/tmac.am (tmac_TESTS): Run test.

	Fixes <https://savannah.gnu.org/bugs/?64037>.



________________________________________________________________________

##### License

Copyright 2023-2025 Free Software Foundation, Inc.
          2023-2026 G. Branden Robinson
               2025 Ingo Schwarze

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:
