3 % Copyright
2009-2010 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
/>.
20 @ TODO
: we need to use a formatted normal_error in
:
29 #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
*/
57 /* ls-hh
: so
, new code only kicks in when we have a callback defined
*/
59 char
*last_error
= NULL;
60 char
*last_lua_error
= NULL;
61 char
*last_warning_tag
= NULL;
62 char
*last_warning_str
= NULL;
63 char
*last_error_context
= NULL;
65 int err_old_setting
= 0 ;
68 void set_last_error_context
(void
)
72 int saved_new_line_char
;
73 int saved_new_string_line
;
74 selector
= new_string
;
75 saved_new_line_char
= new_line_char
;
76 saved_new_string_line
= new_string_line
;
80 xfree
(last_error_context
);
82 last_error_context
= makecstring
(str
);
85 new_line_char
= saved_new_line_char
;
86 new_string_line
= saved_new_string_line
;
96 selector
= err_old_setting
;
98 s_error
= make_string
();
99 s
= makecstring
(s_error
);
101 if
(interaction
== error_stop_mode
) {
105 last_error
= (string
) xmalloc
((unsigned
) (strlen
(s
) + 1));
106 strcpy
(last_error
,s
);
107 callback_id
= callback_defined
(show_error_message_callback
);
108 if
(callback_id
> 0) {
109 run_callback
(callback_id
, "->");
117 void print_err
(const char
*s
)
119 int callback_id
= callback_defined
(show_error_message_callback
);
120 if
(interaction
== error_stop_mode
) {
123 if
(callback_id
> 0) {
124 err_old_setting
= selector
;
125 selector
= new_string
;
128 if
(filelineerrorstylep
) {
134 if
(callback_id
<= 0) {
136 last_error
= (string
) xmalloc
((unsigned
) (strlen
(s
) + 1));
137 strcpy
(last_error
,s
);
141 @ \TeX\ is careful not to call |error| when the print |selector| setting
142 might be unusual. The only possible values of |selector| at the time of
146 \hang|no_print|
(when |interaction
=batch_mode| and |log_file| not yet open
);
148 \hang|term_only|
(when |interaction
>batch_mode| and |log_file| not yet open
);
150 \hang|log_only|
(when |interaction
=batch_mode| and |log_file| is open
);
152 \hang|term_and_log|
(when |interaction
>batch_mode| and |log_file| is open
).
155 void fixup_selector
(boolean logopened
)
157 if
(interaction
== batch_mode
)
160 selector
= term_only
;
162 selector
= selector
+ 2;
165 @ A global variable |deletions_allowed| is set |false| if the |get_next|
166 routine is active when |error| is called
; this ensures that |get_next|
167 and related routines like |get_token| will never be called recursively.
168 A similar interlock is provided by |set_box_allowed|.
171 The global variable |history| records the worst level of error that
172 has been detected. It has four possible values
: |spotless|
, |warning_issued|
,
173 |error_message_issued|
, and |fatal_error_stop|.
175 Another global variable
, |error_count|
, is increased by one when an
176 |error| occurs without an interactive dialog
, and it is reset to zero at
177 the end of every paragraph. If |error_count| reaches
100, \TeX\ decides
178 that there is no point in continuing further.
181 boolean deletions_allowed
; /* is it safe for |error| to call |get_token|?
*/
182 boolean set_box_allowed
; /* is it safe to do a \.
{\\setbox
} assignment?
*/
183 int history
; /* has the source input been clean so far?
*/
184 int error_count
; /* the number of scrolled errors since the last paragraph ended
*/
185 int interrupt
; /* should \TeX\ pause for instructions?
*/
186 boolean OK_to_interrupt
; /* should interrupts be observed?
*/
188 @ The value of |history| is initially |fatal_error_stop|
, but it will
189 be changed to |spotless| if \TeX\ survives the initialization process.
192 void initialize_errors
(void
)
194 if
(interactionoption
== unspecified_mode
)
195 interaction
= error_stop_mode
;
197 interaction
= interactionoption
;
198 deletions_allowed
= true
;
199 set_box_allowed
= true
;
200 OK_to_interrupt
= true
;
201 /* |history| is initialized elsewhere
*/
204 @ It is possible for |error| to be called recursively if some error arises
205 when |get_token| is being used to delete a token
, and
/or if some fatal error
206 occurs while \TeX\ is trying to fix a non-fatal one. But such recursion
208 is never more than two levels deep.
210 @ Individual lines of help are recorded in the array |help_line|.
213 const char
*help_line
[7]; /* helps for the next |error|
*/
214 boolean use_err_help
; /* should the |err_help| list be shown?
*/
216 @ The |jump_out| procedure just cuts across all active procedure levels and
217 exits the program. It is used when there is no recovery from a particular error.
220 __attribute__
((noreturn
))
221 void do_final_end
(void
)
225 if
((history
!= spotless
) && (history != warning_issued))
231 __attribute__
((noreturn
))
234 close_files_and_terminate
();
240 { /* completes the job of error reporting
*/
241 ASCII_code c
; /* what the user types
*/
243 int s1
, s2
, s3
, s4
; /* used to save global variables when deleting tokens
*/
245 flush_err
(); /* hh-ls
*/
246 if
(history
< error_message_issued
)
247 history
= error_message_issued
;
248 callback_id
= callback_defined
(show_error_hook_callback
);
249 if
(callback_id
> 0) {
250 set_last_error_context
();
251 run_callback
(callback_id
, "->");
257 history
= fatal_error_stop
;
260 if
(interaction
== error_stop_mode
) {
261 /* Get user's advice and |return|
*/
264 clear_for_error_prompt
();
270 c
= c
+ 'A'
- 'a'
; /* convert to uppercase
*/
271 /* Interpret code |c| and |return| if done
*/
273 /* It is desirable to provide an `\.E' option here that gives the user
274 an easy way to return from \TeX\ to the system editor
, with the offending
275 line ready to be edited. But such an extension requires some system
276 wizardry
, so the present implementation simply types out the name of the
277 file that should be edited and the relevant line number.
279 There is a secret `\.D' option available when the debugging routines haven't
280 been commented~out.
*/
293 if
(deletions_allowed
) {
294 /* Delete |c-
"0"| tokens and |goto continue|
*/
295 /* We allow deletion of up to
99 tokens at a time
*/
300 align_state
= 1000000;
301 OK_to_interrupt
= false
;
302 if
((last
> first
+ 1) && (buffer[first + 1] >= '0')
303 && (buffer[first + 1] <= '9'))
304 c
= c
* 10 + buffer
[first
+ 1] - '
0'
* 11;
308 get_token
(); /* one-level recursive call of |error| is possible
*/
315 OK_to_interrupt
= true
;
316 help2
("I have just deleted some text, as you asked.",
317 "You can now delete more, or insert, or whatever.");
330 tprint_nl
("You want to edit file ");
331 print
(input_stack
[base_ptr
].name_field
);
334 interaction
= scroll_mode
;
339 /* Print the help information and |goto continue|
*/
343 if
(help_line
[0] == NULL) {
345 ("Sorry, I don't know how to help in this situation.",
346 "Maybe you should try asking a human?");
349 while
(help_line
[i
] != NULL)
350 tprint_nl
(help_line
[i
++]);
351 help4
("Sorry, I already gave what help I could...",
352 "Maybe you should try asking a human?",
353 "An error might have occurred before I noticed any problems.",
354 "``If all else fails, read the instructions.''");
359 /* Introduce new material from the terminal and |return|
*/
360 /* When the following code is executed
, |buffer
[(first
+1)..
(last-1
)]| may
361 contain the material inserted by the user
; otherwise another prompt will
362 be given. In order to understand this part of the program fully
, you need
363 to be familiar with \TeX's input stacks.
*/
365 begin_file_reading
(); /* enter a new syntactic level for terminal input
*/
366 /* now |state
=mid_line|
, so an initial blank space will count as a blank
*/
367 if
(last
> first
+ 1) {
371 prompt_input
("insert>");
375 ilimit
= last
- 1; /* no |end_line_char| ends this line
*/
381 /* Change the interaction level and |return|
*/
382 /* Here the author of \TeX\ apologizes for making use of the numerical
383 relation between |
"Q"|
, |
"R"|
, |
"S"|
, and the desired interaction settings
384 |batch_mode|
, |nonstop_mode|
, |scroll_mode|.
*/
386 interaction
= batch_mode
+ c
- 'Q'
;
387 tprint
("OK, entering ");
390 tprint_esc
("batchmode");
394 tprint_esc
("nonstopmode");
397 tprint_esc
("scrollmode");
406 interaction
= scroll_mode
;
413 /* Print the menu of available options
*/
414 tprint
("Type <return> to proceed, S to scroll future error messages,");
415 tprint_nl
("R to run without stopping, Q to run quietly,");
416 tprint_nl
("I to insert something, ");
418 tprint
("E to edit your file,");
419 if
(deletions_allowed
)
420 tprint_nl
("1 or ... or 9 to ignore the next 1 to 9 tokens of input,");
421 tprint_nl
("H for help, X to quit.");
423 use_err_help
= false
;
428 if
(error_count
== 100) {
429 tprint_nl
("(That makes 100 errors; please try again.)");
430 history
= fatal_error_stop
;
433 /* Put help message on the transcript file
*/
434 if
(interaction
> batch_mode
)
435 decr
(selector
); /* avoid terminal output
*/
441 while
(help_line
[i1
] != NULL)
442 tprint_nl
(help_line
[i1
++]);
445 if
(interaction
> batch_mode
)
446 incr
(selector
); /* re-enable terminal output
*/
450 @ A dozen or so error messages end with a parenthesized integer
, so we
451 save a teeny bit of program space by declaring the following procedure
:
454 void int_error
(int n
)
462 @ In anomalous cases
, the print selector might be in an unknown state
;
463 the following subroutine is called to fix things just enough to keep
464 running a bit longer.
467 void normalize_selector
(void
)
469 if
(log_opened_global
)
470 selector
= term_and_log
;
472 selector
= term_only
;
475 if
(interaction
== batch_mode
)
479 @ The following procedure prints \TeX's last words before dying
483 if
(interaction
== error_stop_mode
)
484 interaction
= scroll_mode
; /* no more interaction
*/
485 if
(log_opened_global
)
488 if
(interaction
> batch_mode
)
491 history
= fatal_error_stop
;
492 jump_out
(); /* irrecoverable error
*/
496 void fatal_error
(const char
*s
)
497 { /* prints |s|
, and that's it
*/
498 normalize_selector
();
499 print_err
("Emergency stop");
504 @ Here is the most dreaded error message
506 void overflow
(const char
*s
, unsigned int n
)
507 { /* stop due to finiteness
*/
508 normalize_selector
();
509 print_err
("TeX capacity exceeded, sorry [");
514 help2
("If you really absolutely need more capacity,",
515 "you can ask a wizard to enlarge me.");
519 @ The program might sometime run completely amok
, at which point there is
520 no choice but to stop. If no previous error has been detected
, that's bad
521 news
; a message is printed that is really intended for the \TeX\
522 maintenance person instead of the user
(unless the user has been
523 particularly diabolical
). The index entries for `this can't happen' may
524 help to pinpoint the problem.
528 void confusion
(const char
*s
)
529 { /* consistency check violated
; |s| tells where
*/
530 normalize_selector
();
531 if
(history
< error_message_issued
) {
532 print_err
("This can't happen (");
535 help1
("I'm broken. Please show this to someone who can fix can fix");
537 print_err
("I can't go on meeting you like this");
538 help2
("One of your faux pas seems to have wounded me deeply...",
539 "in fact, I'm barely conscious. Please fix it and try again.");
544 @ Users occasionally want to interrupt \TeX\ while it's running.
545 If the runtime system allows this
, one can implement
546 a routine that sets the global variable |interrupt| to some nonzero value
547 when such an interrupt is signalled. Otherwise there is probably at least
548 a way to make |interrupt| nonzero using the debugger.
549 @^system dependencies@
>
553 void check_interrupt
(void
)
556 pause_for_instructions
();
559 @ When an interrupt has been detected
, the program goes into its
560 highest interaction level and lets the user have nearly the full flexibility of
561 the |error| routine. \TeX\ checks for interrupts only at times when it is
565 void pause_for_instructions
(void
)
567 if
(OK_to_interrupt
) {
568 interaction
= error_stop_mode
;
569 if
((selector
== log_only
) ||
(selector
== no_print
))
571 print_err
("Interruption");
573 "Try to insert some instructions for me (e.g.,`I\\showlists'),",
574 "unless you just want to quit by typing `X'.");
575 deletions_allowed
= false
;
577 deletions_allowed
= true
;
583 void tex_error
(const char
*msg
, const char
**hlp
)
588 for
(i
= 0; (hlp
[i
] != NULL && i <= 5); i++) {
589 help_line
[i
] = hlp
[i
];
598 @ The |back_error| routine is used when we want to replace an offending token
599 just before issuing an error message. This routine
, like |back_input|
,
600 requires that |cur_tok| has been set. We disable interrupts during the
601 call of |back_input| so that the help message won't be lost.
604 void back_error
(void
)
605 { /* back up one token and call |error|
*/
606 OK_to_interrupt
= false
;
608 OK_to_interrupt
= true
;
614 { /* back up one inserted token and call |error|
*/
615 OK_to_interrupt
= false
;
617 token_type
= inserted
;
618 OK_to_interrupt
= true
;
622 @ When \TeX\ wants to typeset a character that doesn't exist
, the
623 character node is not created
; thus the output routine can assume
624 that characters exist when it sees them. The following procedure
625 prints a warning message unless the user has suppressed it.
628 void char_warning
(internal_font_number f
, int c
)
630 int old_setting
; /* saved value of |tracing_online|
*/
631 int k
; /* index to current digit
; we assume that $
0\L n
<16^
{22}$
*/
632 if
(int_par
(tracing_lost_chars_code
) > 0) {
633 old_setting
= int_par
(tracing_online_code
);
634 if
(int_par
(tracing_lost_chars_code
) > 1)
635 int_par
(tracing_online_code
) = 1;
637 tprint_nl
("Missing character: There is no ");
652 print_the_digs
((eight_bits
) k
);
653 tprint
(") in font ");
656 end_diagnostic
(false
);
657 int_par
(tracing_online_code
) = old_setting
;
663 void wrapup_backend
(void
) {
664 ensure_output_state
(static_pdf
, ST_OMODE_FIX
);
665 switch
(output_mode_used
) {
667 print_err
(" ==> Fatal error occurred, no FMT file produced!");
670 if
(history
== fatal_error_stop
) {
671 remove_pdffile
(static_pdf
); /* will become remove_output_file
*/
672 print_err
(" ==> Fatal error occurred, no output PDF file produced!");
674 finish_pdf_file
(static_pdf
, luatex_version
, get_luatexrevision
());
678 if
(history
== fatal_error_stop
) {
679 print_err
(" ==> Fatal error occurred, bad output DVI file produced!");
680 finish_dvi_file
(static_pdf
, luatex_version
, get_luatexrevision
());
682 finish_dvi_file
(static_pdf
, luatex_version
, get_luatexrevision
());
688 void normal_error
(const char
*t
, const char
*p
)
690 normalize_selector
();
691 if
(interaction
== error_stop_mode
) {
694 if
(filelineerrorstylep
) {
702 tprint
(cur_file_name
);
713 history
= fatal_error_stop
;
719 void normal_error
(const char
*t
, const char
*p
)
721 normalize_selector
();
722 if
(interaction
== error_stop_mode
) {
728 history
= fatal_error_stop
;
735 void normal_warning
(const char
*t
, const char
*p
)
738 if
(strcmp
(t
,"lua") == 0) {
739 int saved_new_line_char
;
740 saved_new_line_char
= new_line_char
;
742 report_id
= callback_defined
(show_lua_error_hook_callback
);
743 if
(report_id
== 0) {
745 help2
("The lua interpreter ran into a problem, so the",
746 "remainder of this lua chunk will be ignored.");
748 (void
) run_callback
(report_id
, "->");
751 new_line_char
= saved_new_line_char
;
753 report_id
= callback_defined
(show_warning_message_callback
);
756 xfree
(last_warning_str
);
757 xfree
(last_warning_tag
);
758 last_warning_str
= (string
) xmalloc
(strlen
(p
) + 1);
759 last_warning_tag
= (string
) xmalloc
(strlen
(t
) + 1);
760 strcpy
(last_warning_str
,p
);
761 strcpy
(last_warning_tag
,t
);
762 run_callback
(report_id
, "->");
768 tprint
(cur_file_name
);
781 if
(history
== spotless
)
782 history
= warning_issued
;
787 static char print_buf
[PRINTF_BUF_SIZE
];
788 __attribute__
((format
(printf
, 2,3)))
789 void formatted_error
(const char
*t
, const char
*fmt
, ...
)
793 vsnprintf
(print_buf
, PRINTF_BUF_SIZE
, fmt
, args
);
794 normal_error
(t
,print_buf
);
798 __attribute__
((format
(printf
, 2,3)))
799 void formatted_warning
(const char
*t
, const char
*fmt
, ...
)
803 vsnprintf
(print_buf
, PRINTF_BUF_SIZE
, fmt
, args
);
804 normal_warning
(t
,print_buf
);