texequivalents.h /size: 106 Kb    last modification: 2025-02-21 11:03
1/*
2    See license.txt in the root of this project.
3*/
4
5# ifndef LMT_EQUIVALENTS_H
6# define LMT_EQUIVALENTS_H
7
8# include "tex/textypes.h"
9
10/*tex
11
12    Like the preceding parameters, the following quantities can be changed at compile time to extend
13    or reduce \TEX's capacity. But if they are changed, it is necessary to rerun the initialization
14    program |INITEX| to generate new tables for the production \TEX\ program. One can't simply make
15    helter-skelter changes to the following constants, since certain rather complex initialization
16    numbers are computed from them. They are defined here using \WEB\ macros, instead of being put
17    into \PASCAL's |const| list, in order to emphasize this distinction.
18
19    The original token interface at the \LUA\ end used the \quote {real} chr values that are offsets
20    into the table of equivalents. However, that is sort of fragile when one also provides ways to
21    construct tokens. For that reason the \LUAMETATEX\ interface is a bit more abstract and therefore
22    can do some testing. After all, the real numbers don't matter. This means that registers for
23    instance run from |0..65535| (without the region offsets).
24
25    In order to make this easier the token registers are now more consistent with the other registers
26    in the sense that there is no longer a special cmd for those registers. This was not that hard to
27    do because most code already was sort of prepared for that move.
28
29    Now, there is one \quote {complication}: integers, dimensions etc references can be registers but
30    also internal variables. This means that we cannot simply remap the eq slots they refer to. When
31    we offset by some base (the first register) we end up with negative indices for the internal ones
32    because they come before this 64K range. So, this is why the \LUA\ interface works with negative
33    numbers for internal variables.
34
35    Another side effect is that we now have the mu glue internals in the muglue region. This is
36    possible because we have separated the subtypes from the chr codes. I might also relocate the
37    special things (like penalties) some day.
38
39    In a couple of cases a specific chr was used that made it possible to share for instance setters.
40    Examples are |\mkern| and |\mskip|. This resulted is (sort of) funny single numbers in the token
41    interface, so we have that now normalized as well (at the cost of a few split functions). Of course
42    that doesn't change the concept, unless one considers the fact that we have more granularity in
43    node subtypes (no longer parallel to the codes, as there are more) an issue. (Actually we can now
44    easily introduce hkern and vkern if we want.)
45
46*/
47
48/*tex
49
50    Each entry in |eqtb| is a |memoryword|. Most of these words are of type |two_halves|, and
51    subdivided into three fields:
52
53    \startitemize
54
55    \startitem
56        The |eq_level| (a quarterword) is the level of grouping at which this equivalent was
57        defined. If the level is |level_zero|, the equivalent has never been defined;
58        |level_one| refers to the outer level (outside of all groups), and this level is also
59        used for global definitions that never go away. Higher levels are for equivalents that
60        will disappear at the end of their group.
61    \stopitem
62
63    \startitem
64        The |eq_type| (another quarterword) specifies what kind of entry this is. There are many
65        types, since each \TEX\ primitive like |\hbox|, |\def|, etc., has its own special code.
66        The list of command codes above includes all possible settings of the |eq_type| field.
67    \stopitem
68
69    \startitem
70        The |equiv| (a halfword) is the current equivalent value. This may be a font number, a
71        pointer into |mem|, or a variety of other things.
72    \stopitem
73
74    \stopitemize
75
76    Many locations in |eqtb| have symbolic names. The purpose of the next paragraphs is to define
77    these names, and to set up the initial values of the equivalents.
78
79    In the first region we have a single entry for the \quote {null csname} of length zero. In
80    \LUATEX, the active characters and and single-letter control sequence names are part of the
81    next region.
82
83    Then comes region 2, which corresponds to the hash table that we will define later. The maximum
84    address in this region is used for a dummy control sequence that is perpetually undefined.
85    There also are several locations for control sequences that are perpetually defined (since they
86    are used in error recovery).
87
88    Region 3 of |eqtb| contains the |number_regs| |\skip| registers, as well as the glue parameters
89    defined here. It is important that the \quote {muskip} parameters have larger numbers than the
90    others.
91
92    Region 4 of |eqtb| contains the local quantities defined here. The bulk of this region is taken
93    up by five tables that are indexed by eight-bit characters; these tables are important to both
94    the syntactic and semantic portions of \TEX. There are also a bunch of special things like font
95    and token parameters, as well as the tables of |\toks| and |\box| registers.
96
97    Region 5 of |eqtb| contains the integer parameters and registers defined here, as well as the
98    |del_code| table. The latter table differs from the |cat_code..math_code| tables that precede it,
99    since delimiter codes are fullword integers while the other kinds of codes occupy at most a
100    halfword. This is what makes region~5 different from region~4. We will store the |eq_level|
101    information in an auxiliary array of quarterwords that will be defined later.
102
103    The integer parameters should really be initialized by a macro package; the following
104    initialization does the minimum to keep \TEX\ from complete failure.
105
106    The final region of |eqtb| contains the dimension parameters defined here, and the |number_regs|
107    |\dimen| registers.
108
109    Beware: in \LUATEX\ we have so many characters (\UNICODE) that we use a dedicated hash system
110    for special codes, math properties etc. This means that we have less in the regions than mentioned
111    here. On the other hand, we do have more registers (attributes) so that makes it a bit larger again.
112
113    The registers get marked as being \quote {undefined} commands. We could actually gove them a the
114    right commmand code etc.\ bur for now we just use the ranges as traditional \TEX\ does.
115
116    Most of the symbolic names and hard codes numbers are not enumerations. There is still room for
117    improvement and occasionally I enter a new round of doing that. However, it talkes a lot of time
118    and checking (more than writing from scratch) as we need to make sure it all behaves like \TEX\
119    does. Quite some code went through several stages of reaching this abstraction, just to make sure
120    that it kept working. These intermediate versions ended up in the \CONTEXT\ distribution to that
121    any issue would show up soon. A rather major step was splitting the |assign_*_cmd|s into
122    internal and register commands and ranges. This was a side effect of getting the token interface
123    at the \LUA\ end a bit nicer; there is really no need to expose the user to codes that demand
124    catching up with the \TEX\ internals when we can just provide a nice interface.
125
126    The font location is kind of special as it holds a halfword data field that points to a font
127    accessor and as such doesn't fit into a counter concept. Otherwise we could have made it a
128    counter. We could probably just use a font id and do a lookup elsewhere because this engine is
129    already doing it differently. So, eventually this needs checking.
130
131*/
132
133/*
134    For practical reasons we have the regions a bit different. For instance, we also have attributes, local
135    boxes, no math characters here, etc. Maybe specification codes sould get their own region.
136
137    HASH FROZEN
138    [I|R]FONTS
139    UNDEFINED
140    [I|R]GLUE
141    [I|R]MUGLUE
142    [I|R]TOKS
143    [I|R]BOXES
144    [I|R]INT
145    [I|R]ATTR
146    [I|R]DIMEN
147    SPECIFICATIONS
148    EQUIVPLUS
149
150    When I'd done a bit of clean up and abstraction (actually it took quite some time because the only
151    reliable way to do it is stepwise with lots of testing) I wondered why there is a difference in
152    the way the level is kept track of. For those entries that store a value directly, a separate
153    |xeq_level| array is used. So, after \quote {following the code}, taking a look at the original
154    implementation, and a walk, I came to the conclusion that because \LUATEX\ uses 64 memory words,
155    we actually don't need that parallel array: we have plenty of room and, the level fields are not
156    shared. In traditional \TEX\ we have a memory word with two faces:
157
158    [level] [type]
159    [    value   ]
160
161    but in \LUATEX\ it's wider. There is no overlap.
162
163    [level] [type] [value]
164
165    So, we can get rid of that extra array. Actually, in the \PASCAL\ source we see that this
166    parallel array is smaller because it only covers the value ranges (the first index starts at
167    the start of the first relevant register range). Keep in mind that the middle part of the hash
168    is registers and when we have a frozen hash size, that part is not present which is why there
169    was that parallel array needed; a side effect of the |extra_hash| extension.
170
171    Another side effect of this simplification is that we can store and use the type which can be
172    handy too.
173
174    For the changes, look for |xeq simplification| comments in the files and for the cleaned up
175    precursor in the archives of luametatex (in case there is doubt). When the save stack was made
176    more efficient the old commented |xeq| code has been removed.
177
178    -----------------------------------
179    null control sequence
180    hash entries (hash_size)
181    multiple frozen control sequences
182    special sequences (font, undefined)
183    -----------------------------------
184    glue registers
185    mu glue registers
186    token registers
187    box registers
188    integer registers
189    attribute registers
190    dimension registers
191    specifications
192    ---------- eqtb size --------------
193    extra hash entries
194    -----------------------------------
195
196    eqtb_top = eqtb_size + hash_extra
197    hash_top = hash_extra == 0 ? undefined_control_sequence : eqtb_top;
198
199    There used to be a large font area but I moved that to the font record so that we don't waste
200    space (it saves some 500K on the format file and plenty of memory).
201
202    Todo: split the eqtb and make the register arrays dynamic. We need to change the save/restore
203    code then and it might have a slight impact on performance (checking what table to use).
204
205*/
206
207/*tex
208    Maybe we should multiply the following by 2 but there is no real gain. Many entries end up in the extended
209    area anyway.
210
211    \starttyping
212    # define hash_size  65536
213    # define hash_prime 55711
214    \stoptyping
215
216    Here |hash_size| is the maximum number of control sequences; it should be at most about
217    |(fix_mem_max - fix_mem_min)/10|. The value of |hash_prime| is a prime number equal to about
218    85 percent of |hash_size|.
219
220    The hash runs in parallel to the eqtb and a large hash table makes for many holes and that
221    compresses badly. For instance:
222
223    590023 => down to 1024 * 512 == 524288 ==> 85% = 445644 => prime 445633/445649
224
225    will make a much larger format and we gain nothing. Actually, because we have extra hash
226    anyway, this whole 85\% criterion is irrelevant: we only need to make sure that we have
227    enough room for the frozen sequences (assuming we stay within the concept).
228
229    primes:
230
231    \starttyping
232     65447  65449  65479  65497  65519  65521 =>  65536 (85% ==  55711)
233    131009 131011 131023 131041 131059 131063 => 131072 (85% == 111409)
234    \stoptyping
235
236    lookups:
237
238    \starttyping
239    n=131040 cs=46426 indirect= 9173
240    n= 65496 cs=46426 indirect=14512
241    \stoptyping
242
243    We don't use the 85% prime (and we % the accumulated hash. Somehow this also performs better,
244    but of course I migbe be wrong.
245
246*/
247
248//define hash_size  65536
249//define hash_prime 65497
250
251//define hash_size  131072                               /*tex 128K */
252//define hash_prime 131041                               /*tex not the 85% prime */
253
254# define hash_size  262144                               /*tex 256K */
255# define hash_prime 262103                               /*tex not the 85% prime */
256
257# define null_cs                 1                       /*tex equivalent of |\csname\endcsname| */
258# define hash_base               (null_cs   + 1)         /*tex beginning of region 2, for the hash table */
259# define frozen_control_sequence (hash_base + hash_size) /*tex for error recovery */
260
261typedef enum deep_frozen_cs_codes {
262    deep_frozen_cs_protection_code = frozen_control_sequence, /*tex inaccessible but definable */
263    deep_frozen_cs_cr_code,                                   /*tex permanent |\cr| */
264    deep_frozen_cs_end_group_code,                            /*tex permanent |\endgroup| */
265    deep_frozen_cs_right_code,                                /*tex permanent |\right| */
266    deep_frozen_cs_fi_code,                                   /*tex permanent |\fi| */
267    deep_frozen_cs_no_if_code,                                /*tex hidden |\noif| */
268    deep_frozen_cs_always_code,                               /*tex hidden internalized |\enforces| */
269    deep_frozen_cs_end_template_code,                         /*tex permanent |\endtemplate| */
270    deep_frozen_cs_relax_code,                                /*tex permanent |\relax| */
271    deep_frozen_cs_end_write_code,                            /*tex permanent |\endwrite| */
272    deep_frozen_cs_dont_expand_code,                          /*tex permanent |\notexpanded:| */
273    deep_frozen_cs_keep_constant_code,                        /*tex permanent |\notexpanded:| */
274    deep_frozen_cs_null_font_code,                            /*tex permanent |\nullfont| */
275    deep_frozen_cs_undefined_code,
276} deep_frozen_cs_codes;
277
278# define first_deep_frozen_cs_location deep_frozen_cs_protection_code
279# define last_deep_frozen_cs_location  deep_frozen_cs_undefined_code
280
281typedef enum glue_codes {
282    /* special ones */
283    additional_page_skip_code,
284    /* normal ones */
285    initial_page_skip_code,
286    initial_top_skip_code,
287    line_skip_code,                /*tex interline glue if |baseline_skip| is infeasible */
288    baseline_skip_code,            /*tex desired glue between baselines */
289    par_skip_code,                 /*tex extra glue just above a paragraph */
290    above_display_skip_code,       /*tex extra glue just above displayed math */
291    below_display_skip_code,       /*tex extra glue just below displayed math */
292    above_display_short_skip_code, /*tex glue above displayed math following short lines */
293    below_display_short_skip_code, /*tex glue below displayed math following short lines */
294    left_skip_code,                /*tex glue at left of justified lines */
295    right_skip_code,               /*tex glue at right of justified lines */
296    top_skip_code,                 /*tex glue at top of main pages */
297    bottom_skip_code,              /*tex glue at bottom of main pages */
298    split_top_skip_code,           /*tex glue at top of split pages */
299    balance_top_skip_code,
300    balance_bottom_skip_code,
301    tab_skip_code,                 /*tex glue between aligned entries */
302    space_skip_code,               /*tex glue between words (if not |zero_glue|) */
303    xspace_skip_code,              /*tex glue after sentences (if not |zero_glue|) */
304    par_fill_left_skip_code,       /*tex glue at the start of the last line of paragraph */
305    par_fill_right_skip_code,      /*tex glue on last line of paragraph */
306    par_init_left_skip_code,
307    par_init_right_skip_code,
308    emergency_left_skip_code,
309    emergency_right_skip_code,
310 /* indent_skip_code,           */ /*tex internal, might go away here */
311 /* left_hang_skip_code,        */ /*tex internal, might go away here */
312 /* right_hang_skip_code,       */ /*tex internal, might go away here */
313 /* correction_skip_code,       */ /*tex internal, might go away here */
314 /* inter_math_skip_code,       */ /*tex internal, might go away here */
315    math_skip_code,                /*tex glue before and after inline math */
316    math_threshold_code,
317    /*tex total number of glue parameters */
318    number_glue_pars,
319} glue_codes;
320
321# define first_glue_code line_skip_code
322# define last_glue_code  math_threshold_code
323
324/*tex
325
326    In addition to the three original predefined muskip registers we have two more. These muskips
327    are used in a symbolic way: by using a reference we can change their values on the fly and the
328    engine will pick up the value set at the end of the formula (and use it in the second pass).
329    In the other engines the threesome are hard coded into the atom pair spacing.
330
331    In \LUAMETATEX\ we have a configurable system so these three registers are only used in the
332    initialization, can be overloaded in the macro package, and are saved in the format file (as
333    any other register). But there can be more than these. Before we had a way to link spacing to
334    arbitrary registers (in the user's register space) we added |\tinymuskip| because we needed it.
335    It is not used in initializations in the engine but is applied in the \CONTEXT\ format. We
336    could throw it out and use just a user register now but we consider it part of the (updated)
337    concept so it will stick around. Even more: we decided that a smaller one makes sense so end
338    June 2022 Mikael and I decided to also provide |\pettymuskip| for which Mikael saw a good use
339    case in the spacing in scripts between ordinary symbols and binary as well as relational ones.
340
341    The Cambridge dictionary describes \quote {petty} as \quotation {not important and not worth
342    giving attention to}, but of course we do! It's just that till not we never saw any request
343    for an upgrade of the math (sub) engine, let alone that \TEX\ users bothered about the tiny
344    and petty spacing artifacts (and posibilities) of the engine. Both internal registers are
345    dedicated to Don Knuth who {\em does} pay a lot attentions to details but who of course will
346    not use this engine and thereby not spoiled. So, they are there and at the same time they
347    are not. But: in \CONTEXT\ they {\em are} definitely used!
348
349*/
350
351typedef enum muglue_codes {
352    zero_muskip_code,
353    petty_muskip_code,            /*tex petty space in math formula */
354    tiny_muskip_code,             /*tex tiny space in math formula */
355    thin_muskip_code,             /*tex thin space in math formula */
356    med_muskip_code,              /*tex medium space in math formula */
357    thick_muskip_code,            /*tex thick space in math formula */
358    /*tex total number of muskip parameters */
359    number_muglue_pars,
360} muglue_codes;
361
362# define first_muglue_code  petty_muskip_code
363# define last_muglue_code   thick_muskip_code
364
365typedef enum tok_codes {
366    output_routine_code,          /*tex points to token list for |\output| */
367    every_par_code,               /*tex points to token list for |\everypar| */
368    every_math_code,              /*tex points to token list for |\everymath| */
369    every_display_code,           /*tex points to token list for |\everydisplay| */
370    every_hbox_code,              /*tex points to token list for |\everyhbox| */
371    every_vbox_code,              /*tex points to token list for |\everyvbox| */
372    every_math_atom_code,         /*tex points to token list for |\everymathatom| */
373    every_job_code,               /*tex points to token list for |\everyjob|*/
374    every_cr_code,                /*tex points to token list for |\everycr| */
375    every_tab_code,               /*tex points to token list for |\everytab| */
376    error_help_code,              /*tex points to token list for |\errhelp|*/
377    every_before_par_code,        /*tex points to token list for |\everybeforepar| */
378    every_eof_code,               /*tex points to token list for |\everyeof| */
379    end_of_group_code,            /*tex collects end-of-group tokens, internal register */
380 // end_of_par_code,
381    /*tex total number of token parameters */
382    number_tok_pars,
383} tok_codes;
384
385# define first_toks_code output_routine_code
386# define last_toks_code  every_eof_code
387
388typedef enum specification_codes {
389    par_shape_code,               /*tex specifies paragraph shape, internal register */
390    par_passes_code,
391    par_passes_exception_code,
392    balance_shape_code,
393    balance_passes_code,
394    balance_final_penalties_code,
395    inter_line_penalties_code,    /*tex additional penalties between lines */
396    club_penalties_code,          /*tex penalties for creating club lines */
397    widow_penalties_code,         /*tex penalties for creating widow lines */
398    display_widow_penalties_code, /*tex ditto, just before a display */
399    broken_penalties_code,
400    orphan_penalties_code,
401    toddler_penalties_code,
402    fitness_classes_code,
403    adjacent_demerits_code,
404    orphan_line_factors_code,
405    math_forward_penalties_code,
406    math_backward_penalties_code,
407    integer_list_code,
408    dimension_list_code,
409    posit_list_code,
410    number_specification_pars,
411} specification_codes;
412
413# define first_specification_code       par_shape_code
414# define last_specification_code        math_backward_penalties_code
415# define first_specification_list_code  integer_list_code
416# define last_specification_list_code   posit_list_code
417
418/*tex Beware: these are indices into |page_builder_state.page_so_far| array! */
419
420typedef enum page_property_codes {
421    page_goal_code,
422    page_vsize_code,
423    page_total_code,
424    page_depth_code,
425    page_excess_code,
426    page_last_height_code, /*tex These might become unsettable */
427    page_last_depth_code,  /*tex These might become unsettable */
428    dead_cycles_code,
429    insert_penalties_code,
430    insert_heights_code,
431    insert_storing_code, /* page */
432    insert_distance_code,
433    insert_multiplier_code,
434    insert_limit_code,
435    insert_storage_code, /* per insert */
436    insert_penalty_code,
437    insert_maxdepth_code,
438    insert_height_code,
439    insert_depth_code,
440    insert_width_code,
441    insert_line_height_code,
442    insert_line_depth_code,
443    insert_stretch_code,
444    insert_shrink_code,
445    /*tex These can't be set: */
446    page_stretch_code,
447    page_fistretch_code,
448    page_filstretch_code,
449    page_fillstretch_code,
450    page_filllstretch_code,
451    page_shrink_code,
452    page_last_stretch_code,
453    page_last_fistretch_code,
454    page_last_filstretch_code,
455    page_last_fillstretch_code,
456    page_last_filllstretch_code,
457    page_last_shrink_code,
458    /* these are hosted here */
459    split_last_depth_code,
460    split_last_height_code,
461    split_last_shrink_code,
462    split_last_stretch_code,
463    /* */
464    mvl_currently_active_code,
465} page_property_codes;
466
467# define first_page_property_code page_goal_code
468# define last_page_property_code  mvl_currently_active_code
469
470/*tex
471    We cheat: these previous bases are to really bases which is why math and del get separated by
472    one. See usage! Todo: group them better (also elsewhere in switches).
473*/
474
475typedef enum int_codes {
476    /* special ones */
477    par_direction_code,
478    math_direction_code,
479    text_direction_code,
480    line_direction_code,
481    cat_code_table_code,
482    glyph_scale_code,
483    glyph_x_scale_code,
484    glyph_y_scale_code,
485    glyph_slant_code,
486    glyph_weight_code,
487    glyph_text_scale_code,
488    glyph_script_scale_code,
489    glyph_scriptscript_scale_code,
490    math_begin_class_code,
491    math_end_class_code,
492    math_left_class_code,
493    math_right_class_code,
494    output_box_code,
495    no_output_box_error_code,
496    new_line_char_code,
497    end_line_char_code,
498    language_code,
499    font_code,
500    hyphenation_mode_code,
501    uc_hyph_code,
502    local_interline_penalty_code,
503    local_broken_penalty_code,
504    local_tolerance_code,
505    local_pre_tolerance_code,
506    adjust_spacing_code,
507    protrude_chars_code,
508    glyph_options_code,
509    discretionary_options_code,
510    overload_mode_code,
511    post_binary_penalty_code,
512    post_relation_penalty_code,
513    pre_binary_penalty_code,
514    pre_relation_penalty_code,
515    eu_factor_code,
516    /* normal ones */
517    pre_tolerance_code,                 /*tex badness tolerance before hyphenation */
518    tolerance_code,                     /*tex badness tolerance after hyphenation */
519    line_penalty_code,                  /*tex added to the badness of every line */
520    hyphen_penalty_code,                /*tex penalty for break after discretionary hyphen */
521    ex_hyphen_penalty_code,             /*tex penalty for break after explicit hyphen */
522    club_penalty_code,                  /*tex penalty for creating a club line */
523    widow_penalty_code,                 /*tex penalty for creating a widow line */
524    display_widow_penalty_code,         /*tex ditto, just before a display */
525    broken_penalty_code,                /*tex penalty for breaking a page at a broken line */
526 // post_binary_penalty_code,           /*tex penalty for breaking after a binary operation */
527 // post_relation_penalty_code,         /*tex penalty for breaking after a relation */
528    pre_display_penalty_code,           /*tex penalty for breaking just before a displayed formula */
529    post_display_penalty_code,          /*tex penalty for breaking just after a displayed formula */
530    pre_inline_penalty_code,            /*tex penalty for breaking just before an inlined formula */
531    post_inline_penalty_code,           /*tex penalty for breaking just after an inlined formula */
532    pre_short_inline_penalty_code,      /*tex penalty for breaking just before a single character inlined formula */
533    post_short_inline_penalty_code,     /*tex penalty for breaking just after a single character inlined formula */
534    short_inline_orphan_penalty_code,
535    inter_line_penalty_code,            /*tex additional penalty between lines */
536    double_hyphen_demerits_code,        /*tex demerits for double hyphen break */
537    final_hyphen_demerits_code,         /*tex demerits for final hyphen break */
538    adj_demerits_code,                  /*tex demerits for adjacent incompatible lines with distance > 1 */
539    double_penalty_mode_code,           /*tex force alternative widow, club, broken penalties */
540    /* mag_code,                        */ /*tex magnification ratio */
541    delimiter_factor_code,              /*tex ratio for variable-size delimiters */
542    looseness_code,                     /*tex change in number of lines for a paragraph */
543    time_code,                          /*tex current time of day */
544    day_code,                           /*tex current day of the month */
545    month_code,                         /*tex current month of the year */
546    year_code,                          /*tex current year of our Lord */
547    show_box_breadth_code,              /*tex nodes per level in |show_box| */
548    show_box_depth_code,                /*tex maximum level in |show_box| */
549    show_node_details_code,             /*tex controls subtype and attribute details */
550    hbadness_code,                      /*tex hboxes exceeding this badness will be shown by |hpack| */
551    vbadness_code,                      /*tex vboxes exceeding this badness will be shown by |vpack| */
552    hbadness_mode_code,                 /*tex controls what gets reported */
553    vbadness_mode_code,                 /*tex controls what gets reported */
554    pausing_code,                       /*tex pause after each line is read from a file */
555    tracing_online_code,                /*tex show diagnostic output on terminal */
556    tracing_macros_code,                /*tex show macros as they are being expanded */
557    tracing_stats_code,                 /*tex show memory usage if \TeX\ knows it */
558    tracing_paragraphs_code,            /*tex show line-break calculations */
559    tracing_pages_code,                 /*tex show page-break calculations */
560    tracing_balancing_code,             /*tex show balance-break calculations */
561    tracing_output_code,                /*tex show boxes when they are shipped out */
562    tracing_lost_chars_code,            /*tex show characters that aren't in the font */
563    tracing_commands_code,              /*tex show command codes at |big_switch| */
564    tracing_restores_code,              /*tex show equivalents when they are restored */
565 // tracing_fonts_code,
566    tracing_assigns_code,               /*tex show assignments */
567    tracing_groups_code,                /*tex show save/restore groups */
568    tracing_ifs_code,                   /*tex show conditionals */
569    tracing_math_code,
570    tracing_mvl_code,
571    tracing_levels_code,                /*tex show levels when tracing */
572    tracing_nesting_code,               /*tex show incomplete groups and ifs within files */
573    tracing_alignments_code,            /*tex show nesting of noalign and preambles */
574    tracing_inserts_code,               /*tex show some info about insert processing */
575    tracing_marks_code,                 /*tex show state of marks */
576    tracing_adjusts_code,               /*tex show state of marks */
577    tracing_hyphenation_code,           /*tex show some info regarding hyphenation */
578    tracing_expressions_code,           /*tex show some info regarding expressions */
579    tracing_nodes_code,                 /*tex show node numbers too */
580    tracing_full_boxes_code,            /*tex show [over/under]full boxes in the log */
581    tracing_penalties_code,
582    tracing_looseness_code,
583    tracing_lists_code,
584    tracing_passes_code,
585    tracing_fitness_code,
586    tracing_toddlers_code,
587    tracing_orphans_code,
588    tracing_loners_code,                /*tex show widow and club penalties calculations */
589 // uc_hyph_code,                       /*tex hyphenate words beginning with a capital letter */
590    output_penalty_code,                /*tex penalty found at current page break */
591    max_dead_cycles_code,               /*tex bound on consecutive dead cycles of output */
592    hang_after_code,                    /*tex hanging indentation changes after this many lines */
593    floating_penalty_code,              /*tex penalty for insertions heldover after a split */
594    global_defs_code,                   /*tex override |\global| specifications */
595    family_code,                        /*tex current family */
596    escape_char_code,                   /*tex escape character for token output */
597    space_char_code,                    /*tex space character */
598    default_hyphen_char_code,           /*tex value of |\hyphenchar| when a font is loaded */
599    default_skew_char_code,             /*tex value of |\skewchar| when a font is loaded */
600 // end_line_char_code,                 /*tex character placed at the right end of the buffer */
601 // new_line_char_code,                 /*tex character that prints as |print_ln| */
602 // language_code,                      /*tex current language */
603 // font_code,                          /*tex current font */
604 // hyphenation_mode_code,
605    left_hyphen_min_code,               /*tex minimum left hyphenation fragment size */
606    right_hyphen_min_code,              /*tex minimum right hyphenation fragment size */
607    holding_inserts_code,               /*tex do not remove insertion nodes from |\box255| */
608    holding_migrations_code,
609    error_context_lines_code,           /*tex maximum intermediate line pairs shown */
610 // local_interline_penalty_code,       /*tex local |\interlinepenalty| */
611 // local_broken_penalty_code,          /*tex local |\brokenpenalty| */
612 // local_tolerance_code,
613 // local_pre_tolerance_code,
614    no_spaces_code,
615    parameter_mode_code,
616 // glyph_scale_code,
617 // glyph_x_scale_code,
618 // glyph_y_scale_code,
619    glyph_data_code,
620    glyph_state_code,
621    glyph_script_code,
622 // glyph_options_code,
623 // glyph_text_scale_code,
624 // glyph_script_scale_code,
625 // glyph_scriptscript_scale_code,
626 // discretionary_options_code,
627 /* glue_data_code, */
628 // cat_code_table_code,
629 // output_box_code,
630    ex_hyphen_char_code,
631    ex_apostrophe_char_code,
632 // adjust_spacing_code,                /*tex level of spacing adjusting */
633    adjust_spacing_step_code,           /*tex level of spacing adjusting step */
634    adjust_spacing_stretch_code,        /*tex level of spacing adjusting stretch */
635    adjust_spacing_shrink_code,         /*tex level of spacing adjusting shrink */
636 // protrude_chars_code,                /*tex protrude chars at left/right edge of paragraphs */
637    pre_display_direction_code,         /*tex text direction preceding a display */
638    last_line_fit_code,                 /*tex adjustment for last line of paragraph */
639    saving_vdiscards_code,              /*tex save items discarded from vlists */
640    saving_hyph_codes_code,             /*tex save hyphenation codes for languages */
641    math_eqno_gap_step_code,            /*tex factor/1000 used for distance between eq and eqno */
642    math_display_skip_mode_code,
643    math_scripts_mode_code,
644    math_limits_mode_code,
645    math_nolimits_mode_code,
646    math_rules_mode_code,
647    math_rules_fam_code,
648    math_penalties_mode_code,
649    math_check_fences_mode_code,
650    math_slack_mode_code,
651    math_skip_mode_code,
652    math_double_script_mode_code,
653    math_font_control_code,
654    math_display_mode_code,
655    math_dict_group_code,
656    math_dict_properties_code,
657    math_pre_display_gap_factor_code,
658 // pre_binary_penalty_code,
659 // pre_relation_penalty_code,
660    first_valid_language_code,
661    automatic_hyphen_penalty_code,
662    explicit_hyphen_penalty_code,
663    exception_penalty_code,
664    copy_lua_input_nodes_code,
665    auto_migration_mode_code,
666    normalize_line_mode_code,
667    normalize_par_mode_code,
668    math_spacing_mode_code,
669    math_grouping_mode_code,
670    math_glue_mode_code,
671 // math_begin_class_code,
672 // math_end_class_code,
673 // math_left_class_code,
674 // math_right_class_code,
675    math_inline_penalty_factor_code,
676    math_display_penalty_factor_code,
677    sup_mark_mode_code,
678 // par_direction_code,
679 // text_direction_code,
680 // math_direction_code,
681 // line_direction_code, /*tex gets remapped so is no real register */
682 // overload_mode_code,
683    auto_paragraph_mode_code,
684    shaping_penalties_mode_code,
685    shaping_penalty_code,
686    single_line_penalty_code,
687    left_twin_demerits_code,
688    right_twin_demerits_code,
689    alignment_cell_source_code,
690    alignment_wrap_source_code,
691 /* page_boundary_penalty_code, */
692    line_break_passes_code,
693    line_break_optional_code,
694    line_break_checks_code,
695    balance_checks_code,
696    balance_break_passes_code,
697    balance_tolerance_code,
698    balance_penalty_code,
699    balance_adj_demerits_code,
700    balance_looseness_code,
701    vsplit_checks_code,
702    etex_expr_mode_code,
703    par_options_code,
704    /*
705        This one was added as experiment to \LUATEX\ (answer to a forwarded question) but as it
706        didn't get tested it will go away. \CONTEXT\ doesn't need it and we don't need to be
707        compatible anyway. Lesson learned.
708    */
709    variable_family_code,
710 // eu_factor_code,
711    math_pre_tolerance_code,
712    math_tolerance_code,
713    empty_paragraph_mode_code,
714    space_factor_mode,
715    space_factor_shrink_limit_code,
716    space_factor_stretch_limit_code,
717    space_factor_overload_code,
718    box_limit_mode_code,
719    script_space_before_factor_code,
720    script_space_between_factor_code,
721    script_space_after_factor_code,
722    /* those below these are not interfaced via primitives */
723    internal_par_state_code,
724    internal_dir_state_code,
725    internal_math_style_code,
726    internal_math_scale_code,
727    /*tex total number of integer parameters */
728    first_math_class_code,
729    last_math_class_code = first_math_class_code + max_n_of_math_classes,
730    first_math_atom_code,
731    last_math_atom_code = first_math_atom_code + max_n_of_math_classes,
732    first_math_options_code,
733    last_math_options_code = first_math_options_code + max_n_of_math_classes,
734    first_math_parent_code,
735    last_math_parent_code = first_math_parent_code + max_n_of_math_classes,
736    first_math_pre_penalty_code,
737    last_math_pre_penalty_code = first_math_pre_penalty_code + max_n_of_math_classes,
738    first_math_post_penalty_code,
739    last_math_post_penalty_code = first_math_post_penalty_code + max_n_of_math_classes,
740    first_math_display_pre_penalty_code,
741    last_math_display_pre_penalty_code = first_math_display_pre_penalty_code + max_n_of_math_classes,
742    first_math_display_post_penalty_code,
743    last_math_display_post_penalty_code = first_math_display_post_penalty_code + max_n_of_math_classes,
744    first_math_ignore_code,
745    last_math_ignore_code = first_math_ignore_code + math_parameter_last,
746    /* */
747    number_integer_pars,
748} int_codes;
749
750# define first_integer_code pre_tolerance_code
751# define last_integer_code  script_space_after_factor_code
752
753typedef enum dimension_codes {
754    /* normal ones */
755    par_indent_code,               /*tex indentation of paragraphs */
756    math_surround_code,            /*tex space around math in text */
757    line_skip_limit_code,          /*tex threshold for |line_skip| instead of |baseline_skip| */
758    hsize_code,                    /*tex line width in horizontal mode */
759    vsize_code,                    /*tex page height in vertical mode */
760    max_depth_code,                /*tex maximum depth of boxes on main pages */
761    split_max_depth_code,          /*tex maximum depth of boxes on split pages */
762    box_max_depth_code,            /*tex maximum depth of explicit vboxes */
763    hfuzz_code,                    /*tex tolerance for overfull hbox messages */
764    vfuzz_code,                    /*tex tolerance for overfull vbox messages */
765    delimiter_shortfall_code,      /*tex maximum amount uncovered by variable delimiters */
766    null_delimiter_space_code,     /*tex blank space in null delimiters */
767    script_space_code,             /*tex extra space after subscript or superscript */
768    pre_display_size_code,         /*tex length of text preceding a display */
769    display_width_code,            /*tex length of line for displayed equation */
770    display_indent_code,           /*tex indentation of line for displayed equation */
771    overfull_rule_code,            /*tex width of rule that identifies overfull hboxes */
772    hang_indent_code,              /*tex amount of hanging indentation */
773 /* h_offset_code,          */     /*tex amount of horizontal offset when shipping pages out */
774 /* v_offset_code,          */     /*tex amount of vertical offset when shipping pages out */
775    emergency_stretch_code,        /*tex reduces badnesses on final pass of line-breaking */
776    emergency_extra_stretch_code,
777    glyph_x_offset_code,
778    glyph_y_offset_code,
779    px_dimension_code,             /*tex This is a historic one, not used but we keep it. */
780    tab_size_code,
781    page_extra_goal_code,
782    ignore_depth_criterion_code,
783    short_inline_math_threshold_code,
784    split_extra_height_code,
785    balance_emergency_stretch_code,
786    balance_emergency_shrink_code,
787    balance_vsize_code,
788    balance_line_height_code,
789    /*tex total number of dimension parameters */
790    number_dimension_pars,
791} dimension_codes;
792
793# define first_dimension_code par_indent_code
794# define last_dimension_code  balance_line_height_code
795
796typedef enum attribute_codes {
797    /*tex total number of attribute parameters */
798    number_attribute_pars,
799} attribute_codes;
800
801typedef enum posit_codes {
802    /*tex total number of posit parameters */
803    number_posit_pars,
804} posit_codes;
805
806typedef enum unit_codes {
807    /*tex total number of unit parameters */
808    number_unit_pars,
809} unit_codes;
810
811
812// typedef enum special_sequence_codes {
813//  // current_font_sequence_code,
814//     undefined_control_sequence_code,
815//     n_of_special_sequences,
816// } special_sequence_codes;
817//
818// /* The last one is frozen_null_font. */
819//
820// # define special_sequence_base         (last_frozen_cs_loc + 1)
821// # define current_font_sequence         (special_sequence_base + current_font_sequence_code)
822// # define undefined_control_sequence    (special_sequence_base + undefined_control_sequence_code)
823// # define first_register_base           (special_sequence_base + n_of_special_sequences)
824
825# define undefined_control_sequence     deep_frozen_cs_undefined_code
826
827# define special_sequence_base          (last_deep_frozen_cs_location + 1)
828# define first_register_base            (last_deep_frozen_cs_location + 1)
829
830# define internal_glue_base             (first_register_base)
831# define register_glue_base             (internal_glue_base + number_glue_pars + 1)
832# define internal_glue_location(a)      (internal_glue_base + (a))
833# define register_glue_location(a)      (register_glue_base + (a))
834# define internal_glue_number(a)        ((a) - internal_glue_base)
835# define register_glue_number(a)        ((a) - register_glue_base)
836
837# define internal_muglue_base           (register_glue_base + max_n_of_glue_registers)
838# define register_muglue_base           (internal_muglue_base + number_muglue_pars + 1)
839# define internal_muglue_location(a)    (internal_muglue_base + (a))
840# define register_muglue_location(a)    (register_muglue_base + (a))
841# define internal_muglue_number(a)      ((a) - internal_muglue_base)
842# define register_muglue_number(a)      ((a) - register_muglue_base)
843
844# define internal_toks_base             (register_muglue_base + max_n_of_muglue_registers)
845# define register_toks_base             (internal_toks_base + number_tok_pars + 1)
846# define internal_toks_location(a)      (internal_toks_base + (a))
847# define register_toks_location(a)      (register_toks_base + (a))
848# define internal_toks_number(a)        ((a) - internal_toks_base)
849# define register_toks_number(a)        ((a) - register_toks_base)
850
851# define internal_box_base              (register_toks_base + max_n_of_toks_registers)
852# define register_box_base              (internal_box_base + number_box_pars + 1)
853# define internal_box_location(a)       (internal_box_base + (a))
854# define register_box_location(a)       (register_box_base + (a))
855# define internal_box_number(a)         ((a) - internal_box_base)
856# define register_box_number(a)         ((a) - register_box_base)
857
858# define internal_integer_base          (register_box_base + max_n_of_box_registers)
859# define register_integer_base          (internal_integer_base + number_integer_pars + 1)
860# define internal_integer_location(a)   (internal_integer_base + (a))
861# define register_integer_location(a)   (register_integer_base + (a))
862# define internal_integer_number(a)     ((a) - internal_integer_base)
863# define register_integer_number(a)     ((a) - register_integer_base)
864
865# define internal_attribute_base        (register_integer_base + max_n_of_integer_registers)
866# define register_attribute_base        (internal_attribute_base + number_attribute_pars + 1)
867# define internal_attribute_location(a) (internal_attribute_base + (a))
868# define register_attribute_location(a) (register_attribute_base + (a))
869# define internal_attribute_number(a)   ((a) - internal_attribute_base)
870# define register_attribute_number(a)   ((a) - register_attribute_base)
871
872# define internal_dimension_base        (register_attribute_base + max_n_of_attribute_registers)
873# define register_dimension_base        (internal_dimension_base + number_dimension_pars + 1)
874# define internal_dimension_location(a) (internal_dimension_base + (a))
875# define register_dimension_location(a) (register_dimension_base + (a))
876# define internal_dimension_number(a)   ((a) - internal_dimension_base)
877# define register_dimension_number(a)   ((a) - register_dimension_base)
878
879# define internal_posit_base            (register_dimension_base + max_n_of_dimension_registers)
880# define register_posit_base            (internal_posit_base + number_posit_pars + 1)
881# define internal_posit_location(a)     (internal_posit_base + (a))
882# define register_posit_location(a)     (register_posit_base + (a))
883# define internal_posit_number(a)       ((a) - internal_posit_base)
884# define register_posit_number(a)       ((a) - register_posit_base)
885
886# define internal_unit_base             (register_posit_base + max_n_of_posit_registers)
887# define internal_unit_location(a)      (internal_unit_base + (a))
888# define internal_unit_number(a)        ((a) - internal_unit_base)
889
890# define internal_specification_base        (internal_unit_base + max_n_of_unit_registers)
891# define internal_specification_location(a) (internal_specification_base + (a))
892# define internal_specification_number(a)   ((a) - internal_specification_base)
893
894# define eqtb_size       (internal_specification_base + number_specification_pars)
895# define eqtb_max_so_far (eqtb_size + lmt_hash_state.hash_data.ptr + 1)
896
897/* below: top or ptr +1 ? */
898
899# define eqtb_indirect_range(n) ((n < internal_glue_base) || ((n > eqtb_size) && (n <= lmt_hash_state.hash_data.top)))
900# define eqtb_out_of_range(n)   ((n >= undefined_control_sequence) && ((n <= eqtb_size) || n > lmt_hash_state.hash_data.top))
901# define eqtb_invalid_cs(n)     ((n == 0) || (n > lmt_hash_state.hash_data.top) || ((n > frozen_control_sequence) && (n <= eqtb_size)))
902
903# define character_in_range(i)  (i >= 0 && i <= max_character_code)
904# define catcode_in_range(i)    (i >= 0 && i <= max_category_code)
905# define family_in_range(i)     (i >= 0 && i <= max_math_family_index)
906# define class_in_range(i)      (i >= 0 && i <= max_math_class_code)
907# define half_in_range(i)       (i >= 0 && i <= max_half_value)
908# define box_index_in_range(i)  (i >= 0 && i <= max_box_index)
909
910/* These also have funny offsets: */
911
912typedef enum align_codes  {
913    tab_mark_code,
914    span_code,
915    omit_code,
916    align_content_code,
917    no_align_code,
918    re_align_code,
919    cr_code,
920    cr_cr_code,
921} align_codes;
922
923/*
924    typedef struct equivalents_state_info {
925    } equivalents_state_info ;
926
927    extern equivalents_state_info lmt_equivalents_state;
928*/
929
930extern void tex_initialize_levels       (void);
931extern void tex_initialize_destructors  (void);
932extern void tex_initialize_equivalents  (void);
933extern void tex_synchronize_equivalents (void);
934extern void tex_initialize_undefined_cs (void);
935extern void tex_dump_equivalents_mem    (dumpstream f);
936extern void tex_undump_equivalents_mem  (dumpstream f);
937
938/*tex
939    The more low level |_field| shortcuts are used when we (for instance) work with copies, as done
940    in the save stack entries. In most cases we use the second triplet of shortcuts. We replaced
941    |equiv(A)| and |equiv_value(A)| by |eq_value(A)}|.
942*/
943
944# define eq_level_field(A) (A).quart01
945# define eq_full_field(A)  (A).quart00
946# define eq_type_field(A)  (A).single00
947# define eq_flag_field(A)  (A).single01
948# define eq_value_field(A) (A).half1
949
950# define eq_level(A)       lmt_hash_state.eqtb[(A)].quart01  /*tex level of definition */
951# define eq_full(A)        lmt_hash_state.eqtb[(A)].quart00
952# define eq_type(A)        lmt_hash_state.eqtb[(A)].single00 /*tex command code for equivalent */
953# define eq_flag(A)        lmt_hash_state.eqtb[(A)].single01
954# define eq_details(A)     lmt_hash_state.eqtb[(A)].half0
955# define eq_value(A)       lmt_hash_state.eqtb[(A)].half1
956
957# define set_eq_level(A,B) lmt_hash_state.eqtb[(A)].quart01  = (quarterword) (B)
958# define set_eq_type(A,B)  lmt_hash_state.eqtb[(A)].single00 = (singleword) (B)
959# define set_eq_flag(A,B)  lmt_hash_state.eqtb[(A)].single01 = (singleword) (B)
960# define set_eq_value(A,B) lmt_hash_state.eqtb[(A)].half1    = (B)
961
962# define copy_eqtb_entry(target,source) lmt_hash_state.eqtb[target] = lmt_hash_state.eqtb[source]
963
964# define equal_eqtb_entries(A,B) ( \
965    (lmt_hash_state.eqtb[(A)].half0 == lmt_hash_state.eqtb[(B)].half0) \
966 && (lmt_hash_state.eqtb[(A)].half1 == lmt_hash_state.eqtb[(B)].half1) \
967)
968
969/* or:
970# define equal_eqtb_entries(A,B) ( \
971    (lmt_hash_state.eqtb[(A)].long0 == lmt_hash_state.eqtb[(B)].long0) \
972)
973*/
974
975typedef enum eq_destructors {
976    eq_none,
977    eq_token_list,
978    eq_node,
979    eq_node_list,
980} eq_destructors;
981
982/*tex
983
984    Because we operate in 64 bit we padd with a halfword, and because if that we have an extra field. Now,
985    because we already no longer need the parallel eqtb level table, we can use this field to store the
986    value alongside which makes that we can turn the dual slot |restore_old_value| and |saved_eqtb| into
987    one which in turn makes stack usage shrink. The performance gain is probably neglectable.
988
989*/
990
991typedef struct save_record {
992    union {
993        quarterword saved_level;
994        quarterword saved_group;
995        quarterword saved_record;
996    };
997    quarterword saved_type;
998    union {
999        halfword saved_value;
1000        halfword saved_value_1;
1001    };
1002    union {
1003        memoryword saved_word;
1004        struct {
1005            halfword saved_value_2;
1006            halfword saved_value_3;
1007        };
1008    };
1009} save_record;
1010
1011typedef struct save_state_info {
1012    save_record  *save_stack;
1013    memory_data   save_stack_data;
1014    quarterword   current_level;        /*tex current nesting level for groups */
1015    quarterword   current_group;        /*tex current group type */
1016    int           current_boundary;     /*tex where the current level begins */
1017 // int           padding;
1018} save_state_info;
1019
1020extern save_state_info lmt_save_state;
1021
1022# define cur_level    lmt_save_state.current_level
1023# define cur_group    lmt_save_state.current_group
1024# define cur_boundary lmt_save_state.current_boundary
1025
1026/*tex
1027
1028    We use the notation |saved(k)| to stand for an item that appears in location |save_ptr + k| of
1029    the save stack. The level field is also available for other purposes, so we have |extra| as an
1030    more generic alias.
1031
1032*/
1033
1034# define save_type(A)    lmt_save_state.save_stack[A].saved_type     /*tex classifies a |save_stack| entry */
1035# define save_record(A)  lmt_save_state.save_stack[A].saved_record
1036# define save_level(A)   lmt_save_state.save_stack[A].saved_level    /*tex saved level for regions 5 and 6, or group code, or ...  */
1037# define save_group(A)   lmt_save_state.save_stack[A].saved_group
1038
1039# define save_value(A)   lmt_save_state.save_stack[A].saved_value    /*tex |eqtb| location or token or |save_stack| location or ... */
1040# define save_word(A)    lmt_save_state.save_stack[A].saved_word     /*tex |eqtb| entry */
1041
1042# define save_value_1(A) lmt_save_state.save_stack[A].saved_value_1
1043# define save_value_2(A) lmt_save_state.save_stack[A].saved_value_2
1044# define save_value_3(A) lmt_save_state.save_stack[A].saved_value_3
1045
1046# define saved_type(A)    lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_type
1047# define saved_record(A)  lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_record
1048# define saved_level(A)   lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_level
1049# define saved_group(A)   lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_group
1050
1051# define saved_value_1(A) lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_value_1
1052# define saved_value_2(A) lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_value_2
1053# define saved_value_3(A) lmt_save_state.save_stack[lmt_save_state.save_stack_data.ptr + (A)].saved_value_3
1054
1055# define reserved_save_stack_slots 32 /* plenty reserve */
1056
1057/*tex
1058
1059    The rather explicit |save_| items indicate a type. They are sometimes used to lookup a specific
1060    field (when tracing).
1061
1062    The save stack is now a bit more hybrid because we use |memoryword| for |value_2| and |value_3|
1063    so this will be cleaned up a bit.
1064
1065*/
1066
1067typedef enum save_types {
1068    /* recovery entries */
1069    restore_old_value_save_type, /*tex a value should be restored later */
1070    restore_zero_save_type,      /*tex an undefined entry should be restored */
1071    insert_tokens_save_type,
1072    restore_lua_save_type,
1073    level_boundary_save_type,    /*tex the beginning of a group */
1074    /* data entries */
1075    saved_record_0,
1076    saved_record_1,
1077    saved_record_2,
1078    saved_record_3,
1079    saved_record_4,
1080    saved_record_5,
1081    saved_record_6,
1082    saved_record_7,
1083    saved_record_8,
1084    saved_record_9,
1085} save_types;
1086
1087typedef enum save_record_types {
1088    unknown_save_type,
1089    box_save_type,
1090    local_box_save_type,
1091    alignment_save_type,
1092    adjust_save_type,
1093    math_save_type,
1094    fraction_save_type,
1095    radical_save_type,
1096    operator_save_type,
1097    math_group_save_type,
1098    choice_save_type,
1099    number_save_type,
1100    insert_save_type,
1101    discretionary_save_type,
1102} save_record_types;
1103
1104/*tex Nota bena: |equiv_value| is the same as |equiv| but sometimes we use that name instead. */
1105
1106// int_par(A) hash_state.eqtb_i_i[(A)].half1
1107
1108# define integer_parameter(A)       eq_value(internal_integer_location(A))
1109# define posit_parameter(A)         eq_value(internal_posit_location(A))
1110# define attribute_parameter(A)     eq_value(internal_attribute_location(A))
1111# define dimension_parameter(A)     eq_value(internal_dimension_location(A))
1112# define toks_parameter(A)          eq_value(internal_toks_location(A))
1113# define glue_parameter(A)          eq_value(internal_glue_location(A))
1114# define muglue_parameter(A)        eq_value(internal_muglue_location(A))
1115# define box_parameter(A)           eq_value(internal_box_location(A))
1116# define specification_parameter(A) eq_value(internal_specification_location(A))
1117# define unit_parameter(A)          eq_value(internal_unit_location(A))
1118
1119# define count_parameter   integer_parameter
1120# define dimen_parameter   dimension_parameter
1121# define skip_parameter    glue_parameter
1122# define muskip_parameter  muglue_parameter
1123
1124# define unit_parameter_hash(l,r)   (26 * (l - 'a') + (r - 'a'))
1125
1126typedef enum unit_classes {
1127    unset_unit_class      = 0,
1128    tex_unit_class        = 1,
1129    pdftex_unit_class     = 2,
1130    luametatex_unit_class = 3,
1131    user_unit_class       = 4,
1132} unit_classes;
1133
1134static inline int unit_parameter_index(int l, int r) {
1135    if (l >= 'a' && l <= 'z' && r >= 'a' && r <= 'z') {
1136        /* okay */
1137    } else {
1138        if (l >= 'A' && l <= 'Z') { 
1139            l |= 0x60;
1140        } else if (l >= 'a' && l <= 'z') {
1141            /* okay */
1142        } else { 
1143            return -1;
1144        }
1145        if (r >= 'A' && r <= 'Z') {
1146            r |= 0x60;
1147        } else if (r >= 'a' && r <= 'z') {
1148            /* okay */
1149        } else { 
1150            return -1;
1151        }
1152    }
1153    return unit_parameter_hash(l,r);
1154}
1155
1156/*tex These come from |\ALEPH| aka |\OMEGA|: */
1157
1158# define is_valid_local_box_code(c) (c >= first_local_box_code && c <= last_local_box_code)
1159
1160typedef enum tex_tracing_levels_codes {
1161    tracing_levels_group    = 0x01,
1162    tracing_levels_input    = 0x02,
1163    tracing_levels_catcodes = 0x04,
1164} tex_tracing_levels_codes;
1165
1166extern void tex_initialize_save_stack  (void);
1167/*     int  tex_room_on_save_stack     (void); */
1168extern void tex_save_halfword_on_stack (quarterword t, halfword v);
1169extern void tex_show_cmd_chr           (halfword cmd, halfword chr);
1170extern void tex_new_save_level         (quarterword group);                        /*tex begin a new level of grouping */
1171extern int  tex_saved_line_at_level    (void);
1172extern void tex_eq_define              (halfword p, singleword cmd, halfword chr); /*tex new data for |eqtb| */
1173extern void tex_eq_word_define         (halfword p, int w);
1174extern void tex_geq_define             (halfword p, singleword cmd, halfword chr); /*tex global |eq_define| */
1175extern void tex_geq_word_define        (halfword p, int w);                        /*tex global |eq_word_define| */
1176extern void tex_save_for_after_group   (halfword t);
1177extern void tex_unsave                 (void);                                     /*tex pops the top level off the save stack */
1178extern void tex_show_save_groups       (void);
1179extern int  tex_located_save_value     (int id);
1180extern void tex_show_save_stack        (void);
1181extern void tex_save_stack_catch_up    (void);
1182
1183/*tex
1184
1185    The |prefixed_command| does not have to adjust |a| so that |a mod 4 = 0|, since the following
1186    routines test for the |\global| prefix as follows. Anyway, in the meantime we reshuffled the
1187    bits and changed a lot.
1188
1189    When we need more bits, we will do this:
1190
1191    One one of these:
1192
1193    \starttyping
1194    primitive_flag   = 00000001 : cannot be changed  system set
1195    permanent_flag   = 00000010 : cannot be changed  \permanent
1196    immutable_flag   = 00000011 : cannot be changed  \immutable
1197    frozen_flag      = 00000100 : can be overloaded  \frozen and \overloaded
1198    mutable_flag     = 00000101 : never checked      \mutable
1199    reserved_1_flag  = 00000110
1200    \stoptyping
1201
1202    Independent, not used combined:
1203
1204    \starttyping
1205    noaligned_flag   = 00001000 : valid align peek   \noaligned (can be more generic: \alignpeekable or \alignable, also span and omit?)
1206    reserved_3_flag  = 00010000 : maybe obsolete indicator
1207    \stoptyping
1208
1209    Informative:
1210
1211    \starttyping
1212    instance_flag    = 00100000 : just a tag         \instance
1213    symbol_flag      = 01000000 : just a tag         \symbolic (or character)
1214    c_quantity_flag  = 01100000
1215    d_quantity-flag  = 10000000
1216    reserved_4_flag  = 10100000
1217    reserved_5_flag  = 11100000
1218    \stoptyping
1219
1220    Maybe names like \flaginstance \flagpermanent etc are better? Now we run out of meaningful
1221    prefixes. Also testing the prefix then becomes more work.
1222
1223*/
1224
1225typedef enum flag_bit {
1226    /* properties and prefixes */
1227    frozen_flag_bit        = 0x000001,
1228    permanent_flag_bit     = 0x000002,
1229    immutable_flag_bit     = 0x000004,
1230    primitive_flag_bit     = 0x000008,
1231    mutable_flag_bit       = 0x000010,
1232    noaligned_flag_bit     = 0x000020,
1233    instance_flag_bit      = 0x000040,
1234    untraced_flag_bit      = 0x000080,
1235    /* prefixes */
1236    global_flag_bit        = 0x000100,
1237    tolerant_flag_bit      = 0x000200,
1238    protected_flag_bit     = 0x000400,
1239    overloaded_flag_bit    = 0x000800,
1240    aliased_flag_bit       = 0x001000,
1241    immediate_flag_bit     = 0x002000,
1242    conditional_flag_bit   = 0x004000,
1243    value_flag_bit         = 0x008000,
1244    semiprotected_flag_bit = 0x010000,
1245    inherited_flag_bit     = 0x020000,
1246    constant_flag_bit      = 0x040000,
1247    deferred_flag_bit      = 0x080000, /* this might move up */
1248    retained_flag_bit      = 0x100000,
1249    constrained_flag_bit   = 0x200000,
1250} flag_bits;
1251
1252/*tex Flags: */
1253
1254# define add_flag(a,b)              ((a) | (b))
1255
1256# define add_frozen_flag(a)         ((a) | frozen_flag_bit)
1257# define add_permanent_flag(a)      ((a) | permanent_flag_bit)
1258# define add_immutable_flag(a)      ((a) | immutable_flag_bit)
1259# define add_primitive_flag(a)      ((a) | primitive_flag_bit)
1260# define add_mutable_flag(a)        ((a) | mutable_flag_bit)
1261# define add_noaligned_flag(a)      ((a) | noaligned_flag_bit)
1262# define add_instance_flag(a)       ((a) | instance_flag_bit)
1263# define add_untraced_flag(a)       ((a) | untraced_flag_bit)
1264
1265# define add_global_flag(a)         ((a) | global_flag_bit)
1266# define add_tolerant_flag(a)       ((a) | tolerant_flag_bit)
1267# define add_protected_flag(a)      ((a) | protected_flag_bit)
1268# define add_semiprotected_flag(a)  ((a) | semiprotected_flag_bit)
1269# define add_overloaded_flag(a)     ((a) | overloaded_flag_bit)
1270# define add_aliased_flag(a)        ((a) | aliased_flag_bit)
1271# define add_immediate_flag(a)      ((a) | immediate_flag_bit)
1272# define add_deferred_flag(a)       ((a) | deferred_flag_bit)
1273# define add_conditional_flag(a)    ((a) | conditional_flag_bit)
1274# define add_value_flag(a)          ((a) | value_flag_bit)
1275# define add_inherited_flag(a)      ((a) | inherited_flag_bit)
1276# define add_constant_flag(a)       ((a) | constant_flag_bit)
1277# define add_retained_flag(a)       ((a) | retained_flag_bit)
1278# define add_constrained_flag(a)    ((a) | constrained_flag_bit)
1279
1280# define remove_flag(a,b)           ((a) & ~(b))
1281
1282# define remove_frozen_flag(a)      ((a) & ~frozen_flag_bit)
1283# define remove_permanent_flag(a)   ((a) & ~permanent_flag_bit)
1284# define remove_immutable_flag(a)   ((a) & ~immutable_flag_bit)
1285# define remove_primitive_flag(a)   ((a) & ~primitive_flag_bit)
1286# define remove_mutable_flag(a)     ((a) & ~mutable_flag_bit)
1287# define remove_noaligned_flag(a)   ((a) & ~noaligned_flag_bit)
1288# define remove_instance_flag(a)    ((a) & ~instance_flag_bit)
1289# define remove_untraced_flag(a)    ((a) & ~untraced_flag_bit)
1290
1291# define remove_global_flag(a)      ((a) & ~global_flag_bit)
1292# define remove_tolerant_flag(a)    ((a) & ~tolerant_flag_bit)
1293# define remove_protected_flag(a)   ((a) & ~protected_flag_bit)
1294# define remove_overloaded_flag(a)  ((a) & ~overloaded_flag_bit)
1295# define remove_aliased_flag(a)     ((a) & ~aliased_flag_bit)
1296# define remove_immediate_flag(a)   ((a) & ~immediate_flag_bit)
1297# define remove_deferred_flag(a)    ((a) & ~deferred_flag_bit)
1298# define remove_conditional_flag(a) ((a) & ~conditional_flag_bit)
1299# define remove_value_flag(a)       ((a) & ~value_flag_bit)
1300
1301# define is_frozen(a)               (((a) & frozen_flag_bit))
1302# define is_permanent(a)            (((a) & permanent_flag_bit))
1303# define is_immutable(a)            (((a) & immutable_flag_bit))
1304# define is_primitive(a)            (((a) & primitive_flag_bit))
1305# define is_mutable(a)              (((a) & mutable_flag_bit))
1306# define is_noaligned(a)            (((a) & noaligned_flag_bit))
1307# define is_instance(a)             (((a) & instance_flag_bit))
1308# define is_untraced(a)             (((a) & untraced_flag_bit))
1309
1310# define is_global(a)               (((a) & global_flag_bit))
1311# define is_tolerant(a)             (((a) & tolerant_flag_bit))
1312# define is_protected(a)            (((a) & protected_flag_bit))
1313# define is_semiprotected(a)        (((a) & semiprotected_flag_bit))
1314# define is_overloaded(a)           (((a) & overloaded_flag_bit))
1315# define is_aliased(a)              (((a) & aliased_flag_bit))
1316# define is_immediate(a)            (((a) & immediate_flag_bit))
1317# define is_deferred(a)             (((a) & deferred_flag_bit))
1318# define is_conditional(a)          (((a) & conditional_flag_bit))
1319# define is_value(a)                (((a) & value_flag_bit))
1320# define is_inherited(a)            (((a) & inherited_flag_bit))
1321# define is_constant(a)             (((a) & constant_flag_bit))
1322# define is_retained(a)             (((a) & retained_flag_bit))
1323# define is_constrained(a)          (((a) & constrained_flag_bit))
1324
1325# define is_expandable(cmd)         (cmd > max_command_cmd)
1326
1327# define global_or_local(a)         (is_global(a) ? level_one : cur_level)
1328
1329# define has_flag_bits(p,a)         ((p) & (a))
1330
1331# define remove_overload_flags(a)   ((a) & ~(permanent_flag_bit | immutable_flag_bit | primitive_flag_bit))
1332
1333# define make_eq_flag_bits(a)       ((singleword) ((a) & 0xFF))
1334# define has_eq_flag_bits(p,a)      (eq_flag(p) & (a))
1335# define set_eq_flag_bits(p,a)      set_eq_flag(p, make_eq_flag_bits(a))
1336
1337static inline singleword tex_flags_to_cmd(int flags)
1338{
1339    if (is_constant(flags)) {
1340        return constant_call_cmd;
1341    } else if (is_tolerant(flags)) {
1342        return is_protected    (flags) ? tolerant_protected_call_cmd :
1343              (is_semiprotected(flags) ? tolerant_semi_protected_call_cmd : tolerant_call_cmd);
1344    } else {
1345        return is_protected    (flags) ? protected_call_cmd :
1346              (is_semiprotected(flags) ? semi_protected_call_cmd : call_cmd);
1347    }
1348}
1349
1350/*tex
1351    The macros and functions for the frozen, tolerant, protected cmd codes are gone but
1352    can be found in the archive. We now have just one |call_cmd| with properties stored
1353    elsewhere.
1354
1355    int g -> singleword g
1356*/
1357
1358extern int  tex_define_permitted   (halfword cs, halfword prefixes);
1359extern void tex_define             (int g, halfword p, singleword cmd, halfword chr);
1360extern void tex_define_again       (int g, halfword p, singleword cmd, halfword chr);
1361extern void tex_define_inherit     (int g, halfword p, singleword flag, singleword cmd, halfword chr);
1362extern void tex_define_swapped     (int g, halfword p1, halfword p2, int force);
1363extern void tex_forced_define      (int g, halfword p, singleword flag, singleword cmd, halfword chr);
1364extern void tex_word_define        (int g, halfword p, halfword w);
1365/*     void tex_forced_word_define (int g, halfword p, singleword flag, halfword w); */
1366
1367/*tex
1368
1369    The |*_par| macros expand to the variables that are (in most cases) also accessible at the users
1370    end. Most are registers but some are in the (stack) lists. More |*_par| will move here: there is
1371    no real need for these macros but because there were already a bunch and because they were defined
1372    all over the place we moved them here.
1373
1374*/
1375
1376# define local_left_box_par               box_parameter(local_left_box_code)
1377# define local_middle_box_par             box_parameter(local_middle_box_code)
1378# define local_right_box_par              box_parameter(local_right_box_code)
1379
1380# define balance_emergency_shrink_par     dimension_parameter(balance_emergency_shrink_code)
1381# define balance_emergency_stretch_par    dimension_parameter(balance_emergency_stretch_code)
1382# define balance_vsize_par                dimension_parameter(balance_vsize_code)
1383# define balance_line_height_par          dimension_parameter(balance_line_height_code)
1384# define box_max_depth_par                dimension_parameter(box_max_depth_code)
1385# define box_max_depth_par                dimension_parameter(box_max_depth_code)
1386# define delimiter_shortfall_par          dimension_parameter(delimiter_shortfall_code)
1387# define display_indent_par               dimension_parameter(display_indent_code)
1388# define display_width_par                dimension_parameter(display_width_code)
1389# define emergency_extra_stretch_par      dimension_parameter(emergency_extra_stretch_code)
1390# define emergency_stretch_par            dimension_parameter(emergency_stretch_code)
1391# define glyph_x_offset_par               dimension_parameter(glyph_x_offset_code)
1392# define glyph_y_offset_par               dimension_parameter(glyph_y_offset_code)
1393# define hang_indent_par                  dimension_parameter(hang_indent_code)
1394# define hfuzz_par                        dimension_parameter(hfuzz_code)
1395# define hsize_par                        dimension_parameter(hsize_code)
1396# define ignore_depth_criterion_par       dimension_parameter(ignore_depth_criterion_code)
1397# define line_skip_limit_par              dimension_parameter(line_skip_limit_code)
1398# define math_surround_par                dimension_parameter(math_surround_code)
1399# define max_depth_par                    dimension_parameter(max_depth_code)
1400# define null_delimiter_space_par         dimension_parameter(null_delimiter_space_code)
1401# define null_delimiter_space_par         dimension_parameter(null_delimiter_space_code)
1402# define overfull_rule_par                dimension_parameter(overfull_rule_code)
1403# define page_extra_goal_par              dimension_parameter(page_extra_goal_code)
1404# define par_indent_par                   dimension_parameter(par_indent_code)
1405# define pre_display_size_par             dimension_parameter(pre_display_size_code)
1406# define px_dimension_par                 dimension_parameter(px_dimension_code)
1407# define script_space_par                 dimension_parameter(script_space_code)
1408# define short_inline_math_threshold_par  dimension_parameter(short_inline_math_threshold_code)
1409# define split_extra_height_par           dimension_parameter(split_extra_height_code)
1410# define split_max_depth_par              dimension_parameter(split_max_depth_code)
1411# define tab_size_par                     dimension_parameter(tab_size_code)
1412# define vfuzz_par                        dimension_parameter(vfuzz_code)
1413# define vsize_par                        dimension_parameter(vsize_code)
1414
1415# define additional_page_skip_par         glue_parameter(additional_page_skip_code)
1416# define balance_bottom_skip_par          glue_parameter(balance_bottom_skip_code)
1417# define balance_top_skip_par             glue_parameter(balance_top_skip_code)
1418# define baseline_skip_par                glue_parameter(baseline_skip_code)
1419# define bottom_skip_par                  glue_parameter(bottom_skip_code)
1420# define emergency_left_skip_par          glue_parameter(emergency_left_skip_code)
1421# define emergency_right_skip_par         glue_parameter(emergency_right_skip_code)
1422# define initial_page_skip_par            glue_parameter(initial_page_skip_code)
1423# define initial_top_skip_par             glue_parameter(initial_top_skip_code)
1424# define left_skip_par                    glue_parameter(left_skip_code)
1425# define line_skip_par                    glue_parameter(line_skip_code)
1426# define math_skip_par                    glue_parameter(math_skip_code)
1427# define math_threshold_par               glue_parameter(math_threshold_code)
1428# define par_fill_left_skip_par           glue_parameter(par_fill_left_skip_code)
1429# define par_fill_right_skip_par          glue_parameter(par_fill_right_skip_code)
1430# define par_init_left_skip_par           glue_parameter(par_init_left_skip_code)
1431# define par_init_right_skip_par          glue_parameter(par_init_right_skip_code)
1432# define right_skip_par                   glue_parameter(right_skip_code)
1433# define space_skip_par                   glue_parameter(space_skip_code)
1434# define split_top_skip_par               glue_parameter(split_top_skip_code)
1435# define tab_skip_par                     glue_parameter(tab_skip_code)
1436# define top_skip_par                     glue_parameter(top_skip_code)
1437# define xspace_skip_par                  glue_parameter(xspace_skip_code)
1438
1439# define adj_demerits_par                 integer_parameter(adj_demerits_code)
1440# define adjust_spacing_par               integer_parameter(adjust_spacing_code)
1441# define adjust_spacing_shrink_par        integer_parameter(adjust_spacing_shrink_code)
1442# define adjust_spacing_step_par          integer_parameter(adjust_spacing_step_code)
1443# define adjust_spacing_stretch_par       integer_parameter(adjust_spacing_stretch_code)
1444# define alignment_cell_source_par        integer_parameter(alignment_cell_source_code)
1445# define alignment_wrap_source_par        integer_parameter(alignment_wrap_source_code)
1446# define auto_migration_mode_par          integer_parameter(auto_migration_mode_code)
1447# define auto_paragraph_mode_par          integer_parameter(auto_paragraph_mode_code)
1448# define automatic_hyphen_penalty_par     integer_parameter(automatic_hyphen_penalty_code)
1449# define balance_adj_demerits_par         integer_parameter(balance_adj_demerits_code)
1450# define balance_break_passes_par         integer_parameter(balance_break_passes_code)
1451# define balance_checks_par               integer_parameter(balance_checks_code)
1452# define balance_looseness_par            integer_parameter(balance_looseness_code)
1453# define balance_tolerance_par            integer_parameter(balance_tolerance_code)
1454# define balance_penalty_par              integer_parameter(balance_penalty_code)
1455# define box_limit_mode_par               integer_parameter(box_limit_mode_code)
1456# define broken_penalty_par               integer_parameter(broken_penalty_code)
1457# define cat_code_table_par               integer_parameter(cat_code_table_code)
1458# define club_penalty_par                 integer_parameter(club_penalty_code)
1459# define copy_lua_input_nodes_par         integer_parameter(copy_lua_input_nodes_code)
1460# define cur_fam_par                      integer_parameter(family_code)
1461# define cur_font_par                     integer_parameter(font_code)
1462# define cur_lang_par                     integer_parameter(language_code)
1463# define day_par                          integer_parameter(day_code)
1464# define default_hyphen_char_par          integer_parameter(default_hyphen_char_code)
1465# define default_skew_char_par            integer_parameter(default_skew_char_code)
1466# define delimiter_factor_par             integer_parameter(delimiter_factor_code)
1467# define discretionary_options_par        integer_parameter(discretionary_options_code)
1468# define display_skip_mode_par            integer_parameter(math_display_skip_mode_code)
1469# define display_widow_penalty_par        integer_parameter(display_widow_penalty_code)
1470# define double_hyphen_demerits_par       integer_parameter(double_hyphen_demerits_code)
1471# define double_penalty_mode_par          integer_parameter(double_penalty_mode_code)
1472# define end_line_char_par                integer_parameter(end_line_char_code)
1473# define error_context_lines_par          integer_parameter(error_context_lines_code)
1474# define escape_char_par                  integer_parameter(escape_char_code)
1475# define etex_expr_mode_par               integer_parameter(etex_expr_mode_code)
1476# define eu_factor_par                    integer_parameter(eu_factor_code)
1477# define ex_hyphen_char_par               integer_parameter(ex_hyphen_char_code)
1478# define ex_apostrophe_char_par           integer_parameter(ex_apostrophe_char_code)
1479# define ex_hyphen_penalty_par            integer_parameter(ex_hyphen_penalty_code)
1480# define exception_penalty_par            integer_parameter(exception_penalty_code)
1481# define explicit_hyphen_penalty_par      integer_parameter(explicit_hyphen_penalty_code)
1482# define final_hyphen_demerits_par        integer_parameter(final_hyphen_demerits_code)
1483# define first_valid_language_par         integer_parameter(first_valid_language_code)
1484# define floating_penalty_par             integer_parameter(floating_penalty_code)
1485# define global_defs_par                  integer_parameter(global_defs_code)
1486# define glyph_data_par                   integer_parameter(glyph_data_code)
1487# define glyph_options_par                integer_parameter(glyph_options_code)
1488# define glyph_scale_par                  integer_parameter(glyph_scale_code)
1489# define glyph_script_par                 integer_parameter(glyph_script_code)
1490# define glyph_script_scale_par           integer_parameter(glyph_script_scale_code)
1491# define glyph_scriptscript_scale_par     integer_parameter(glyph_scriptscript_scale_code)
1492# define glyph_slant_par                  integer_parameter(glyph_slant_code)
1493# define glyph_state_par                  integer_parameter(glyph_state_code)
1494# define glyph_text_scale_par             integer_parameter(glyph_text_scale_code)
1495# define glyph_weight_par                 integer_parameter(glyph_weight_code)
1496# define glyph_x_scale_par                integer_parameter(glyph_x_scale_code)
1497# define glyph_y_scale_par                integer_parameter(glyph_y_scale_code)
1498# define hang_after_par                   integer_parameter(hang_after_code)
1499# define hbadness_par                     integer_parameter(hbadness_code)
1500# define hbadness_mode_par                integer_parameter(hbadness_mode_code)
1501# define holding_inserts_par              integer_parameter(holding_inserts_code)
1502# define holding_migrations_par           integer_parameter(holding_migrations_code)
1503# define hyphen_penalty_par               integer_parameter(hyphen_penalty_code)
1504# define hyphenation_mode_par             integer_parameter(hyphenation_mode_code)
1505# define inter_line_penalty_par           integer_parameter(inter_line_penalty_code)
1506# define internal_dir_state_par           integer_parameter(internal_dir_state_code)
1507# define internal_math_scale_par          integer_parameter(internal_math_scale_code)
1508# define internal_math_style_par          integer_parameter(internal_math_style_code)
1509# define internal_par_state_par           integer_parameter(internal_par_state_code)
1510# define language_par                     integer_parameter(language_code)
1511# define last_line_fit_par                integer_parameter(last_line_fit_code)
1512# define left_hyphen_min_par              integer_parameter(left_hyphen_min_code)
1513# define left_twin_demerits_par           integer_parameter(left_twin_demerits_code)
1514# define line_break_checks_par            integer_parameter(line_break_checks_code)
1515# define line_break_optional_par          integer_parameter(line_break_optional_code)
1516# define line_break_passes_par            integer_parameter(line_break_passes_code)
1517# define line_penalty_par                 integer_parameter(line_penalty_code)
1518# define local_broken_penalty_par         integer_parameter(local_broken_penalty_code)
1519# define local_interline_penalty_par      integer_parameter(local_interline_penalty_code)
1520# define local_pre_tolerance_par          integer_parameter(local_pre_tolerance_code)
1521# define local_tolerance_par              integer_parameter(local_tolerance_code)
1522# define looseness_par                    integer_parameter(looseness_code)
1523# define math_begin_class_par             integer_parameter(math_begin_class_code)
1524# define math_check_fences_par            integer_parameter(math_check_fences_mode_code)
1525# define math_dict_group_par              integer_parameter(math_dict_group_code)
1526# define math_dict_properties_par         integer_parameter(math_dict_properties_code)
1527# define math_direction_par               integer_parameter(math_direction_code)
1528# define math_display_mode_par            integer_parameter(math_display_mode_code)
1529# define math_display_penalty_factor_par  integer_parameter(math_display_penalty_factor_code)
1530# define math_double_script_mode_par      integer_parameter(math_double_script_mode_code)
1531# define math_end_class_par               integer_parameter(math_end_class_code)
1532# define math_eqno_gap_step_par           integer_parameter(math_eqno_gap_step_code)
1533# define math_font_control_par            integer_parameter(math_font_control_code)
1534# define math_glue_mode_par               integer_parameter(math_glue_mode_code)
1535# define math_grouping_mode_par           integer_parameter(math_grouping_mode_code)
1536# define math_inline_penalty_factor_par   integer_parameter(math_inline_penalty_factor_code)
1537# define math_left_class_par              integer_parameter(math_left_class_code)
1538# define math_limits_mode_par             integer_parameter(math_limits_mode_code)
1539# define math_nolimits_mode_par           integer_parameter(math_nolimits_mode_code)
1540# define math_penalties_mode_par          integer_parameter(math_penalties_mode_code)
1541# define math_pre_display_gap_factor_par  integer_parameter(math_pre_display_gap_factor_code)
1542# define math_pre_tolerance_par           integer_parameter(math_pre_tolerance_code)
1543# define math_right_class_par             integer_parameter(math_right_class_code)
1544# define math_rules_fam_par               integer_parameter(math_rules_fam_code)
1545# define math_rules_mode_par              integer_parameter(math_rules_mode_code)
1546# define math_scripts_mode_par            integer_parameter(math_scripts_mode_code)
1547# define math_skip_mode_par               integer_parameter(math_skip_mode_code)
1548# define math_slack_mode_par              integer_parameter(math_slack_mode_code)
1549# define math_spacing_mode_par            integer_parameter(math_spacing_mode_code)
1550# define math_tolerance_par               integer_parameter(math_tolerance_code)
1551# define empty_paragraph_mode_par         integer_parameter(empty_paragraph_mode_code)
1552# define max_dead_cycles_par              integer_parameter(max_dead_cycles_code)
1553# define month_par                        integer_parameter(month_code)
1554# define new_line_char_par                integer_parameter(new_line_char_code)
1555# define no_output_box_error_par          integer_parameter(no_output_box_error_code)
1556# define no_spaces_par                    integer_parameter(no_spaces_code)
1557# define normalize_line_mode_par          integer_parameter(normalize_line_mode_code)
1558# define normalize_par_mode_par           integer_parameter(normalize_par_mode_code)
1559# define output_box_par                   integer_parameter(output_box_code)
1560# define overload_mode_par                integer_parameter(overload_mode_code)
1561# define par_direction_par                integer_parameter(par_direction_code)
1562# define par_options_par                  integer_parameter(par_options_code)
1563# define parameter_mode_par               integer_parameter(parameter_mode_code)
1564# define pausing_par                      integer_parameter(pausing_code)
1565# define post_display_penalty_par         integer_parameter(post_display_penalty_code)
1566# define post_inline_penalty_par          integer_parameter(post_inline_penalty_code)
1567# define post_short_inline_penalty_par    integer_parameter(post_short_inline_penalty_code)
1568# define pre_display_direction_par        integer_parameter(pre_display_direction_code)
1569# define pre_display_penalty_par          integer_parameter(pre_display_penalty_code)
1570# define pre_inline_penalty_par           integer_parameter(pre_inline_penalty_code)
1571# define pre_short_inline_penalty_par     integer_parameter(pre_short_inline_penalty_code)
1572# define pre_tolerance_par                integer_parameter(pre_tolerance_code)
1573# define protrude_chars_par               integer_parameter(protrude_chars_code)
1574# define right_hyphen_min_par             integer_parameter(right_hyphen_min_code)
1575# define right_twin_demerits_par          integer_parameter(right_twin_demerits_code)
1576# define saving_hyph_codes_par            integer_parameter(saving_hyph_codes_code)
1577# define saving_vdiscards_par             integer_parameter(saving_vdiscards_code)
1578# define script_space_after_factor_par    integer_parameter(script_space_after_factor_code)
1579# define script_space_before_factor_par   integer_parameter(script_space_before_factor_code)
1580# define script_space_between_factor_par  integer_parameter(script_space_between_factor_code)
1581# define shaping_penalties_mode_par       integer_parameter(shaping_penalties_mode_code)
1582# define shaping_penalty_par              integer_parameter(shaping_penalty_code)
1583# define short_inline_orphan_penalty_par  integer_parameter(short_inline_orphan_penalty_code)
1584# define show_box_breadth_par             integer_parameter(show_box_breadth_code)
1585# define show_box_depth_par               integer_parameter(show_box_depth_code)
1586# define show_node_details_par            integer_parameter(show_node_details_code)
1587# define single_line_penalty_par          integer_parameter(single_line_penalty_code)
1588# define space_char_par                   integer_parameter(space_char_code)
1589# define space_factor_mode_par            integer_parameter(space_factor_mode)
1590# define space_factor_overload_par        integer_parameter(space_factor_overload_code)
1591# define space_factor_shrink_limit_par    integer_parameter(space_factor_shrink_limit_code)
1592# define space_factor_stretch_limit_par   integer_parameter(space_factor_stretch_limit_code)
1593# define sup_mark_mode_par                integer_parameter(sup_mark_mode_code)
1594# define text_direction_par               integer_parameter(text_direction_code)
1595# define time_par                         integer_parameter(time_code)
1596# define tolerance_par                    integer_parameter(tolerance_code)
1597# define tracing_adjusts_par              integer_parameter(tracing_adjusts_code)
1598# define tracing_alignments_par           integer_parameter(tracing_alignments_code)
1599# define tracing_assigns_par              integer_parameter(tracing_assigns_code)
1600# define tracing_balancing_par            integer_parameter(tracing_balancing_code)
1601# define tracing_commands_par             integer_parameter(tracing_commands_code)
1602# define tracing_expressions_par          integer_parameter(tracing_expressions_code)
1603# define tracing_fitness_par              integer_parameter(tracing_fitness_code)
1604# define tracing_full_boxes_par           integer_parameter(tracing_full_boxes_code)
1605# define tracing_groups_par               integer_parameter(tracing_groups_code)
1606# define tracing_hyphenation_par          integer_parameter(tracing_hyphenation_code)
1607# define tracing_ifs_par                  integer_parameter(tracing_ifs_code)
1608# define tracing_inserts_par              integer_parameter(tracing_inserts_code)
1609# define tracing_levels_par               integer_parameter(tracing_levels_code)
1610# define tracing_lists_par                integer_parameter(tracing_lists_code)
1611# define tracing_loners_par               integer_parameter(tracing_loners_code)
1612# define tracing_looseness_par            integer_parameter(tracing_looseness_code)
1613# define tracing_lost_chars_par           integer_parameter(tracing_lost_chars_code)
1614# define tracing_macros_par               integer_parameter(tracing_macros_code)
1615# define tracing_marks_par                integer_parameter(tracing_marks_code)
1616# define tracing_math_par                 integer_parameter(tracing_math_code)
1617# define tracing_mvl_par                  integer_parameter(tracing_mvl_code)
1618# define tracing_nesting_par              integer_parameter(tracing_nesting_code)
1619# define tracing_nodes_par                integer_parameter(tracing_nodes_code)
1620# define tracing_online_par               integer_parameter(tracing_online_code)
1621# define tracing_orphans_par              integer_parameter(tracing_orphans_code)
1622# define tracing_output_par               integer_parameter(tracing_output_code)
1623# define tracing_pages_par                integer_parameter(tracing_pages_code)
1624# define tracing_paragraphs_par           integer_parameter(tracing_paragraphs_code)
1625# define tracing_passes_par               integer_parameter(tracing_passes_code)
1626# define tracing_penalties_par            integer_parameter(tracing_penalties_code)
1627# define tracing_restores_par             integer_parameter(tracing_restores_code)
1628# define tracing_stats_par                integer_parameter(tracing_stats_code)
1629# define tracing_toddlers_par             integer_parameter(tracing_toddlers_code)
1630# define uc_hyph_par                      integer_parameter(uc_hyph_code)
1631# define variable_family_par              integer_parameter(variable_family_code)
1632# define vbadness_par                     integer_parameter(vbadness_code)
1633# define vbadness_mode_par                integer_parameter(vbadness_mode_code)
1634# define vsplit_checks_par                integer_parameter(vsplit_checks_code)
1635# define widow_penalty_par                integer_parameter(widow_penalty_code)
1636# define year_par                         integer_parameter(year_code)
1637
1638# define med_muskip_par                   muglue_parameter(med_muskip_code)
1639# define petty_muskip_par                 muglue_parameter(petty_muskip_code)
1640# define thick_muskip_par                 muglue_parameter(thick_muskip_code)
1641# define thin_muskip_par                  muglue_parameter(thin_muskip_code)
1642# define tiny_muskip_par                  muglue_parameter(tiny_muskip_code)
1643
1644# define end_of_group_par                 toks_parameter(end_of_group_code)
1645# define error_help_par                   toks_parameter(error_help_code)
1646# define every_before_par_par             toks_parameter(every_before_par_code)
1647# define every_cr_par                     toks_parameter(every_cr_code)
1648# define every_display_par                toks_parameter(every_display_code)
1649# define every_eof_par                    toks_parameter(every_eof_code)
1650# define every_hbox_par                   toks_parameter(every_hbox_code)
1651# define every_job_par                    toks_parameter(every_job_code)
1652# define every_math_atom_par              toks_parameter(every_math_atom_code)
1653# define every_math_par                   toks_parameter(every_math_code)
1654# define every_par_par                    toks_parameter(every_par_code)
1655# define every_tab_par                    toks_parameter(every_tab_code)
1656# define every_vbox_par                   toks_parameter(every_vbox_code)
1657# define output_routine_par               toks_parameter(output_routine_code)
1658
1659# define adjacent_demerits_par            specification_parameter(adjacent_demerits_code)
1660# define balance_passes_par               specification_parameter(balance_passes_code)
1661# define balance_shape_par                specification_parameter(balance_shape_code)
1662# define balance_final_penalties_par      specification_parameter(balance_final_penalties_code)
1663# define broken_penalties_par             specification_parameter(broken_penalties_code)
1664# define club_penalties_par               specification_parameter(club_penalties_code)
1665# define display_widow_penalties_par      specification_parameter(display_widow_penalties_code)
1666# define fitness_classes_par              specification_parameter(fitness_classes_code)
1667# define inter_line_penalties_par         specification_parameter(inter_line_penalties_code)
1668# define math_backward_penalties_par      specification_parameter(math_backward_penalties_code)
1669# define math_forward_penalties_par       specification_parameter(math_forward_penalties_code)
1670# define orphan_line_factors_par          specification_parameter(orphan_line_factors_code)
1671# define orphan_penalties_par             specification_parameter(orphan_penalties_code)
1672# define par_passes_exception_par         specification_parameter(par_passes_exception_code)
1673# define par_passes_par                   specification_parameter(par_passes_code)
1674# define par_shape_par                    specification_parameter(par_shape_code)
1675# define toddler_penalties_par            specification_parameter(toddler_penalties_code)
1676# define widow_penalties_par              specification_parameter(widow_penalties_code)
1677
1678# define end_line_char_inactive           ((end_line_char_par < 0) || (end_line_char_par > max_endline_character))
1679
1680/*tex
1681    We keep these as reference but they are no longer equivalent to regular \TEX\ because we have
1682    class based penalties instead.
1683*/
1684
1685/*define post_binary_penalty_par          integer_parameter(post_binary_penalty_code)   */
1686/*define post_relation_penalty_par        integer_parameter(post_relation_penalty_code) */
1687/*define pre_binary_penalty_par           integer_parameter(pre_binary_penalty_code)    */
1688/*define pre_relation_penalty_par         integer_parameter(pre_relation_penalty_code)  */
1689
1690typedef enum math_glue_modes {
1691    math_glue_stretch_code = 0x01,
1692    math_glue_shrink_code  = 0x02,
1693    math_glue_limit_code   = 0x04,
1694} math_glue_modes;
1695
1696# define math_glue_stretch_enabled ((math_glue_mode_par & math_glue_stretch_code) == math_glue_stretch_code)
1697# define math_glue_shrink_enabled  ((math_glue_mode_par & math_glue_shrink_code) == math_glue_shrink_code)
1698# define math_glue_limit_enabled   ((math_glue_mode_par & math_glue_limit_code) == math_glue_limit_code)
1699# define default_math_glue_mode    (math_glue_stretch_code | math_glue_shrink_code)
1700
1701typedef enum auto_paragraph_modes {
1702    auto_paragraph_text  = 0x01,
1703    auto_paragraph_macro = 0x02,
1704    auto_paragraph_go_on = 0x04,
1705} auto_paragraph_modes;
1706
1707# define auto_paragraph_mode(flag) ((auto_paragraph_mode_par) & (flag))
1708
1709typedef enum shaping_penalties_mode_bits {
1710    inter_line_penalty_shaping = 0x01,
1711    widow_penalty_shaping      = 0x02,
1712    club_penalty_shaping       = 0x04,
1713    broken_penalty_shaping     = 0x08,
1714} shaping_penalties_mode_bits;
1715
1716# define is_shaping_penalties_mode(what,flag) ((what) & (flag))
1717
1718/*tex
1719    We keep these three as reference but because they are backend related they are basically
1720    no-ops and ignored.
1721*/
1722
1723/*define h_offset_par                    dimension_parameter(h_offset_code) */
1724/*define v_offset_par                    dimension_parameter(v_offset_code) */
1725/*define mag_par                         integer_parameter(mag_code) */
1726
1727/*tex
1728    This tracer is mostly there for debugging purposes. Therefore what gets traced and how might
1729    change depending on my needs.
1730*/
1731
1732typedef enum tracing_lists_codes {
1733    trace_direction_list_code = 0x0001,
1734    trace_paragraph_list_code = 0x0002,
1735    trace_linebreak_list_code = 0x0004,
1736} tracing_lists_codes;
1737
1738# define tracing_direction_lists         ((tracing_lists_par & trace_direction_list_code) == trace_direction_list_code)
1739# define tracing_paragraph_lists         ((tracing_lists_par & trace_paragraph_list_code) == trace_paragraph_list_code)
1740# define tracing_linebreak_lists         ((tracing_lists_par & trace_linebreak_list_code) == trace_linebreak_list_code)
1741
1742typedef enum hyphenation_mode_bits {
1743    normal_hyphenation_mode              = 0x00001,
1744    automatic_hyphenation_mode           = 0x00002,
1745    explicit_hyphenation_mode            = 0x00004,
1746    syllable_hyphenation_mode            = 0x00008,
1747    uppercase_hyphenation_mode           = 0x00010,
1748    compound_hyphenation_mode            = 0x00020,
1749    strict_start_hyphenation_mode        = 0x00040,
1750    strict_end_hyphenation_mode          = 0x00080,
1751    automatic_penalty_hyphenation_mode   = 0x00100,
1752    explicit_penalty_hyphenation_mode    = 0x00200,
1753    permit_glue_hyphenation_mode         = 0x00400,
1754    permit_all_hyphenation_mode          = 0x00800,
1755    permit_math_replace_hyphenation_mode = 0x01000,
1756    force_check_hyphenation_mode         = 0x02000,
1757    lazy_ligatures_hyphenation_mode      = 0x04000,
1758    force_handler_hyphenation_mode       = 0x08000,
1759    feedback_compound_hyphenation_mode   = 0x10000,
1760    ignore_bounds_hyphenation_mode       = 0x20000,
1761    collapse_hyphenation_mode            = 0x40000,
1762    replace_apostrophe_hyphenation_mode  = 0x80000,
1763} hyphenation_mode_bits;
1764
1765# define hyphenation_permitted(a,b)   (((a) & (b)) == (b))
1766# define set_hyphenation_mode(a,b)    ((a) | (b))
1767# define unset_hyphenation_mode(a,b)  ((a) & ~(b))
1768# define flip_hyphenation_mode(a,b)   ((b) ? set_hyphenation_mode(a,b) : unset_hyphenation_mode(a,b))
1769# define default_hyphenation_mode     (normal_hyphenation_mode | automatic_hyphenation_mode | explicit_hyphenation_mode | syllable_hyphenation_mode | compound_hyphenation_mode | force_handler_hyphenation_mode | feedback_compound_hyphenation_mode)
1770
1771typedef enum normalize_line_mode_bits {
1772    normalize_line_mode          = 0x0001,
1773    parindent_skip_mode          = 0x0002,
1774    swap_hangindent_mode         = 0x0004,
1775    swap_parshape_mode           = 0x0008,
1776    break_after_dir_mode         = 0x0010,
1777    remove_margin_kerns_mode     = 0x0020, /*tex When unpacking an hbox \unknown\ a \PDFTEX\ leftover. */
1778    clip_width_mode              = 0x0040,
1779    flatten_discretionaries_mode = 0x0080,
1780    discard_zero_tab_skips_mode  = 0x0100,
1781    flatten_h_leaders_mode       = 0x0200,
1782    balance_inline_math_mode     = 0x0400,
1783} normalize_line_mode_bits;
1784
1785typedef enum normalize_par_mode_bits {
1786    normalize_par_mode            = 0x0001,
1787    flatten_v_leaders_mode        = 0x0002, /* used to be 0x200 */
1788    limit_prev_graf_mode          = 0x0004,
1789    /*tex Conform etex we reset but one can wonder (ms mail/discussion) so we now have a flag. */
1790    keep_interline_penalties_mode = 0x0008,
1791    /*tex Maybe add some more control over the resets. */
1792    remove_trailing_spaces_mode   = 0x0010,
1793} normalize_par_mode_bits;
1794
1795typedef enum parameter_mode_bits {
1796    parameter_escape_mode = 0x0001,
1797} parameter_mode_bits;
1798
1799# define normalize_line_mode_option(a) ((normalize_line_mode_par & a) == a)
1800# define normalize_par_mode_option(a)  ((normalize_par_mode_par  & a) == a)
1801
1802typedef enum auto_migration_mode_bits {
1803     auto_migrate_mark   = 0x01,
1804     auto_migrate_insert = 0x02,
1805     auto_migrate_adjust = 0x04,
1806     auto_migrate_pre    = 0x08,
1807     auto_migrate_post   = 0x10,
1808} auto_migration_mode_bits;
1809
1810# define auto_migrating_mode_permitted(what,flag) ((what & flag) == flag)
1811
1812# define attribute_register(j) eq_value(register_attribute_location(j))
1813# define posit_register(j)     eq_value(register_posit_location(j))
1814# define box_register(j)       eq_value(register_box_location(j))
1815# define integer_register(j)   eq_value(register_integer_location(j))
1816# define dimension_register(j) eq_value(register_dimension_location(j))
1817# define muglue_register(j)    eq_value(register_muglue_location(j))
1818# define glue_register(j)      eq_value(register_glue_location(j))
1819# define toks_register(j)      eq_value(register_toks_location(j))
1820//define unit_register(j)      eq_value(register_unit_location(j))
1821
1822# define count_register  integer_register
1823# define dimen_register  dimension_register
1824# define skip_register   glue_register
1825# define muskip_register muglue_register
1826
1827/*
1828    Injecting these frozen tokens can for instance happen when we scan for an integer or dimension
1829    and run into an |\else| or |\fi| because (guess what) these scanners gobble trailing spaces! In
1830    that case the |deep_frozen_relax_token| gets pushed back and can for instance end up in an
1831    expansion (macro, write, etc) because we only look ahead. However, we can catch this side effect
1832    in the scanners (that we redefined anyway). Removing those |\relax|'s was on the todo list and
1833    now happens in the scanners. Actually it's one reason why we often use constants in tests
1834    because these don't have that side effect because the scanner then quite earlier.) Another place
1835    where that happens is in the |\input| command but there we can use braces. It is a typical
1836    example of a more cosmetic adaptation that got a bit more priority when we converted the
1837    \CONTEXT\ codebase from \MKIV\ to \LMTX, where testing involved checking the results. I also have
1838    to check the other frozen tokens that can get reported when we have for instance alignments. It
1839    is also why some of these tokens have an associated (private but serialized) |\csname|.
1840
1841    For the record: we can these tokens deep_frozen because we don't want them to be confused with
1842    the |\frozen| user macros and the ones below are really deeply hidden, although sometimes they
1843    do surface.
1844
1845*/
1846
1847typedef enum deep_frozen_cs_tokens {
1848    deep_frozen_protection_token   = cs_token_flag + deep_frozen_cs_protection_code,
1849    deep_frozen_cr_token           = cs_token_flag + deep_frozen_cs_cr_code,
1850    deep_frozen_end_group_token    = cs_token_flag + deep_frozen_cs_end_group_code,
1851    deep_frozen_right_token        = cs_token_flag + deep_frozen_cs_right_code,
1852    deep_frozen_fi_token           = cs_token_flag + deep_frozen_cs_fi_code,
1853    deep_frozen_end_template_token = cs_token_flag + deep_frozen_cs_end_template_code,
1854    deep_frozen_relax_token        = cs_token_flag + deep_frozen_cs_relax_code,
1855    deep_frozen_end_write_token    = cs_token_flag + deep_frozen_cs_end_write_code,
1856    deep_frozen_dont_expand_token  = cs_token_flag + deep_frozen_cs_dont_expand_code,
1857    deep_frozen_null_font_token    = cs_token_flag + deep_frozen_cs_null_font_code,
1858    deep_frozen_undefined_token    = cs_token_flag + deep_frozen_cs_undefined_code,
1859} deep_frozen_cs_tokens;
1860
1861/*tex
1862
1863    The next has been simplified and replaced by |\hyphenatiomode| but we keep it as reminder:
1864
1865    \starttabulate[|T|T|T|]
1866    \NC hyphen_penalty_mode_par \NC automatic_disc (-)           \NC explicit_disc (\-) \NC \NR
1867    \HL
1868    \NC 0 (default)             \NC ex_hyphen_penalty_par        \NC ex_hyphen_penalty_par \NC \NR
1869    \NC 1                       \NC hyphen_penalty_par           \NC hyphen_penalty_par \NC \NR
1870    \NC 2                       \NC ex_hyphen_penalty_par        \NC hyphen_penalty_par \NC \NR
1871    \NC 3                       \NC hyphen_penalty_par           \NC ex_hyphen_penalty_par \NC \NR
1872    \NC 4                       \NC automatic_hyphen_penalty_par \NC explicit_disc_penalty_par \NC \NR
1873    \NC 5                       \NC ex_hyphen_penalty_par        \NC explicit_disc_penalty_par \NC \NR
1874    \NC 6                       \NC hyphen_penalty_par           \NC explicit_disc_penalty_par \NC \NR
1875    \NC 7                       \NC automatic_hyphen_penalty_par \NC ex_hyphen_penalty_par \NC \NR
1876    \NC 8                       \NC automatic_hyphen_penalty_par \NC hyphen_penalty_par \NC \NR
1877    \stoptabulate
1878
1879*/
1880
1881extern halfword tex_automatic_disc_penalty (halfword mode);
1882extern halfword tex_explicit_disc_penalty  (halfword mode);
1883
1884/*tex
1885
1886    We add a bit more abstraction when setting the system parameters. This is not really needed 
1887    but it moves all the |eq_| assignments to a place where we can keep an eye on them.
1888
1889*/
1890
1891# define tex_gq_word_define tex_geq_word_define
1892# define tex_gq_define      tex_geq_define
1893
1894# define update_tex_glyph_data(a,v)             tex_word_define(a, internal_integer_location(glyph_data_code), v)
1895# define update_tex_glyph_state(a,v)            tex_word_define(a, internal_integer_location(glyph_state_code), v)
1896# define update_tex_glyph_script(a,v)           tex_word_define(a, internal_integer_location(glyph_script_code), v)
1897# define update_tex_family(a,v)                 tex_word_define(a, internal_integer_location(family_code), v)
1898# define update_tex_language(a,v)               tex_word_define(a, internal_integer_location(language_code), v)
1899# define update_tex_font(a,v)                   tex_word_define(a, internal_integer_location(font_code), v)
1900
1901# define update_tex_display_indent(v)           tex_eq_word_define(internal_dimension_location(display_indent_code), v)
1902# define update_tex_display_width(v)            tex_eq_word_define(internal_dimension_location(display_width_code), v)
1903# define update_tex_hang_after(v)               tex_eq_word_define(internal_integer_location(hang_after_code), v)
1904# define update_tex_hang_indent(v)              tex_eq_word_define(internal_dimension_location(hang_indent_code), v)
1905# define update_tex_looseness(v)                tex_eq_word_define(internal_integer_location(looseness_code), v)
1906# define update_tex_single_line_penalty(v)      tex_eq_word_define(internal_integer_location(single_line_penalty_code), v)
1907# define update_tex_left_twin_demerits(v)       tex_eq_word_define(internal_integer_location(left_twin_demerits_code), v)
1908# define update_tex_right_twin_demerits(v)      tex_eq_word_define(internal_integer_location(right_twin_demerits_code), v)
1909# define update_tex_math_direction(v)           tex_eq_word_define(internal_integer_location(math_direction_code), v)
1910# define update_tex_internal_par_state(v)       tex_eq_word_define(internal_integer_location(internal_par_state_code), v)
1911# define update_tex_internal_dir_state(v)       tex_eq_word_define(internal_integer_location(internal_dir_state_code), v)
1912# define update_tex_internal_math_style(v)      tex_eq_word_define(internal_integer_location(internal_math_style_code), v)
1913# define update_tex_internal_math_scale(v)      tex_eq_word_define(internal_integer_location(internal_math_scale_code), v)
1914# define update_tex_output_penalty(v)           tex_gq_word_define(internal_integer_location(output_penalty_code), v)
1915# define update_tex_par_direction(v)            tex_eq_word_define(internal_integer_location(par_direction_code), v)
1916# define update_tex_pre_display_direction(v)    tex_eq_word_define(internal_integer_location(pre_display_direction_code), v)
1917# define update_tex_pre_display_size(v)         tex_eq_word_define(internal_dimension_location(pre_display_size_code), v)
1918# define update_tex_text_direction(v)           tex_eq_word_define(internal_integer_location(text_direction_code), v)
1919# define update_tex_line_break_checks(v)        tex_eq_word_define(internal_integer_location(line_break_checks_code), v)
1920
1921# define update_tex_font_identifier(v)          tex_eq_word_define(internal_integer_location(font_code), v)
1922# define update_tex_glyph_scale(v)              tex_eq_word_define(internal_integer_location(glyph_scale_code), v)
1923# define update_tex_glyph_x_scale(v)            tex_eq_word_define(internal_integer_location(glyph_x_scale_code), v)
1924# define update_tex_glyph_y_scale(v)            tex_eq_word_define(internal_integer_location(glyph_y_scale_code), v)
1925# define update_tex_glyph_slant(v)              tex_eq_word_define(internal_integer_location(glyph_slant_code), v)
1926# define update_tex_glyph_weight(v)             tex_eq_word_define(internal_integer_location(glyph_weight_code), v)
1927
1928# define update_tex_math_left_class(v)          tex_eq_word_define(internal_integer_location(math_left_class_code), v)
1929# define update_tex_math_right_class(v)         tex_eq_word_define(internal_integer_location(math_right_class_code), v)
1930
1931# define update_tex_adjacent_demerits(v)        tex_eq_define(internal_specification_location(adjacent_demerits_code),       specification_reference_cmd, v)
1932# define update_tex_balance_passes(v)           tex_eq_define(internal_specification_location(balance_passes_code),          specification_reference_cmd, v)
1933# define update_tex_balance_shape(v)            tex_eq_define(internal_specification_location(balance_shape_code),           specification_reference_cmd, v)
1934# define update_tex_balance_final_penalties(v)  tex_eq_define(internal_specification_location(balance_final_penalties_code), specification_reference_cmd, v)
1935# define update_tex_broken_penalties(v)         tex_eq_define(internal_specification_location(broken_penalties_code),        specification_reference_cmd, v)
1936# define update_tex_club_penalties(v)           tex_eq_define(internal_specification_location(club_penalties_code),          specification_reference_cmd, v)
1937# define update_tex_display_widow_penalties(v)  tex_eq_define(internal_specification_location(display_widow_penalties_code), specification_reference_cmd, v)
1938# define update_tex_fitness_classes(v)          tex_eq_define(internal_specification_location(fitness_classes_code),         specification_reference_cmd, v)
1939# define update_tex_inter_line_penalties(v)     tex_eq_define(internal_specification_location(inter_line_penalties_code),    specification_reference_cmd, v)
1940# define update_tex_orphan_line_factors_code(v) tex_eq_define(internal_specification_location(orphan_line_factors_code),     specification_reference_cmd, v)
1941# define update_tex_orphan_penalties(v)         tex_eq_define(internal_specification_location(orphan_penalties_code),        specification_reference_cmd, v)
1942# define update_tex_par_passes(v)               tex_eq_define(internal_specification_location(par_passes_code),              specification_reference_cmd, v)
1943# define update_tex_par_passes_exception(v)     tex_eq_define(internal_specification_location(par_passes_exception_code),    specification_reference_cmd, v)
1944# define update_tex_par_shape(v)                tex_eq_define(internal_specification_location(par_shape_code),               specification_reference_cmd, v)
1945# define update_tex_toddler_penalties(v)        tex_eq_define(internal_specification_location(toddler_penalties_code),       specification_reference_cmd, v)
1946# define update_tex_widow_penalties(v)          tex_eq_define(internal_specification_location(widow_penalties_code),         specification_reference_cmd, v)
1947
1948# define update_tex_end_of_group(v)             tex_eq_define(internal_toks_location(end_of_group_code), internal_toks_reference_cmd, v)
1949
1950# define update_tex_local_left_box(v)           tex_eq_define(internal_box_location(local_left_box_code),  internal_box_reference_cmd, v);
1951# define update_tex_local_middle_box(v)         tex_eq_define(internal_box_location(local_middle_box_code), internal_box_reference_cmd, v);
1952# define update_tex_local_right_box(v)          tex_eq_define(internal_box_location(local_right_box_code), internal_box_reference_cmd, v);
1953
1954# define update_tex_font_local(f,v)             tex_eq_define(f, set_font_cmd, v); /* Here |f| already has the right offset. */
1955# define update_tex_font_global(f,v)            tex_gq_define(f, set_font_cmd, v); /* Here |f| already has the right offset. */
1956
1957# define update_tex_tab_skip_local(v)           tex_eq_define(internal_glue_location(tab_skip_code), internal_glue_reference_cmd, v);
1958# define update_tex_tab_skip_global(v)          tex_gq_define(internal_glue_location(tab_skip_code), internal_glue_reference_cmd, v);
1959
1960# define update_tex_box_local(n,v)              tex_eq_define(register_box_location(n), register_box_reference_cmd, v);
1961# define update_tex_box_global(n,v)             tex_gq_define(register_box_location(n), register_box_reference_cmd, v);
1962
1963# define update_tex_emergency_left_skip(v)      tex_eq_define(internal_glue_location(emergency_left_skip_code), internal_glue_reference_cmd, v);
1964# define update_tex_emergency_right_skip(v)     tex_eq_define(internal_glue_location(emergency_right_skip_code), internal_glue_reference_cmd, v);
1965
1966# define update_tex_additional_page_skip(v)     tex_gq_define(internal_glue_location(additional_page_skip_code), internal_glue_reference_cmd, v)
1967
1968# define update_tex_local_interline_penalty(v)  tex_eq_word_define(internal_integer_location(local_interline_penalty_code), v);
1969# define update_tex_local_broken_penalty(v)     tex_eq_word_define(internal_integer_location(local_broken_penalty_code), v);
1970# define update_tex_local_tolerance(v)          tex_eq_word_define(internal_integer_location(local_tolerance_code), v);
1971# define update_tex_local_pre_tolerance(v)      tex_eq_word_define(internal_integer_location(local_pre_tolerance_code), v);
1972
1973# define box_limit_mode_hlist ((box_limit_mode_par & box_limit_hlist) == box_limit_hlist)
1974# define box_limit_mode_vlist ((box_limit_mode_par & box_limit_vlist) == box_limit_vlist)
1975# define box_limit_mode_line  ((box_limit_mode_par & box_limit_line) == box_limit_line)
1976
1977/*tex For the moment here; a preparation for a dedicated insert structure. */
1978
1979# define insert_content(A)    box_register(A)
1980# define insert_multiplier(A) count_register(A)
1981# define insert_maxheight(A)  dimension_register(A)
1982# define insert_distance(A)   skip_register(A)
1983
1984typedef enum cs_errors {
1985    cs_no_error,
1986    cs_null_error,
1987    cs_below_base_error,
1988    cs_undefined_error,
1989    cs_out_of_range_error,
1990} cs_errors;
1991
1992extern int tex_cs_state(halfword p) ;
1993
1994typedef enum badness_modes {
1995    badness_mode_nothing   = 0x00,
1996    badness_mode_underfull = 0x01,
1997    badness_mode_loose     = 0x02,
1998    badness_mode_tight     = 0x04,
1999    badness_mode_overfull  = 0x08,
2000    badness_mode_all       = 0x0F,
2001} badness_modes;
2002
2003# endif
2004