1% mainbody.w
2%
3% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
4%
5% This file is part of LuaTeX.
6%
7% LuaTeX is free software; you can redistribute it and/or modify it under
8% the terms of the GNU General Public License as published by the Free
9% Software Foundation; either version 2 of the License, or (at your
10% option) any later version.
11%
12% LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14% FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15% License for more details.
16%
17% You should have received a copy of the GNU General Public License along
18% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
19
20\def\eTeX{e-\TeX}
21\def\Aleph{Aleph}
22\def\pdfTeX{pdf\TeX}
23
24@ @c
25
26
27#include "ptexlib.h"
28
29@
30pdfTeX is copyright (C) 1996-2006 Han The Thanh, <thanh@@pdftex.org>.
31
32e-TeX is copyright (C) 1994,98 by Peter Breitenlohner.
33
34This is LuaTeX, a continuation of $\pdfTeX$ and $\Aleph$.  LuaTeX is a
35document compiler intended to simplify high-quality typesetting for
36many of the world's languages.  It is an extension of D. E. Knuth's
37\TeX, which was designed essentially for the typesetting of languages
38using the Latin alphabet.
39
40The $\Aleph$ subsystem loosens many of the restrictions imposed by~\TeX:
41register numbers are no longer limited to 8~bits;  fonts may have more
42than 256~characters;  more than 256~fonts may be used;  etc.
43
44% This program is directly derived from Donald E. Knuth's TeX;
45% the change history which follows and the reward offered for finders of
46% bugs refer specifically to TeX; they should not be taken as referring
47% to LuaTeX, pdfTeX, nor e-TeX, although the change history is relevant in that it
48% demonstrates the evolutionary path followed.  This program is not TeX;
49% that name is reserved strictly for the program which is the creation
50% and sole responsibility of Professor Knuth.
51
52% Version 0 was released in September 1982 after it passed a variety of tests.
53% Version 1 was released in November 1983 after thorough testing.
54% Version 1.1 fixed ``disappearing font identifiers'' et alia (July 1984).
55% Version 1.2 allowed `0' in response to an error, et alia (October 1984).
56% Version 1.3 made memory allocation more flexible and local (November 1984).
57% Version 1.4 fixed accents right after line breaks, et alia (April 1985).
58% Version 1.5 fixed \the\toks after other expansion in \edefs (August 1985).
59% Version 2.0 (almost identical to 1.5) corresponds to "Volume B" (April 1986).
60% Version 2.1 corrected anomalies in discretionary breaks (January 1987).
61% Version 2.2 corrected "(Please type...)" with null \endlinechar (April 1987).
62% Version 2.3 avoided incomplete page in premature termination (August 1987).
63% Version 2.4 fixed \noaligned rules in indented displays (August 1987).
64% Version 2.5 saved cur_order when expanding tokens (September 1987).
65% Version 2.6 added 10sp slop when shipping leaders (November 1987).
66% Version 2.7 improved rounding of negative-width characters (November 1987).
67% Version 2.8 fixed weird bug if no \patterns are used (December 1987).
68% Version 2.9 made \csname\endcsname's "relax" local (December 1987).
69% Version 2.91 fixed \outer\def\a0{}\a\a bug (April 1988).
70% Version 2.92 fixed \patterns, also file names with complex macros (May 1988).
71% Version 2.93 fixed negative halving in allocator when mem_min<0 (June 1988).
72% Version 2.94 kept open_log_file from calling fatal_error (November 1988).
73% Version 2.95 solved that problem a better way (December 1988).
74% Version 2.96 corrected bug in "Infinite shrinkage" recovery (January 1989).
75% Version 2.97 corrected blunder in creating 2.95 (February 1989).
76% Version 2.98 omitted save_for_after at outer level (March 1989).
77% Version 2.99 caught $$\begingroup\halign..$$ (June 1989).
78% Version 2.991 caught .5\ifdim.6... (June 1989).
79% Version 2.992 introduced major changes for 8-bit extensions (September 1989).
80% Version 2.993 fixed a save_stack synchronization bug et alia (December 1989).
81% Version 3.0 fixed unusual displays; was more \output robust (March 1990).
82% Version 3.1 fixed nullfont, disabled \write{\the\prevgraf} (September 1990).
83% Version 3.14 fixed unprintable font names and corrected typos (March 1991).
84% Version 3.141 more of same; reconstituted ligatures better (March 1992).
85% Version 3.1415 preserved nonexplicit kerns, tidied up (February 1993).
86% Version 3.14159 allowed fontmemsize to change; bulletproofing (March 1995).
87% Version 3.141592 fixed \xleaders, glueset, weird alignments (December 2002).
88% Version 3.1415926 was a general cleanup with minor fixes (February 2008).
89
90
91% Although considerable effort has been expended to make the LuaTeX program
92% correct and reliable, no warranty is implied; the authors disclaim any
93% obligation or liability for damages, including but not limited to
94% special, indirect, or consequential damages arising out of or in
95% connection with the use or performance of this software. This work has
96% been a ``labor of love'' and the authors hope that users enjoy it.
97
98A large piece of software like \TeX\ has inherent complexity that cannot
99be reduced below a certain level of difficulty, although each individual
100part is fairly simple by itself. The \.{WEB} language is intended to make
101the algorithms as readable as possible, by reflecting the way the
102individual program pieces fit together and by providing the
103cross-references that connect different parts. Detailed comments about
104what is going on, and about why things were done in certain ways, have
105been liberally sprinkled throughout the program.  These comments explain
106features of the implementation, but they rarely attempt to explain the
107\TeX\ language itself, since the reader is supposed to be familiar with
108{\sl The \TeX book}.
109@.WEB@>
110@:TeXbook}{\sl The \TeX book@>
111
112The present implementation has a long ancestry, beginning in the summer
113of~1977, when Michael~F. Plass and Frank~M. Liang designed and coded
114a prototype
115@^Plass, Michael Frederick@>
116@^Liang, Franklin Mark@>
117@^Knuth, Donald Ervin@>
118based on some specifications that the author had made in May of that year.
119This original proto\TeX\ included macro definitions and elementary
120manipulations on boxes and glue, but it did not have line-breaking,
121page-breaking, mathematical formulas, alignment routines, error recovery,
122or the present semantic nest; furthermore,
123it used character lists instead of token lists, so that a control sequence
124like \.{\\halign} was represented by a list of seven characters. A
125complete version of \TeX\ was designed and coded by the author in late
1261977 and early 1978; that program, like its prototype, was written in the
127{\mc SAIL} language, for which an excellent debugging system was
128available. Preliminary plans to convert the {\mc SAIL} code into a form
129somewhat like the present ``web'' were developed by Luis Trabb~Pardo and
130@^Trabb Pardo, Luis Isidoro@>
131the author at the beginning of 1979, and a complete implementation was
132created by Ignacio~A. Zabala in 1979 and 1980. The \TeX82 program, which
133@^Zabala Salelles, Ignacio Andr\'es@>
134was written by the author during the latter part of 1981 and the early
135part of 1982, also incorporates ideas from the 1979 implementation of
136@^Guibas, Leonidas Ioannis@>
137@^Sedgewick, Robert@>
138@^Wyatt, Douglas Kirk@>
139\TeX\ in {\mc MESA} that was written by Leonidas Guibas, Robert Sedgewick,
140and Douglas Wyatt at the Xerox Palo Alto Research Center.  Several hundred
141refinements were introduced into \TeX82 based on the experiences gained with
142the original implementations, so that essentially every part of the system
143has been substantially improved. After the appearance of ``Version 0'' in
144September 1982, this program benefited greatly from the comments of
145many other people, notably David~R. Fuchs and Howard~W. Trickey.
146A final revision in September 1989 extended the input character set to
147eight-bit codes and introduced the ability to hyphenate words from
148different languages, based on some ideas of Michael~J. Ferguson.
149@^Fuchs, David Raymond@>
150@^Trickey, Howard Wellington@>
151@^Ferguson, Michael John@>
152
153No doubt there still is plenty of room for improvement, but the author
154is firmly committed to keeping \TeX82 ``frozen'' from now on; stability
155and reliability are to be its main virtues.
156
157On the other hand, the \.{WEB} description can be extended without changing
158the core of \TeX82 itself, and the program has been designed so that such
159extensions are not extremely difficult to make.
160The |banner| string defined here should be changed whenever \TeX\
161undergoes any modifications, so that it will be clear which version of
162\TeX\ might be the guilty party when a problem arises.
163@^extensions to \TeX@>
164@^system dependencies@>
165
166This program contains code for various features extending \TeX,
167therefore this program is called `\eTeX' and not
168`\TeX'; the official name `\TeX' by itself is reserved
169for software systems that are fully compatible with each other.
170A special test suite called the ``\.{TRIP} test'' is available for
171helping to determine whether a particular implementation deserves to be
172known as `\TeX' [cf.~Stanford Computer Science report CS1027,
173November 1984].
174
175A similar test suite called the ``\.{e-TRIP} test'' is available for
176helping to determine whether a particular implementation deserves to be
177known as `\eTeX'.
178
179@ This is the first of many sections of \TeX\ where global variables are
180defined.
181
182@c
183boolean luainit;                /* are we using lua for initializations  */
184boolean tracefilenames;         /* print file open-close  info? */
185
186
187@ This program has two important variations: (1) There is a long and slow
188version called \.{INITEX}, which does the extra calculations needed to
189@.INITEX@>
190initialize \TeX's internal tables; and (2)~there is a shorter and faster
191production version, which cuts the initialization to a bare minimum.
192
193@c
194boolean ini_version;            /* are we \.{INITEX}? */
195boolean dump_option;            /* was the dump name option used? */
196boolean dump_line;              /* was a \.{\%\AM format} line seen? */
197int bound_default;              /* temporary for setup */
198char *bound_name;               /* temporary for setup */
199int error_line;                 /* width of context lines on terminal error messages */
200int half_error_line;            /* width of first lines of contexts in terminal
201                                   error messages; should be between 30 and |error_line-15| */
202int max_print_line;             /* width of longest text lines output; should be at least 60 */
203int max_strings;                /* maximum number of strings; must not exceed |max_halfword| */
204int strings_free;               /* strings available after format loaded */
205int font_k;                     /* loop variable for initialization */
206int buf_size;                   /* maximum number of characters simultaneously present in
207                                   current lines of open files and in control sequences between
208                                   \.{\\csname} and \.{\\endcsname}; must not exceed |max_halfword| */
209int stack_size;                 /* maximum number of simultaneous input sources */
210int max_in_open;                /* maximum number of input files and error insertions that
211                                   can be going on simultaneously */
212int param_size;                 /* maximum number of simultaneous macro parameters */
213int nest_size;                  /* maximum number of semantic levels simultaneously active */
214int save_size;                  /* space for saving values outside of current group; must be
215                                   at most |max_halfword| */
216int expand_depth;               /* limits recursive calls of the |expand| procedure */
217int parsefirstlinep;            /* parse the first line for options */
218int filelineerrorstylep;        /* format messages as file:line:error */
219int haltonerrorp;               /* stop at first error */
220boolean quoted_filename;        /* current filename is quoted */
221
222@ @c
223int get_luatexversion(void)
224{
225    return luatex_version;
226}
227
228int get_luatexsvn(void)
229{
230    return luatex_svn;
231}
232
233str_number get_luatexrevision(void)
234{
235    return luatex_revision;
236}
237
238int get_luatex_date_info(void)
239{
240    return luatex_date_info;    /* todo, silly value */
241}
242
243
244@ This is it: the part of \TeX\ that executes all those procedures we have
245written.
246
247We have noted that there are two versions of \TeX82. One, called \.{INITEX},
248@.INITEX@>
249has to be run first; it initializes everything from scratch, without
250reading a format file, and it has the capability of dumping a format file.
251The other one is called `\.{VIRTEX}'; it is a ``virgin'' program that needs
252@.VIRTEX@>
253to input a format file in order to get started.
254
255@c
256#define const_chk(A) do {			\
257	if (A < inf_##A) A = inf_##A;		\
258	if (A > sup_##A) A = sup_##A;		\
259    } while (0)
260
261#define setup_bound_var(A,B,C) do {				\
262	if (luainit>0) {					\
263	    get_lua_number("texconfig",B,&C);			\
264	    if (C==0) C=A;					\
265	} else {						\
266	    integer x;						\
267	    setupboundvariable(&x, B, A);			\
268	    C = (int)x;						\
269	}							\
270    } while (0)
271
272
273int ready_already = 0;
274
275int main_initialize(void)
276{
277    /* In case somebody has inadvertently made bad settings of the ``constants,''
278       \LuaTeX\ checks them using a variable called |bad|. */
279    int bad = 0;
280    /* Bounds that may be set from the configuration file. We want the user to
281       be able to specify the names with underscores, but \.{TANGLE} removes
282       underscores, so we're stuck giving the names twice, once as a string,
283       once as the identifier. How ugly. */
284
285    setup_bound_var(15000, "max_strings", max_strings);
286    setup_bound_var(100, "strings_free", strings_free);
287    setup_bound_var(3000, "buf_size", buf_size);
288    setup_bound_var(50, "nest_size", nest_size);
289    setup_bound_var(15, "max_in_open", max_in_open);
290    setup_bound_var(60, "param_size", param_size);
291    setup_bound_var(4000, "save_size", save_size);
292    setup_bound_var(300, "stack_size", stack_size);
293    setup_bound_var(16384, "dvi_buf_size", dvi_buf_size);
294    setup_bound_var(79, "error_line", error_line);
295    setup_bound_var(50, "half_error_line", half_error_line);
296    setup_bound_var(79, "max_print_line", max_print_line);
297    setup_bound_var(0, "hash_extra", hash_extra);
298    setup_bound_var(72, "pk_dpi", pk_dpi);
299    setup_bound_var(10000, "expand_depth", expand_depth);
300
301    /* Check other constants against their sup and inf. */
302    const_chk(buf_size);
303    const_chk(nest_size);
304    const_chk(max_in_open);
305    const_chk(param_size);
306    const_chk(save_size);
307    const_chk(stack_size);
308    const_chk(dvi_buf_size);
309    const_chk(max_strings);
310    const_chk(strings_free);
311    const_chk(hash_extra);
312    const_chk(pk_dpi);
313    if (error_line > ssup_error_line)
314        error_line = ssup_error_line;
315
316    /* array memory allocation */
317    buffer = xmallocarray(packed_ASCII_code, (unsigned) buf_size);
318    nest = xmallocarray(list_state_record, (unsigned) nest_size);
319    save_stack = xmallocarray(save_record, (unsigned) save_size);
320    input_stack = xmallocarray(in_state_record, (unsigned) stack_size);
321    input_file = xmallocarray(alpha_file, (unsigned) max_in_open);
322    input_file_callback_id = xmallocarray(int, (unsigned) max_in_open);
323    line_stack = xmallocarray(int, (unsigned) max_in_open);
324    eof_seen = xmallocarray(boolean, (unsigned) max_in_open);
325    grp_stack = xmallocarray(save_pointer, (unsigned) max_in_open);
326    if_stack = xmallocarray(pointer, (unsigned) max_in_open);
327    source_filename_stack = xmallocarray(str_number, (unsigned) max_in_open);
328    full_source_filename_stack = xmallocarray(char *, (unsigned) max_in_open);
329    param_stack = xmallocarray(halfword, (unsigned) param_size);
330    dvi_buf = xmallocarray(eight_bits, (unsigned) dvi_buf_size);
331
332    if (ini_version) {
333        fixmem = xmallocarray(smemory_word, fix_mem_init + 1);
334        memset(voidcast(fixmem), 0, (fix_mem_init + 1) * sizeof(smemory_word));
335        fix_mem_min = 0;
336        fix_mem_max = fix_mem_init;
337        eqtb_top = eqtb_size + hash_extra;
338        if (hash_extra == 0)
339            hash_top = undefined_control_sequence;
340        else
341            hash_top = eqtb_top;
342        hash = xmallocarray(two_halves, (unsigned) (hash_top + 1));
343        memset(hash, 0, sizeof(two_halves) * (unsigned) (hash_top + 1));
344        eqtb = xmallocarray(memory_word, (unsigned) (eqtb_top + 1));
345        memset(eqtb, 0, sizeof(memory_word) * (unsigned) (eqtb_top + 1));
346        init_string_pool_array((unsigned) max_strings);
347        reset_cur_string();
348    }
349    /* Check the ``constant'' values... */
350    if ((half_error_line < 30) || (half_error_line > error_line - 15))
351        bad = 1;
352    if (max_print_line < 60)
353        bad = 2;
354    if (dvi_buf_size % 8 != 0)
355        bad = 3;
356    if (hash_prime > hash_size)
357        bad = 5;
358    if (max_in_open >= 128)
359        bad = 6;
360    /* Here are the inequalities that the quarterword and halfword values
361       must satisfy (or rather, the inequalities that they mustn't satisfy): */
362    if ((min_quarterword > 0) || (max_quarterword < 0x7FFF))
363        bad = 11;
364    if ((min_halfword > 0) || (max_halfword < 0x3FFFFFFF))
365        bad = 12;
366    if ((min_quarterword < min_halfword) || (max_quarterword > max_halfword))
367        bad = 13;
368    if (font_base < min_quarterword)
369        bad = 15;
370    if ((save_size > max_halfword) || (max_strings > max_halfword))
371        bad = 17;
372    if (buf_size > max_halfword)
373        bad = 18;
374    if (max_quarterword - min_quarterword < 0xFFFF)
375        bad = 19;
376    if (cs_token_flag + eqtb_size + hash_extra > max_halfword)
377        bad = 21;
378    if (bad > 0) {
379        wterm_cr();
380        fprintf(term_out,
381                "Ouch---my internal constants have been clobbered! ---case %d",
382                (int) bad);
383    } else {
384        initialize();           /* set global variables to their starting values */
385        if (ini_version) {
386            /* initialize all the primitives */
387            no_new_control_sequence = false;
388            first = 0;
389            initialize_commands();
390            initialize_etex_commands();
391            init_str_ptr = str_ptr;
392            no_new_control_sequence = true;
393            fix_date_and_time();
394        }
395        ready_already = 314159;
396    }
397    return bad;
398}
399
400@ @c
401void main_body(void)
402{
403    static char pdftex_map[] = "pdftex.map";
404    int bad = main_initialize();
405    history = fatal_error_stop; /* in case we quit during initialization */
406    t_open_out();               /* open the terminal for output */
407    if (!luainit)
408        tracefilenames = true;
409    if (bad > 0) {
410        goto FINAL_END;
411    }
412    print_banner(luatex_version_string, luatex_svn);
413
414    /* Get the first line of input and prepare to start */
415    /* When we begin the following code, \TeX's tables may still contain garbage;
416       the strings might not even be present. Thus we must proceed cautiously to get
417       bootstrapped in.
418
419       But when we finish this part of the program, \TeX\ is ready to call on the
420       |main_control| routine to do its work.
421     */
422    initialize_inputstack();    /* this copies the command-line */
423    if (buffer[iloc] == '*')
424        incr(iloc);
425    if ((format_ident == 0) || (buffer[iloc] == '&') || dump_line) {
426        char *fname = NULL;
427        if (format_ident != 0 && !ini_version)
428            initialize();       /* erase preloaded format */
429        if ((fname = open_fmt_file()) == NULL)
430            goto FINAL_END;
431        if (!load_fmt_file(fname)) {
432            zwclose(fmt_file);
433            goto FINAL_END;
434        }
435        zwclose(fmt_file);
436        while ((iloc < ilimit) && (buffer[iloc] == ' '))
437            incr(iloc);
438    }
439    if (pdf_output_option != 0)
440        int_par(pdf_output_code) = pdf_output_value;
441    if (pdf_draftmode_option != 0)
442        pdf_draftmode = static_pdf->draftmode = pdf_draftmode_value;
443    pdf_init_map_file((char *) pdftex_map);
444    if (end_line_char_inactive)
445        decr(ilimit);
446    else
447        buffer[ilimit] = (packed_ASCII_code) int_par(end_line_char_code);
448    fix_date_and_time();
449    /*if (ini_version)*/
450    /*    make_pdftex_banner();*/
451    random_seed = (microseconds * 1000) + (epochseconds % 1000000);
452    init_randoms(random_seed);
453    initialize_math();
454    fixup_selector(log_opened_global);
455    check_texconfig_init();
456    if ((iloc < ilimit) && (get_cat_code(int_par(cat_code_table_code),
457                                         buffer[iloc]) != escape_cmd))
458        start_input();          /* \.{\\input} assumed */
459    /* DIR: Initialize |text_dir_ptr| */
460    text_dir_ptr = new_dir(0);
461
462    history = spotless;         /* ready to go! */
463    /* Initialize synctex primitive */
464    synctexinitcommand();
465    main_control();             /* come to life */
466    flush_node(text_dir_ptr);
467    final_cleanup();            /* prepare for death */
468    close_files_and_terminate();
469  FINAL_END:
470    do_final_end();
471}
472
473
474@ Here we do whatever is needed to complete \TeX's job gracefully on the
475local operating system. The code here might come into play after a fatal
476error; it must therefore consist entirely of ``safe'' operations that
477cannot produce error messages. For example, it would be a mistake to call
478|str_room| or |make_string| at this time, because a call on |overflow|
479might lead to an infinite loop.
480@^system dependencies@>
481
482Actually there's one way to get error messages, via |prepare_mag|;
483but that can't cause infinite recursion.
484@^recursion@>
485
486This program doesn't bother to close the input files that may still be open.
487
488@c
489void close_files_and_terminate(void)
490{
491    int k;                      /* all-purpose index */
492    int callback_id;
493    PDF pdf = static_pdf;
494    callback_id = callback_defined(stop_run_callback);
495    /* Finish the extensions */
496    for (k = 0; k <= 15; k++)
497        if (write_open[k])
498            lua_a_close_out(write_file[k]);
499    if (int_par(tracing_stats_code) > 0) {
500        if (callback_id == 0) {
501            /* Output statistics about this job */
502            /* The present section goes directly to the log file instead of using
503               |print| commands, because there's no need for these strings to take
504               up |string_pool| memory when a non-{\bf stat} version of \TeX\ is being used.
505             */
506
507            if (log_opened_global) {
508                fprintf(log_file,
509                        "\n\nHere is how much of LuaTeX's memory you used:\n");
510                fprintf(log_file, " %d string%s out of %d\n",
511                        (int) (str_ptr - init_str_ptr),
512                        (str_ptr == (init_str_ptr + 1) ? "" : "s"),
513                        (int) (max_strings - init_str_ptr + STRING_OFFSET));
514                fprintf(log_file, " %d,%d words of node,token memory allocated",
515                        (int) var_mem_max, (int) fix_mem_max);
516                print_node_mem_stats();
517                fprintf(log_file,
518                        " %d multiletter control sequences out of %ld+%d\n",
519                        (int) cs_count, (long) hash_size, (int) hash_extra);
520                fprintf(log_file, " %d font%s using %d bytes\n",
521                        (int) max_font_id(), (max_font_id() == 1 ? "" : "s"),
522                        (int) font_bytes);
523                fprintf(log_file,
524                        " %di,%dn,%dp,%db,%ds stack positions out of %di,%dn,%dp,%db,%ds\n",
525                        (int) max_in_stack, (int) max_nest_stack,
526                        (int) max_param_stack, (int) max_buf_stack,
527                        (int) max_save_stack + 6, (int) stack_size,
528                        (int) nest_size, (int) param_size, (int) buf_size,
529                        (int) save_size);
530            }
531        }
532    }
533    wake_up_terminal();
534    ensure_output_state(pdf, ST_OMODE_FIX);
535    switch (pdf->o_mode) {
536    case OMODE_NONE:           /* during initex run */
537        break;
538    case OMODE_PDF:
539        if (history == fatal_error_stop) {
540            remove_pdffile(pdf);
541            print_err
542                (" ==> Fatal error occurred, no output PDF file produced!");
543        } else
544            finish_pdf_file(pdf, luatex_version, get_luatexrevision());
545        break;
546    case OMODE_DVI:
547        finish_dvi_file(pdf, luatex_version, get_luatexrevision());
548        break;
549    case OMODE_LUA:
550        finish_lua_file(pdf);
551        break;
552    default:
553        assert(0);
554    }
555    /* Close {\sl Sync\TeX} file and write status */
556    synctexterminate(log_opened_global);       /* Let the {\sl Sync\TeX} controller close its files. */
557
558    free_text_codes();
559    free_math_codes();
560    if (log_opened_global) {
561        wlog_cr();
562        selector = selector - 2;
563        if ((selector == term_only) && (callback_id == 0)) {
564            tprint_nl("Transcript written on ");
565            tprint_file_name(NULL, texmf_log_name, NULL);
566            print_char('.');
567            print_ln();
568        }
569        lua_a_close_out(log_file);
570    }
571}
572
573
574@ We get to the |final_cleanup| routine when \.{\\end} or \.{\\dump} has
575been scanned and |its_all_over|\kern-2pt.
576
577@c
578void final_cleanup(void)
579{
580    int c;                      /* 0 for \.{\\end}, 1 for \.{\\dump} */
581    halfword i;                 /*  for looping marks  */
582    c = cur_chr;
583    if (job_name == 0)
584        open_log_file();
585    while (input_ptr > 0)
586        if (istate == token_list)
587            end_token_list();
588        else
589            end_file_reading();
590    while (open_parens > 0) {
591        report_stop_file(filetype_tex);
592        decr(open_parens);
593    }
594    if (cur_level > level_one) {
595        tprint_nl("(\\end occurred inside a group at level ");
596        print_int(cur_level - level_one);
597        print_char(')');
598        show_save_groups();
599    }
600    while (cond_ptr != null) {
601        tprint_nl("(\\end occurred when ");
602        print_cmd_chr(if_test_cmd, cur_if);
603        if (if_line != 0) {
604            tprint(" on line ");
605            print_int(if_line);
606        }
607        tprint(" was incomplete)");
608        if_line = if_line_field(cond_ptr);
609        cur_if = subtype(cond_ptr);
610        temp_ptr = cond_ptr;
611        cond_ptr = vlink(cond_ptr);
612        flush_node(temp_ptr);
613    }
614    if (callback_defined(stop_run_callback) == 0)
615        if (history != spotless)
616            if ((history == warning_issued) || (interaction < error_stop_mode))
617                if (selector == term_and_log) {
618                    selector = term_only;
619                    tprint_nl
620                        ("(see the transcript file for additional information)");
621                    selector = term_and_log;
622                }
623    if (c == 1) {
624        if (ini_version) {
625            for (i = 0; i <= biggest_used_mark; i++) {
626                delete_top_mark(i);
627                delete_first_mark(i);
628                delete_bot_mark(i);
629                delete_split_first_mark(i);
630                delete_split_bot_mark(i);
631            }
632            for (c = last_box_code; c <= vsplit_code; c++)
633                flush_node_list(disc_ptr[c]);
634            if (last_glue != max_halfword)
635                delete_glue_ref(last_glue);
636            while (pseudo_files != null)
637                pseudo_close(); /* flush pseudo files */
638            store_fmt_file();
639            return;
640        }
641        tprint_nl("(\\dump is performed only by INITEX)");
642        return;
643    }
644}
645
646@ Once \TeX\ is working, you should be able to diagnose most errors with
647the \.{\\show} commands and other diagnostic features.
648An additional routine called |debug_help|
649will come into play when you type `\.D' after an error message;
650|debug_help| also occurs just before a fatal error causes \TeX\ to succumb.
651@^debugging@>
652@^system dependencies@>
653
654The interface to |debug_help| is primitive, but it is good enough when used
655with a debugger that allows you to set breakpoints and to read
656variables and change their values. After getting the prompt `\.{debug \#}', you
657type either a negative number (this exits |debug_help|), or zero (this
658goes to a location where you can set a breakpoint, thereby entering into
659dialog with the debugger), or a positive number |m| followed by
660an argument |n|. The meaning of |m| and |n| will be clear from the
661program below. (If |m=13|, there is an additional argument, |l|.)
662@.debug \#@>
663
664@c
665#ifdef DEBUG
666void debug_help(void)
667{                               /* routine to display various things */
668    int k;
669    int m = 0, n = 0, l = 0;
670    while (1) {
671        wake_up_terminal();
672        tprint_nl("debug # (-1 to exit):");
673        update_terminal();
674        (void) fscanf(term_in, "%d", &m);
675        if (m < 0)
676            return;
677        else if (m == 0)
678            abort();            /* go to every label at least once */
679        else {
680            (void) fscanf(term_in, "%d", &n);
681            switch (m) {
682            case 1:
683                print_word(varmem[n]);  /* display |varmem[n]| in all forms */
684                break;
685            case 2:
686                print_int(info(n));
687                break;
688            case 3:
689                print_int(link(n));
690                break;
691            case 4:
692                print_word(eqtb[n]);
693                break;
694            case 6:
695                print_int(save_type(n));
696                print_int(save_level(n));
697                print_word(save_word(n));
698                break;
699            case 7:
700                show_box(n);    /* show a box, abbreviated by |show_box_depth| and |show_box_breadth| */
701                break;
702            case 8:
703                breadth_max = 10000;
704                depth_threshold = 0x7FFFFFFF;
705                show_node_list(n);      /* show a box in its entirety */
706                break;
707            case 9:
708                show_token_list(n, null, 1000);
709                break;
710            case 10:
711                print(n);
712                break;
713            case 13:
714                (void) fscanf(term_in, "%d", &l);
715                print_cmd_chr(n, l);
716                break;
717            case 14:
718                for (k = 0; k <= n; k++)
719                    print(buffer[k]);
720                break;
721            case 15:
722                font_in_short_display = null_font;
723                short_display(n);
724                break;
725            default:
726                tprint("?");
727                break;
728            }
729        }
730    }
731}
732#endif
733