Hi, Tadziu! At 2021-03-20T17:03:52+0100, Tadziu Hoffmann wrote: > > > > in spite of the warnings. Are the warnings a bug? > > > It seems so. Would you be willing to file this report > > as a Savannah ticket? > > Do not remove the warnings. They are not a bug.
Thank you for this writeup. It is quite clear and consistent with my study of the code last fall[1]. (Nevertheless, I didn't completely understand it, and that, combined with a bias from the older report of Savannah #45502 I had recently reviewed, led me to fear we had yet another incompatibility on our hands.) I'd like to keep #60260 open as a documentation issue and adapt your explanation into an addition to the Texinfo manual. Is that okay with you .if/.ie/.el are a matter of recurring confusion. > Here is how .ie and .el work: > > * .ie evaluates its condition "c" and pushes "not(c)" onto a > stack. Then, if "c" is true, it executes the rest of the > line, otherwise it simply discards it. > > * .el pops a value "z" from the stack. If "z" is true, it > executes the rest of the line, otherwise it discards it. Yes; specifically, this stack is called "if_else_stack" in the source. > Now consider again the code > > .de mymac > .ie '\\$1'a' CASE a > .el .ie '\\$1'b' CASE b > .el .ie '\\$1'c' CASE c > .el CASE z > .. > > and imagine calling this as > > .mymac a > > Then, step by step, this is what happens: > > 1) First line: the condition evaluates to "true", so .ie > pushes "false" onto the stack. The stack now contains one > item. "CASE a" is output, since the condition was "true". > > 2) Second line: .el pops the previously pushed value "false" > off the stack. The stack is now empty. Since "false" > was popped, the rest of the line is discarded. > > 3) Third line: .el tries to pop a value off the stack, > but the stack is empty, therefore a warning is printed. > Since no "true" was popped, the rest of the line is > discarded. > > 4) Fourth line: .el tries to pop a value off the stack, > but the stack is still empty, therefore a warning is > printed. Since no "true" was popped, the rest of the > line is discarded. > > So, superficially it might appear as if the code were doing the > right thing. But now imagine that .mymac was called as part of > a larger .ie branch. THEN THOSE TWO .el REQUESTS WILL POP VALUES > FROM THE STACK THAT MOST PROBABLY WERE NOT INTENDED FOR THEM. My first attempt to contrive this situation (attached) did not succeed in provoking such bad behavior, but I think you have a valid point. > With no warnings to indicate that the logic of .mymac was flawed > when called in isolation, imagine the frustration of trying to > debug the behavior of troff in that larger context under the > (wrong) assumption that .mymac was in fact correct. I would add that we should add an exhibit of a right way to do what is desired, since *roff has no C-like "switch" or Lisp-like "cond". .de My . tm --- mymac called with '\\$1' --- . ie '\\$1'a' .tm CASE a . el \{\ . ie '\\$1'b' .tm CASE b . el \{\ . ie '\\$1'c' .tm CASE c . el \{\ . tm Got something else (\\$1) . \}\}\} .. .My a .My b .My c .My d A recursive descent parser for anything but a trivial language in *roff would be quite a spectacle of nesting, wouldn't it? Regards, Branden
avera-mod.roff
Description: Troff document
signature.asc
Description: PGP signature