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