From 036ac8053295dca0267097de75f41c28d201e07d Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Wed, 29 Apr 2026 21:04:42 +0100 Subject: [PATCH] groff: add patch reverting problematic commit from upstream The recent 50fca07b8e98d987eab929212651a9e004e959e7 bump from groff 1.23 to 1.24.1 caused a massive regression in performance when rendering big manpages, like `man 5 configuration.nix`. This was traced to some recent changes upstream to the continuous rendering mode, that triggered a dormant bug in the code. See: - https://savannah.gnu.org/bugs/?68145 - https://lists.gnu.org/archive/html/groff/2026-03/msg00087.html Sadly even applying the recent fixes upstream doesn't fix the issue completely. It seems that the previous behavior was to render the manpage continuously, while the new behavior tries to render the whole manpage in one go. So while the fixes helps, it is never going to recover the same performance as before the bump. So this is an alternative approach: revert the upstream patch that causes the issue, reverting to the previous rendering behavior. This will make the rendering fast regardless of the optimizations. Alternative for #514498. Fixes: #513348. --- .../0001-Revert-man-Fix-Savannah-65190.patch | 184 ++++++++++++++++++ pkgs/by-name/gr/groff/package.nix | 7 + 2 files changed, 191 insertions(+) create mode 100644 pkgs/by-name/gr/groff/0001-Revert-man-Fix-Savannah-65190.patch diff --git a/pkgs/by-name/gr/groff/0001-Revert-man-Fix-Savannah-65190.patch b/pkgs/by-name/gr/groff/0001-Revert-man-Fix-Savannah-65190.patch new file mode 100644 index 000000000000..8b9e1ed11ff1 --- /dev/null +++ b/pkgs/by-name/gr/groff/0001-Revert-man-Fix-Savannah-65190.patch @@ -0,0 +1,184 @@ +diff --git a/ChangeLog b/ChangeLog +index 29dfaab41..0e35e38c0 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -8410,35 +8410,6 @@ Version 1.24.0 released 2026-02-28 + + 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. +diff --git a/tmac/an.tmac b/tmac/an.tmac +index 9a885b120..68eea1793 100644 +--- a/tmac/an.tmac ++++ b/tmac/an.tmac +@@ -90,8 +90,22 @@ .de1 an-leading-space-trap + . nop \h'\\n[lss]u'\c + .. + . +-.de1 an*bp +-. if \\n[.br] .br ++.\" Define alternate requests to handle continuous rendering. ++.\" ++.\" This .ne replacement avoids page breaks; instead, the page length is ++.\" increased to the necessary amount. ++.de an-ne ++. ie \\n[.$] .nr an-amount (v;\\$*) ++. el .nr an-amount 1v ++. if (\\n[an-amount] >= \\n[.t]) \ ++. pl +(\\n[an-amount]u - \\n[.t]u + 1v) ++. rr an-amount ++.. ++. ++.\" This .bp replacement for continuous rendering mode adjusts the page ++.\" length to the current position so that no empty lines are inserted. ++.de an-bp ++. pl \\n[nl]u + .. + . + .\" We need an end-of-input macro to flush any pending output line and +@@ -102,11 +116,21 @@ .de1 an*end-document + . an*input-trap + . if '\\n[.z]'an*paragraph-tag' .an*TP-trap + . if \\n[cR] \{\ ++. \" We might have a pending output line that is not yet broken, and ++. \" also be 1v from the bottom of the page. If we break (or flush) ++. \" the output line now, the page will get ejected afterward and ++. \" troff will exit because we're in an end-of-input macro--our ++. \" footer will never be output. So, if that is the case, further ++. \" extend the page length by 1v. ++. if ((\\n[.p] - \\n[nl]) <= \\n[.V]) .pl +1v ++. br ++. pl +1v + . sp 1v + . an-footer + . \" If we're processing multiple documents and have started a new + . \" one, draw a line between this footer and the next header. + . if !'\\n[.F]'' \{\ ++. pl +1v + . nf + . ti 0 + . nr an*rule-length (\\n[LL]u - 1n) +@@ -119,11 +143,15 @@ .de1 an*end-document + . \} + . ds an*previous-page-ref-string \" empty + . ch an-header +-. \" At the end of the last document, the file name becomes empty; +-. \" force the page length to match the vertical drawing position in +-. \" continuous rendering mode. +-. ie \\n[cR] .if '\\n[.F]'' .pl \\n[nl]u +-. el .an*break-page-with-new-number ++. an*break-page-with-new-number ++.. ++. ++.\" Move macros into place for continuous rendering. ++.de an-set-up-continuous-rendering ++. rn ne an-real-ne ++. rn bp an-real-bp ++. rn an-ne ne ++. rn an-bp bp + .. + . + .de an*reset-text-parameters +@@ -336,7 +364,7 @@ .de1 TH + . \" Clear the page header trap so it is not sprung with stale + . \" information. + . ch an-header +-. if !\\n[cR] .an*break-page-with-new-number ++. an*break-page-with-new-number + . \} + . if \\n[C] .rr P + . +@@ -488,9 +516,13 @@ .de1 PD + .. + . + .\" Write the page header; can be redefined by man.local. ++.\" ++.\" In continuous rendering mode, we need to extend the page length to ++.\" accommodate the vertical size of our header (plus any spacing). + .if d PT .ig + .de1 PT +-. if !\\n[cR] .sp (.5i - .5m) ++. ie \\n[cR] .pl +1v ++. el .sp (.5i - .5m) + . \" Attach a bookmark to the page header on the first page of a new + . \" man(7) document; a changed identifier or section indicates this. + . if !'\\*[an*page-ref-string]'\\*[an*previous-page-ref-string]' \{\ +@@ -499,13 +531,17 @@ .de1 PT + . ds an*previous-page-ref-string "\\*[an*page-ref-string] + . \} + . tl '\\*[an-pageref]'\\*[an-extra3]'\\*[an-pageref]' +-. ie \\n[cR] .sp 1v +-. el .sp .5i ++. ie \\n[cR] \{\ ++. pl +1v ++. sp 1v ++. \} ++. el .sp .5i + .. + . + .\" Write the page footer; can be redefined by man.local. + .if d BT .ig + .de1 BT ++. if \\n[cR] .pl +1v + . ie \\n[D] \{\ + . if o .tl '\\*[an*ifoot]'\\*[an-extra1]'\\*[an*ofoot]' + . if e .tl '\\*[an*ofoot]'\\*[an-extra1]'\\*[an*ifoot]' +@@ -1793,13 +1829,8 @@ .de1 EN + .\} + .rm an*ident-style + . +-.\" In continuous rendering mode, make page breaks less potent and the +-.\" page length "infinite". +-.if \n[cR] \{\ +-. rn bp an*real-bp +-. rn an*bp bp +-. pl \n[.R]u/1v +-.\} ++.if \n[cR] \ ++. an-set-up-continuous-rendering + . + .\" If rendering HTML, suppress headers and footers. + .nr an-suppress-header-and-footer 0 +diff --git a/tmac/tmac.am b/tmac/tmac.am +index 6a5f5da8b..7412b84c6 100644 +--- a/tmac/tmac.am ++++ b/tmac/tmac.am +@@ -267,6 +267,7 @@ tmac_XFAIL_TESTS = \ + tmac/tests/an-ext_ME-punct-hyphenates.sh \ + tmac/tests/an-ext_UE-breaks-before-long-URIs.sh \ + tmac/tests/an-ext_UE-punct-hyphenates.sh \ ++ tmac/tests/an_report-useful-line-numbers-in-diagnostics.sh \ + tmac/tests/e_footnotes-work-with-columns.sh \ + tmac/tests/pdf_bookmark-starting-with-control-char-works.sh + XFAIL_TESTS += $(tmac_XFAIL_TESTS) diff --git a/pkgs/by-name/gr/groff/package.nix b/pkgs/by-name/gr/groff/package.nix index df39f833e3b3..19a99dead88e 100644 --- a/pkgs/by-name/gr/groff/package.nix +++ b/pkgs/by-name/gr/groff/package.nix @@ -44,6 +44,13 @@ stdenv.mkDerivation (finalAttrs: { hash = "sha256-dOKBl5W2r/QxrqyYPWOpyJaO6roqLrp9+LpMe0Hnz9g="; }; + patches = [ + # This revert a upstream refactor in continuous rendering mode, but this + # causes a big performance regression for big manpages like + # `man 5 configuration.nix`. + ./0001-Revert-man-Fix-Savannah-65190.patch + ]; + outputs = [ "out" "man"