1
4
5# include "luametatex.h"
6
7print_state_info lmt_print_state = {
8 .logfile = NULL,
9 .loggable_info = NULL,
10 .selector = 0,
11 .tally = 0,
12 .terminal_offset = 0,
13 .logfile_offset = 0,
14 .new_string_line = 0,
15 .trick_buffer = { 0 },
16 .trick_count = 0,
17 .first_count = 0,
18 .saved_selector = 0,
19 .font_in_short_display = 0,
20 .saved_logfile = NULL,
21 .saved_logfile_offset = 0,
22};
23
24
42
43
104
105void tex_print_ln(void)
106{
107 switch (lmt_print_state.selector) {
108 case no_print_selector_code:
109 break;
110 case terminal_selector_code:
111 fputc('\n', stdout);
112 lmt_print_state.terminal_offset = 0;
113 break;
114 case logfile_selector_code:
115 fputc('\n', lmt_print_state.logfile);
116 lmt_print_state.logfile_offset = 0;
117 break;
118 case terminal_and_logfile_selector_code:
119 fputc('\n', stdout);
120 fputc('\n', lmt_print_state.logfile);
121 lmt_print_state.terminal_offset = 0;
122 lmt_print_state.logfile_offset = 0;
123 break;
124 case pseudo_selector_code:
125 break;
126 case new_string_selector_code:
127 if (lmt_print_state.new_string_line > 0) {
128 tex_print_char(lmt_print_state.new_string_line);
129 }
130 break;
131 case luabuffer_selector_code:
132 lmt_newline_to_buffer();
133 break;
134 default:
135 break;
136 }
137
138}
139
140
141
152
153void tex_print_char(int s)
154{
155 if (s < 0 || s > 255) {
156 tex_formatted_warning("print", "weird character %i", s);
157 } else {
158 switch (lmt_print_state.selector) {
159 case no_print_selector_code:
160 break;
161 case terminal_selector_code:
162 if (s == new_line_char_par) {
163 fputc('\n', stdout);
164 lmt_print_state.terminal_offset = 0;
165 } else {
166 fputc(s, stdout);
167 ++lmt_print_state.terminal_offset;
168 }
169 break;
170 case logfile_selector_code:
171 if (s == new_line_char_par) {
172 fputc('\n', lmt_print_state.logfile);
173 lmt_print_state.logfile_offset = 0;
174 } else {
175 fputc(s, lmt_print_state.logfile);
176 ++lmt_print_state.logfile_offset;
177 }
178 break;
179 case terminal_and_logfile_selector_code:
180 if (s == new_line_char_par) {
181 fputc('\n', stdout);
182 fputc('\n', lmt_print_state.logfile);
183 lmt_print_state.terminal_offset = 0;
184 lmt_print_state.logfile_offset = 0;
185 } else {
186 fputc(s, stdout);
187 fputc(s, lmt_print_state.logfile);
188 ++lmt_print_state.terminal_offset;
189 ++lmt_print_state.logfile_offset;
190 }
191 break;
192 case pseudo_selector_code:
193 if (lmt_print_state.tally < lmt_print_state.trick_count) {
194 lmt_print_state.trick_buffer[lmt_print_state.tally % lmt_error_state.line_limits.size] = (unsigned char) s;
195 }
196 ++lmt_print_state.tally;
197 break;
198 case new_string_selector_code:
199 tex_append_char((unsigned char) s);
200 break;
201 case luabuffer_selector_code:
202 lmt_char_to_buffer((char) s);
203 break;
204 default:
205 break;
206 }
207 }
208}
209
210
225
226
227
228static void tex_aux_uprint(int s)
229{
230
231
238 if (s == new_line_char_par && lmt_print_state.selector < pseudo_selector_code) {
239 tex_print_ln();
240 } else if (s <= 0x7F) {
241 tex_print_char(s);
242 } else if (s <= 0x7FF) {
243 tex_print_char(0xC0 + (s / 0x40));
244 tex_print_char(0x80 + (s % 0x40));
245 } else if (s <= 0xFFFF) {
246 tex_print_char(0xE0 + (s / 0x1000));
247 tex_print_char(0x80 + ((s % 0x1000) / 0x40));
248 tex_print_char(0x80 + ((s % 0x1000) % 0x40));
249 } else {
250 tex_print_char(0xF0 + (s / 0x40000));
251 tex_print_char(0x80 + ((s % 0x40000) / 0x1000));
252 tex_print_char(0x80 + (((s % 0x40000) % 0x1000) / 0x40));
253 tex_print_char(0x80 + (((s % 0x40000) % 0x1000) % 0x40));
254 }
255}
256
257void tex_print_tex_str(int s)
258{
259 if (s >= lmt_string_pool_state.string_pool_data.ptr) {
260 tex_normal_warning("print", "bad string pointer");
261 } else if (s < cs_offset_value) {
262 if (s < 0) {
263 tex_normal_warning("print", "bad string offset");
264 } else {
265 tex_aux_uprint(s);
266 }
267 } else if (lmt_print_state.selector == new_string_selector_code) {
268 tex_append_string(str_string(s), (unsigned) str_length(s));
269 } else {
270 unsigned char *j = str_string(s);
271 for (unsigned i = 0; i < str_length(s); i++) {
272 tex_print_char(j[i]);
273 }
274 }
275}
276
277
283
284void tex_print_nlp(void)
285{
286 if (lmt_print_state.new_string_line > 0) {
287 tex_print_char(lmt_print_state.new_string_line);
288 } else {
289 switch (lmt_print_state.selector) {
290 case terminal_selector_code:
291 if (lmt_print_state.terminal_offset > 0) {
292 fputc('\n', stdout);
293 lmt_print_state.terminal_offset = 0;
294 }
295 break;
296 case logfile_selector_code:
297 if (lmt_print_state.logfile_offset > 0) {
298 fputc('\n', lmt_print_state.logfile);
299 lmt_print_state.logfile_offset = 0;
300 }
301 break;
302 case terminal_and_logfile_selector_code:
303 if (lmt_print_state.terminal_offset > 0) {
304 fputc('\n', stdout);
305 lmt_print_state.terminal_offset = 0;
306 }
307 if (lmt_print_state.logfile_offset > 0) {
308 fputc('\n', lmt_print_state.logfile);
309 lmt_print_state.logfile_offset = 0;
310 }
311 break;
312 case luabuffer_selector_code:
313 lmt_newline_to_buffer();
314 break;
315 }
316 }
317}
318
319
325
326void tex_print_str(const char *s)
327{
328 int logfile = 0;
329 int terminal = 0;
330 switch (lmt_print_state.selector) {
331 case no_print_selector_code:
332 return;
333 case terminal_selector_code:
334 terminal = 1;
335 break;
336 case logfile_selector_code:
337 logfile = 1;
338 break;
339 case terminal_and_logfile_selector_code:
340 logfile = 1;
341 terminal = 1;
342 break;
343 case pseudo_selector_code:
344 while ((*s) && (lmt_print_state.tally < lmt_print_state.trick_count)) {
345 lmt_print_state.trick_buffer[lmt_print_state.tally % lmt_error_state.line_limits.size] = (unsigned char) *s++;
346 lmt_print_state.tally++;
347 }
348 return;
349 case new_string_selector_code:
350 tex_append_string((const unsigned char *) s, (unsigned) strlen(s));
351 return;
352 case luabuffer_selector_code:
353 lmt_string_to_buffer(s);
354 return;
355 default:
356 return;
357 }
358 if (terminal || logfile) {
359 int len = (int) strlen(s);
360 if (logfile && ! lmt_fileio_state.log_opened) {
361 logfile = 0;
362 }
363 if (len > 0) {
364 int newline = s[len-1] == '\n';
365 if (logfile) {
366 fputs(s, lmt_print_state.logfile);
367 if (newline) {
368 lmt_print_state.logfile_offset = 0;
369 } else {
370 lmt_print_state.logfile_offset += len;
371 }
372 }
373 if (terminal) {
374 fputs(s, stdout);
375 if (newline) {
376 lmt_print_state.terminal_offset = 0;
377 } else {
378 lmt_print_state.terminal_offset += len;
379 }
380 }
381 }
382 }
383}
384
385
395
396void tex_print_banner(void)
397{
398 fprintf(
399 stdout,
400 "%s %s\n",
401 lmt_engine_state.luatex_banner,
402 lmt_engine_state.dump_name
403 );
404}
405
406void tex_print_log_banner(void)
407{
408 fprintf(
409 lmt_print_state.logfile,
410 "engine: %s, format id: %s, time stamp: %d-%d-%d %d:%d, startup file: %s, job name: %s",
411 lmt_engine_state.luatex_banner,
412 lmt_engine_state.dump_name,
413 year_par, month_par > 12 ? 0 : month_par, day_par, time_par / 60, time_par % 60,
414 lmt_engine_state.startup_filename ? lmt_engine_state.startup_filename : "-",
415 lmt_engine_state.startup_jobname ? lmt_engine_state.startup_jobname : "-"
416 );
417}
418
419void tex_print_version_banner(void)
420{
421 fputs(lmt_engine_state.luatex_banner, stdout);
422}
423
424
430
431void tex_print_tex_str_esc(strnumber s)
432{
433
434 int c = escape_char_par;
435 if (c >= 0) {
436 tex_print_tex_str(c);
437 }
438 if (s) {
439 tex_print_tex_str(s);
440 }
441}
442
443
444
445void tex_print_str_esc(const char *s)
446{
447
448 int c = escape_char_par;
449 if (c >= 0) {
450 tex_print_tex_str(c);
451 }
452 if (s) {
453 tex_print_str(s);
454 }
455}
456
457
465
466void tex_print_int(int n)
467{
468
469 if (n < 0) {
470 tex_print_char('-');
471 n = -n;
472 }
473 if (n >= 0 && n <= 9) {
474 tex_print_char('0' + n);
475 } else if (n >= 0 && n <= 99) {
476 tex_print_char('0' + n/10);
477 tex_print_char('0' + n%10);
478 } else {
479 int k = 0;
480 unsigned char digits[24];
481
482
483
484
485 do {
486 digits[k] = '0' + (unsigned char) (n % 10);
487 n = n / 10;
488 ++k;
489 } while (n != 0);
490 while (k-- > 0) {
491 tex_print_char(digits[k]);
492 }
493 }
494}
495
496
511
512void tex_print_dimension(scaled s, int unit)
513{
514 if (s == 0) {
515 tex_print_str("0.0");
516 } else {
517
518 scaled delta = 10;
519 char buffer[20] = { 0 } ;
520 int i = 0;
521 if (s < 0) {
522
523 tex_print_char('-');
524 s = -s;
525 }
526
527 tex_print_int(s / unity);
528 buffer[i++] = '.';
529 s = 10 * (s % unity) + 5;
530 do {
531 if (delta > unity) {
532
533 s = s + 0x8000 - 50000;
534 }
535 buffer[i++] = (unsigned char) ('0' + (s / unity));
536 s = 10 * (s % unity);
537 delta *= 10;
538 } while (s > delta);
539
540 tex_print_str(buffer);
541 }
542 if (unit != no_unit) {
543 tex_print_unit(unit);
544 }
545}
546
547void tex_print_sparse_dimension(scaled s, int unit)
548{
549 if (s == 0) {
550 tex_print_char('0');
551 } else if (s == unity) {
552 tex_print_char('1');
553 } else {
554
555 scaled delta = 10;
556 char buffer[20];
557 int i = 0;
558 if (s < 0) {
559
560 tex_print_char('-');
561
562 s = -s;
563 }
564
565 tex_print_int(s / unity);
566 s = 10 * (s % unity) + 5;
567 do {
568 if (delta > unity) {
569
570 s = s + 0100000 - 50000;
571 }
572 buffer[i++] = (unsigned char) ('0' + (s / unity));
573 s = 10 * (s % unity);
574 delta *= 10;
575 } while (s > delta);
576 if (i == 1 && buffer[i-1] == '0') {
577
578 } else {
579 buffer[i++] = '\0';
580 tex_print_char('.');
581 tex_print_str(buffer);
582 }
583 }
584 if (unit != no_unit) {
585 tex_print_unit(unit);
586 }
587}
588
589
592
593void tex_print_posit(halfword s)
594{
595 char b[32];
596 sprintf(b, "%.20g", tex_posit_to_double(s));
597 tex_print_str(b);
598}
599
600
606
607void tex_print_hex(long long sn)
608{
609 if (sn == 0) {
610 tex_print_char('0');
611 } else {
612 unsigned long long n = 0;
613 int k = 0;
614 unsigned char digits[24];
615 if (sn < 0) {
616 tex_print_char('-');
617 n = (unsigned long long) -sn;
618 } else {
619 n = (unsigned long long) sn;
620 }
621 do {
622 unsigned char d = (unsigned char) (n % 16);
623 if (d < 10) {
624 digits[k] = '0' + d;
625 } else {
626 digits[k] = 'A' - 10 + d;
627 }
628 n = n / 16;
629 ++k;
630 } while (n != 0);
631 while (k-- > 0) {
632 tex_print_char(digits[k]);
633 }
634 }
635}
636
637void tex_print_qhex(long long n)
638{
639 tex_print_char('"');
640 tex_print_hex(n);
641}
642
643void tex_print_uhex(long long n)
644{
645 tex_print_str("U+");
646
647 if (n < 16) {
648 tex_print_char('0');
649 }
650 if (n < 256) {
651 tex_print_char('0');
652 }
653 if (n < 4096) {
654 tex_print_char('0');
655 }
656 tex_print_hex(n);
657}
658
659static void tex_print_xhex(long long n)
660{
661 tex_print_char('"');
662
663 if (n < 0xF) {
664 tex_print_char('0');
665 }
666 if (n < 0xFF) {
667 tex_print_char('0');
668 }
669 if (n < 0xFFF) {
670 tex_print_char('0');
671 }
672 if (n < 0xFFFF) {
673 tex_print_char('0');
674 }
675 if (n < 0xFFFFF) {
676 tex_print_char('0');
677 }
678 if (n < 0xFFFFFF) {
679 tex_print_char('0');
680 }
681 if (n < 0xFFFFFFF) {
682 tex_print_char('0');
683 }
684 tex_print_hex(n);
685}
686
687
694
695void tex_print_roman_int(int n)
696{
697 char mystery[] = "m2d5c2l5x2v5i";
698 char *j = (char *) mystery;
699 int v = 1000;
700 while (1) {
701 while (n >= v) {
702 tex_print_char(*j);
703 n = n - v;
704 }
705 if (n <= 0) {
706
707 return;
708 } else {
709 char *k = j + 2;
710 int u = v / (*(k - 1) - '0');
711 if (*(k - 1) == '2') {
712 k = k + 2;
713 u = u / (*(k - 1) - '0');
714 }
715 if (n + u >= v) {
716 tex_print_char(*k);
717 n = n + u;
718 } else {
719 j = j + 2;
720 v = v / (*(j - 1) - '0');
721 }
722 }
723 }
724}
725
726
732
733void tex_print_current_string(void)
734{
735 for (int j = 0; j < lmt_string_pool_state.string_temp_top; j++) {
736 tex_print_char(lmt_string_pool_state.string_temp[j++]);
737 }
738}
739
740
749
750void tex_print_cs_checked(halfword p)
751{
752 switch (tex_cs_state(p)) {
753 case cs_no_error:
754 {
755 strnumber t = cs_text(p);
756 if (t < 0 || t >= lmt_string_pool_state.string_pool_data.ptr) {
757 tex_print_str(error_string_nonexistent(13));
758 } else if (tex_is_active_cs(t)) {
759 tex_print_tex_str(active_cs_value(t));
760 } else {
761 tex_print_tex_str_esc(t);
762 if (! tex_single_letter(t) || (tex_get_cat_code(cat_code_table_par, aux_str2uni(str_string(t))) == letter_cmd)) {
763 tex_print_char(' ');
764 }
765 }
766 }
767 break;
768 case cs_null_error:
769 tex_print_str_esc("csname");
770 tex_print_str_esc("endcsname");
771 tex_print_char(' ');
772 break;
773 case cs_below_base_error:
774 tex_print_str(error_string_impossible(11));
775 break;
776 case cs_undefined_error:
777 tex_print_str_esc("undefined");
778 tex_print_char(' ');
779 break;
780 case cs_out_of_range_error:
781 tex_print_str(error_string_impossible(12));
782 break;
783 }
784}
785
786
792
793void tex_print_cs(halfword p)
794{
795 if (p == null_cs) {
796 tex_print_str_esc("csname");
797 tex_print_str_esc("endcsname");
798 } else {
799 strnumber t = cs_text(p);
800 if (tex_is_active_cs(t)) {
801 tex_print_tex_str(active_cs_value(t));
802 } else {
803 tex_print_tex_str_esc(t);
804 }
805 }
806}
807
808void tex_print_cs_name(halfword p)
809{
810 if (p != null_cs) {
811 strnumber t = cs_text(p);
812 if (tex_is_active_cs(t)) {
813 tex_print_tex_str(active_cs_value(t));
814 } else {
815 tex_print_tex_str(t);
816 }
817 }
818}
819
820
826
827void tex_print_glue(scaled d, int order, int unit)
828{
829 tex_print_dimension(d, no_unit);
830 if ((order < normal_glue_order) || (order > filll_glue_order)) {
831 tex_print_str("foul");
832 } else if (order > normal_glue_order) {
833 tex_print_str("fi");
834 while (order > fi_glue_order) {
835 tex_print_char('l');
836 --order;
837 }
838 } else {
839 tex_print_unit(unit);
840 }
841}
842
843
844
845void tex_print_unit(int unit)
846{
847 if (unit != no_unit) {
848 tex_print_str(unit == pt_unit ? "pt" : "mu");
849 }
850}
851
852void tex_print_spec(int p, int unit)
853{
854 if (p < 0) {
855 tex_print_char('*');
856 } else if (p == 0) {
857 tex_print_dimension(0, unit);
858 } else {
859 tex_print_dimension(glue_amount(p), unit);
860 if (glue_stretch(p)) {
861 tex_print_str(" plus ");
862 tex_print_glue(glue_stretch(p), glue_stretch_order(p), unit);
863 }
864 if (glue_shrink(p)) {
865 tex_print_str(" minus ");
866 tex_print_glue(glue_shrink(p), glue_shrink_order(p), unit);
867 }
868 }
869}
870
871void tex_print_fontspec(int p)
872{
873 tex_print_int(font_spec_identifier(p));
874 if (font_spec_scale(p) != unused_scale_value) {
875 tex_print_str(" scale ");
876 tex_print_int(font_spec_scale(p));
877 }
878 if (font_spec_x_scale(p) != unused_scale_value) {
879 tex_print_str(" xscale ");
880 tex_print_int(font_spec_x_scale(p));
881 }
882 if (font_spec_y_scale(p) != unused_scale_value) {
883 tex_print_str(" yscale ");
884 tex_print_int(font_spec_y_scale(p));
885 }
886 if (font_spec_slant(p)) {
887 tex_print_str(" slant ");
888 tex_print_int(font_spec_slant(p));
889 }
890 if (font_spec_weight(p)) {
891 tex_print_str(" weight ");
892 tex_print_int(font_spec_weight(p));
893 }
894}
895
896
897
898void tex_print_mathspec(int p)
899{
900 if (p) {
901 mathcodeval m = tex_get_math_spec(p);
902 tex_show_mathcode_value(m, node_subtype(p));
903 } else {
904 tex_print_str("[invalid mathspec]");
905 }
906}
907
908
943
944void tex_print_char_identifier(halfword c)
945{
946 if (c <= 0x10FFFF) {
947 char b[10];
948 if ( (c >= 0x00E000 && c <= 0x00F8FF) || (c >= 0x0F0000 && c <= 0x0FFFFF) ||
949 (c >= 0x100000 && c <= 0x10FFFF) || (c >= 0x00D800 && c <= 0x00DFFF) ) {
950 sprintf(b, "0x%06X", c);
951 tex_print_str(b);
952 } else {
953 sprintf(b, "U+%06X", c);
954 tex_print_str(b);
955 tex_print_char(' ');
956 tex_print_tex_str(c);
957 }
958 }
959}
960
961void tex_print_font_identifier(halfword f)
962{
963
964 if (tex_is_valid_font(f)) {
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995 tex_print_format("<%i: %s @ %p>", f, font_name(f), font_size(f));
996
997
998 } else {
999 tex_print_str("<*>");
1000 }
1001}
1002
1003void tex_print_font_specifier(halfword e)
1004{
1005 if (e && tex_is_valid_font(font_spec_identifier(e))) {
1006 tex_print_format("<%i: %i %i %i %i %i>", font_spec_identifier(e), font_spec_scale(e), font_spec_x_scale(e), font_spec_y_scale(e), font_spec_slant(e), font_spec_weight(e));
1007 } else {
1008 tex_print_str("<*>");
1009 }
1010}
1011
1012void tex_print_font(halfword f)
1013{
1014 if (! f) {
1015 tex_print_str("nullfont");
1016 } else if (tex_is_valid_font(f)) {
1017 tex_print_str(font_name(f));
1018
1019
1023 tex_print_format(" at %p", font_size(f));
1024
1025 } else {
1026 tex_print_str("nofont");
1027 }
1028}
1029
1030
1031
1032void tex_short_display(halfword p)
1033{
1034 tex_print_levels();
1035 if (p) {
1036 tex_print_short_node_contents(p);
1037 } else {
1038 tex_print_str("empty list");
1039 }
1040}
1041
1042
1043
1044void tex_print_token_list(const char *s, halfword p)
1045{
1046 tex_print_levels();
1047 tex_print_str("..");
1048 if (s) {
1049 tex_print_str(s);
1050 tex_print_char(' ');
1051 }
1052 tex_print_char('{');
1053 if ((p >= 0) && (p <= (int) lmt_token_memory_state.tokens_data.top)) {
1054 tex_show_token_list(p, 0, 0);
1055 } else {
1056 tex_print_str(error_string_clobbered(21));
1057 }
1058 tex_print_char('}');
1059}
1060
1061
1062
1063void tex_print_rule_dimension(scaled d)
1064{
1065 if (d == null_flag) {
1066 tex_print_char('*');
1067 } else {
1068 tex_print_dimension(d, pt_unit);
1069 }
1070}
1071
1072
1092
1093void tex_show_box(halfword p)
1094{
1095
1096 tex_show_node_list(p, show_box_depth_par, show_box_breadth_par);
1097 tex_print_ln();
1098}
1099
1100
1107
1108void tex_begin_diagnostic(void)
1109{
1110 lmt_print_state.saved_selector = lmt_print_state.selector;
1111 if ((tracing_online_par <= 0) && (lmt_print_state.selector == terminal_and_logfile_selector_code)) {
1112 lmt_print_state.selector = logfile_selector_code;
1113 if (lmt_error_state.history == spotless) {
1114 lmt_error_state.history = warning_issued;
1115 }
1116 }
1117 tex_print_levels();
1118}
1119
1120
1121
1122void tex_end_diagnostic(void)
1123{
1124 tex_print_nlp();
1125 lmt_print_state.selector = lmt_print_state.saved_selector;
1126}
1127
1128static void tex_print_padding(void)
1129{
1130 switch (lmt_print_state.selector) {
1131 case terminal_selector_code:
1132 if (! odd(lmt_print_state.terminal_offset)) {
1133 tex_print_char(' ');
1134 }
1135 break;
1136 case logfile_selector_code:
1137 case terminal_and_logfile_selector_code:
1138 if (! odd(lmt_print_state.logfile_offset)) {
1139 tex_print_char(' ');
1140 }
1141 break;
1142 case luabuffer_selector_code:
1143 break;
1144 }
1145}
1146
1147void tex_print_levels(void)
1148{
1149 int l0 = tracing_levels_par;
1150 tex_print_nlp();
1151 if (l0 > 0) {
1152 int l1 = (l0 & tracing_levels_group) == tracing_levels_group;
1153 int l2 = (l0 & tracing_levels_input) == tracing_levels_input;
1154 int l4 = (l0 & tracing_levels_catcodes) == tracing_levels_catcodes;
1155 if (l1) {
1156 tex_print_int(cur_level);
1157 tex_print_char(':');
1158 }
1159 if (l2) {
1160 tex_print_int(lmt_input_state.input_stack_data.ptr);
1161 tex_print_char(':');
1162 }
1163 if (l4) {
1164 tex_print_int(cat_code_table_par);
1165 tex_print_char(':');
1166 }
1167 if (l1 || l2 || l4) {
1168 tex_print_char(' ');
1169 }
1170 tex_print_padding();
1171 }
1172}
1173
1174
1201
1202const char *tex_print_format_args(const char *format, va_list args)
1203{
1204 while (1) {
1205 int chr = *format++;
1206 switch (chr) {
1207 case '\0':
1208 return va_arg(args, char *);
1209 case '%':
1210 {
1211 chr = *format++;
1212 switch (chr) {
1213 case '\0':
1214 return va_arg(args, char *);
1215 case 'c':
1216 tex_print_char(va_arg(args, int));
1217 break;
1218 case 'd':
1219 tex_print_str(tex_aux_subtype_str(va_arg(args, int)));
1220 break;
1221 case 'e':
1222 tex_print_str_esc(NULL);
1223 break;
1224 case 'i':
1225 tex_print_int(va_arg(args, int));
1226 break;
1227 case 'l':
1228 tex_print_levels();
1229 break;
1230 case 'n':
1231 tex_print_extended_subtype(null, (quarterword) va_arg(args, int));
1232 break;
1233 case 'm':
1234 tex_print_cs_checked(va_arg(args, int));
1235 break;
1236 case 's':
1237 tex_print_str(va_arg(args, char *));
1238 break;
1239 case 'p':
1240 tex_print_dimension(va_arg(args, scaled), pt_unit);
1241 break;
1242 case 'q':
1243 tex_print_char('\'');
1244 tex_print_str(va_arg(args, char *));
1245 tex_print_char('\'');
1246 break;
1247 case 'x':
1248 tex_print_qhex(va_arg(args, int));
1249 break;
1250
1255 case 'B':
1256 {
1257 scaled b = va_arg(args, halfword);
1258 if (b == awful_bad) {
1259 tex_print_char('*');
1260 } else {
1261 tex_print_int(b);
1262 }
1263 break;
1264 }
1265 case 'C':
1266 {
1267 int cmd = va_arg(args, int);
1268 int val = va_arg(args, int);
1269 tex_print_cmd_chr((singleword) cmd, val);
1270 break;
1271 }
1272 case 'D':
1273 {
1274 scaled s = va_arg(args, scaled);
1275 int u = va_arg(args, int);
1276 tex_print_dimension(s, u);
1277 break;
1278 }
1279 case 'E':
1280 tex_print_str_esc(va_arg(args, char *));
1281 break;
1282 case 'G':
1283 {
1284 halfword g = va_arg(args, int);
1285 tex_print_group(g);
1286 break;
1287 }
1288 case 'F':
1289 {
1290 halfword i = va_arg(args, int);
1291 tex_print_font_identifier(i);
1292 break;
1293 }
1294 case 'L':
1295 {
1296
1297 halfword line = va_arg(args, int);
1298 if (line) {
1299 tex_print_str(" entered on line ");
1300 tex_print_int(line);
1301 }
1302 break;
1303 }
1304 case 'N':
1305 {
1306 halfword node = va_arg(args, int);
1307 if (node) {
1308 tex_print_str(lmt_interface.node_data[node_type(node)].name);
1309 }
1310 break;
1311 }
1312 case 'M':
1313 {
1314 halfword mode = va_arg(args, int);
1315 tex_print_str(tex_string_mode(mode));
1316 break;
1317 }
1318 case 'P':
1319 {
1320 scaled total = va_arg(args, int);
1321 scaled stretch = va_arg(args, int);
1322 scaled fistretch = va_arg(args, int);
1323 scaled filstretch = va_arg(args, int);
1324 scaled fillstretch = va_arg(args, int);
1325 scaled filllstretch = va_arg(args, int);
1326 scaled shrink = va_arg(args, int);
1327 tex_print_dimension(total, pt_unit);
1328 if (stretch) {
1329 tex_print_str(" plus ");
1330 tex_print_dimension(stretch, pt_unit);
1331 } else if (fistretch) {
1332 tex_print_str(" plus ");
1333 tex_print_dimension(fistretch, no_unit);
1334 tex_print_str(" fi");
1335 } else if (filstretch) {
1336 tex_print_str(" plus ");
1337 tex_print_dimension(filstretch, no_unit);
1338 tex_print_str(" fil");
1339 } else if (fillstretch) {
1340 tex_print_str(" plus ");
1341 tex_print_dimension(fillstretch, no_unit);
1342 tex_print_str(" fill");
1343 } else if (filllstretch) {
1344 tex_print_str(" plus ");
1345 tex_print_dimension(fillstretch, no_unit);
1346 tex_print_str(" filll");
1347 }
1348 if (shrink) {
1349 tex_print_str(" minus ");
1350 tex_print_dimension(shrink, pt_unit);
1351 }
1352 break;
1353 }
1354 case 'Q':
1355 {
1356 scaled s = va_arg(args, scaled);
1357 int u = va_arg(args, int);
1358 tex_print_spec(s, u);
1359 break;
1360 }
1361 case 'R':
1362 {
1363 halfword d = va_arg(args, int);
1364 tex_print_rule_dimension(d);
1365 break;
1366 }
1367 case 'S':
1368 {
1369 halfword cs = va_arg(args, int);
1370 tex_print_cs(cs);
1371 break;
1372 }
1373 case 'T':
1374 {
1375 strnumber s = va_arg(args, int);
1376 tex_print_tex_str(s);
1377 break;
1378 }
1379 case 'U':
1380 {
1381 halfword c = va_arg(args, int);
1382 tex_print_uhex(c);
1383 break;
1384 }
1385 case 'X':
1386 {
1387 halfword x = va_arg(args, int);
1388 tex_print_xhex(x);
1389 break;
1390 }
1391 case '2':
1392 {
1393 halfword c = va_arg(args, int);
1394 switch (c) {
1395 case direction_l2r : tex_print_str("l2r"); break;
1396 case direction_r2l : tex_print_str("r2l"); break;
1397 default : tex_print_str("unset"); break;
1398 }
1399 break;
1400 }
1401 case '%':
1402 tex_print_char('%');
1403 break;
1404
1405
1406
1407
1408
1409
1410
1411
1412 default:
1413
1414 break;
1415 }
1416 }
1417 break;
1418 case '\n':
1419 case '\r':
1420 tex_print_nlp();
1421 break;
1422 default:
1423 tex_print_char(chr);
1424 break;
1425 }
1426 }
1427}
1428
1429void tex_print_format(const char *format, ...)
1430{
1431 va_list args;
1432 va_start(args, format);
1433 tex_print_format_args(format, args);
1434 va_end(args);
1435}
1436
1437
1445
1446void tex_print_group(int e)
1447{
1448 int line = tex_saved_line_at_level();
1449 tex_print_str(lmt_interface.group_code_values[cur_group].name);
1450 if (cur_group != bottom_level_group) {
1451 tex_print_str(" group");
1452 if (line) {
1453 tex_print_str(e ? " entered at line " : " at line ");
1454 tex_print_int(line);
1455 }
1456 }
1457}
1458
1459void tex_print_message(const char *s)
1460{
1461 tex_print_nlp();
1462 tex_print_char('(');
1463 tex_print_str(s);
1464 tex_print_char(')');
1465 tex_print_nlp();
1466}
1467 |