Version 1.24.1 released 2026-03-14 ================================== 2026-03-11 G. Branden Robinson * tmac/troffrc (ptr): Disclose correct groff version number when reporting rename of `ptr` request. 2026-03-11 G. Branden Robinson * src/roff/troff/number.cpp (is_valid_term): Improve error diagnostic when encountering an invalid character in a numeric expression; say "containing", not "starting with". 2026-03-13 Deri James * src/devices/gropdf/gropdf.pl: Use sequential tag names to avoid possible random duplicates. Fixes . Reverts commit cdb97b9590, 9 March. Thanks to Dave Kemper for the code suggestion. 2026-03-09 G. Branden Robinson * src/roff/troff/input.cpp (do_translate): Stop throwing assertions if one of the participants (source or destination) in a character translation is a non-character. Historical documents like Ritchie's "C Reference Manual" from Sixth Edition Unix (1975) did things like `.tr ~\|`. This is no longer a worthwhile idiom--if indeed it ever was, since strings were available even then, but especially not since 1990 or so with GNU troff's `char` and related requests--but we should not abort the formatter on encountering them. Actually _supporting_ such translations, in compatibility mode only, is under consideration for groff 1.25. Throw error when encountering `tr` requests that attempt to operate on non-characters outside of compatibility mode. Fixes . Thanks to Clem Cole for the report. Problem introduced by me in commit 52025b06f5, 21 November, in the course of adding many assertions to GNU troff to try to smoke out transitions into invalid formatter state and code that should be unreachable but isn't. This instance fooled me because we did nothing useful (nor consistent with AT&T troff behavior) with the non-character translation participant; see above regarding future plans. 2026-03-09 G. Branden Robinson [troff]: Regression-test Savannah #68132. * src/roff/groff/tests/\ do-not-abort-applying-tr-request-to-non-char.sh: Do it. * src/roff/groff/groff.am (groff_TESTS): Run test. 2026-03-08 Deri James * src/devices/gropdf/gropdf.pl: Seed random number generator if `SOURCE_DATE_EPOCH` environment variable is set. Supports reproducible builds. Thanks to Peng Zhang for report and suggested fix. Fixes . 2026-03-03 Rocket Ma * src/preproc/eqn/eqn.am (neqn): `-f $(SH_DEPS_SED_SCRIPT)` should be placed before further `-e` substitutions so that it does not impact the later expressions. This fixes the sed command to replace "@g@" in neqn.sh correctly. The `/^$/N` in "shdeps.sed" (generated by Keith Marshall's "arch/misc/ shdeps.sh") might be implicated. Fixes . [Problem introduced by me in commit 2b86c9332c, 4 February. --GBR] 2026-03-03 G. Branden Robinson [eqn]: Regression-test Savannah #68115. * src/preproc/eqn/tests/neqn-smoke-test.sh: Do it. * src/preproc/eqn/eqn.am (eqn_TESTS): Run test. Version 1.24.0 released 2026-02-28 ================================== 2026-02-27 G. Branden Robinson * doc/webpage.ms: Add disclaimer noting that file is an example, so it may contain outdated facts, stale URLs, and similar. Fixes . Thanks to Bjarni Ingi Gislason for the report. 2026-02-27 G. Branden Robinson * src/preproc/preconv/tests/smoke-test.sh: Refactor and extensively annotate assumptions about the character encoding used by the "C" locale on the host system, which influences but does not _determine_ that which preconv uses. preconv doesn't fall all the way back to "ANSI_X3.4-1968", a.k.a. US-ASCII, because GNU troff is designed to assume that its input uses an encoding where every 8-bit value has a code point assignment, which is not true of the 7-bit US-ASCII. The upshot is that preconv assumes an encoding of ISO 8859-1 in such cases. Practically speaking, this test now assumes that preconv falls back to ISO 8859-1 on macOS/Darwin systems just as it does on GNU libc-based systems. It's a pity that the equivalent of the shell command "locale charmap" (supported by glibc) is not standardized by POSIX. Thanks to Alexis Hildebrandt for the report in and for field-testing revisions to the script, and to him and John Gardner for discussion. 2026-02-22 G. Branden Robinson * src/roff/groff/tests/\ current-language-and-environment-in-sync.sh: Fix comment so it's truthful whether or not a code change reverted in February 2025 is reimplemented. Fixes . Thanks to Bjarni Ingi Gislason for the report. 2026-02-27 G. Branden Robinson * doc/doc.am (doc/pic.html): (doc/webpage.html): Restore technique of changing directories into the build tree before running "groff -T html"; pre-grohtml assumes that the argument to post-grohtml's `-D` option is a file specification resolvable relative to HTML "" elements, which is inflexible, and prevents us from writing to "$@.tmp". Thanks to Bjarni Ingi Gislason for the report in . Problem introduced by me in commit e9da162af8, 2026-02-07. 2026-02-21 G. Branden Robinson * doc/doc.am (doc/webpage.html): Also pass `$(doc_builddir)` as an `-I` option argument to groff, just as we do in the "doc/webpage.ps" target. Thanks to Bjarni Ingi Gislason for the report in and Deri James for the analysis in . My commit c81db845da, 2022-04-06 introduced a latent bug that my commit e9da162af8, 2026-02-07 exposed. 2026-02-20 G. Branden Robinson [gropdf]: Regression-test Savannah #68077. * src/devices/gropdf/tests/interpret-grout-correctly.sh: Do it. * src/devices/gropdf/gropdf.am (gropdf_TESTS): Run test. 2026-02-20 G. Branden Robinson * src/preproc/tbl/tests/boxed-TH-tables-work-on-utf8-device.sh: Resolve spurious test failures on FreeBSD 14.0 and 15.0, NetBSD 10.0, and OpenBSD 7.8: tolerate output from od(1) that is padded out with spaces to the 73rd column. Thanks to Bruno Haible for the report. 2026-02-20 Deri James * src/devices/gropdf/gropdf.pl: Test for null string rather than 'false' (which includes "0"). Fixes . Thanks to G. Branden Robinson for report. 2026-02-20 Deri James Support a build scenario where Ghostscript is not available but the URW fonts are. In that case, gropdf can operate at its full feature service level; configure it to do so. * configure.ac: Define new Automake conditional variable, `HAVE_URW_FONTS_OR_HAVE_GHOSTSCRIPT`, that records the fact written on the tin. * font/devpdf/devpdf.am: Revise Automake control flow to use this new variable instead of simply `HAVE_GHOSTSCRIPT`. Continues fixing . 2026-02-20 G. Branden Robinson * gnulib: Refresh stable/2026-01 branch to obtain commits b527e616ee, 87979f8c12, d731598147, f1f8e13ce8, and 61561de9e2, which should fix a build error in C++ code on FreeBSD 14. Thanks to Bruno Haible. 2026-02-17 G. Branden Robinson * font/devpdf/util/BuildFoundries.pl (LoadFoundry): Clarify warning diagnostic message when a font description file is unavailable; "foundry ''" can look like a logic error. Refer to "default foundry" instead in that scenario. 2026-02-17 G. Branden Robinson Eliminate new but superfluous Automake variable. * configure.ac: Drop `AM_CONDITIONAL()` defining `GROPDF_INTER`, which is confusingly named (it meant "not the basic service level", not the "inter[mediate]" one specifically), not directly coupled to the availability of a feature of the build host (but instead based on the value of a shell variable that _was_ being used just for reporting, and with this commit is again limited to that purpose), and duplicates the semantics of an existing Automake variable, `HAVE_GHOSTSCRIPT`. See the definition of `GROFF_GROPDF_DEPENDENCIES_CHECK` in "m4/groff.m4". * font/devpdf/devpdf.am: Append to macro `devpdffont_descriptions_from_devps` contingently on Automake variable `HAVE_GHOSTSCRIPT` rather than the disappearing `GROPDF_INTER`. Fixes . 2026-01-20 Deri James Install groff fonts according to gropdf mode. Full : All 35 Postscript 2 fonts + 35 URW fonts Intermediate : All 35 Postscript 2 fonts Basic : Just 14 PDF standard fonts {Reinstates groff 1.23.0 behaviour.} * configure.ac: Add Automake variable `GROPDF_INTER`. Set if not in basic mode. * font/devpdf/devpdf.am: Split groff fonts list into 3 so that the 3 modes above can be accommodated, based on the two Automake variables `GROPDF_INTER` and `HAVE_URW_FONTS`. * m4/groff.m4 (GROFF_GROPDF_DEPENDENCIES_CHECK): Fix logic error setting `gropdf_service_level` shell variable. Begins fixing . 2026-02-12 G. Branden Robinson Add another URW font directory search path. * font/devpdf/Foundry.in: * m4/groff.m4 (GROFF_URW_FONTS_CHECK): Add "/usr/share/fonts/type1" directory to search path for URW font files. That is apparently (yet another?) location Arch Linux keeps them in. Continues fixing . Thanks to Morten Bo Johansen for the report in . 2026-02-12 G. Branden Robinson Re-order URW font directory search path. * font/devpdf/Foundry.in: * m4/groff.m4 (GROFF_URW_FONTS_CHECK): Alter ordering of directories to attempt to find separately packaged URW fonts, which might in principle get updated more frequently than those shipped with Ghostscript, before those supplied by Ghostscript itself. This procedure cannot be perfectly reliable using _any_ ordering because host systems can update their Ghostscript and URW font packages (if any) on separate and arbitrary schedules, and these matters are outside of groff's control. If groff finds the "wrong" URW fonts (or can't find them at all), use the "--with-urw-fonts-dir=" option to groff's "configure" script to point it at the correct ones. 2026-01-20 Deri James * src/devices/gropdf/gropdf.pl: Allow whitespace after grout 'w' command. Fixes . Thanks to G. Branden Robinson for report and patch and Dave (for guidance). 2026-02-08 G. Branden Robinson * src/devices/gropdf/gropdf.pl: Rename new `--opt` command-line option to `--format-options`, with short `-f` synonym. * src/devices/gropdf/gropdf.1.man (Options): Update. Fixes . 2026-02-08 G. Branden Robinson Simplify handling of ".version" file. * Makefile.am (.version): Spell target name without a leading `$(top_srcdir)/` interpolation, which caused a build failure using Debian's package of BSD make when performing a "make dist" in an in-tree build. * src/devices/xditview/xditview.am ($(GXDITVIEW_GROFF_VERSION_H): * src/libs/libgroff/libgroff.am (src/libs/libgroff/version.cpp): * src/roff/troff/troff.am (src/roff/troff/majorminor.cpp): Update dependencies on ".version" accordingly. * Makefile.am: Stop appending ".version" to the `EXTRA_DIST` and `BUILT_SOURCES` macros--it's unnecessary. The file is now an ordinary build artifact. Tested with "make check" and "make distcheck" in four configurations: the Cartesian product of {BSD, GNU} make with {in-, out-of-}tree builds. 2026-02-08 G. Branden Robinson * doc/doc.am: Simplify generation of HTML documents with groff. (doc/pic.html, doc/webpage.html): Stop changing directories as part of the target recipe; instead, alter the argument to grohtml's `-j` option to include the name of the desired subdirectory. Drop test for existence of separate image files afterward. Since the fix for Savannah #67133 last May, we should be able to rely on groff to exit with a nonzero status if grohtml fails. Tested with "make check" and "make distcheck" in four configurations: the Cartesian product of {BSD, GNU} make with {in-, out-of-}tree builds. 2026-02-07 G. Branden Robinson * src/preproc/tbl/table.cpp (table::compute_overall_width): Distinguish formatting-time diagnostics emitted when a table oversets; when the table is centered, note the fact because it might not overrun the line length but instead has reduced the indentation, which can be ugly in a different way. * src/preproc/tbl/tbl.1.man (Region options)
: Advise of circumstance in which formatting-time diagnostic is issued. 2026-02-06 G. Branden Robinson * src/roff/troff/env.cpp: Revert refactoring from commit 8b165f90ef, 29 December, which caused spurious "spurious end trap token detected!" error diagnostics when breaking pages with Matt Bishop's "mn" macro package (used by the NetHack Guidebook). Because a variable was renamed later the same day, this reversion was done by hand. Still to be understood: why the `br` request handler needs to use `token::next()` instead of `skip_line()` as most request handlers do. Fixes . 2026-02-06 G. Branden Robinson * update-copyright.sh: Drop (unshipped) script. I implement a different approach to the problem it solves; see the "HACKING" file. 2026-02-05 G. Branden Robinson * doc/doc.am (maintainer-clean-local): Clean "gnu.eps" file in "maintainer mode". 2026-02-05 G. Branden Robinson * Makefile.am: Add ".version" file to `MOSTLYCLEANFILES` macro. 2026-02-05 G. Branden Robinson * src/roff/troff/number.cpp (is_valid_term): Reintroduce warning in category "tab" when a tab character starts a numeric expression. Lacking it caused the formatter to throw a huge number of error diagnostics (with no harmful effect on formatting, thus unproductively alarming the user) when springing traps in Matt Bishop's vintage "mn" macro package. Fixes . Partially reverts commit 64711b3a875, 14 November. 2026-01-20 Deri James Change location of the Inline::C build directory. * src/devices/gropdf/gropdf.pl: Update copyright. Include module File::Path (part of perl since before version 5.8). Adjust location of Inline::C's cache directory according to XDG standards, rather than $HOME/_Inline. Fixes . Thanks to Bruno Haible for the information in . 2026-02-04 G. Branden Robinson Stop using `${1+"$@"}` to kludge around old broken shells. The (forthcoming) Autoconf 2.73 manual explains. ---snip--- You may see usages like ‘${1+"$@"}’ in older shell scripts designed to work around a portability problem in ancient shells. Unfortunately this runs afoul of bugs in more-recent shells, and nowadays it is better to use plain ‘"$@"’ instead. The portability problem with ancient shells was significant. When there are no positional arguments ‘"$@"’ should be discarded, but the original Unix version 7 Bourne shell mistakenly treated it as equivalent to ‘""’ instead, and many ancient shells followed its lead. For many years shell scripts worked around this portability problem by using ‘${1+"$@"}’ instead of ‘"$@"’, and you may see this usage in older scripts. Unfortunately, ‘${1+"$@"}’ does not work with ‘ksh93’ M 93t+ (2009) as shipped in AIX 7.2 {2015}, as this shell drops a trailing empty argument: $ set a b c "" $ set ${1+"$@"} $ echo $# 3 Also, ‘${1+"$@"}’ does not work with Zsh 4.2.6 (2005) and earlier, as shipped in Mac OS X releases before 10.5, as this old Zsh incorrectly word splits the result: zsh $ emulate sh zsh $ for i in "$@"; do echo $i; done Hello World ! zsh $ for i in ${1+"$@"}; do echo $i; done Hello World ! ---end snip--- In light of all this winning by elite shell developers, use plain, idiomatic `"$@"` instead, relying on downstream distributors to patch the handful of occurrences in groff should their deployments be boxed in by a buggy /bin/sh. * src/preproc/eqn/neqn.sh: * src/roff/nroff/nroff.sh: * test-groff.in: Do it. 2026-02-03 G. Branden Robinson * m4/groff.m4 (GROFF_URW_FONTS_CHECK): Stop blanking `urwfontsdir` shell variable unconditionally. Fixes problem with groff 1.24.0.rc2 reported by Alexis Hildebrandt in . 2026-02-03 G. Branden Robinson * font/devpdf/util/BuildFoundries.pl (LoadFoundry): Clarify diagnostic messages. A digital font, like "URWGothic-DemiOblique.t1", is not the same thing as a font description file for groff, like "ABI". We do our users no favors by conflating these two concepts. 2026-02-03 G. Branden Robinson * font/devpdf/util/BuildFoundries.pl (LoadFoundry): Tweak warning diagnostic to describe the decision being taken and the reason for it. Set `notFoundFont` scalar to 1 only if this diagnostic was unexpected because the `urwfontsupport` scalar didn't match "no". This way we don't spray the (usually enormous) "path(s) used for searching" diagnostic for no apparent reason. 2026-02-03 Dariusz Chilimoniuk * tmac/hyphen.pl: New file adds Polish hyphenation patterns and exceptions. * tmac/pl.tmac: New file adds groff locale for Polish. * tmac/tmac.am: Add the foregoing files to the `TMACNORMALFILES` macro. * LICENSES: Add copyright and license notices from CTAN Polish hyphenation patterns. * src/roff/groff/test/initialization-is-quiet.sh: Verify lack of warnings when Polish l10n macro file is loaded (`-m pl`). * tmac/tests/e_ld-works.sh: Test Polish translation. * tmac/tests/localization-works.sh: Test Polish localization. * doc/groff.texi.in (ms language and localization) (Input Encodings, Manipulating Hyphenation): * doc/ms.ms.in (Language and localization): * man/groff_tmac.5.man (Localization packages): * tmac/groff_ms.7.man (Language and localization): Note availability of Polish localization. Fixes . 2026-02-03 G. Branden Robinson [build]: Kill off `GROFF_GHOSTSCRIPT_AVAILABILITY_NOTICE`. * m4/groff.m4 (GROFF_GHOSTSCRIPT_AVAILABILITY_NOTICE): Delete. * configure.ac: Stop interpolating same. Completes (the revised) "action item D" from . I've abandoned "action item B". 2026-02-03 G. Branden Robinson [build]: Report gropdf service level in configuration summary. * m4/groff.m4 (GROFF_GROPDF_DEPENDENCIES_CHECK): Drop unused shell variables `use_gropdf` and `gropdf_missing_deps`. Add new shell variable `gropdf_service_level`, to be used (only) for reporting an intelligible meaning to a human in the configuration summary. Default value to "full". If URW fonts are unavailable, demote value to "intermediate". If Ghostscript is unavailable, demote value to "basic". * configure.ac: Rearrange summary and disclose gropdf service level in it. Report URW font directory (if applicable) after Ghostscript command name and before the gropdf service level, since the first two determine the last. Completes "action item C" from . 2026-02-03 G. Branden Robinson [build]: Kill off `GROFF_GROPDF_PROGRAM_NOTICE`. * m4/groff.m4 (GROFF_GROHTML_PROGRAM_NOTICE): Delete. * configure.ac: Stop interpolating same. 2026-02-03 G. Branden Robinson * configure.ac: Delete `AM_CONDITIONAL` for no-longer-used `USE_GROPDF` configuration parameter. 2026-02-01 G. Branden Robinson * doc/doc.am: De-parameterize production and installation of PDF documents created by groff. We now build all such files regardless of gropdf(1)'s service level (see its man page). Update population of `pdfmomoption`, `groffmanpagesoption`, `PROCESSEDDOCFILES_PDF`, `docpdfdocdir`, and `nodist_docpdfdoc_DATA` accordingly. ($(PROCESSEDDOCFILES_PDF)): Target now exists unconditionally. (mostlyclean_doc): Unconditionally delete these built files. Completes "action item E" from . 2026-02-03 G. Branden Robinson * configure.ac: Disclose identity of Ghostscript command discovered by Autoconf in configuration summary. Completes "action item A" from . 2026-01-31 G. Branden Robinson * src/roff/troff/input.cpp (token::description): Fix assertion failures (potential and actual) by supplying descriptions even of internally generated token types. While a user _should_ never be exposed to these in a diagnostic message, the event is not impossible (and said descriptions could be helpful to groff developers in tracking down the "impossible" situation). Fixes . Thanks to Deri James for the report. 2026-01-29 G. Branden Robinson * src/devices/grodvi/grodvi.1.man (FT): * src/devices/grolj4/grolj4.1.man (FT): * src/devices/gropdf/gropdf.1.man (FT): * src/devices/grops/grops.1.man (FT): Suppress screeching ("-w font") from formatter if a font used for illustrating the typeface repertoire is unavailable. Using a text typeface to depict its own name is typographical gravy. 2026-01-29 G. Branden Robinson * font/devpdf/util/BuildFoundries.pl (LoadFoundry): Tweak wording of warning diagnostic; favor "cannot" over "unable to" or "can't". (RunAfmtodit): Clarify warning diagnostic: this script _could_ pass unrecognized options to afmtodit(1); it _chooses_ not to. Also use the word "option" instead of "flag"--not all of afmtodit's command-line options are Boolean-valued. Continues the long process of fixing Savannah #66519. 2026-01-29 G. Branden Robinson Propagate "configure" shell variable `urwfontsupport` into "BuildFoundries" script, quieting build-time warnings when URW font support is explicitly deconfigured. * m4/groff.m4 (GROFF_URW_FONTS_SUPPORT): `AC_SUBST` `urwfontsupport` so that it is defined in Makefiles. * font/devpdf/devpdf.am (BuildFoundries): Add `urwfontsupport` to set of sed(1) substitutions performed when generating target. * font/devpdf/util/BuildFoundries.pl: Add `urwfontsupport` scalar, taking value of corresponding sed substitution. (LoadFoundry): Suppress warning about unavailable font if `urwfontsupport` matches "no". 2026-01-29 G. Branden Robinson * m4/groff.m4 (GROFF_URW_FONTS_CHECK): Stop emptying shell variable `urwfontsdir` if the URW fonts aren't found. This variable _had_ been used both to store the directory where they were found _and_ as an indicator of whether URW font support was expected by the configuring user. We now have `urwfontsupport` for the latter purpose, and blanking out `urwfontsdir` had the undesirable side effect of suppressing the message that the `GROFF_URW_FONTS_NOTICE` macro emits, preventing notification of the user that their intention to configure URW font support was foiled. 2026-01-29 G. Branden Robinson * configure.ac: Identify the report at the end of the configuration process as the "configuration summary"; I've been using this term for years when collecting information from users reporting bugs. 2026-01-29 G. Branden Robinson * gnulib: Refresh stable/2026-01 branch to obtain commit dc9ad4ec31, which should fix a build error in C++ code on FreeBSD 15. Thanks to Bruno Haible. 2026-01-28 G. Branden Robinson * doc/groff.texi.in: Adapt manual content to the configured groff command prefix. If the build is configured without a leading "g"--omitting it has been groff's default for many years, possibly forever--then our Texinfo manual now omits that prefix when mentioning the affected commands (all replacements for AT&T troff commands). This way, if you select a command prefix, say "limbo", and rebuild the Texinfo manual, the manual reflects the prefix used by your build configuration, and talks about "limboeqn", "limbotroff", "limborefer", and so on. Fixes . 2026-01-27 G. Branden Robinson * tmac/tests/an_MR-internal-hyperlinks-work-with-pdfmom.sh: * tmac/tests/andoc_internal-hyperlinks-work-with-pdfmom.sh: Fix regex to correctly quote a closing parenthesis _not_ used as an ERE grouping operator. Fixes spurious test failures on NetBSD. Sadly, neither GNU grep 3.6 nor 3.12.14 warned me of my mistake. Thanks to Bruno Haible for the report. 2026-01-27 G. Branden Robinson * src/preproc/tbl/tests/boxed-TH-tables-work-on-utf8-device.sh: Fix excessively strict regex, which caused test failure with OpenBSD od(1) (and NetBSD's), because that implementation spaces the columns of its output more widely than GNU coreutils's od(1). Thanks to Bruno Haible for the report. 2026-01-26 G. Branden Robinson * arch/mingw/grap2graph.cmd: Revise version info. - Drop "GNU" from reported version string; this is a contributed program--its shell script equivalent is in contrib/ grap2graph--not a GNU program. - Bump reported version to 1.24.0. 2026-01-26 G. Branden Robinson * font/devpdf/devpdf.am ($(devpdffont_descriptions_from_devps) ($(devpdffontencdata), font/devpdf/SS) ($(devpdf_builddir)/symbolsl.afm) ($(devpdf_builddir)/symbolsl.pfb, $(devpdffontmapdata)): Copy files with `cp -fp`, not just `cp -f`, preventing spurious rebuilds of these targets. 2026-01-26 G. Branden Robinson * font/devpdf/devpdf.am (all): Drop unnecessary phony target. 2026-01-26 G. Branden Robinson * font/devpdf/devpdf.am [HAVE_URW_FONTS]: Shift conditional so that we define a target rule for `$(devpdffont_descriptions_for_urw)` only if the `HAVE_URW_FONTS` Automake variable is defined. 2026-01-26 G. Branden Robinson * font/devpdf/devpdf.am ($(devpdffont_descriptions_for_urw)): Drop interpolations of no-longer-used `DEFAULT_BASE35_FONTS` and `URW_BASE35_FONTS` macros. 2026-01-26 G. Branden Robinson * doc/doc.am: Abstract "-P-e" option to gropdf into new macro, `groffmanpagesoption`. We can't use it if the build is configured without URW fonts to embed, so define the macro only if `HAVE_URW_FONTS` _and_ `USE_GROPDF`. (doc/groff-man-pages.pdf): Interpolate macro instead of hard-coding "-P-e". 2026-01-26 G. Branden Robinson * font/devpdf/tests/check-default-foundry.sh.in: Die with "hard error" if test script cannot locate the "Foundry" file. Skip remainder of test (for fonts not in the PostScript Level 1/PDF "base 14") if the "URW" section of the "Foundry" file is absent. 2026-01-25 G. Branden Robinson * m4/groff.m4 (GROFF_PERL): Update error messages. Refer to Perl "executable", not "binary"; whether an executable is an object file is not our concern. When failing because the available version of Perl is too old, report the minimum version we require. 2026-01-25 G. Branden Robinson * doc/doc.am: Abstract `-P-W` option to "gropdf" into a new macro, `pdfmomoption`, populating it only if, at configuration time, both `HAVE_URW_FONTS` and `USE_GROPDF` were enabled. 2026-01-25 G. Branden Robinson * font/devpdf/util/BuildFoundries.pl (Warn): Don't set the exit status to a nonzero value on warnings. This script issues quite a few warnings at gropdf's "Basic service" level. 2026-01-25 G. Branden Robinson * m4/groff.m4 (GROFF_URW_FONTS_SUPPORT): New Autoconf macro creates a "with" configuration option, permitting the host environment to easily switch off the search for URW fonts and defeat all of the consequent features without the "configure" script issuing a lengthy warning about failure to find the aforementioned fonts. New shell variable `urwfontsupport` indicates the configuration's desired status (which still defaults on). (GROFF_URW_FONTS_CHECK): Add dependency on the foregoing macro. Initialize `urwfontsdir` shell variable to empty unconditionally, permitting it to be updated later if the URW font feature isn't disabled. Nest most of the work of this macro inside a conditional on `urwfontsupport`. Continue to unconditionally populate and `AC_SUBST`-itute `groff_have_urw_fonts` and `urwfontsdir`, because "configure.ac", "test-mom.sh.in", "mom.am", "font/devpdf/Foundry.in", "devpdf.am", and "check-urw-foundry.sh.in" variously rely on them to behave appropriately for the configuration. 2026-01-24 G. Branden Robinson * doc/doc.am: Update `DOC_SED` macro to also perform substituion of "@PAGE@" with the contents of the `PAGE` (Auto)make macro. We can thus refer directly to this configuration parameter in our Texinfo manual without directing the reader to a man page. 2026-01-22 G. Branden Robinson * tmac/groff_man.7.man.in (Document structure macros): * tmac/groff_mdoc.7.man (Title macros): Explicitly recommend ISO 8601 date format. Fixes . Thanks to Alex Colomar for the suggestion. 2026-01-21 G. Branden Robinson * Makefile.am: Add "filename-length-max=99" to `AUTOMAKE_OPTIONS` macro so that a "dist" build fails if the file names get too long for a V7 tar archive. Consequently, the build should now fail earlier if "distcheck" would fail because test scripts are missing because their file names were too long to be archived. See the GNU Automake 1.16.3 manual, §17.2 "List of Automake options". 2026-01-20 Bruno Haible * src/libs/libgroff/libgroff.am: Drop `libgroff_a_LIBADD` macro definition. It was used incorrectly to add "lib/libgnu.a" to "libgroff.a", but that's invalid. Archives used for static linking cannot nest. 2026-01-20 Bruno Haible * doc/doc.am: * font/devpdf/devpdf.am: * tmac/tmac.am: Fix portability problem involving BSD Make. Define `*_builddir` macros without interpolating `top_builddir`. groff does not use recursive make; all file specifications are resolved relative to the top of the build tree, so the interpolation is unnecessary, and with BSD Make it causes spurious failures because that implementation uses strings, not file identities, as the nodes of its dependency graph. So if you ask for "foo" to be built but have only a rule for a target named "./foo", BSD Make fails, whereas GNU Make does not. 2026-01-21 G. Branden Robinson * font/devps/devps.am: Drop unused macro `devps_builddir`. Automake itself doesn't require it, and we never interpolate it. 2026-01-20 G. Branden Robinson * bootstrap: Resync with upstream. 2026-01-20 G. Branden Robinson * gnulib: Update to stable/2026-01. 2021-08-11 Douglas McIlroy * src/prepic/pic/pic.1.man (Caveats): Explain dotted/dashed line space scaling, since this document is not yet a full _pic_ reference. Fixes . 2026-01-20 Deri James * src/devices/gropdf/gropdf.1.man: Update copyright. Remove references to .pdfmarkstart/end (they don't exist). If no link-text in internal link (pdfhref L) use text associated with the tag-name when it was created. When manually closing hotlink text (after using -S) previous text colour (\*[pdf:curcol]) should be restored. Add section describing parameters used in pdf.tmac. Remove stale information about importing graphics. 2026-01-18 G. Branden Robinson [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 * 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 . Thanks to Bjarni Ingi Gislason for the report and Deri James for the analysis and solution. 2026-01-16 G. Branden Robinson * 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 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 * 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 . Thanks to Branden Robinson for the suggested improvement. 2026-01-15 G. Branden Robinson * src/devices/gropdf/gropdf.1.man (Macros) : Document macros. Fixes . Thanks to Deri James for supplying an overview of features in Savannah #67665. 2026-01-14 G. Branden Robinson * 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 . Thanks to Bjarni Ingi Gislason for the report. 2026-01-10 G. Branden Robinson [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 . 2026-01-09 G. Branden Robinson * 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 [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 . 2026-01-09 G. Branden Robinson [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 . 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 [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 * 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 * src/roff/groff/groff.am (EXTRA_DIST): Ship "small-gnu-head.png" test artifact in distribution archive. 2026-01-05 G. Branden Robinson * 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 * 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 . 2026-01-04 G. Branden Robinson * tmac/groff_mdoc.7.man (Other possible pitfalls): Advise composers of mdoc(7) documents to use `\-` for copy-and-pastable hyphen-minus characters. Fixes . Thanks to Bjarni Ingi Gislason for pointing out incorrect usage in sudo(8). 2026-01-03 G. Branden Robinson * 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 * gnulib: Refresh stable/2025-07 branch. We need some recent fixes that have landed there. See and . 2026-01-01 G. Branden Robinson * 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 * 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 [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 [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 * 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 [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 * 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 [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 * 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 * 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 * 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 * src/roff/troff/input.cpp (process_macro_package_argument): Clarify fatal diagnostic message. 2025-12-29 G. Branden Robinson [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 [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 * 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 * 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 * 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 . 2025-12-26 G. Branden Robinson * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 . 2025-12-21 G. Branden Robinson * 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 . I hope. 2025-12-21 G. Branden Robinson [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) : 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 . Problem appears to date back to groff's birth. 2025-12-21 G. Branden Robinson * src/roff/groff/tests/check-delimiter-validity.sh: Add regression test for Savannah #67842. 2025-12-21 G. Branden Robinson * src/roff/troff/input.cpp (token::description): Drop `assert()`-ion that is reachable with invalid input. 2025-12-21 G. Branden Robinson [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 [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 [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 [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 [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 [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) : 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 , 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * bootstrap.conf (gnulib_modules): Add stdcountof-h. Continues the long process of fixing Savannah #66518. 2025-12-19 G. Branden Robinson [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, families, 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 * 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 [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 * 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 * 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 * 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 * 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 [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 * 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 [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 * src/roff/troff/number.cpp: Drop unnecessary header file inclusion. 2025-12-19 G. Branden Robinson [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 . Continues commit d330127900, 6 December. 2025-12-18 G. Branden Robinson * 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 . 2025-12-18 G. Branden Robinson * 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 * 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 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 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 * 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 * 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 * 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 . 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 [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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 . Thanks to Dave Kemper for the report. 2025-12-12 G. Branden Robinson * 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 . 2025-12-12 G. Branden Robinson * 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 * 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 . Thanks to Dave Kemper for the discussion. 2025-12-10 G. Branden Robinson * 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 * 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 * 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` rather 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 successfully 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 * 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 * 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 * 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 * 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 * 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 . 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 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 * 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 * 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 * 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 * src/roff/troff/input.cpp (define_class_request): Add assertion and, if preprocessor `NDEBUG` symbol is defined, guard against null pointer dereference. 2025-12-05 G. Branden Robinson * 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 * 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 . Problem appears to date back to commit 1cb8dd7bde, 13 December 2010. 2025-12-05 G. Branden Robinson [groff]: Regression-test Savannah #67771. * src/roff/groff/tests/class-request-works.sh: Do it. 2025-12-05 G. Branden Robinson [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 * 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 [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 [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 . Thanks to Dave Kemper for prompting me to better understand this aspect of GNU troff's design. 2025-12-03 G. Branden Robinson [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 * 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 * src/roff/troff/input.cpp (token::description): Return the node token description using the correct buffer. 2025-12-02 G. Branden Robinson * src/roff/troff/input.cpp (token::description): Hedge against programmer carelessness. If someone creates a node type without a human-readable description, pre-populate the buffer describing it with a revealing description that is less frustrating than nothing at all. 2025-12-01 G. Branden Robinson * 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 and . 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 * 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 . Thanks to Dave Kemper for the report. Problem introduced by me in commit 77d8f728d, 4 September. 2025-12-01 G. Branden Robinson [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 * 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 * 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 * src/roff/troff/div.h: Drop unnecessary declaration of `begin_page()`. 2025-11-30 G. Branden Robinson * 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 * 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 * src/roff/troff/number.cpp (is_valid_term): Adjust wording of warnings in "syntax" category. 2025-11-30 G. Branden Robinson * 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 * 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 . Problem dates back to introduction of `warnscale` request in commit 9993a881c1, 5 May 2002. 2025-11-30 G. Branden Robinson * 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 . Problem dates back to introduction of `warnscale` request in commit 9993a881c1, 5 May 2002. 2025-11-30 G. Branden Robinson * 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 [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 * 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 . Problem observable since groff 1.22.3 and appears to date back to groff's birth. 2025-11-26 G. Branden Robinson [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 * 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 * 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 * 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 * 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 [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 * src/roff/troff/reg.cpp (dump_register): Add assertion. 2025-11-24 G. Branden Robinson * 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 * src/roff/troff/input.cpp (are_comparands_equal): Fix code style nit; parenthesize formally complex expression. 2025-11-24 G. Branden Robinson * 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 * 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 * 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 * 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 * 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 * 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 . 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 * src/roff/groff/tests/check-delimiter-validity.sh: Regression-test Savannah #67744. 2025-11-28 G. Branden Robinson * 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 * src/roff/troff/token.h: Add new inline member function `is_node()` to aid input parser diagnostics. 2025-11-28 G. Branden Robinson * 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 * src/roff/troff/input.cpp (token::is_usable_as_delimiter): Use new node token description member function. 2025-11-23 G. Branden Robinson [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 * 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 * 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 * 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 * src/roff/troff/input.cpp (assign_escape_character): Improve diagnostic when user fumbles escape character selection. 2025-11-23 G. Branden Robinson * 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 * 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 * 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 * 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 * src/roff/troff/input.cpp (do_translate): Fix copy-and-paste braino in assertion message. 2025-11-21 G. Branden Robinson * 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 * 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 * 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 * src/roff/troff/input.cpp (token::description): Report the node type of node tokens when describing them. 2025-11-21 G. Branden Robinson [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 * 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 * 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 * 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 * src/roff/troff/input.cpp (print_character_request) (remove_character): Simplify logic. `token::description()` describes indexed characters adequately. 2025-11-19 G. Branden Robinson * 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 [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 * 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 * src/roff/troff/input.cpp (read_title_parts): Avoid null pointer dereference. 2025-11-19 G. Branden Robinson * 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 * 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 * 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 * src/roff/troff/input.cpp (encode_character_for_device_output): Avoid null pointer dereference. 2025-11-19 G. Branden Robinson * src/roff/troff/input.cpp (get_line_arg): Add assertion. 2025-11-19 G. Branden Robinson * 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 [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 * 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 * 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 [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 [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 * 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 . 2025-11-18 G. Branden Robinson * 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 * src/roff/troff/input.cpp (token::get_char): Recognize existence of indexed characters in diagnostic messages. 2025-11-19 G. Branden Robinson * 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 . Thanks to Dave Kemper for the report. Problem introduced by me in commit 493a01c02d4, 28 June 2020. 2025-11-07 G. Branden Robinson * 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 . Thanks to Dave Kemper for the report and to him and Deri for the code review. 2025-11-16 G. Branden Robinson * 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 * 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 * 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 * src/roff/troff/env.cpp (add_hyphenation_exceptions): Instrument seemingly impossible scenario. 2025-11-16 G. Branden Robinson * 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 * src/roff/troff/input.cpp (hyphenation_patterns_file_code): Fix code style nit; parenthesize formally complex expressions. 2025-11-16 G. Branden Robinson * src/roff/troff/env.cpp (line_spacing): Clarify diagnostic message. 2025-11-16 G. Branden Robinson [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 * 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 * 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 * 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 [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 * 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 [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 * src/roff/troff/input.cpp (length_request): Drop erroneous assertion that failed and cored on `.length \&`. 2025-11-17 G. Branden Robinson * 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 * 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 [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 * 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 . 2025-11-14 G. Branden Robinson * 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 * Makefile.am: Include "contrib/install-font/install-font.am". 2025-11-14 G. Branden Robinson [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 (2/2). 2025-11-14 G. Branden Robinson [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 (1/2). 2025-11-14 G. Branden Robinson * 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 * src/roff/troff/input.cpp (token::description): Improve quotation of special character names. 2025-11-14 G. Branden Robinson * src/roff/troff/input.cpp (token::description): Improve diagnostics when encountering an indexed character. 2025-11-13 G. Branden Robinson [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 * 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 * 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 * 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 * 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 [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 * 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 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 * src/preproc/pic/pic.ypp (ordinal): Replace C-style type cast with value construction. 2025-11-10 G. Branden Robinson 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 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 [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 [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 foregoing 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 . Thanks to Deri James for the report. 2025-11-07 G. Branden Robinson [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 * 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 * 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 * 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 * src/devices/gropdf/TODO: Drop stale item. Fixes . Thanks to Deri James for the discussion. 2025-11-06 G. Branden Robinson * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * src/devices/grolbp/lbp.cpp (main): Eliminate dead store. 2025-11-04 G. Branden Robinson [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 * 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 * src/roff/troff/input.cpp (psbb_locator::psbb_locator): Clarify error diagnostic. 2025-11-04 G. Branden Robinson [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 * 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 * 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 * 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 [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 [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 [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 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 [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 * 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 [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 . 2025-10-31 G. Branden Robinson * 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 [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 * src/roff/troff/input.cpp: Slightly refactor. (is_conditional_expression_true): Parenthesize formally complex expressions. 2025-10-31 G. Branden Robinson * 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 * 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 [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 * 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 * 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 . 2025-10-29 G. Branden Robinson * 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 . 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 [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 * 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 * 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 [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 * 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 * 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 . Problem originally recorded by James Clark in groff 1.06, September 1992. 2025-10-26 G. Branden Robinson * 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 * 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 * src/roff/troff/input.cpp (process_input_stack ): 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) : * src/roff/troff/troff.1.man (Warnings) : Document it. 2025-10-22 G. Branden Robinson [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 [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 [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 . Problem appears to date back to pdfmom's birth in commit f2a501fff5, 31 August 2012. 2025-10-21 G. Branden Robinson [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 [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 * 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 * 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 * tmac/an.tmac (an*end-hyperlink): Work around apparently overpowered--or buggy--`chop` request. Annotate landmine. 2025-10-20 G. Branden Robinson * 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 * 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 [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 [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 * 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 . 2025-10-20 G. Branden Robinson * 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 * tmac/an.tmac: Initialize more state to prevent warnings when formatting degenerate documents. 2025-10-20 G. Branden Robinson * src/roff/troff/input.cpp (usage): Resync usage message with man page synopsis. 2025-10-20 G. Branden Robinson * 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 * 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 . Thanks to Morten Bo Johansen for the report. 2025-10-09 G. Branden Robinson * 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 [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 . Thanks to Doug McIlroy for the report (way back in 2011!). Problem is at least that old. 2025-10-09 G. Branden Robinson [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 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 . 2025-10-08 G. Branden Robinson * 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 [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 [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 * 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 [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 * bootstrap: Resync with upstream. 2025-10-07 G. Branden Robinson * gnulib: Update to stable/2025-07. 2025-10-07 G. Branden Robinson [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 [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 [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 * 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 [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 [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 * 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 * 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 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 [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 [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 * 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 [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 [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 [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 [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 * 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 [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 [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 * 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 . Problem appears to date back to groff's birth. 2025-10-04 G. Branden Robinson [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 * 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 [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 [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 [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 * 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 * 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 * 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 * 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 (considered in combination with many other recent asciification changes). 2025-09-18 G. Branden Robinson * 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 . Thanks to Alex Colomar and Russ Allbery for the discussion. 2025-09-18 G. Branden Robinson * 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 . Thanks to Deri James for pushing device extension commands to the limit, exposing this defect. 2025-09-18 G. Branden Robinson [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 [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 * 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 * 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 * 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 * 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 . Problem appears to date back to groff's birth. 2025-09-17 G. Branden Robinson [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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 [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 * 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 [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 [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 [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 * 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 * 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 * 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 * 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 [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 [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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 [gropdf]: Fix. * src/devices/gropdf/gropdf.pl (AssignGlyph): Check if the glyph has a Unicode value before testing it!!! Fixes thanks to Branden for the "heads up". 2025-09-11 Deri James [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 * doc/doc.am (DOC_GROFF): Move `-M` option that is present only for the sake of building "grnexmpl.ps" from this macro... (doc/grnexmpl.ps): ...to this target rule. 2025-09-02 G. Branden Robinson 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 [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 [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 [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 [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 [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 [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 * src/roff/troff/input.cpp (charinfo::dump): Report Unicode mapping corresponding to character. 2025-09-04 G. Branden Robinson [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 * 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 * tmac/html.tmac: * tmac/tty.tmac: Define special character `ru` for device. 2025-08-30 G. Branden Robinson * src/roff/troff/input.cpp (encode_character_for_device_output): Add advice to warning diagnostic. 2025-08-30 G. Branden Robinson * 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 * 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 * 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 * 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 [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 . 2025-08-28 Dave Kemper * 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 . 2025-08-13 G. Branden Robinson * 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 . 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 * 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 . 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 * 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 * 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 * 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 * 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 . Thanks to Dave Kemper for the discussion. 2025-08-10 G. Branden Robinson * 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 * doc/ms.ms.in: Fix missing brace escape sequence. Fixes . Continues commit ca42eb2c73, 7 August. Thanks to Bjarni Ingi Gislason for the report. 2025-08-08 G. Branden Robinson * 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 * 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 * 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 * doc/ms.ms.in: Report groff version in page footers. 2025-08-07 G. Branden Robinson [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 * 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 . 2025-08-06 G. Branden Robinson * 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 * 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 * 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 [devpdf]: Improve diagnostics from "BuildFoundries" script. * font/devpdf/util/BuildFoundries.pl (RunAfmtodit): Diagnose return code from running afmtodit. Fixes thanks to G. Branden Robinson for report and patch. 2025-08-02 G. Branden Robinson * tmac/groff_man.7.man.in: Un-deprecate `HP` macro. Retain cautionary language addressing its limited utility. Fixes . Thanks to Alan Coopersmith and Thomas Dickey for the discussion in and those evidently silently assenting to . 2025-08-02 G. Branden Robinson [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 [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 [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 [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 * 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 * 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 [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 [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 * 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 . Continues commit d8cd70f3a8c, 18 May. Discovered in conversation with Ingo Schwarze. 2025-08-02 G. Branden Robinson * 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 * 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 * 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 * 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 * 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 [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 (4/4). Thanks to Russ Allbery for posing the challenge. 2025-07-27 G. Branden Robinson [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 (3/4). Thanks to Russ Allbery for posing the challenge. 2025-07-27 G. Branden Robinson [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 (2/4). Thanks to Russ Allbery for posing the challenge. 2025-07-27 G. Branden Robinson [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 (1/4). Thanks to Russ Allbery for posing the challenge. 2025-07-30 G. Branden Robinson * 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 * 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 * 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 * doc/groff.texi.in (Debugging): Expand `ab`, `fl` discussion. Fixes . Thanks to Dave Kemper for bringing details of `ab` behavior to my attention. 2025-07-27 G. Branden Robinson [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 * 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 * font/devpdf/devpdf.am (font/devpdf/download): Drop `--strict` option from rule command. The `BuildFoundries` script no longer supports it. Fixes . Thanks to Bjarni Ingi Gislason for the report. 2025-07-27 Deri James [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 . Thanks to G. Branden Robinson for report. 2025-07-25 G. Branden Robinson * 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 . 2025-07-26 G. Branden Robinson [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 [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 * 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 * 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 * tmac/tests/an-ext_synopses_do_not_automatically_hyphenate.sh: Add test. * tmac/tmac.am (tmac_TESTS): Run it. 2025-07-24 Deri James * 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 * 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 * tmac/mdoc/doc-common (Sh, Ss): Fix missing brace escape sequences. 2025-07-16 G. Branden Robinson [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 [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 [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 * tmac/mdoc/doc-common (Sh): Fix missing brace escape sequence. 2025-07-17 G. Branden Robinson * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * tmac/tests/an_paragraph-reset-preserves-line-length.sh: Add test. * tmac/tmac.am (tmac_TESTS): Run it. 2025-07-20 G. Branden Robinson * 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 * 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 * 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 * src/devices/grolj4/lj4.cpp (lookup_paper_size): Return type-correct constructed values. 2025-07-14 G. Branden Robinson * 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 * 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 . 2025-07-14 G. Branden Robinson * 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 * 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 [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 * 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 * 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 * tmac/eqnrc: Drop unnecessary 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 [pic]: Stop validating non-interpreted 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * src/devices/grolj4/lj4.cpp: Relocate definition of `lookup_paper_size()`, eliminating need for forward declaration. 2025-07-10 G. Branden Robinson * 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 * 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 * 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 [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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * src/preproc/html/pre-html.cpp (get_line): Slightly refactor. Use named variables more and constant literals less. 2025-07-10 G. Branden Robinson * 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 [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 [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 * 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 * 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 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 * [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 * 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 * 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 * 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 . 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 * 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 * 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 [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 [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 [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 * 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 * src/utils/afmtodit/afmtodit.pl: Fix missing word in fatal diagnostic message. 2025-07-08 G. Branden Robinson * src/devices/gropdf/gropdf.pl (LoadDownload): Trivially refactor. Rename scalar `anyDownloadFilefound` to `anyDownloadFileFound` for proper camel casery. 2025-07-08 G. Branden Robinson [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 * 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 [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 . Problem dates back at least to groff 1.02, 2 June 1991. 2025-07-06 G. Branden Robinson [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 * 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 [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 . Thanks to Doug McIlroy for the discussion. 2025-07-03 G. Branden Robinson * src/utils/addftinfo/addftinfo.cpp (usage): Summarize purpose of command when help is requested. 2025-07-03 G. Branden Robinson * 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 [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 * 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 * 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 * doc/doc.am ($(GROFF_INFO)) [HAVE_MAKEINFO]: Make target creation depend on `HAVE_MAKEINFO` configuration variable. 2025-06-30 G. Branden Robinson * tmac/tty.tmac: Fix misspelled special character identifiers when defining fallback characters for accented basic Latin letters. Fixes . Problem introduced by me in commit 8f9988d4eb, 25 August. Thanks to Bjarni Ingi Gislason for the report. 2025-07-04 G. Branden Robinson * 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 * 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 [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 * 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 * src/devices/gropdf/gropdf.pl (do_x): Trivially refactor. Rename scalar `FDnm` to `fileName`. 2025-07-04 G. Branden Robinson * 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 * 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 * 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 * 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 * 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 * src/devices/gropdf/gropdf.pl (LoadFont): Recast diagnostic message. Continues fixing Savannah #66519. 2025-07-04 G. Branden Robinson * 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 * 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 * 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 . Thanks to Dave Kemper for the report. 2025-07-03 G. Branden Robinson * 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 * 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 * 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 * src/devices/gropdf/gropdf.pl (LoadDownload): Skip lines that consist only of whitespace. Continues fixing Savannah #67268. 2025-07-04 G. Branden Robinson [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 [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 [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 [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 [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 * tmac/pdf.tmac (pdf:SS): Delete now-unused macro. Fixes . 2025-06-26 G. Branden Robinson * 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 . 2025-06-26 G. Branden Robinson * 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 . 2025-06-26 G. Branden Robinson 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 [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 * src/utils/grog/grog.pl (interpret_line): Recognize new `pfp` and `pftr` request names. 2025-06-28 Deri James * font/devpdf/generate/StandardSymSL.sfd: Adjust glyph positions within cell to match grops rendering. * font/devpdf/StandardSymSL.pfb: Regenerate from changes above. Fixes . 2025-06-26 G. Branden Robinson * 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 * 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 * doc/groff.texi.in (Strings) : * man/groff_diff.7.man (New requests) : Document pitfall. Fixes . 2025-06-21 G. Branden Robinson * 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 * 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 * 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 . Thanks to Collin Funk for the report. 2025-06-21 G. Branden Robinson [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 substitutum. 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 Remove unnecessary call to pdf parser. * src/devices/gropdf/gropdf.pl (do_X) : Parse Title/Level manually. 2025-06-21 Deri James Saner ordering of perl switch statement. * src/devices/gropdf/gropdf.pl (do_X): handle pdfmark commands first. 2025-06-20 Deri James [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 . 2025-06-16 Dave Kemper * 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 . [Problem introduced by me in commit 8b6ccbce48, 13 May. --GBR] 2025-06-19 G. Branden Robinson * 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 * 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 * 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 * 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 [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 * 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 [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 . 2025-06-06 G. Branden Robinson * 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 * tmac/an-ext.tmac (SY): The single-argument form of `SY` need not set an unbreakable 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) : Document this fact. Fixes a regression from groff 1.23.0. Thanks to Alex Colomar for the report. 2025-06-05 G. Branden Robinson * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 [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 [troff]: Extend `font_info` class. I need this so I can implement a font mounting position list 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 * 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 * 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 * 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 * 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 [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 [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 * 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 * 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 * 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 * 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 * 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 [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 * 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 * 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 * 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 * 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 * 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 . 2025-06-03 G. Branden Robinson * 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 * 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 * src/roff/troff/input.cpp (token::next): Drop unnecessary temporary variable from `\F` escape sequence handler. 2025-06-03 G. Branden Robinson * 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 * 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 [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 [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 * 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 * 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 . [Problem introduced by me in commit 658f7afb8e, 2 January. --GBR] 2025-05-30 G. Branden Robinson [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 * src/roff/troff/input.cpp (read_title_parts): Fix code style nit; parenthesize formally complex expressions. 2025-05-30 G. Branden Robinson [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 * 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 * 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 * 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 [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 . 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 [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 * src/preproc/html/pre-html.cpp: Enable debugging code, ripping out use of preprocessor to disable it. 2025-05-19 G. Branden Robinson * 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 * 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 * src/preproc/html/pre-html.cpp (imageList::createImage) [DEBUGGING]: Fix syntax error in disabled code. 2025-05-18 G. Branden Robinson [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 continuously 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 (2/2). 2025-05-18 G. Branden Robinson [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 (1/2). 2025-05-17 G. Branden Robinson [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 [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 [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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * src/roff/troff/input.cpp (print_streams): Mark as `static` since this function requires no external linkage. 2025-05-15 G. Branden Robinson [troff]: Continue fixing Savannah #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 . 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 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 * 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 * 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 [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 * 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 [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 . Problem appears to date back to groff 1.06 (1992). 2025-05-16 G. Branden Robinson 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 * 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 [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 [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 [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 environment): ...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 * 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 * 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 * 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 [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 [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 * 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 * src/roff/troff/node.cpp (container_node::dump_node): Give contained node list a JSON key name. 2025-05-13 G. Branden Robinson * 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 * src/roff/troff/node.cpp (make_glyph_node): Assign Boolean, not integer, literal, to variable of type `bool`. 2025-05-13 G. Branden Robinson * 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 * 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 [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 [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 [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 * 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 * tmac/doc.tmac (Bd): Fix code style nit. Perform "strict" string comparison when using formatted output comparison operator to perform matching on macro argument. See subsection/node "Operators in Conditionals" in groff's Texinfo manual. See . 2025-05-07 G. Branden Robinson [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 [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 * 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 . Thanks to Andrew Bower for the report. 2025-05-02 G. Branden Robinson * 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 * tmac/doc.tmac: Save and restore AT&T troff compatibility mode, as man(7) does. Fixes . Thanks to Bjarni Ingi Gislason for the report. 2025-05-02 G. Branden Robinson * 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 . Thanks to наб for the report. Reverts a change I made in groff 1.23.0. 2025-04-30 G. Branden Robinson [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 [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 [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 [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 * 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 * 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 * 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 * src/roff/troff/input.cpp (glyph_to_name): Parenthesize formally complex expression. 2025-04-25 G. Branden Robinson * 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 * 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 [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 * src/include/stringclass.h (operator+): Fix code style nit: reorder equality comparisons to avoid inadvertent lvalue assignment. 2025-04-23 G. Branden Robinson * src/include/stringclass.h (operator[], string::empty) (operator+, string::substring): Fix code style nit: parenthesize formally complex expressions. 2025-04-22 G. Branden Robinson * 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 [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 [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 [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 * 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 [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 [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 [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 [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 [troff]: Slightly 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 [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 [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 * 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 [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 * 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 [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 . Problem appears to date back to groff's birth. 2025-04-20 G. Branden Robinson [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 * 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 * 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 [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 [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 [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 [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 [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 * 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 * 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 * src/roff/troff/input.cpp: Refactor `grostream` class for memory safety. (struct grostream): 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 * 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 * 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 * src/roff/troff/input.cpp (grostream::grostream): Null-terminate `mode` structure member as well. 2025-04-12 G. Branden Robinson * 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 * 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 [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 * 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 . 2025-04-11 G. Branden Robinson * 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 * 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 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 . 2025-04-11 G. Branden Robinson [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 * 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 . Thanks to Lennart Jablonka for prompting this idea. 2025-04-11 G. Branden Robinson * 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 * 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 * 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 [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 [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 [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 * 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 * 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 * 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 * 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 * 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 . 2025-04-03 G. Branden Robinson [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 [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 * 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 * 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 * 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 * 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-conforming shell, and skip test if a conforming one doesn't seem to be present. 2025-03-30 G. Branden Robinson [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 * 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 * 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 * 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 * 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 * 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 * 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 * gnulib: Update stable/2025-01 branch to commit 3fbc2c7bb3, 3 March. 2025-03-27 G. Branden Robinson [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 * 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 * src/roff/troff/input.c (main): Finish migrating to modern getopt_long(3) usage: drop `opterr` assignment. 2025-03-26 G. Branden Robinson * src/utils/grog/grog.pl (interpret_line): Recognize `pchar` as a GNU troff request. 2025-03-26 G. Branden Robinson * 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 * 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 * 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 * 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 * 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 . Thanks to Dave Kemper for the report. Problem introduced by me in commit 6bf627403c, 4 September. 2025-03-21 G. Branden Robinson * 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 * tmac/fallbacks.tmac: Allow recognition of more Unicode characters in output formats where Savannah #63332 isn't an issue. Fixes . 2025-03-21 G. Branden Robinson [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 . Thanks to Bjarni Ingi Gislason for the report. Problem introduced by me in commit 25ef9f6bda, 26 February. 2025-03-21 G. Branden Robinson [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 [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 . 2025-03-20 G. Branden Robinson [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) : * man/groff.7.man (Request short reference) : * man/groff_diff.7.man (Other differences): Document it. 2025-03-17 G. Branden Robinson [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 * 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 * 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 * 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 [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 [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 * 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 . Thanks to Dave Kemper for the report. Problem appears to date back to groff's birth. 2025-03-17 G. Branden Robinson [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 * 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 * 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 * 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 * 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 * 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 [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 * 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 [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 * 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 * 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 * 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 [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 [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 [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 [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 [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 [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 [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 [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 [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 [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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 derived 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 * 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 [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 [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 [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 [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 Further rationalize header file inclusions. * src/libs/libgroff/string.cpp: Include assert.h and string.h. Annotate why. 2025-03-15 G. Branden Robinson [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 [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 * src/roff/troff/number.cpp (is_valid_term): When warning of an invalid scaling unit, report the character encountered. 2025-03-14 Deri James [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 . 2025-03-13 Deri James [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 . 2025-03-05 G. Branden Robinson [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 * 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 [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 * 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 * src/roff/troff/node.cpp (hline_node::~hline_node) (vline_node::~vline_node): Fix code style nit, simplifying. 2025-03-02 G. Branden Robinson * 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 . Problem introduced by me in commit f087165933, 7 December. 2025-03-02 G. Branden Robinson [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 * 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 * 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 [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) : * man/groff.7.man (Request short reference) : * man/groff_diff.7.man (New requests) : Document it. 2025-02-26 G. Branden Robinson * 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 * 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 * 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 [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 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 . Thanks to Dave Kemper for the report. Problem appears to date back to groff's birth. 2025-02-24 G. Branden Robinson * 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 * 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 . Thanks to Benno Schulenberg for the report. 2025-02-23 G. Branden Robinson [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 [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 [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) : * man/groff.7.man (Request short reference) : * man/groff_diff.7.man (Altered requests) : (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 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 * 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 * 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 * src/libs/libgroff/font.cpp: Include "string.h" standard header file, since we (now) use strerror(3). 2025-02-21 G. Branden Robinson [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 [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 [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 * 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 [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 [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 * 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 * 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 * src/roff/troff/input.cpp (get_charinfo): Use C++ `static_cast` operator instead of C-style type cast. 2025-02-08 G. Branden Robinson * 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 * 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 * src/roff/groff/groff.am (groff_XFAIL_TESTS): Add ".../current-language-and-environment-in-sync.sh". 2025-02-04 G. Branden Robinson 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 [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 * 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 * 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 * src/roff/troff/input.cpp (token::description): When describing special character, include its identifier. 2025-01-28 G. Branden Robinson * 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 . Thanks to Dave Kemper for the report. Savannah #66526 is implicated. 2025-01-27 G. Branden Robinson * src/roff/troff/env.cpp (environment::choose_breakpoint): Reparenthesize (very) complex expression, restoring documented behavior of hyphenation space feature. Fixes . Thanks to Dave Kemper for the report. Problem introduced by me in commit d2dceabb83, 30 August. 2025-01-27 G. Branden Robinson [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 [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 * 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 * 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 . Thanks to Dave Kemper for the report. 2025-01-17 G. Branden Robinson * 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 [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 [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 * 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 * 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 [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 * 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 . Thanks to Dave Kemper for the report. 2025-01-15 G. Branden Robinson 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 [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 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 [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 [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 [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 [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 * 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 . 2025-01-14 G. Branden Robinson [man]: Regression-test Savannah #66664. * tmac/tests/an_title-abbreviation-works.sh: Add test case. 2025-01-14 G. Branden Robinson * src/roff/troff/env.cpp (do_input_trap): Directly copy Boolean value instead of using a control structure. 2025-01-07 Ingo Schwarze * 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 * 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 . 2025-01-05 G. Branden Robinson [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 [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 * 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 . 2025-01-02 G. Branden Robinson * src/preproc/tbl/main.cpp (main): Distinguish `ferror()` status and `fflush(stdout)` failures when cleaning up before exit. 2024-12-24 Collin Funk 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 . 2025-01-02 G. Branden Robinson * bootstrap: Resync with gnulib upstream. 2025-01-02 G. Branden Robinson * gnulib: Update to stable/2025-01. 2025-01-01 G. Branden Robinson * src/utils/afmtodit/afmtodit.pl: Report input file name and line number in diagnostic messages. Fixes . 2025-01-01 G. Branden Robinson * src/utils/afmtodit/afmtodit.pl: Migrate diagnostics to newly developing wording convention. See . 2024-12-26 G. Branden Robinson * m4/groff.m4 (GROFF_MAKE_DEFINES_RM): Quote name of "make" command in "checking" message for clarity. 2024-12-26 G. Branden Robinson [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 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 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 . Co-authored-by: "G. Branden Robinson" 2024-12-21 G. Branden Robinson * 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 * src/include/lf.h: Include "stringclass.h" header file, since we refer to groff's `string` type. 2024-12-21 G. Branden Robinson * src/include/stringclass.h: Introduce `GROFF_STRINGCLASS_H` include guard. 2024-12-21 G. Branden Robinson * 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 * src/utils/xtotroff/xtotroff.c (main): Throw assertion if we don't handle `getopt_long()`'s return value. 2024-12-21 G. Branden Robinson * 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 * 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 * 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 * 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 * 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 [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 * 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 [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 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 . 2024-12-10 G. Branden Robinson [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 * tmac/tmac.am (TMACNORMALFILES): Ship "psfig.tmac". 2024-12-10 G. Branden Robinson * 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 [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 [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 [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 * 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 * 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 * src/utils/lkbib/lkbib.cpp (usage): If asked for `--help`, summarize command purpose in message. 2024-12-08 G. Branden Robinson [troff]: Disable `cf` request in safer mode. * src/roff/troff/input.cpp (copy_file): Do it. * doc/groff.texi.in (I/O) : * man/groff.7.man (Request short reference) : * man/groff_diff.7.man (Restricted requests): Document it. * NEWS: Add item. Fixes . 2024-12-08 G. Branden Robinson * 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 "" header file to ensure visibility of `FILE`, `putc()` and `sprintf()` symbols. Include "" 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 [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 [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 [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 [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 [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 [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 Data provided to .pso must terminate with \n. * tmac/pdfpic.tmac: Add terminating linefeed. Fixes thanks to Bjarni Ingi Gislason for the report and solution. 2024-12-06 G. Branden Robinson 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 * 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 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 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 . 2024-12-05 G. Branden Robinson 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 [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 [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 * 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 . 2024-12-04 G. Branden Robinson * 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 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 * src/preproc/eqn/main.cpp (usage): If asked for `--help`, summarize command purpose in message. 2024-12-03 G. Branden Robinson * src/preproc/tbl/main.cpp (usage): If asked for `--help`, summarize command purpose in message. 2024-12-03 G. Branden Robinson * 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 * src/preproc/soelim/soelim.cpp (usage): * src/preproc/soelim/soelim.1.man: Revise program description. 2024-12-03 G. Branden Robinson * 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 * 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 * 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 * 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 * src/roff/troff/input.cpp (system_request, pipe_output): Call `tok.next()` at end of non-error path. Fixes . Thanks to Deri James for the report. Problem introduced by me in commit 24e314b94c3, 12 November. 2024-12-02 G. Branden Robinson [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 * src/devices/xditview/xditview.c (Syntax): Align wording of usage message better with those of other output drivers. 2024-12-02 G. Branden Robinson 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 * src/preproc/grn/hdb.cpp: Include "" header file to ensure visibility of `atoi()` declaration. Problem detected on Solaris 10. 2024-11-30 G. Branden Robinson Reduce header file inclusion spam. * src/include/lib.h: Drop inclusion of "" 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` "" in files that directly use the symbols it exposes. 2024-11-30 G. Branden Robinson * 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 [gropdf]: Using \*[PDFLB] does not work. * tmac/pdf.tmac: Simplify string and fix misconception about PDFNOTE.WIDTH and PDFNOTE.HEIGHT. Fixes . 2024-11-30 G. Branden Robinson [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 * 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 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 [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 [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 * 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 * src/roff/groff/pipeline.c: Sort (and annotate) inclusions of standard header files. 2024-11-30 G. Branden Robinson 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 "" 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 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 "" 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 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 " inclusion do the work, and include "" unconditionally. 2024-11-29 G. Branden Robinson [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 [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 [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 * 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 [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 [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 [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 [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 [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 [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 [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 [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 [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 [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 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 . 2024-11-27 G. Branden Robinson [libgroff]: Improve header-file inclusion hygiene. * src/include/itable.h: * src/include/lib.h: * src/include/ptable.h: * src/include/stringclass.h: Drop Autoconf ""-inclusion boilerplate. Per Paul Eggert, "You shouldn't need to put "#include " 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 . 2024-11-27 G. Branden Robinson [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 * 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 [lookbib]: Align with modern groff conventions. * src/utils/lookbib/lookbib.cpp: Include system library headers before local ones. 2024-11-27 G. Branden Robinson [indxbib]: Align with modern groff conventions. * src/utils/indxbib/indxbib.cpp: Include system library headers before local ones. 2024-11-27 G. Branden Robinson * src/roff/troff/hvunits.h: Drop Autoconf ""-inclusion boilerplate; troff's ".cpp" files reliably have it now. 2024-11-27 G. Branden Robinson [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 ""-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 [groff]: Align with modern groff conventions. * src/roff/groff/groff.cpp: Include system library headers before local ones. 2024-11-27 G. Branden Robinson [tbl]: Align with modern groff conventions. * src/preproc/tbl/main.cpp: * src/preproc/tbl/table.cpp: Add Autoconf ""-inclusion boilerplate to these translation units. 2024-11-27 G. Branden Robinson [soelim]: Align with modern groff conventions. * src/preproc/soelim/soelim.cpp: Include system library headers before local ones. 2024-11-27 G. Branden Robinson [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 ""- inclusion boilerplate to these translation units. 2024-11-27 G. Branden Robinson [preconv]: Align with modern groff conventions. * src/preproc/preconv/preconv.cpp: Include system library headers before local ones. 2024-11-27 G. Branden Robinson [pre-grohtml]: Align with modern groff conventions. * src/preproc/html/pushback.cpp: Add Autoconf ""- 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 [libgroff]: Align with modern groff conventions. * src/libs/libgroff/make-uniuni.cpp: Update script that generates "uniuni.cpp" to add Autoconf ""-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 ""- 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 [libdriver]: Align with modern groff conventions. * src/libs/libdriver/input.cpp: Add Autoconf ""- 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 [grotty]: Align with modern groff conventions. * src/devices/grotty/tty.cpp: Add Autoconf ""- inclusion boilerplate to this translation unit. Include required system library header files. 2024-11-27 G. Branden Robinson [grops]: Align with modern groff conventions. * src/devices/grops/ps.cpp: * src/devices/grops/psrm.cpp: Add Autoconf ""- inclusion boilerplate to these translation units. Include system library headers before local ones. 2024-11-27 G. Branden Robinson [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 ""- 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 [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 ""-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 [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 ""-inclusion boilerplate to these translation units. * src/preproc/grn/hpoint.cpp: Drop unnecessary inclusion of "". 2024-11-27 G. Branden Robinson * 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 ""-inclusion boilerplate to these translation units. * src/preproc/eqn/other.cpp: Include "" since `fprintf()` and `printf()` are used. 2024-11-27 G. Branden Robinson * 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 * 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 ""- inclusion boilerplate to this translation unit. 2024-11-27 G. Branden Robinson * src/utils/hpftodit/hpftodit.cpp: * src/utils/hpftodit/hpuni.cpp: Align with modern groff conventions. Add Autoconf ""-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 ""; none of its symbols (`is*()`) are directly used. 2024-11-27 G. Branden Robinson [troff]: Align with modern groff conventions. * src/roff/troff/div.cpp: * src/roff/troff/input.cpp: Add Autoconf ""-inclusion boilerplate to these translation units. Include system library headers before local ones. * src/roff/troff/input.cpp: Fix code style nits. Include "" 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 * 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 "", 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 * src/include/ptable.h: Include "" header, since the macros this file defines use `malloc()` and `free()`. 2024-11-27 G. Branden Robinson * src/utils/addftinfo/addftinfo.cpp: Align with modern groff conventions. Add Autoconf ""-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 * bootstrap.conf: Add "getopt-gnu" to `gnulib_modules`. 2024-11-27 G. Branden Robinson * 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 . 2024-11-27 G. Branden Robinson * 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 [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 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 . Thanks to Sven Schober for the report, analysis, and for proposing fixes. 2024-11-27 G. Branden Robinson 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 * 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 . 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 * 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 . 2024-11-21 G. Branden Robinson * 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 . Thanks to Bjarni Ingi Gislason for the report. 2024-11-21 G. Branden Robinson * 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 * 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 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 . 2024-11-20 TANAKA Takuji 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 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 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 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 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 * 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 * 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) : * man/groff_diff.7.man (New requests) : Recast, strengthening parallel with `so` request. * NEWS: Document `pso` request's new handling of a leading neutral double quote. 2024-11-21 G. Branden Robinson * 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 . 2024-11-19 G. Branden Robinson [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 . 2024-11-19 G. Branden Robinson [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 * src/preproc/soelim/soelim.1.man (Description): * src/preproc/soelim/soelim.cpp (usage): Revise description. 2024-11-19 G. Branden Robinson * src/roff/troff/div.cpp (DIVERSION_LENGTH_MAX): Declare as `const`. 2024-11-19 G. Branden Robinson * Makefile.am (EXTRA_DIST): Ship "ChangeLog.123". 2024-11-19 G. Branden Robinson * Makefile.am (EXTRA_DIST): Re-sort with `LC_COLLATE=C`. 2024-11-14 G. Branden Robinson 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 Stop distributing pdfmark. It is now separately maintained. Please visit for the latest version. (Update: In April 2025, hosting moved to .) * 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 . 2024-11-14 G. Branden Robinson * NEWS: Explain changes to `\X` and `.device` argument processing. Fixes . Thanks to Nikita Ivanov for the report. 2024-11-14 G. Branden Robinson * 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 . Thanks to Rob Kolstad for the report. 2024-11-14 G. Branden Robinson * 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 * 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 . Thanks to Sven Schober for the report. 2024-11-13 G. Branden Robinson * 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 . Thanks to Bjarni Gislason for the report. 2024-11-13 G. Branden Robinson * 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 * 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) (Other Differences): * man/groff.7.man (Request short reference) : * man/groff_diff.7.man (New requests) : (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 . 2024-11-12 G. Branden Robinson [soelim]: Read argument to `so` request in a more GNU troff-ish fashion (and a more AT&T troff-ish fashion, 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 . 2024-11-12 G. Branden Robinson [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 [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 * 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 * 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 * 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 * tmac/groff_man.7.man.in (Options) <-rCHECKSTYLE>: Document feature introduced in groff 1.23.0. Fixes . Thanks to Alex Colomar for the report. 2024-11-10 G. Branden Robinson * 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 [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 * 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 * src/roff/troff/input.cpp (pipe_source_request): Drop branch unreachable since commit 6dee590de8, 12 September. 2024-11-09 G. Branden Robinson * 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 * src/roff/troff/input.cpp (pipe_source_request): Align wording of warning diagnostics with each other. 2024-11-09 G. Branden Robinson * 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 * 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 * 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 * 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 [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 * src/roff/troff/input.cpp (has_arg): Return false at EOF, too. 2024-11-08 G. Branden Robinson [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 [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 * 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 * 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 . Problem introduced by me prior to groff 1.23.0 when I rewrote the tool. 2024-11-07 G. Branden Robinson [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 . Thanks to Rob Kolstad for the report and the suggestion. 2024-11-07 G. Branden Robinson * 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 * 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 * 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 * 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 * 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 [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 * tmac/sv.tmac: Fix typo in translation, present since birth {commit 4f906e7d0c, 3 March 2006}. 2024-11-04 G. Branden Robinson [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 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 . 2024-10-30 G. Branden Robinson * 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 * 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 * src/roff/troff/env.cpp (environment::print_env): Describe automatic hyphenation mode in plain English. 2024-10-29 G. Branden Robinson * 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 [troff]: The `pcolor` request now accepts color identifiers as arguments. * src/roff/troff/input.cpp (report_color): Do it. * doc/groff.texi.in (Debugging) : * man/groff.7.man (Request short reference) : * man/groff_diff.7.man (New requests) : Document it. * NEWS: Update item. 2024-10-29 G. Branden Robinson * 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 Fix for 4-bit eps images * src/devices/gropdf/gropdf.pl: Use correct BitsPerComponent when converting to raw format. 2024-11-02 Deri James Import change in perl 5.40. See . * src/devices/gropdf/pdfmom.pl: * src/devices/gropdf/gropdf.pl: * src/utils/afmtodit/afmtodit.pl: Warning issued for unknown method fixed. Fixes . Thanks to Bjarni Gislason for the report, see . 2024-10-28 G. Branden Robinson 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 and follow-ups. 2024-10-24 G. Branden Robinson 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 * 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 * 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 [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 dereference 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 * 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 * man/groff.7.man: * man/groff_diff.7.man: * src/preproc/eqn/eqn.1.man: * tmac/groff_mdoc.7.man: Fix spelling errors. Fixes (2/2). Thanks to Bjarni Ingi Gislason for the report. 2024-10-19 G. Branden Robinson * 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 . Thanks to Sven Schober for the report and for determining the workaround. 2024-10-19 G. Branden Robinson * 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 * 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 [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 * 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 * src/utils/xtotroff/xtotroff.c (main): Emit our own diagnostic for an invalid command-line option. 2024-10-18 G. Branden Robinson * src/utils/pfbtops/pfbtops.c (main): Emit our own diagnostic for an invalid command-line option. 2024-10-18 G. Branden Robinson * src/roff/groff/groff.cpp (main): Emit our own diagnostic for an invalid command-line option. 2024-10-18 G. Branden Robinson * src/utils/pfbtops/pfbtops.c (main): Call `assert()` to catch programmer error in command-line option handling. 2024-10-18 G. Branden Robinson * src/utils/lookbib/lookbib.cpp (main): Make `assert()` message communicative. 2024-10-18 G. Branden Robinson 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 * 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 Use new \X''. * tmac/pdf.tmac: The new \X'' code does no flush, perfect for hotspots. Thanks Branden. 2024-10-18 Deri James Foundries are only a single letter. * src/devices/gropdf/gropdf.pl: Look for single letter followed by '-'. Fixes . Thanks to наб for the report. 2024-10-17 G. Branden Robinson * 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 * src/devices/xditview/xditview.c (NewFile): Populate `current_file_name` with `name` more cautiously since the latter originates in the `argv` array. Fixes . 2024-08-14 Lukas Javorsky * src/preproc/refer/ref.cpp (same_reference): Fix array comparison warning by comparing elements individually. Fixes . 2024-08-14 Lukas Javorsky * 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 . 2024-10-17 G. Branden Robinson * doc/pic.ms: Fix omission of `linethick` variable from "Semi-Formal Grammar" section. Fixes . Thanks to an anonymous contributor for the report and patch. 2024-10-17 G. Branden Robinson [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 . Thanks to Dave Kemper for the report. 2024-10-17 G. Branden Robinson * 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 * 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 * src/roff/troff/input.cpp (parse_output_page_list): `const`ify function argument. 2024-10-16 G. Branden Robinson * 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 . 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 [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 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 * 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 * 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 (1/2). Thanks to Dave Kemper for the report. 2024-10-14 Dave Kemper * tmac/en.tmac: Map hcodes of Latin-1 characters with diacritical marks that are used in English words to their unadorned ASCII counterparts. Fixes . 2024-10-14 G. Branden Robinson * 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 . Thanks to Bjarni Ingi Gislason for the report. 2024-10-14 G. Branden Robinson * 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 Work around debian's ImageMagick policy. * src/devices/gropdf/gropdf.pl: Don't use perlmagick to embed PDFs Fixes . Thanks to Branden for the report. 2024-10-13 G. Branden Robinson * 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 . Thanks to Joerg van den Hoff for the report. 2024-10-13 G. Branden Robinson [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 * 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 * 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 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 [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 * 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 * tmac/an.tmac (TH): Clarify language in style warning messages. 2024-10-11 G. Branden Robinson * tmac/an.tmac (TH): Simplify logic populating center header. 2024-10-11 G. Branden Robinson * 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 * 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 * src/devices/grops/psrm.cpp (read_uint_arg): Boolify. 2024-10-11 G. Branden Robinson * 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 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 * 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 * tmac/an.tmac: * tmac/doc.tmac: Fix code style nits; parallelize handling of rendering option registers and strings. 2024-10-10 G. Branden Robinson * 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 * 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 * src/preproc/tbl/table.cpp (table::add_entry): Fix logic error in *roff escape sequence detection, exposed by UTP document . 2024-10-11 Deri James * src/devices/gropdf/gropdf.pl: When switching writing direction (\X'pdf: xrev') ensure any buffered output is flushed. 2024-10-06 G. Branden Robinson * 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 * 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 * 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 * bootstrap.conf: Add "memmem" to `gnulib_modules`. 2024-10-06 G. Branden Robinson * 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 * src/roff/troff/reg.cpp (dump_register): Remove garbage from `errprint()` format string. Fixes . Thanks to Bjarni Ingi Gislason for the report. 2024-10-04 G. Branden Robinson * 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 * src/preproc/tbl/table.cpp: Add C preprocessor macro storing the name of a groff register for saving the state of line numbering 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 . 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 * src/preproc/tbl/tests/save-and-restore-line-numbering.sh: Add regression test for Savannah #66290. 2024-10-03 G. Branden Robinson * src/roff/groff/tests/\ write-request-handles-empty-second-arg.sh: Revise signal handling. 2024-09-27 G. Branden Robinson * 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 * 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 * 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 . Problem appears to date back to groff's birth. 2024-09-26 G. Branden Robinson [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 * 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 * src/roff/troff/input.cpp (pipe_output): Shorten diagnostics. 2024-09-26 G. Branden Robinson [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 * 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 * 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 * 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 . 2024-09-21 G. Branden Robinson * 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 * 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 * src/utils/afmtodit/afmtodit.tables: Update using the Unicode 16.0.0 version of the "UnicodeData.txt" file. 2024-09-21 G. Branden Robinson * src/utils/afmtodit/afmtodit.tables: Update with freshly changed "make-afmtodit-tables" script, adding ~192 mappings. Fixes (2/2). Thanks to Deri James for the report. 2024-09-21 G. Branden Robinson * 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 (1/2). Thanks to Deri James for the report. 2024-09-21 G. Branden Robinson * 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 * 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 . 2024-09-21 G. Branden Robinson * src/roff/groff/groff.cpp (main): Clarify verbose output. 2024-09-21 G. Branden Robinson * 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 [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 * 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 * src/roff/troff/input.cpp (decode_string_args): Improve error diagnostic to disclose more context. 2024-09-21 G. Branden Robinson * 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 * 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 * 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 * src/include/color.h: Fix code style nit: drop unnecessary `#include`. 2024-09-17 G. Branden Robinson * src/roff/troff/input.cpp (report_composite_characters): Fix code style nit: eliminate unnecessary temporary variable. 2024-09-15 G. Branden Robinson [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 . * 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 * 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 [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 [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 [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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 . Thanks to Helge Kreutzmann and the manpage-l10n project for the report. 2024-09-11 G. Branden Robinson * 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 * 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 * 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 * src/preproc/html/pre-html.cpp (dump_args): "`#if 0` out" function with no call sites. 2024-09-10 G. Branden Robinson * 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 * src/roff/troff/env.cpp (indent, temporary_indent): Report amount of computed indentation when warning of negative value. 2024-09-10 G. Branden Robinson * src/roff/troff/input.cpp (possibly_handle_first_page_transition): Boolify. 2024-09-10 G. Branden Robinson * 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 * 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 * 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 * 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 * 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 * 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 * 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 * src/roff/troff/div.cpp (begin_page): Boolify local variable `got_arg`. 2024-09-09 G. Branden Robinson * 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 * 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 * src/roff/troff/div.cpp (class diversion): Drop unused member variables `any_chars_added` and `needs_push`. 2024-09-09 G. Branden Robinson * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 [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 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 [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 [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 * 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 * 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 * 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 * 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 [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 (1/2). 2024-09-05 G. Branden Robinson * 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 * 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 * 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 * src/roff/nroff/nroff.sh: Update usage message, noting support for options -[aDIZ]. 2024-09-04 G. Branden Robinson * 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 * Makefile.am: Revise and update internal documentation. Fixes . Thanks to Bjarni Ingi Gislason for the report. 2024-09-04 G. Branden Robinson * src/roff/troff/input.cpp (usage): Break lines in usage message. 2024-09-04 G. Branden Robinson * 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 [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 * 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 * 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 . 2024-09-04 G. Branden Robinson * 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 . 2024-09-04 G. Branden Robinson * src/roff/troff/env.cpp (point_size, override_sizes): Ignore request in nroff mode, like `fam`. 2024-09-03 G. Branden Robinson * 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 . 2024-09-03 G. Branden Robinson 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 . (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 * 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 . (We need regression tests.) 2024-09-03 G. Branden Robinson [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 * 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 * 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 * 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 * 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 * src/roff/troff/node.cpp (associate_style_with_font_position): Clarify warning diagnostic. 2024-09-02 G. Branden Robinson * 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 * 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 [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 . 2024-09-02 G. Branden Robinson [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 [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 . 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 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 [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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * src/roff/troff/env.cpp (environment::choose_breakpoint): Fix code style nit: parenthesize complex expressions. 2024-08-30 G. Branden Robinson * 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 [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 * 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 * 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 [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 * src/libs/libgroff/unicode.cpp (valid_unicode_code_sequence): Tighten wording of error diagnostic. 2024-08-30 G. Branden Robinson * src/roff/troff/input.cpp (usage): Sync language with troff(1). 2024-08-28 G. Branden Robinson Update with respect to Unicode 15.1.0. * src/libs/libgroff/uniuni.cpp: * src/utils/afmtodit/afmtodit.tables: Regenerate. Fixes . 2024-08-28 G. Branden Robinson * 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 * 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 [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 * 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 * 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 [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 [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 * 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 * 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 * 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 * 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 * 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 [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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 [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 * 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 [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 [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 * 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 [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 * 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 * font/devascii/R.proto: Map `ad` (dieresis accent) special character as yet another alias of `"` on the ASCII output device. 2024-08-23 G. Branden Robinson * 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 [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 * 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 * 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 * tmac/pdf.tmac (pdfclean): Drop unused macro. 2024-08-21 G. Branden Robinson * m4/groff.m4 (GROFF_WCOREFLAG): Include header file in test program, since it calls exit(3). Thanks to Eli Schwartz for noting the problem. Continues fixing . 2024-08-25 G. Branden Robinson * 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 [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 . * 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:- "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 [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 * font/devps/ZDR: Regenerate. 2024-08-21 G. Branden Robinson * font/devps/ZD: Regenerate using updated dingbats.map. Fixes . Thanks to Deri James and Dave Kemper for (extensive) consultation. 2024-04-29 Deri James * font/devps/generate/dingbats.map: Update to map many more Unicode code points to Zapf Dingbats glyphs. 2024-08-21 G. Branden Robinson * 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 . 2024-08-21 G. Branden Robinson * 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 * 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 . 2024-08-20 G. Branden Robinson * 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 * 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 * NEWS: Add items for Deri's just-committed new features. 2024-06-22 Deri James [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 . 2024-08-19 G. Branden Robinson * font/devcp1047/*: Recursively delete. * Makefile.am: Stop including the Automake file therein. * MANIFEST: De-document. * NEWS: Note withdrawal of "cp1047" device support. Fixes . 2024-08-19 G. Branden Robinson * tmac/cp1047.tmac: Delete. * tmac/tmac.am (TMACNORMALFILES): Stop shipping it. Continues fixing . 2024-08-19 G. Branden Robinson * src/roff/nroff/nroff.sh: Drop support for "cp1047" output device. Continues fixing . 2024-08-19 G. Branden Robinson * tmac/an.tmac: Drop support for "cp1047" output device. Continues fixing . 2024-08-19 G. Branden Robinson * tmac/doc.tmac: Drop support for "cp1047" output device. Continues fixing . 2024-08-19 G. Branden Robinson * tmac/eqnrc: Drop eqn(1) support for "cp1047" output device. Continues fixing . 2024-08-19 G. Branden Robinson * tmac/fallbacks.tmac: * tmac/troffrc: * tmac/tty.tmac: Drop "cp1047" output device support. Continues fixing . 2024-08-19 G. Branden Robinson * m4/groff.m4 (GROFF_EBCDIC, GROFF_OS390): Drop macros. * configure.ac: Stop using them. Continues fixing . 2024-08-19 G. Branden Robinson [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 . 2024-08-19 G. Branden Robinson * src/roff/troff/input.h: Drop input character definitions for CCSID (code page) 1047 (EBCDIC). Continues fixing . 2024-08-19 G. Branden Robinson * 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 * 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 [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 [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 . 2024-08-19 G. Branden Robinson * 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 * 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 * 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 . Thanks to Hanno Boeck for the report. 2024-08-19 G. Branden Robinson [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 [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 [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 [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 [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 * 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 * src/roff/troff/input.cpp (do_zero_width): Tweak `\Z` diagnostic output. 2024-08-18 G. Branden Robinson * 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 * 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 * 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 * 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 * 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 * 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 * 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 . 2024-08-17 G. Branden Robinson * 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 * 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 [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 . 2024-08-17 G. Branden Robinson * 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 foo1 bar After: $ printf 'foo\A\naz\nbar\n' | ./build/test-groff -a foo1bar * src/roff/groff/tests/\ some_escapes_accept_newline_delimiters.sh: Update test expectations. 2024-08-17 G. Branden Robinson * src/roff/troff/input.cpp (interpolate_register): Add assertion to blow up on null pointer dereference. 2024-08-17 G. Branden Robinson [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 [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 * src/roff/troff/reg.cpp (define_register): Warn when garbage encountered in numeric expression argument to `nr` request. Fixes . 2024-08-17 G. Branden Robinson [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 * 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 * 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 . 2024-08-16 G. Branden Robinson * 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 [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 [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 [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 * 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 . 2024-08-14 G. Branden Robinson * src/roff/troff/env.cpp (override_sizes): Refer to size range as "invalid", not "bad", in warning diagnostic. 2024-08-14 Lukas Javorsky * 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 . 2024-08-14 G. Branden Robinson [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 * 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 [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 [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 . Thanks to Dave Kemper for the discussion. 2024-08-13 G. Branden Robinson * 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 * 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 * src/roff/groff/tests/arithmetic-works.sh: Add more test cases. 2024-08-13 G. Branden Robinson * src/roff/troff/node.cpp (troff_output_file::flush_tbuf): Add assertion: the type size should be positive. 2024-08-13 G. Branden Robinson * src/include/symbol.h (class symbol): Boolify `is_null()` and `is_empty()` member functions. 2024-08-13 G. Branden Robinson [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 * 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 * 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 * src/roff/troff/node.cpp: Drop Autoconf-guarded inclusion of . 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 [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 and annotate why. * src/roff/troff/reg.cpp: Include and annotate why. 2024-08-13 G. Branden Robinson * 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 * 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 * 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 * 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 * tmac/andoc.tmac: Annotate "unnecessary" control lines. Fixes . 2024-08-09 G. Branden Robinson * 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 . I've made similar ones myself. 2024-08-09 G. Branden Robinson * 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 * 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 * tmac/doc-old.tmac: Drop spurious dot in control line. Fixes . 2024-08-08 Dave Kemper * tmac/tty.tmac: Revise fallback character for • (bullet) to asterisk, affecting "ascii" and "latin1" output devices. Fixes . Thanks to Jeff Conrad for the report. 2024-08-08 G. Branden Robinson * 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 . 2024-08-08 G. Branden Robinson [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 . 2024-08-08 G. Branden Robinson * 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 . 2024-08-07 G. Branden Robinson * 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 [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 [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 (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 [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 (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 * src/roff/troff/node.cpp (set_font_specific_special_fonts): Adjust diagnostic message for clarity (and relative brevity). 2024-08-07 G. Branden Robinson * 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 [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 . 2024-08-03 G. Branden Robinson * 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 . 2024-08-03 G. Branden Robinson 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 . Thanks to Werner Lemberg for the discussion in . 2024-07-31 G. Branden Robinson * 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) : * man/groff_diff.7.man (New requests) : Document loosened restriction. Fixes . Thanks to Carsten Kunze for the report and Dave Kemper for a test case that clarified matters. 2024-07-31 G. Branden Robinson 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 * 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) : * man/groff_diff.7.man (New requests) : Document that the request aborts processing its arguments upon encountering an invalid one. Continues . Thanks to Dave Kemper for further discussion. 2024-08-01 G. Branden Robinson * doc/groff.texi.in (Manipulating Hyphenation) : * man/groff_diff.7.man (New requests) : 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 * 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 .) 2024-07-30 G. Branden Robinson * 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 . Thanks to Dave Kemper for the report. 2024-07-30 G. Branden Robinson * 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 * 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 . Thanks to Dave Kemper for the report. 2024-07-25 G. Branden Robinson * 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 * src/roff/troff/number.cpp (is_valid_expression_start): Fix missing space in diagnostic message. 2024-07-25 G. Branden Robinson * src/roff/troff/number.cpp (vunits::vunits, hunits::hunits): Migrate to C23 checked arithmetic macros. Throw error if addition overflows. Fixes . (For real this time, fingers crossed.) 2024-07-25 G. Branden Robinson * src/roff/groff/tests/arithmetic-works.sh: Add more tests. 2024-07-25 G. Branden Robinson * src/roff/troff/number.cpp (vunits::vunits, hunits::hunits): Move common subexpression to a temporary variable to prepare for reuse in C23 checked arithmetic macros. 2024-07-25 G. Branden Robinson [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 * 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 * 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 . Thanks to Morten Bo Johansen for the report. 2024-07-20 G. Branden Robinson 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 * src/roff/troff/input.cpp (is_char_usable_as_delimiter): Reject `|`. Fixes . 2024-07-19 G. Branden Robinson 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 [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 . 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 * 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 [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 * 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 . 2024-07-16 G. Branden Robinson * 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 * bootstrap: Resync with gnulib upstream. Thanks to Dave Kemper for the report and Collin Funk for the suggested fix. Fixes . 2024-07-15 G. Branden Robinson * src/roff/troff/number.cpp (is_valid_term): Trivially refactor; simplify tautologous Boolean expression. 2024-07-15 G. Branden Robinson * 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 . 2024-07-14 G. Branden Robinson * 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 * tmac/groff_mdoc.7.man: Manipulate type size and vertical spacing only in troff mode. 2024-07-14 G. Branden Robinson * 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 * 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 * 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 * 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 [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 . 2024-07-13 G. Branden Robinson * 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 . Thanks to Dave Kemper for the report. 2024-07-13 G. Branden Robinson * 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 * tmac/tests/an-ext_SY-and-YS-work.sh: Test new behavior of `YS` when given an argument. 2024-07-13 G. Branden Robinson * 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 * 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 * 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 * 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 * 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 * 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 . 2024-07-13 G. Branden Robinson * 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 [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 * 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 * src/roff/nroff/nroff.sh: Tweak shell pattern for clarity. 2024-07-12 G. Branden Robinson Update gnulib to stable/2024-07. Point to 0ba13435a9362bec0ff5fd0830907b9fac723e41. 2024-03-16 Alejandro Colomar * 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 (6/6). 2024-03-16 Alejandro Colomar * src/utils/indxbib/indxbib.cpp (check_integer_arg): Collapse related tests. Fixes (4/4). 2024-03-16 Alejandro Colomar * 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 (3/4). 2024-03-16 Alejandro Colomar * src/utils/indxbib/indxbib.cpp (check_integer_arg): Clear `errno` before calling `strtol()`. Otherwise, `errno` may hold `ERANGE` from before. See strtol(3). Fixes (2/4). 2024-03-16 Alejandro Colomar * src/utils/indxbib/indxbib.cpp (check_integer_arg): Don't `else` after [[noreturn]]. Fixes (1/4). 2024-03-16 Alejandro Colomar [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 (5/6). 2024-03-16 Alejandro Colomar * src/devices/grolbp/lbp.cpp (main): Remove bogus (and redundant) check. `str == end` can only happen if strtol(3) returns 0. Fixes (4/6). 2024-03-16 Alejandro Colomar * 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 (3/6). 2024-03-16 Alejandro Colomar * 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 (2/6). 2024-03-16 Alejandro Colomar * 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 (1/6). 2024-07-12 G. Branden Robinson [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 . 2024-07-11 G. Branden Robinson * 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 * src/roff/nroff/nroff.sh: Describe program briefly when invoked with `--help` option. 2024-07-11 G. Branden Robinson * 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 * src/roff/troff/node.cpp (class composite_node): Declare `dump_node()` member function. (composite_node::dump_node): Implement. 2024-07-11 G. Branden Robinson * 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 * 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 * tmac/e.tmac: Add debugging advice for developers. Fixes . 2024-07-09 Bjarni Ingi Gislason [docs]: Fix doubled word typos. Fixes . 2024-07-09 Dave Kemper [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 . 2024-07-09 G. Branden Robinson 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 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 . Thanks to Bjarni Ingi Gislason for the report. 2024-07-09 G. Branden Robinson * 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 * doc/groff.texi.in (while): * man/groff_diff.7.man (New requests) : Point out that the `slimit` register can be used to _lower_ the formatter's internal stack size limit as well. Fixes . Thanks to Bjarni Ingi Gislason for the report and Dave Kemper for the suggestion. 2024-07-06 G. Branden Robinson * tmac/an-ext.tmac (SY): Drop unnecessary `do` request. 2024-06-28 Dave Kemper * doc/groff.texi.in: Drop relict macro call in example. Fixes . 2024-06-23 G. Branden Robinson * 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 * 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 [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 . Thanks to Morten Bo Johansen for reporting this issue. 2024-06-21 G. Branden Robinson * 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 [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 [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 [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 * src/roff/troff/mtsm.cpp (mtsm::inherit): Fix failing test. 2024-06-20 G. Branden Robinson 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 . 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 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 * src/utils/grog/grog.pl (do_line): Recognize new `pline` request forthcoming in groff 1.24 release. 2024-06-10 G. Branden Robinson * 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 * src/roff/troff/input.cpp (token::next, interpolate_arg): Tighten up null-terminated string traversal. 2024-06-05 G. Branden Robinson [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 . 2024-06-05 G. Branden Robinson [ms]: Fix Savannah #64005 (again). * tmac/s.tmac (bp): Fix thinko swapping the normal and no-break control characters. Fixes . Thanks to Deri James for catching this misbehavior. 2024-06-05 G. Branden Robinson [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 * tmac/doc.tmac: Drop nilpotent junk from end of file. Fixes . Thanks to Bjarni Ingi Gislason for the report. 2024-06-04 G. Branden Robinson * m4/groff.m4 (GROFF_WCOREFLAG): Use `AC_LANG_PROGRAM` more idiomatically; stop explicitly defining `main()`. Reportedly resolves implicit function declaration warnings from Clang. Fixes . Thanks to Eli Schwartz for the report. 2024-06-04 G. Branden Robinson * src/roff/troff/input.cpp (interpolate_arg): Stop embedding unprintable input characters in messages diagnosing invalid syntax. See and follow-ups. 2024-05-16 G. Branden Robinson * 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 * src/roff/troff/node.cpp (dbreak_node::dump_node): Drop extraneous space from output. 2024-05-25 Deri James [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 [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 [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 [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 * tmac/an.tmac (EE): Define macro with `de1` request, not `de`. Fixes . Thanks to Bjarni Ingi Gislason for the report. Problem introduced by me in commit 15f8188656, 21 February 2022. 2024-05-11 G. Branden Robinson [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 . Thanks to Dave Kemper for the report, and to him, Peter Schaffter, and Deri James for the discussion. 2024-05-11 G. Branden Robinson 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 . 2024-05-09 G. Branden Robinson * 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 * 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 * 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 . Thanks to Bjarni Ingi Gislason for the report. 2024-05-08 G. Branden Robinson * 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 * 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 * 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 * tmac/an-ext.tmac (YS): Clear `mS` register unconditionally. 2024-05-06 G. Branden Robinson * 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 * 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 * src/roff/troff/env.cpp (environment::print_env): Fix typo in environment report. 2024-05-04 G. Branden Robinson * 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 * 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 [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 [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 * 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 [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 * 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 * 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 * 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 * 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 [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 * 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 * 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 * 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 * 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 * 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 [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 [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 parameter 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 [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 [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 [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 * 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 * 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 * 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 [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 * tmac/an-ext.tmac (mQ): Remove `mU` string once unneeded. 2024-04-24 Deri James [gropdf] ignore 'Cspace' as input * src/devices/gropdf/gropdf.pl: As grops does. 2024-04-24 Deri James [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 [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 * tmac/tmac.am ($(M4CHECK)): Ensure directory exists to house the stamp file before attempting to create the latter. 2024-04-17 Deri James [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 [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 [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 * tmac/an-ext.tmac : Trivially refactor. Rename string used to store URI hyperlink from `m1` to `mU`. 2024-04-15 G. Branden Robinson * 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 [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 . Thanks to Paul Eggert for the report. 2024-04-05 G. Branden Robinson * 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 . 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 [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 * 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 * src/roff/troff/input.cpp: Refactor. Replace bespoke class `bool_stack` with STL `stack`. 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 * 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 * 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 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 . 2024-04-12 Deri James 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 afmtodit.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 * 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 [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) : * NEWS: Document this. See, e.g., . 2024-03-24 G. Branden Robinson * 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 [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 * 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 * 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 [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 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 . 2024-03-23 G. Branden Robinson [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 . 2024-03-22 G. Branden Robinson * 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 * src/preproc/eqn/main.cpp (main): Fix missing space in diagnostic message. 2024-03-20 G. Branden Robinson * 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 * 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 * 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 * 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) : 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 * 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 * 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 . 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 [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 * 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 * 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 . Thanks to Thomas Dickey for the report. 2024-03-16 G. Branden Robinson * tmac/tests/an_inner-footer-abbreviation-works.sh: Add regression test case for Savannah #65469. 2024-03-16 G. Branden Robinson [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 unnecessary 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 , 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 * 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 * 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 [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 . * 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 * 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 [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 [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 * 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 [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 . Thanks to Alex Colomar for the report. 2024-03-15 G. Branden Robinson [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 [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 . 2024-03-15 G. Branden Robinson [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 . Thanks to Russ Allbery for the report. 2024-03-15 G. Branden Robinson [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 * 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 [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 (at long last). 2024-03-12 G. Branden Robinson [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 [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 [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 * 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 * 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 * 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 * src/roff/troff/input.cpp: Trivially refactor. (do_special): Rename this... (do_device_control): ...to this. 2024-03-07 G. Branden Robinson * 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 * 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 and follow-up discussion there. Fixes . Thanks to an anonymous submitter for the report. 2024-03-04 G. Branden Robinson * tmac/pdf.tmac (pdf*href): Fix (harmless?) `ie`/`if` thinko. 2024-03-04 G. Branden Robinson [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 * doc/GMPfront.t.in: Resync `MR` replacement with its counterpart in "an.tmac". 2024-03-04 G. Branden Robinson * tmac/pdf.tmac (pdf*href): Fix excess escaping. 2024-03-04 G. Branden Robinson * 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 [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 * 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 [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) : Update macro synopsis and description. 2024-03-03 G. Branden Robinson * 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 * 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 * tmac/an.tmac (SH): Fix code style nit. 2024-03-03 G. Branden Robinson * 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 * 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 * tmac/doc.tmac (Xr): Fix dead store to string. 2024-03-01 G. Branden Robinson * NEWS: * doc/groff.texi.in: * man/groff.7.man: * man/groff_diff.7.man: Document new `hydefault` feature. Fixes . 2024-03-01 G. Branden Robinson [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 * src/roff/troff/env.cpp (hyphenate_request): If given no argument, set hyphenation mode to the configured default. 2024-03-01 G. Branden Robinson [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 * 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 * 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 [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 * 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 * 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++ preprocessor 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 * src/roff/troff/env.cpp (environment::print_env): Report environment's numeric hyphenation mode, not just its meaning. 2024-03-01 G. Branden Robinson [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 [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 and follow-ups. 2024-02-25 G. Branden Robinson [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: " 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 * tmac/tests/doc_Xr-works.sh: Add checks of inline `Pf` and `Ns` call behavior after `Xr`. 2024-02-25 G. Branden Robinson * 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 [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 * tmac/tests/doc_Xr-works.sh: Unit-test `Xr` macro. * tmac/tmac.am (tmac_TESTS): Run test. 2024-02-21 G. Branden Robinson * 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 * 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 * 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 * 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 [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 [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 * 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 * src/preproc/eqn/main.cpp: This file includes header . As part of the C++ standard library, provides a bunch of stuff, including `atexit()`, in the global name space; it need not provide that stuff in the `std` name space. See . 2024-02-17 G. Branden Robinson * 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 . Thanks to Deri James for the report. 2024-02-17 G. Branden Robinson [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 * 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 * 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 * 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 * 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 * tmac/pdf.tmac (pdfbookmark): Drop unused register storing computed length of `pdf:clean` string, `pdf:clean:len`. 2024-02-17 G. Branden Robinson * src/roff/troff/input.cpp (do_define_string, length_request): Drop redundant diagnostic message on invalid string identifiers. 2024-02-16 G. Branden Robinson [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 [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 [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 . 2024-02-08 G. Branden Robinson 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. 2024-02-04 G. Branden Robinson 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 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 * doc/doc.am (doc/groff-man-pages.pdf): Add dependency on "pdfmom". 2024-02-03 G. Branden Robinson * 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 * 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 * src/roff/troff/env.cpp (print_hyphenation_exceptions): Flush the standard error stream once the list is written. 2024-02-02 G. Branden Robinson [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 [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 . 2024-02-01 G. Branden Robinson * 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 * 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 * 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 * 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 * 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 * 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 * tmac/tests/an_TP-works.sh: Add unit test. * tmac/tmac.am (tmac_TESTS): Run test. 2024-02-01 G. Branden Robinson * 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 * 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 * 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 * 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 [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 * 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 * 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 * doc/doc.am (DOCFILES_INST): Ship "GMPfront.t" in the distribution archive. 2024-01-31 G. Branden Robinson * 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 . 2024-01-30 G. Branden Robinson * 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 . 2024-01-30 G. Branden Robinson * 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 * doc/doc.am (doc/groff-man-pages.pdf): Register dependency on "doc/GMPfront.t". 2024-01-30 G. Branden Robinson * tmac/an.tmac (MR): Support hyperlinked man page cross references in PDF. Fixes . 2024-01-30 G. Branden Robinson * src/preproc/tbl/table.cpp (table::add_entry): Recast recently added diagnostic message. 2024-01-26 Deri James 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 (pdfmom needs `--help` option). 2024-01-29 G. Branden Robinson [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 . 2024-01-29 G. Branden Robinson [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 . Thanks to the anonymous submitter for a reproducing case and a correct suggestion of the offending commit. 2024-01-29 G. Branden Robinson [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 [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 * tmac/an.tmac (MT, ME, UR, UE): Throw warnings on bad nesting. 2024-01-28 G. Branden Robinson * tmac/an.tmac (an*begin-hyperlink): Repair damage I introduced in commit 6f12a82806, 27 January. 2024-01-28 G. Branden Robinson * 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 . 2024-01-28 G. Branden Robinson * 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 * tmac/tests/doc_Lk-works.sh: Add unit test. * tmac/tmac.am (tmac_TESTS): Run test. 2024-01-28 G. Branden Robinson * tmac/doc.tmac (Mt, Lk): Validate arguments. 2024-01-28 G. Branden Robinson * tmac/tests/doc_Mt-works.sh: Test "direct" `Mt` call. 2024-01-27 G. Branden Robinson * 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 * 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 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 . 2024-01-25 G. Branden Robinson [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 * doc/groff.texi: Resolve warnings thrown by Texinfo 7.1. Fixes . Thanks to Bjarni Ingi Gislason for the report. 2024-01-23 G. Branden Robinson [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 * doc/doc.am (doc/webpage.ms): Register dependency on "tmac/pspic.tmac". 2024-01-17 G. Branden Robinson * 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 . 2024-01-17 G. Branden Robinson [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 * 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 * 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 [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 [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 [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 * 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 * 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 [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 [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 [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 . 2024-01-08 G. Branden Robinson * 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 [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 [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 [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 [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 [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 [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 * 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 * 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 [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 * 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 [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 . Thanks to Deri James, Dave Kemper, and Peter Schaffter for the discussion. 2024-01-05 G. Branden Robinson [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 [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 * src/roff/troff/node.cpp (make_glyph_node): Trivially refactor; Boolify local variable. 2024-01-04 Deri James font/devpdf/Foundry.in: Fix Savannah #65115. * font/devpdf/Foundry.in: Fix BMI, BMR mapping swap. Fixes . Thanks to Bjarni Ingi Gislason for the report. 2024-01-04 Deri James [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 . 2024-01-04 G. Branden Robinson * src/utils/grog/grog.pl: Trivially refactor; simplify code. 2024-01-03 G. Branden Robinson * 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 * 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 [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 [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 . 2024-01-03 G. Branden Robinson * src/devices/gropdf/gropdf.pl: Report only "basename" of program name in diagnostic messages. Fixes . Thanks to Dave Kemper for the code review. 2024-01-03 Deri James [gropdf]: Add `pdfpagenumbering` macro. * tmac/pdf.tmac: Do it. * src/devices/gropdf/gropdf.1.man: Document it. 2024-01-03 G. Branden Robinson 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 [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 * src/preproc/tbl/tbl.1.man (roff interface): Fix incorrect claim regarding `#T` register. 2024-01-02 G. Branden Robinson [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 * 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 [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 [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 . 2023-12-29 G. Branden Robinson [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 * 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 * 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 [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 . Thanks to Bjarni Ingi Gislason for the report. 2023-12-10 Deri James [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 [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 * src/devices/grotty/tty.cpp (tty_printer::end_page): Add `assert()` to check invariant. 2023-12-29 G. Branden Robinson * 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 * 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 * 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 [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 * 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 [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 [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 [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 . 2023-12-27 G. Branden Robinson 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 * 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 [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 * 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 * 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 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 . 2023-12-07 G. Branden Robinson * 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 * 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 [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 * src/roff/troff/node.cpp (select_underline_font) (set_font_specific_special_fonts): Tweak diagnostic messages. 2023-12-02 G. Branden Robinson * 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 [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 . 2023-12-01 G. Branden Robinson * doc/groff.texi: Fix typos. Fixes . Thanks to Bjarni Ingi Gislason for the report. 2023-11-29 G. Branden Robinson [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 diagnostic. (associate_style_with_font_position): Throw warning in category `missing` if given only one argument. 2023-11-29 G. Branden Robinson [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 * 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 * 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 * 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 * 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 diagnostic when no character arguments are present. 2023-11-27 G. Branden Robinson * doc/groff.texi (Miscellaneous): Clarify behavior of `mc`. Fixes . Thanks to Bjarni Ingi Gislason for the report. 2023-11-27 G. Branden Robinson * src/preproc/html/pre-html.cpp (makeTempFiles): Stop explicitly specifying parameters redundantly with their default values. 2023-11-27 G. Branden Robinson [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 [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 [build]: In source files that #include , ensure that we #include 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 . Also see . Thanks to Mike Fulton for the report. 2023-11-14 G. Branden Robinson * src/roff/troff/number.cpp: Rename some enumeration constants. - `BAD` -> `INVALID` - `ABSOLUTE` -> `ASSIGN` 2023-11-13 G. Branden Robinson [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 * src/roff/troff/number.cpp (is_valid_expression): Boolify and rename local variable from `overflow` to `had_overflow`. 2023-11-09 Paul Eggert [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 . Problem introduced by me in commit 4fad0459bb, 2022-01-05. -- GBR, 2023-11-10} 2023-11-10 G. Branden Robinson * src/roff/troff/input.cpp (device_request, output_request): Throw warning diagnostic if no arguments given. 2023-11-06 Pim * 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 . Thanks to Damian McGuckin for reporting this problem on the groff mailing list. 2023-11-06 G. Branden Robinson * src/roff/troff/node.cpp (embolden_font): Do nothing if in nroff mode. Fixes . 2023-11-06 G. Branden Robinson * 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 [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 * 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 [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 [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 and 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 * 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 * 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 * 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 * 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 * 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 * 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 . Thanks to Bjarni Ingi Gislason for the report. 2023-11-03 G. Branden Robinson * 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 * 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 . 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 * 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 * 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 . Thanks to an anonymous bug submitter for the report and the patch. 2023-10-13 G. Branden Robinson * 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 * 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 * src/roff/troff/input.cpp (while_break_request) (while_continue_request): Clarify diagnostic messages. 2023-10-07 G. Branden Robinson [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 [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 [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 * 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 * 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 * 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 [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 [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 . 2023-09-25 G. Branden Robinson [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 * 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 . Thanks to Bjarni Ingi Gislason for the report. 2023-09-25 G. Branden Robinson [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 . Thanks to Dave Kemper for the report and testing this code change. 2023-09-22 G. Branden Robinson * doc/doc.am (doc/meintro_fr.ps): Depend on tbl, resolving race in sufficiently parallelized builds. Overlooked in commit 92349ae223, 2022-05-30. Fixes . Thanks to Alexander Kanavin for the report. 2023-09-16 G. Branden Robinson * 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 . Thanks to Alexander Kanavin for the report. 2023-09-15 G. Branden Robinson * 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 [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 * 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 [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 * 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 * 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 * 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 [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 [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 * tmac/doc.tmac (doc-str-Ar-default): Use unbreakable space between "file" and ellipsis. 2023-09-06 G. Branden Robinson * 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 [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 uninitialized. Problem appears to date back to commit ea5a42d080, 2002-01-24. Fixes . 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 [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 * 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 [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 . 2023-09-03 G. Branden Robinson * 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 * src/devices/grotty/tests/osc8_works.sh: Port test to newer conventions. 2023-09-01 G. Branden Robinson [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 [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 * tmac/tests/localization-works.sh: Test hyphenation modes for Spanish and Russian. 2023-08-31 G. Branden Robinson * 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 [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 [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 [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 * 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 * 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 * src/roff/troff/node.cpp (translate_font): Validate arguments. 2023-08-27 G. Branden Robinson [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 [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 * src/preproc/eqn/main.cpp (main): Trivially refactor; demote `int` `load_startup_file` to Boolean `want_startup_file`. 2023-08-25 G. Branden Robinson [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 . 2023-08-24 G. Branden Robinson * 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 [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 * doc/pic.ms: Document `PY` macro, new to groff 1.23.0. Fixes . 2023-08-22 Dave Kemper * 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 * 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 . 2023-08-21 G. Branden Robinson * 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 * 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 . 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 * src/roff/troff/node.cpp (class tfont_spec): Stop declaring copy constructor. The implicitly defined one suffices. Resolves "-Wdeprecated-copy" warning from GCC. Fixes . Thanks to Bjarni Ingi Gislason for the report. 2023-08-16 G. Branden Robinson * 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. 2023-08-12 G. Branden Robinson 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 * src/utils/indxbib/indxbib.am (install_indxbib): Use `$(LN_S)`, not `ln -s`. 2023-08-11 G. Branden Robinson [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 [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 . Thanks to Alex Colomar for the report. 2023-08-09 G. Branden Robinson [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 . Thanks to Thorsten Glaser and Ingo Schwarze for the discussion. 2023-08-05 G. Branden Robinson [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 [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 [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 * 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 [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 a.k.a. Debian #1038391. Thanks to наб for the report and a good test case. 2023-08-04 G. Branden Robinson [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 [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 . 2023-08-03 G. Branden Robinson * src/roff/troff/node.cpp (zoom_font): Validate arguments more. Invalid inputs could have bizarre consequences. Fixes . 2023-08-02 G. Branden Robinson 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 * 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 * 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 . Thanks to Bjarni Ingi Gislason for the report. 2023-07-29 G. Branden Robinson * 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 . Thanks to Bjarni Ingi Gislason for the report. 2023-07-28 G. Branden Robinson [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 * 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 [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 . Thanks to Dave Kemper for feedback. 2023-07-21 G. Branden Robinson * src/roff/troff/node.cpp (unbreakable_space_node::tprint): Write word marker ('w' command) to output. * NEWS: Add item. Fixes . 2023-07-21 G. Branden Robinson * 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 * 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 [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) : Sync. Fixes . Thanks to Dave Kemper for the report and review. 2023-07-25 G. Branden Robinson * 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 * 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 [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 [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 [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 . 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 * 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 . 2023-07-16 G. Branden Robinson * 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 * 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 nevertheless 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 * 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 * 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 [eqn]: Clarify diagnostic message. * src/preproc/eqn/lex.cpp (do_delim): Do it. Thanks to Doug McIlroy for the report . 2023-06-23 G. Branden Robinson [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 [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 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) : : * src/devices/xditview/Dvi.c (ClassInitialize): * src/include/symbol.h (class symbol) : * 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 * src/roff/troff/env.cpp (font_change): Trivially refactor. Simplify conditionals. 2023-05-30 G. Branden Robinson [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 [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 * 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 * 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) : * man/groff.7.man (Request short reference) : Document this change. * NEWS: Add item. 2023-05-19 G. Branden Robinson [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 * 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 * 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 * 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 [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 "  " entity instead of " ". * src/preproc/eqn/eqn.1.man (Customization): Document feature. * NEWS: Add item. Fixes . Thanks to Doug McIlroy for the report and Damian McGuckin for the discussion. 2023-05-19 G. Branden Robinson [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 [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 * src/roff/troff/hvunits.h: Boolify. (class vunits, class hunits, vunits::is_zero, hunits::is_zero): Do it. 2023-05-13 G. Branden Robinson * 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 * 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 [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 * 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 [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 [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 [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 [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 [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 [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 [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 * src/include/lf.h (interpret_lf_args): * src/libs/libgroff/lf.cpp (interpret_lf_args): Boolify. 2023-04-28 G. Branden Robinson [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 [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 [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 [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 . Thanks to Damian McGuckin, Doug McIlroy, and Ralph Corderoy for support and suggestions. 2023-04-07 G. Branden Robinson * 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 * 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 [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 * 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 * src/roff/troff/input.cpp (temp_iterator::temp_iterator): Skip allocation of zero-length arrays. Resolves "-Walloc-zero" warning from GCC. Fixes . Thanks to Bjarni Ingi Gislason for the report. 2023-04-02 G. Branden Robinson * 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 * 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 [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 [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) : (format::format) : (format::add_rows) : (format::~format) : (struct input_entry_format) : (input_entry_format::input_entry_format) : (input_entry_format::debug_print) : (process_format) : (process_data) ([anonymous] enum) : * src/preproc/tbl/table.cpp: * src/preproc/tbl/table.h (enum format_type) (class table) , add_single_hline, add_double_hline, add_vlines, print_single_hline, print_double_hline: Rename these... * src/preproc/tbl/main.cpp (struct format) : (format::format) : (format::add_rows) : (format::~format) : (struct input_entry_format) : (input_entry_format::input_entry_format) : (input_entry_format::debug_print) : (process_format) : (process_data) ([anonymous] enum) : * src/preproc/tbl/table.cpp: * src/preproc/tbl/table.h (enum format_type) (class table) , add_single_hrule, add_double_hrule, add_vrules, print_single_hrule, print_double_hrule: ...to these. 2023-02-25 G. Branden Robinson [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 . Thanks to the mandoc(1) project for documenting the issue in a regression test. 2023-04-16 G. Branden Robinson [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 * 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 . Thanks to Brian Inglis for the report. 2023-05-13 G. Branden Robinson [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 . Thanks to Deri James for the report. 2023-05-01 G. Branden Robinson [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 [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 [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 * 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 . 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 [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 * 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 [tests]: Add Spanish language support (5/5). * src/roff/groff/tests/localization_works.sh: * tmac/tests/e_ld-works.sh: Test it. Fixes . Thanks to Eloi Montañés. 2023-03-13 G. Branden Robinson [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 [tmac]: Add Spanish language support (3/5). * tmac/hyphen.es: * tmac/es.tmac: Update editor aids. 2023-03-13 G. Branden Robinson [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 [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 [tests]: Add Russian language support (7/7). * src/roff/groff/tests/localization_works.sh: * tmac/tests/e_ld-works.sh: Test it. Fixes . Thanks to Nikita Ivanov. 2023-03-08 G. Branden Robinson [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 [tmac]: Add Russian language support (5/7). * tmac/tmac.am (TMACNORMALFILES): Ship new Russian language support files. 2023-03-08 G. Branden Robinson [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 [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 Add Russian language support (2/7). LICENSES: Update for CTAN Russian hyphenation patterns. 2023-03-08 Nikita Ivanov [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 * 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 [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 . 2023-04-07 G. Branden Robinson [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 [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 . Thanks to Michał Kruszewski for reporting the problem and Dave Kemper for identifying the cause. 2023-04-05 G. Branden Robinson [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 * 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 . Thanks to Alex Colomar for reporting an issue that brought this one to light. 2023-03-24 G. Branden Robinson [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 * 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 . 2023-05-13 G. Branden Robinson * tmac/tests/an-ext_SY-and-YS-work.sh: Add test. * tmac/tmac.am (tmac_TESTS): Run test. 2023-04-28 G. Branden Robinson [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 [doc]: Abstract document dependencies on the mom package. * doc/doc.am (doc/automake.pdf): Replace dependency with new macro `TMAC_PACKAGE_MOM`. Aligns with (4/4). 2023-04-03 G. Branden Robinson [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 (2/4). 2023-04-03 G. Branden Robinson [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 (1/4). 2023-04-03 G. Branden Robinson [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 [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 [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 m4/groff.m4 (GROFF_TMAC): Eliminate garbage leading space from contents of `tmac_wrap` shell variable. 2023-03-13 G. Branden Robinson [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 receiving 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 . 2023-03-11 G. Branden Robinson * 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 , later reported anonymously. 2023-03-10 G. Branden Robinson * doc/doc.am (maintainer-clean-local): Remove temporary "*.t2d" and "*.t2p" directories created by texi2dvi. 2023-04-20 Bruno Haible [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 . --GBR, 2023-07-10} 2023-04-20 G. Branden Robinson * 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 * 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 [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 . ________________________________________________________________________ ##### 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: