3
Copyright 2009 Taco Hoekwater <taco@luatex.org>
5
This file is part of LuaTeX.
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.
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.
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/>. */
24
static const char __svn_version[] =
25
"$Id: errors.c 3261 2009-12-18 11:38:21Z taco $"
26
"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.50.0/source/texk/web2c/luatexdir/tex/errors.c $";
28
#define new_line_char int_par(new_line_char_code)
31
When something anomalous is detected, \TeX\ typically does something like this:
32
$$\vbox{\halign{#\hfil\cr
33
|print_err("Something anomalous has been detected");|\cr
34
|help3("This is the first line of my offer to help.")|\cr
35
|("This is the second line. I'm trying to")|\cr
36
|("explain the best way for you to proceed.");|\cr
38
A two-line help message would be given using |help2|, etc.; these informal
39
helps should use simple vocabulary that complements the words used in the
40
official error message that was printed. (Outside the U.S.A., the help
41
messages should preferably be translated into the local vernacular. Each
42
line of help is at most 60 characters long, in the present implementation,
43
so that |max_print_line| will not be exceeded.)
45
The |print_err| procedure supplies a `\.!' before the official message,
46
and makes sure that the terminal is awake if a stop is going to occur.
47
The |error| procedure supplies a `\..' after the official message, then it
48
shows the location of the error; and if |interaction=error_stop_mode|,
49
it also enters into a dialog with the user, during which time the help
50
message may be printed.
51
@^system dependencies@>
54
int interaction; /* current level of interaction */
55
int interactionoption; /* set from command line */
58
void print_err(char *s)
60
if (interaction == error_stop_mode) {
63
if (filelineerrorstylep)
72
\TeX\ is careful not to call |error| when the print |selector| setting
73
might be unusual. The only possible values of |selector| at the time of
76
\yskip\hang|no_print| (when |interaction=batch_mode|
77
and |log_file| not yet open);
79
\hang|term_only| (when |interaction>batch_mode| and |log_file| not yet open);
81
\hang|log_only| (when |interaction=batch_mode| and |log_file| is open);
83
\hang|term_and_log| (when |interaction>batch_mode| and |log_file| is open).
87
void fixup_selector(boolean log_opened)
89
if (interaction == batch_mode)
94
selector = selector + 2;
98
A global variable |deletions_allowed| is set |false| if the |get_next|
99
routine is active when |error| is called; this ensures that |get_next|
100
and related routines like |get_token| will never be called recursively.
101
A similar interlock is provided by |set_box_allowed|.
104
The global variable |history| records the worst level of error that
105
has been detected. It has four possible values: |spotless|, |warning_issued|,
106
|error_message_issued|, and |fatal_error_stop|.
108
Another global variable, |error_count|, is increased by one when an
109
|error| occurs without an interactive dialog, and it is reset to zero at
110
the end of every paragraph. If |error_count| reaches 100, \TeX\ decides
111
that there is no point in continuing further.
114
boolean deletions_allowed; /* is it safe for |error| to call |get_token|? */
115
boolean set_box_allowed; /* is it safe to do a \.{\\setbox} assignment? */
116
int history; /* has the source input been clean so far? */
117
int error_count; /* the number of scrolled errors since the last paragraph ended */
118
int interrupt; /* should \TeX\ pause for instructions? */
119
boolean OK_to_interrupt; /* should interrupts be observed? */
123
The value of |history| is initially |fatal_error_stop|, but it will
124
be changed to |spotless| if \TeX\ survives the initialization process.
127
void initialize_errors(void)
129
if (interactionoption == unspecified_mode)
130
interaction = error_stop_mode;
132
interaction = interactionoption;
133
deletions_allowed = true;
134
set_box_allowed = true;
135
OK_to_interrupt = true;
136
/* |history| is initialized elsewhere */
140
It is possible for |error| to be called recursively if some error arises
141
when |get_token| is being used to delete a token, and/or if some fatal error
142
occurs while \TeX\ is trying to fix a non-fatal one. But such recursion
144
is never more than two levels deep.
148
Individual lines of help are recorded in the array |help_line|.
151
char *help_line[7]; /* helps for the next |error| */
152
boolean use_err_help; /* should the |err_help| list be shown? */
155
The |jump_out| procedure just cuts across all active procedure levels and
156
exits the program. It is used when there is no recovery from a particular error.
159
void do_final_end(void)
163
if ((history != spotless) && (history != warning_issued))
171
close_files_and_terminate();
176
{ /* completes the job of error reporting */
177
ASCII_code c; /* what the user types */
179
int s1, s2, s3, s4; /* used to save global variables when deleting tokens */
182
if (history < error_message_issued)
183
history = error_message_issued;
185
callback_id = callback_defined(show_error_hook_callback);
187
t = run_callback(callback_id, "->");
190
history = fatal_error_stop;
193
if (interaction == error_stop_mode) {
194
/* Get user's advice and |return| */
197
clear_for_error_prompt();
203
c = c + 'A' - 'a'; /* convert to uppercase */
204
/* Interpret code |c| and |return| if done */
206
/* It is desirable to provide an `\.E' option here that gives the user
207
an easy way to return from \TeX\ to the system editor, with the offending
208
line ready to be edited. But such an extension requires some system
209
wizardry, so the present implementation simply types out the name of the
210
file that should be edited and the relevant line number.
212
There is a secret `\.D' option available when the debugging routines haven't
213
been commented~out. */
226
if (deletions_allowed) {
227
/* Delete \(c)|c-"0"| tokens and |goto continue| */
228
/* We allow deletion of up to 99 tokens at a time */
233
align_state = 1000000;
234
OK_to_interrupt = false;
235
if ((last > first + 1) && (buffer[first + 1] >= '0')
236
&& (buffer[first + 1] <= '9'))
237
c = c * 10 + buffer[first + 1] - '0' * 11;
241
get_token(); /* one-level recursive call of |error| is possible */
248
OK_to_interrupt = true;
249
help2("I have just deleted some text, as you asked.",
250
"You can now delete more, or insert, or whatever.");
263
tprint_nl("You want to edit file ");
264
slow_print(input_stack[base_ptr].name_field);
267
interaction = scroll_mode;
272
/* Print the help information and |goto continue| */
275
use_err_help = false;
277
if (help_line[0] == NULL) {
279
("Sorry, I don't know how to help in this situation.",
280
"Maybe you should try asking a human?");
283
while (help_line[i] != NULL)
284
tprint_nl(help_line[i++]);
285
help4("Sorry, I already gave what help I could...",
286
"Maybe you should try asking a human?",
287
"An error might have occurred before I noticed any problems.",
288
"``If all else fails, read the instructions.''");
293
/* Introduce new material from the terminal and |return| */
294
/* When the following code is executed, |buffer[(first+1)..(last-1)]| may
295
contain the material inserted by the user; otherwise another prompt will
296
be given. In order to understand this part of the program fully, you need
297
to be familiar with \TeX's input stacks. */
299
begin_file_reading(); /* enter a new syntactic level for terminal input */
300
/* now |state=mid_line|, so an initial blank space will count as a blank */
301
if (last > first + 1) {
305
prompt_input("insert>");
309
ilimit = last - 1; /* no |end_line_char| ends this line */
315
/* Change the interaction level and |return| */
316
/* Here the author of \TeX\ apologizes for making use of the numerical
317
relation between |"Q"|, |"R"|, |"S"|, and the desired interaction settings
318
|batch_mode|, |nonstop_mode|, |scroll_mode|. */
320
interaction = batch_mode + c - 'Q';
321
tprint("OK, entering ");
324
tprint_esc("batchmode");
328
tprint_esc("nonstopmode");
331
tprint_esc("scrollmode");
340
interaction = scroll_mode;
346
/* Print the menu of available options */
348
("Type <return> to proceed, S to scroll future error messages,");
349
tprint_nl("R to run without stopping, Q to run quietly,");
350
tprint_nl("I to insert something, ");
352
tprint("E to edit your file,");
353
if (deletions_allowed)
355
("1 or ... or 9 to ignore the next 1 to 9 tokens of input,");
356
tprint_nl("H for help, X to quit.");
361
if (error_count == 100) {
362
tprint_nl("(That makes 100 errors; please try again.)");
363
history = fatal_error_stop;
366
/* Put help message on the transcript file */
367
if (interaction > batch_mode)
368
decr(selector); /* avoid terminal output */
374
while (help_line[i] != NULL)
375
tprint_nl(help_line[i++]);
378
if (interaction > batch_mode)
379
incr(selector); /* re-enable terminal output */
385
A dozen or so error messages end with a parenthesized integer, so we
386
save a teeny bit of program space by declaring the following procedure:
389
void int_error(int n)
398
In anomalous cases, the print selector might be in an unknown state;
399
the following subroutine is called to fix things just enough to keep
400
running a bit longer.
403
void normalize_selector(void)
406
selector = term_and_log;
408
selector = term_only;
411
if (interaction == batch_mode)
415
/* The following procedure prints \TeX's last words before dying */
419
if (interaction == error_stop_mode)
420
interaction = scroll_mode; /* no more interaction */
424
if (interaction > batch_mode)
427
history = fatal_error_stop;
428
jump_out(); /* irrecoverable error */
431
void fatal_error(char *s)
432
{ /* prints |s|, and that's it */
433
normalize_selector();
434
print_err("Emergency stop");
439
void lua_norm_error(char *s)
440
{ /* lua found a problem */
441
int saved_new_line_char;
442
saved_new_line_char = new_line_char;
444
print_err("LuaTeX error ");
446
help2("The lua interpreter ran into a problem, so the",
447
"remainder of this lua chunk will be ignored.");
449
new_line_char = saved_new_line_char;
452
void lua_fatal_error(char *s)
453
{ /* lua found a problem */
455
normalize_selector();
456
print_err("LuaTeX fatal error ");
461
/* Here is the most dreaded error message */
463
void overflow(char *s, int n)
464
{ /* stop due to finiteness */
465
normalize_selector();
466
print_err("TeX capacity exceeded, sorry [");
471
help2("If you really absolutely need more capacity,",
472
"you can ask a wizard to enlarge me.");
477
The program might sometime run completely amok, at which point there is
478
no choice but to stop. If no previous error has been detected, that's bad
479
news; a message is printed that is really intended for the \TeX\
480
maintenance person instead of the user (unless the user has been
481
particularly diabolical). The index entries for `this can't happen' may
482
help to pinpoint the problem.
486
void confusion(char *s)
487
{ /* consistency check violated; |s| tells where */
488
normalize_selector();
489
if (history < error_message_issued) {
490
print_err("This can't happen (");
493
help1("I'm broken. Please show this to someone who can fix can fix");
495
print_err("I can't go on meeting you like this");
496
help2("One of your faux pas seems to have wounded me deeply...",
497
"in fact, I'm barely conscious. Please fix it and try again.");
503
Users occasionally want to interrupt \TeX\ while it's running.
504
If the \PASCAL\ runtime system allows this, one can implement
505
a routine that sets the global variable |interrupt| to some nonzero value
506
when such an interrupt is signalled. Otherwise there is probably at least
507
a way to make |interrupt| nonzero using the \PASCAL\ debugger.
508
@^system dependencies@>
512
void check_interrupt(void)
515
pause_for_instructions();
520
When an interrupt has been detected, the program goes into its
521
highest interaction level and lets the user have nearly the full flexibility of
522
the |error| routine. \TeX\ checks for interrupts only at times when it is
526
void pause_for_instructions(void)
528
if (OK_to_interrupt) {
529
interaction = error_stop_mode;
530
if ((selector == log_only) || (selector == no_print))
532
print_err("Interruption");
534
"Try to insert some instructions for me (e.g.,`I\\showlists'),",
535
"unless you just want to quit by typing `X'.");
536
deletions_allowed = false;
538
deletions_allowed = true;
545
void tex_error(char *msg, char **hlp)
550
for (i = 0; (hlp[i] != NULL && i <= 5); i++) {
551
help_line[i] = hlp[i];
561
The |back_error| routine is used when we want to replace an offending token
562
just before issuing an error message. This routine, like |back_input|,
563
requires that |cur_tok| has been set. We disable interrupts during the
564
call of |back_input| so that the help message won't be lost.
567
void back_error(void)
568
{ /* back up one token and call |error| */
569
OK_to_interrupt = false;
571
OK_to_interrupt = true;
576
{ /* back up one inserted token and call |error| */
577
OK_to_interrupt = false;
579
token_type = inserted;
580
OK_to_interrupt = true;
586
When \TeX\ wants to typeset a character that doesn't exist, the
587
character node is not created; thus the output routine can assume
588
that characters exist when it sees them. The following procedure
589
prints a warning message unless the user has suppressed it.
592
void char_warning(internal_font_number f, int c)
594
int old_setting; /* saved value of |tracing_online| */
595
int k; /* index to current digit; we assume that $0\L n<16^{22}$ */
596
if (int_par(tracing_lost_chars_code) > 0) {
597
old_setting = int_par(tracing_online_code);
598
if (int_par(tracing_lost_chars_code) > 1)
599
int_par(tracing_online_code) = 1;
601
tprint_nl("Missing character: There is no ");
617
tprint(") in font ");
620
end_diagnostic(false);
621
int_par(tracing_online_code) = old_setting;