Follow-up Comment #7, bug #64285 (project groff): I haven't pushed this to my private branch, but I did push a set of unit tests for all the drawing commands.
Here's what I have at present in my working copy for this ticket. Find some preparatory commits first. These are in fact the first commits I have queued after `branden-2023-07-05`. Deri, do you find this to be more complete? commit be20c8f61fd0e5529b0a60821ac0f043ef918d0f Author: G. Branden Robinson <g.branden.robin...@gmail.com> AuthorDate: Thu Jun 8 19:46:29 2023 -0500 Commit: G. Branden Robinson <g.branden.robin...@gmail.com> CommitDate: Wed Jul 5 15:57:37 2023 -0500 [troff]: Slightly refactor. * src/roff/troff/node.cpp (troff_output_file::determine_line_limits): Slightly refactor. Stop repeating code. Add new Boolean, `do_generic_limit_check`, defaulting true. In the switch that handles various drawing commands, set it false for those that perform specialized output limit checks. Explicitly handle 'f' drawing command (though it has been deprecated since groff 1.19 in 2003). Tested with ./build/test-groff -pet -ms -Z doc/pic.ms ./build/test-groff -M ./doc -ge -me -Z doc/grnexmpl.me before and after. No change. diff --git a/ChangeLog b/ChangeLog index 447d530c7..a53763d0b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,16 @@ * src/roff/groff/groff.am (groff_TESTS): Run tests. +2023-06-08 G. Branden Robinson <g.branden.robin...@gmail.com> + + * src/roff/troff/node.cpp + (troff_output_file::determine_line_limits): Slightly refactor. + Stop repeating code. Add new Boolean, `do_generic_limit_check`, + defaulting true. In the switch that handles various drawing + commands, set it false for those that perform specialized output + limit checks. Explicitly handle 'f' drawing command (though it + has been deprecated since groff 1.19 in 2003). + 2023-06-08 G. Branden Robinson <g.branden.robin...@gmail.com> [man, mdoc]: Parameterize page offset. diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp index 4d872189e..e2bbcfa9e 100644 --- a/src/roff/troff/node.cpp +++ b/src/roff/troff/node.cpp @@ -1373,6 +1373,7 @@ void troff_output_file::determine_line_limits(char code, hvpair *point, int npoints) { int i, x, y; + bool do_generic_limit_check = true; if (!is_on()) return; @@ -1385,6 +1386,7 @@ void troff_output_file::determine_line_limits(char code, hvpair *point, output_vpos - point[0].h.to_units()/2); check_output_limits(output_hpos + point[0].h.to_units(), output_vpos + point[0].h.to_units()/2); + do_generic_limit_check = false; break; case 'E': case 'e': @@ -1392,6 +1394,7 @@ void troff_output_file::determine_line_limits(char code, hvpair *point, output_vpos - point[0].v.to_units()/2); check_output_limits(output_hpos + point[0].h.to_units(), output_vpos + point[0].v.to_units()/2); + do_generic_limit_check = false; break; case 'P': case 'p': @@ -1403,15 +1406,9 @@ void troff_output_file::determine_line_limits(char code, hvpair *point, y += point[i].v.to_units(); check_output_limits(x, y); } + do_generic_limit_check = false; break; case 't': - x = output_hpos; - y = output_vpos; - for (i = 0; i < npoints; i++) { - x += point[i].h.to_units(); - y += point[i].v.to_units(); - check_output_limits(x, y); - } break; case 'a': double c[2]; @@ -1434,16 +1431,13 @@ void troff_output_file::determine_line_limits(char code, hvpair *point, } // fall through case 'l': - x = output_hpos; - y = output_vpos; - check_output_limits(x, y); - for (i = 0; i < npoints; i++) { - x += point[i].h.to_units(); - y += point[i].v.to_units(); - check_output_limits(x, y); - } + case 'f': // deprecated in groff 1.19 break; default: + break; + } + + if (do_generic_limit_check) { x = output_hpos; y = output_vpos; for (i = 0; i < npoints; i++) { commit 2096210e7a301b4b2b727c9bc24382ececf14ba3 Author: G. Branden Robinson <g.branden.robin...@gmail.com> AuthorDate: Thu Jun 8 20:11:09 2023 -0500 Commit: G. Branden Robinson <g.branden.robin...@gmail.com> CommitDate: Wed Jul 5 15:57:37 2023 -0500 [troff]: Refactor to clarify. * src/roff/troff/node.cpp (troff_output_file::determine_line_limits): Make the 'l', 't', and '~' commands (more clearly) use the generic output limit check. More clearly make the 'a' command not use it. Tested with ./build/test-groff -pet -ms -Z doc/pic.ms ./build/test-groff -M ./doc -ge -me -Z doc/grnexmpl.me before and after. No change. diff --git a/ChangeLog b/ChangeLog index a53763d0b..c113ff858 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,13 @@ * src/roff/groff/groff.am (groff_TESTS): Run tests. +2023-06-08 G. Branden Robinson <g.branden.robin...@gmail.com> + + * src/roff/troff/node.cpp + (troff_output_file::determine_line_limits): Make the 'l', 't', + and '~' commands (more clearly) use the generic output limit + check. More clearly make the 'a' command not use it. + 2023-06-08 G. Branden Robinson <g.branden.robin...@gmail.com> * src/roff/troff/node.cpp diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp index e2bbcfa9e..9a0b23a93 100644 --- a/src/roff/troff/node.cpp +++ b/src/roff/troff/node.cpp @@ -1408,8 +1408,6 @@ void troff_output_file::determine_line_limits(char code, hvpair *point, } do_generic_limit_check = false; break; - case 't': - break; case 'a': double c[2]; int p[4]; @@ -1427,10 +1425,11 @@ void troff_output_file::determine_line_limits(char code, hvpair *point, &minx, &maxx, &miny, &maxy); check_output_limits(minx, miny); check_output_limits(maxx, maxy); - break; } - // fall through + break; case 'l': + case 't': + case '~': case 'f': // deprecated in groff 1.19 break; default: commit bc4802369a01dfeaecfba0a474b68bcf11f76330 Author: G. Branden Robinson <g.branden.robin...@gmail.com> AuthorDate: Thu Jun 8 23:31:26 2023 -0500 Commit: G. Branden Robinson <g.branden.robin...@gmail.com> CommitDate: Wed Jul 5 15:57:37 2023 -0500 [troff]: Warn on unrecognized drawing command. * src/roff/troff/node.cpp (troff_output_file::determine_line_limits): Throw syntax warning if an unrecognized drawing command is encountered; it is not ignored, but does use the generic output limit check. * doc/groff.texi (Drawing Geometric Objects): * man/groff.7.man (Drawing commands): Document handling of unrecognized drawing commands. * doc/groff.texi (Warnings): * src/roff/troff/troff.1.man (Warnings): Document new use of "syntax" warning category. diff --git a/ChangeLog b/ChangeLog index c113ff858..de9715348 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,13 @@ * src/roff/groff/groff.am (groff_TESTS): Run tests. +2023-06-08 G. Branden Robinson <g.branden.robin...@gmail.com> + + * src/roff/troff/node.cpp + (troff_output_file::determine_line_limits): Throw syntax warning + if an unrecognized drawing command is encountered; it is not + ignored, but does use the generic output limit check. + 2023-06-08 G. Branden Robinson <g.branden.robin...@gmail.com> * src/roff/troff/node.cpp diff --git a/doc/groff.texi b/doc/groff.texi index 2d5841d8c..37a25e8b4 100644 --- a/doc/groff.texi +++ b/doc/groff.texi @@ -14239,6 +14239,14 @@ @node Drawing Geometric Objects default. @end table @endDefesc + +Unrecognized drawing commands cause GNU @code{troff} to emit a warning +in the @code{syntax} category, but are still sent to the output device +to support device-specific extensions. Such commands are assumed to +update the drawing position to the final coordinate pair in their +argument list. To override this assumption, wrap such a drawing command +escape sequence with the @code{\Z} escape sequence. @xref{Page +Motions}. @c END Keep (roughly) parallel with subsection "Drawing commands" of @c groff(7). @@ -16897,8 +16905,9 @@ @node Warnings A self-contradictory hyphenation mode was requested; an empty or incomplete numeric expression was encountered; an operand to a numeric operator was missing; an attempt was made to define a recursive, empty, -or nonsensical character class; or a @code{groff} extension conditional -expression operator was used while in compatibility mode. +or nonsensical character class; an unrecognized drawing command was +encountered; or a @code{groff} extension conditional expression operator +was used while in compatibility mode. @item di @itemx 256 diff --git a/man/groff.7.man b/man/groff.7.man index 8d8d9bbd0..80db157b7 100644 --- a/man/groff.7.man +++ b/man/groff.7.man @@ -5539,6 +5539,25 @@ .SS "Drawing commands" selects a thickness proportional to the type size; this is the default. .LE +. +. +.P +Unrecognized drawing commands cause GNU +.I troff \" GNU +to emit a warning in the +.B syntax +category, +but are still sent to the output device to support device-specific +extensions. +. +Such commands are assumed to update the drawing position to the final +coordinate pair in their argument list. +. +To override this assumption, +wrap such a drawing command escape sequence with the +.B \[rs]Z +escape sequence. +.\" @xref{Page Motions}. .\" END Keep (roughly) parallel with groff.texi node "Drawing .\" commands". . diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp index 9a0b23a93..f1b35017b 100644 --- a/src/roff/troff/node.cpp +++ b/src/roff/troff/node.cpp @@ -1433,6 +1433,7 @@ void troff_output_file::determine_line_limits(char code, hvpair *point, case 'f': // deprecated in groff 1.19 break; default: + warning(WARN_SYNTAX, "unrecognized drawing command '%1'", code); break; } diff --git a/src/roff/troff/troff.1.man b/src/roff/troff/troff.1.man index d83c4a515..03815da01 100644 --- a/src/roff/troff/troff.1.man +++ b/src/roff/troff/troff.1.man @@ -744,6 +744,7 @@ .SH Warnings an attempt was made to define a recursive, empty, or nonsensical character class; +an unrecognized drawing command was encountered; or a .I groff extension conditional expression operator was used while in commit 0578e5c6564e6b6860b1019f1526f1614518ae22 Author: G. Branden Robinson <g.branden.robin...@gmail.com> Date: Thu Jun 8 23:08:53 2023 -0500 [troff, grn, pic]: Fix Savannah #64285. * src/roff/troff/node.cpp (troff_output_file::determine_line_limits): Make 't' drawing command perform no limit check at all. The limit check had the side effect of updating the drawing position. Consequently... * src/preproc/grn/hgraph.cpp (HGSetBrush): * src/preproc/pic/troff.cpp (troff_output::line_thickness): Stop emitting horizontal motion escape sequences to offset the drawing position advancement side effect. Fixes <https://savannah.gnu.org/bugs/?64155>. Thanks to Steve Izma for the report, which came within 2 days of me removing the verbiage warning about this weird side effect from our Texinfo manual. Tested with ./build/test-groff -pet -ms -Z doc/pic.ms ./build/test-groff -M ./doc -ge -me -Z doc/grnexmpl.me before and after. This time there were differences, as we'd expect. Changes to pic-processed documents look like this: @@ -1905,7 +1905,6 @@ V301200 H97200 Dt -1000 0 -h1000 n12000 0 V319200 H97200 @@ -1927,7 +1926,6 @@ V301200 H97200 Dt 100 0 -H97200 n12000 0 V319200 H187200 Note the repeated absolute horizontal motion in the second hunk. In the first, a relative horizontal motion has gone entirely missing...but immediately prior to a line break documentary command and absolute motion in both axes. Changes to grn-processed documents look like this: @@ -235,7 +235,7 @@ H79600 n14400 0 V203400 -H72850 +H73600 Dt 750 0 n14400 0 V387862 @@ -347,7 +347,7 @@ DP 0 3385 -1692 0 -1692 -1692 1692 -1693 1692 0 n14400 0 V203400 -H73150 +H73600 Dt 450 0 n14400 0 V315093 Here, we see horizontal motions larger by exactly as much as the line thickness drawing commands formerly caused. Moreover, the only differences in PostScript output... ./build/test-groff -pet -ms doc/pic.ms ./build/test-groff -M ./doc -ge -me doc/grnexmpl.me ...are updates to the "CreationDate" comment. diff --git a/ChangeLog b/ChangeLog index de9715348..a4a5017f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,24 @@ * src/roff/groff/groff.am (groff_TESTS): Run tests. +2023-06-08 G. Branden Robinson <g.branden.robin...@gmail.com> + + [troff, grn, pic]: Fix Savannah #64285. + + * src/roff/troff/node.cpp + (troff_output_file::determine_line_limits): Make 't' drawing + command perform no limit check at all. The limit check had the + side effect of updating the drawing position. Consequently... + * src/preproc/grn/hgraph.cpp (HGSetBrush): + * src/preproc/pic/troff.cpp (troff_output::line_thickness): + Stop emitting horizontal motion escape sequences to offset the + drawing position advancement side effect. + + Fixes <https://savannah.gnu.org/bugs/?64155>. Thanks to Steve + Izma for the report, which came within 2 days of me removing the + verbiage warning about this weird side effect from our Texinfo + manual. + 2023-06-08 G. Branden Robinson <g.branden.robin...@gmail.com> * src/roff/troff/node.cpp diff --git a/src/preproc/grn/hgraph.cpp b/src/preproc/grn/hgraph.cpp index 9ed81a449..38fc83f8b 100644 --- a/src/preproc/grn/hgraph.cpp +++ b/src/preproc/grn/hgraph.cpp @@ -399,7 +399,7 @@ HGSetBrush(int mode) } if (linethickness != thick[mode]) { linethickness = thick[mode]; - printf("\\h'-%.2fp'\\D't %.2fp'", linethickness, linethickness); + printf("\\D't %.2fp'", linethickness); printed = 1; } if (printed) diff --git a/src/preproc/pic/troff.cpp b/src/preproc/pic/troff.cpp index 3dc87a721..00d244c84 100644 --- a/src/preproc/pic/troff.cpp +++ b/src/preproc/pic/troff.cpp @@ -475,7 +475,7 @@ void troff_output::line_thickness(double p) if (p < 0.0) p = RELATIVE_THICKNESS; if (driver_extension_flag && p != last_line_thickness) { - printf("\\D't %.3fp'\\h'%.3fp'\n.sp -1\n", p, -p); + printf("\\D't %.3fp'\n.sp -1\n", p); last_line_thickness = p; } } diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp index f1b35017b..43c75898d 100644 --- a/src/roff/troff/node.cpp +++ b/src/roff/troff/node.cpp @@ -1427,8 +1427,10 @@ void troff_output_file::determine_line_limits(char code, hvpair *point, check_output_limits(maxx, maxy); } break; - case 'l': case 't': + do_generic_limit_check = false; + break; + case 'l': case '~': case 'f': // deprecated in groff 1.19 break; _______________________________________________________ Reply to this item at: <https://savannah.gnu.org/bugs/?64285> _______________________________________________ Message sent via Savannah https://savannah.gnu.org/