bug-groff
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug #56499] adjacent trap behavior undocumented and probably undesirabl


From: G. Branden Robinson
Subject: [bug #56499] adjacent trap behavior undocumented and probably undesirable
Date: Sat, 17 Dec 2022 20:02:01 -0500 (EST)

Update of bug #56499 (project groff):

                Severity:              3 - Normal => 4 - Important          
                  Status:                    None => Confirmed              

    _______________________________________________________

Follow-up Comment #1:

I think I have nearly root-caused this, and it's going to take some internal
fiddling to resolve.

There's a member function called `top_level_diversion::find_next_trap()`.

https://git.savannah.gnu.org/cgit/groff.git/tree/src/roff/troff/div.cpp?id=88e89ebe9ce3931b49fb3cbd7fa20eacb03bf69f#n339

Here's what I think right now.

Only one of its callers, `top_level_diversion::distance_to_next_trap()`, has
its needs completely met.  This function's job is to compute a value for the
\n[.t] register, I think.

The other three callers...

top_level_diversion::output()
top_level_diversion::space()
top_level_diversion::begin_page()

...I believe _wrongly assume_ that there will be only one next trap to be
sprung.  But as Dave has documented at length, there could be more than one,
and moreover while their positions in basic units may differ, traps at
different places may lie within the same vertical motion quantum of the output
device.  (I believe this explains the Heisenbuggy boundary issues, e.g., why
you might see "trap 2" sprung but not "trap 1", particularly when the traps
are not "aligned to the grid" of the document's vertical spacing.  An analogy
with the horrible problems OS kernel programmers had to learn about involving
memory page boundaries when virtual memory systems came into vogue also comes
to my mind.)

Specifically, in ::output and ::space we see logic like this:


trap *next_trap = find_next_trap(&next_trap_pos);

  if (vertical_position_traps_flag && next_trap != 0 && y >= next_trap_pos) {
    vertical_position = next_trap_pos;
    nl_reg_contents = vertical_position.to_units();
    truncated_space = y - vertical_position;
    spring_trap(next_trap->nm);
  }



Notice that this _does not iterate_.

Also, ::output performs logic like this twice, with close similarities.  I am
wondering if a common function that springs all traps until a given position
_pos_ is warranted.

But not really "all", maybe.  The weird phenomenon of "active" traps hiding
earlier-planted ones at the same position has a long pedigree.  We might need
to retain it, even as weird as it is, for historical compatibility.

But a trap should _not_ be able to hide another trap at a _different_ position
in basic units, no matter how coarse the vertical motion quantum of the
device, but it can, and that is what is causing the grief that Dave reported.

It may also lie at the knotted root of a dozen entangled _me_(7) package
footnote-management bugs.

This item should be high on the priority list for post-1.23.0.


    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?56499>

_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]