[tex-k] incorrect simplification of alpha assignment in mf

Tim Stadelmann mail at timstadelmann.de
Thu Nov 14 00:56:50 CET 2024


Dear Karl,

Thanks for your feedback on my report. I’m glad you actually took the
time to come back to this matter, even though it’s obviously a rather
minor issue and not urgent at all.

This reminds me of another inconsistency I noticed in the original
Metafont code some time ago but never got around to reporting.

The observation concerns the explanation in section in 799 that
stash_cur_exp is not called when cur_type equals token_list, which
is at odds with the actual behavior of the the published code.

If, inside the macro_call procedure, the code in section 728 appends a
suffix or text parameter to the argument list, cur_type retains its
value of token_list.  This remains true even after returning to
get_x_next in section 718. If, after the subsequent call to get_next,
cur_cmd has the value defined_macro, macro_call is entered again in
the next iteration of the repeat-until loop.  The value of cur_type
remains unchanged until get_x_next is called again in section 733,
line 3, during argument scanning.  Consequently, the code in section
718 calls stash_cur_exp with cur_type equal to token_list,
contradicting the statement in section 799, line 16, that
stash_cur_exp 'is not used when cur_type = token list'.

This behavior can be observed in a debugger and occurs, for example,
whenever the 'dot' macro defined in cmbase.mf is expanded.  The
following input file provides a minimal example reproducing the issue:

    def foo expr e = enddef;
    def bar text t = foo \0 enddef;
    bar x;
    end

Arguably, the precondition in section 800, line 18, that 'it is
permissible to call get_x_next only when they are alive or dormant,'
is already violated in this case.  In section 728, the ownership of
the token list referenced by cur_exp and cur_type has effectively been
transferred to the argument list of the macro invocation, so one could
consider them 'dead' as described, somewhat indirectly, in section
800.

This inconsistency does not affect the correct operation of the
program, as the token list is never accessed outside of stash_cur_exp
and unstash_cur_exp.  However, to resolve it, the simplest and least
intrusive approach would likely be to replace

    info(p) ← cur_exp

in section 728, line 5, with

    begin info(p) ← cur_exp; cur_type ← vacuous; end
    
This change would leave the current expression 'dormant' irrespective
of its initial type, ensuring that the preconditions of get_x_next and
stash_cur_exp are always satisfied.

	Best wishes,

	Tim



> Am 13.11.2024 um 18:29 schrieb Karl Berry <karl at freefriends.org>:
> 
> Hi Tim and all - over three years later, but I finally removed the
> incorrect change in mf.ch that you found (in TL r72839):
> @x
>  alpha:=take_fraction(take_fraction(major_axis,
> ..
> 
> I also put your test file in the pile for Knuth to consider as an
> addition to trap.mf.
> 
> tracingpens:=1;
> pickup pencircle xscaled 37 yscaled 11 rotated 70;
> end;
> 
> Your original report, for reference:
> https://tug.org/pipermail/tex-k/2021-August/003648.html
> 
> Perhaps someone will be interested enough to see if there is any change
> to existing mf font rasterizations as a result. Presumably/hopefully,
> any such changes will be tiny ... --thanks, karl.




More information about the tex-k mailing list.