Background: https://savannah.gnu.org/bugs/index.php?64212
Now's a good time to tell me if this is a bad idea. :P The idea is to make it easier to debug issues like the following. https://savannah.gnu.org/bugs/index.php?56499 https://savannah.gnu.org/bugs/index.php?58447 Here's the patch. commit 0ccb60f70e3f6bf2355663a389f8e83af53c8c52 Author: G. Branden Robinson <g.branden.robin...@gmail.com> Date: Wed Jul 26 02:58:27 2023 -0500 [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 Localization Traps): * man/groff.7.man (Read-only registers): * man/groff_diff.7.man (New registers): Document it. * src/roff/groff/tests/dot-trap_register_works.sh: Test it. * src/roff/groff/groff.am (groff_TESTS): Run test. * NEWS: Add item. Fixes <https://savannah.gnu.org/bugs/?64212>. Thanks to Dave Kemper for feedback. diff --git a/ChangeLog b/ChangeLog index a184500e1..d5311f09c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +2023-07-26 G. Branden Robinson <g.branden.robin...@gmail.com> + + [troff]: Add new `.trap` built-in register. + + * src/roff/troff/div.h (class diversion, class macro_diversion, + class top_level_diversion): Declare new member function + `get_next_trap_name`. + * src/roff/troff/div.cpp (macro_diversion::get_next_trap_name): + New member function returns name of diversion trap if any, and + if its position is greater than the vertical drawing position, + otherwise an empty string. + (top_level_diversion::get_next_trap_name): New member function + returns the name of the next vertical position trap, if any, + otherwise an empty string. + (class next_trap_name_reg): New class has one member, a + `get_string()` function. + (next_trap_name_reg::get_string): New function. + (init_div_requests): Add `.trap` to the register dictionary and + wire it up to `next_trap_name_reg`. + + * doc/groff.texi (Page Localization Traps): + * man/groff.7.man (Read-only registers): + * man/groff_diff.7.man (New registers): Document it. + + * src/roff/groff/tests/dot-trap_register_works.sh: Test it. + * src/roff/groff/groff.am (groff_TESTS): Run test. + + * NEWS: Add item. + + Fixes <https://savannah.gnu.org/bugs/?64212>. Thanks to Dave + Kemper for feedback. + 2023-07-21 G. Branden Robinson <g.branden.robin...@gmail.com> * src/roff/troff/node.cpp (unbreakable_space_node::tprint): diff --git a/NEWS b/NEWS index 92a895cf2..0bd1348f5 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,9 @@ o GNU troff output now reports unbreakable spaces (those produced with the `\~` escape sequence) as word breaks with the documentary 'w' command, just as regular breakable spaces do. +o A new read-only, string-valued register, `.trap`, interpolates the + name of the next vertical position trap that will be sprung. + eqn --- diff --git a/doc/groff.texi b/doc/groff.texi index e8e62c05c..a5d66e112 100644 --- a/doc/groff.texi +++ b/doc/groff.texi @@ -14693,6 +14693,13 @@ @node Page Location Traps sense to interpolate it outside of macros called by traps. @endDefreg +@Defreg {.trap} +@cindex next trap name register (@code{.trap}) +@cindex trap name, next, register (@code{.trap}) +This read-only, string-valued register interpolates the name of the next +vertical position trap that will be sprung. +@endDefreg + @Defreg {.pe} @cindex @code{bp} request, and traps (@code{.pe}) @cindex traps, sprung by @code{bp} request (@code{.pe}) diff --git a/man/groff.7.man b/man/groff.7.man index 91809aefb..ce1ae7779 100644 --- a/man/groff.7.man +++ b/man/groff.7.man @@ -6265,6 +6265,16 @@ .SS "Read-only registers" (string-valued). . .TP +.REG .trap +Name of the next vertical position trap that will be sprung +(string-valued); +see +.request .wh , +.request .ch , +and +.request .dt . +. +.TP .REG .trunc Amount of vertical space truncated by the most recently sprung vertical position trap, diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man index 90901ea56..da35a3b78 100644 --- a/man/groff_diff.7.man +++ b/man/groff_diff.7.man @@ -4469,6 +4469,14 @@ .SS "New registers" . . .TP +.B \[rs]n[.trap] +Interpolate the name of the next vertical position trap that will be +sprung. +. +This is a string-valued register. +. +. +.TP .B \[rs]n[.trunc] Interpolate amount of vertical space truncated by the most recently sprung page location trap, diff --git a/src/roff/groff/groff.am b/src/roff/groff/groff.am index 306677bf9..d33f86d51 100644 --- a/src/roff/groff/groff.am +++ b/src/roff/groff/groff.am @@ -44,6 +44,7 @@ groff_TESTS = \ 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/draw-arc.sh \ src/roff/groff/tests/draw-circle.sh \ src/roff/groff/tests/draw-ellipse.sh \ diff --git a/src/roff/groff/tests/dot-trap_register_works.sh b/src/roff/groff/tests/dot-trap_register_works.sh new file mode 100755 index 000000000..810e2cb50 --- /dev/null +++ b/src/roff/groff/tests/dot-trap_register_works.sh @@ -0,0 +1,71 @@ +#!/bin/sh +# +# Copyright (C) 2023 Free Software Foundation, Inc. +# +# This file is part of groff. +# +# groff is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# groff is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +groff="${abs_top_builddir:-.}/test-groff" + +fail= + +wail () { + echo ...FAILED >&2 + fail=yes +} + +input='.pl 3v +.de bomb +.tm Boom! +.. +.nf +.wh 1v bomb +.ptr +.tm A: .trap=\n[.trap] +foo nl=\n[nl]u +.tm B: .trap=\n[.trap] +bar nl=\n[nl]u' + +error=$(printf "%s\n" "$input" | "$groff" -T ascii 2>&1 > /dev/null) +echo "$error" + +echo "checking operation of .trap register prior to trap" +echo "$error" | grep -Fqx 'A: .trap=bomb' || wail + +echo "checking operation of .trap register when no traps remain" +echo "$error" | grep -Fqx 'B: .trap=' || wail + +input='.de XX +.tm SNAP! +.. +.di DD +.dt 1v XX +.tm A: .trap=\n[.trap] +.nf +foo +.tm B: .trap=\n[.trap] +.di' + +error=$(printf "%s\n" "$input" | "$groff" -T ascii 2>&1 > /dev/null) +echo "$error" + +echo "checking operation of .trap in diversion, prior to trap" +echo "$error" | grep -Fqx 'A: .trap=XX' || wail + +echo "checking operation of .trap in diversion, after trap" +echo "$error" | grep -Fqx 'B: .trap=' || wail + +test -z "$FAIL" diff --git a/src/roff/troff/div.cpp b/src/roff/troff/div.cpp index f4dc06f33..f1f1ebda5 100644 --- a/src/roff/troff/div.cpp +++ b/src/roff/troff/div.cpp @@ -250,6 +250,15 @@ vunits macro_diversion::distance_to_next_trap() return vunits(INT_MAX - vresolution); } +const char *macro_diversion::get_next_trap_name() +{ + if (!diversion_trap.is_null() + && (diversion_trap_pos > vertical_position)) + return diversion_trap.contents(); + else + return ""; +} + void macro_diversion::transparent_output(unsigned char c) { mac->append(c); @@ -372,6 +381,16 @@ vunits top_level_diversion::distance_to_next_trap() return d - vertical_position; } +const char *top_level_diversion::get_next_trap_name() +{ + vunits next_trap_pos; + trap *next_trap = find_next_trap(&next_trap_pos); + if (0 /* nullptr */ == next_trap) + return ""; + else + return next_trap->nm.contents(); +} + void top_level_diversion::output(node *nd, int retain_size, vunits vs, vunits post_vs, hunits width) { @@ -1059,6 +1078,16 @@ const char *diversion_name_reg::get_string() return curdiv->get_diversion_name(); } +class next_trap_name_reg : public reg { +public: + const char *get_string(); +}; + +const char *next_trap_name_reg::get_string() +{ + return curdiv->get_next_trap_name(); +} + class page_number_reg : public general_reg { public: page_number_reg(); @@ -1194,6 +1223,7 @@ void init_div_requests() register_dictionary.define(".pe", new page_ejecting_reg); register_dictionary.define(".pn", new next_page_number_reg); register_dictionary.define(".t", new distance_to_next_trap_reg); + register_dictionary.define(".trap", new next_trap_name_reg); register_dictionary.define(".trunc", new constant_vunits_reg(&truncated_space)); register_dictionary.define(".vpt", diff --git a/src/roff/troff/div.h b/src/roff/troff/div.h index 15c7807a5..6180caa0b 100644 --- a/src/roff/troff/div.h +++ b/src/roff/troff/div.h @@ -57,6 +57,7 @@ public: vunits get_vertical_position() { return vertical_position; } vunits get_high_water_mark() { return high_water_mark; } virtual vunits distance_to_next_trap() = 0; + virtual const char * get_next_trap_name() = 0; void need(vunits); const char *get_diversion_name() { return nm.contents(); } virtual void set_diversion_trap(symbol, vunits) = 0; @@ -84,6 +85,7 @@ public: void vjustify(symbol); #endif /* COLUMN */ vunits distance_to_next_trap(); + const char *get_next_trap_name(); void set_diversion_trap(symbol, vunits); void clear_diversion_trap(); void copy_file(const char *filename); @@ -125,6 +127,7 @@ public: hunits get_page_offset() { return page_offset; } vunits get_page_length() { return page_length; } vunits distance_to_next_trap(); + const char *get_next_trap_name(); void add_trap(symbol nm, vunits pos); void change_trap(symbol nm, vunits pos); void remove_trap(symbol); Regards, Branden
signature.asc
Description: PGP signature