~ubuntu-branches/ubuntu/wily/luatex/wily

« back to all changes in this revision

Viewing changes to source/texk/web2c/luatexdir/tex/printing.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2010-04-29 00:47:19 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20100429004719-o42etkqe90n97b9e
Tags: 0.60.1-1
* new upstream release, adapt build-script patch
* disable patch: upstream-epstopdf_cc_no_xpdf_patching, included upstream
* disable patch: libpoppler-0.12, not needed anymore

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* printing.c
2
 
   
3
 
   Copyright 2009 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
 
 
21
 
#include <ptexlib.h>
22
 
 
23
 
static const char _svn_version[] =
24
 
    "$Id: printing.c 3261 2009-12-18 11:38:21Z taco $"
25
 
    "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.50.0/source/texk/web2c/luatexdir/tex/printing.c $";
26
 
 
27
 
#define font_id_text(A) cs_text(font_id_base+(A))
28
 
 
29
 
#define wlog(A)      fputc(A,log_file)
30
 
#define wterm(A)     fputc(A,term_out)
31
 
 
32
 
extern char *ptexbanner;
33
 
 
34
 
/*
35
 
Messages that are sent to a user's terminal and to the transcript-log file
36
 
are produced by several `|print|' procedures. These procedures will
37
 
direct their output to a variety of places, based on the setting of
38
 
the global variable |selector|, which has the following possible
39
 
values:
40
 
 
41
 
\yskip
42
 
\hang |term_and_log|, the normal setting, prints on the terminal and on the
43
 
  transcript file.
44
 
 
45
 
\hang |log_only|, prints only on the transcript file.
46
 
 
47
 
\hang |term_only|, prints only on the terminal.
48
 
 
49
 
\hang |no_print|, doesn't print at all. This is used only in rare cases
50
 
  before the transcript file is open.
51
 
 
52
 
\hang |pseudo|, puts output into a cyclic buffer that is used
53
 
  by the |show_context| routine; when we get to that routine we shall discuss
54
 
  the reasoning behind this curious mode.
55
 
 
56
 
\hang |new_string|, appends the output to the current string in the
57
 
  string pool.
58
 
 
59
 
\hang 0 to 15, prints on one of the sixteen files for \.{\\write} output.
60
 
 
61
 
\yskip
62
 
\noindent The symbolic names `|term_and_log|', etc., have been assigned
63
 
numeric codes that satisfy the convenient relations |no_print+1=term_only|,
64
 
|no_print+2=log_only|, |term_only+2=log_only+1=term_and_log|.
65
 
 
66
 
Three additional global variables, |tally| and |term_offset| and
67
 
|file_offset|, record the number of characters that have been printed
68
 
since they were most recently cleared to zero. We use |tally| to record
69
 
the length of (possibly very long) stretches of printing; |term_offset|
70
 
and |file_offset|, on the other hand, keep track of how many characters
71
 
have appeared so far on the current line that has been output to the
72
 
terminal or to the transcript file, respectively.
73
 
*/
74
 
 
75
 
alpha_file log_file;            /* transcript of \TeX\ session */
76
 
int selector = term_only;       /* where to print a message */
77
 
int dig[23];                    /* digits in a number being output */
78
 
int tally = 0;                  /* the number of characters recently printed */
79
 
int term_offset = 0;            /* the number of characters on the current terminal line */
80
 
int file_offset = 0;            /* the number of characters on the current file line */
81
 
packed_ASCII_code trick_buf[(ssup_error_line + 1)];     /* circular buffer for pseudoprinting */
82
 
int trick_count;                /* threshold for pseudoprinting, explained later */
83
 
int first_count;                /* another variable for pseudoprinting */
84
 
boolean inhibit_par_tokens = false;     /*  for minor adjustments to |show_token_list|  */
85
 
 
86
 
/* To end a line of text output, we call |print_ln| */
87
 
 
88
 
void print_ln(void)
89
 
{                               /* prints an end-of-line */
90
 
    switch (selector) {
91
 
    case term_and_log:
92
 
        wterm_cr();
93
 
        wlog_cr();
94
 
        term_offset = 0;
95
 
        file_offset = 0;
96
 
        break;
97
 
    case log_only:
98
 
        wlog_cr();
99
 
        file_offset = 0;
100
 
        break;
101
 
    case term_only:
102
 
        wterm_cr();
103
 
        term_offset = 0;
104
 
        break;
105
 
    case no_print:
106
 
    case pseudo:
107
 
    case new_string:
108
 
        break;
109
 
    default:
110
 
        fprintf(write_file[selector], "\n");
111
 
        break;
112
 
    }
113
 
}                               /* |tally| is not affected */
114
 
 
115
 
/*
116
 
  The |print_char| procedure sends one byte to the desired destination.
117
 
  All printing comes through |print_ln| or |print_char|.
118
 
*/
119
 
 
120
 
#define wterm_char(A) do {                              \
121
 
    if ((A>=0x20)||(A==0x0A)||(A==0x0D)||(A==0x09)) {   \
122
 
      wterm(A);                                 \
123
 
    } else {                                            \
124
 
      if (term_offset+2>=max_print_line) {              \
125
 
        wterm_cr(); term_offset=0;                      \
126
 
      }                                                 \
127
 
      incr(term_offset); wterm('^');                    \
128
 
      incr(term_offset); wterm('^');                    \
129
 
      wterm(A+64);                                      \
130
 
    }                                                   \
131
 
  } while (0)
132
 
 
133
 
#define needs_wrapping(A,B)                             \
134
 
  (((A>=0xC0)&&(A<=0xDF)&&(B+2>=max_print_line))||      \
135
 
   ((A>=0xE0)&&(A<=0xEF)&&(B+3>=max_print_line))||      \
136
 
   ((A>=0xF0)&&(B+4>=max_print_line)))
137
 
 
138
 
#define fix_term_offset(A)       do {                   \
139
 
    if (needs_wrapping(A,term_offset)){                 \
140
 
      wterm_cr(); term_offset=0;                        \
141
 
    }                                                   \
142
 
  } while (0)
143
 
 
144
 
#define fix_log_offset(A)        do {                   \
145
 
    if (needs_wrapping(A,file_offset)){                 \
146
 
      wlog_cr(); file_offset=0;                         \
147
 
    }                                                   \
148
 
  } while (0)
149
 
 
150
 
void print_char(int s)
151
 
{                               /* prints a single byte */
152
 
    assert(s >= 0 && s < 256);
153
 
    if (s == int_par(new_line_char_code)) {
154
 
        if (selector < pseudo) {
155
 
            print_ln();
156
 
            return;
157
 
        }
158
 
    }
159
 
    switch (selector) {
160
 
    case term_and_log:
161
 
        fix_term_offset(s);
162
 
        fix_log_offset(s);
163
 
        wterm_char(s);
164
 
        wlog(s);
165
 
        incr(term_offset);
166
 
        incr(file_offset);
167
 
        if (term_offset == max_print_line) {
168
 
            wterm_cr();
169
 
            term_offset = 0;
170
 
        }
171
 
        if (file_offset == max_print_line) {
172
 
            wlog_cr();
173
 
            file_offset = 0;
174
 
        }
175
 
        break;
176
 
    case log_only:
177
 
        fix_log_offset(s);
178
 
        wlog(s);
179
 
        incr(file_offset);
180
 
        if (file_offset == max_print_line) {
181
 
            wlog_cr();
182
 
            file_offset = 0;
183
 
        }
184
 
        break;
185
 
    case term_only:
186
 
        fix_term_offset(s);
187
 
        wterm_char(s);
188
 
        incr(term_offset);
189
 
        if (term_offset == max_print_line) {
190
 
            wterm_cr();
191
 
            term_offset = 0;
192
 
        }
193
 
        break;
194
 
    case no_print:
195
 
        break;
196
 
    case pseudo:
197
 
        if (tally < trick_count)
198
 
            trick_buf[tally % error_line] = s;
199
 
        break;
200
 
    case new_string:
201
 
        append_char(s);
202
 
        break;                  /* we drop characters if the string space is full */
203
 
    default:
204
 
        fprintf(write_file[selector], "%c", s);
205
 
    }
206
 
    incr(tally);
207
 
}
208
 
 
209
 
/*
210
 
An entire string is output by calling |print|. Note that if we are outputting
211
 
the single standard ASCII character \.c, we could call |print("c")|, since
212
 
|"c"=99| is the number of a single-character string, as explained above. But
213
 
|print_char("c")| is quicker, so \TeX\ goes directly to the |print_char|
214
 
routine when it knows that this is safe. (The present implementation
215
 
assumes that it is always safe to print a visible ASCII character.)
216
 
@^system dependencies@>
217
 
 
218
 
The first 256 entries above the 17th unicode plane are used for a
219
 
special trick: when \TeX\ has to print items in that range, it will
220
 
instead print the character that results from substracting 0x110000
221
 
from that value. This allows byte-oriented output to things like
222
 
\.{\\specials} and \.{\\pdfliterals}. Todo: Perhaps it would be useful
223
 
to do the same substraction while typesetting.
224
 
*/
225
 
 
226
 
void print(int s)
227
 
{                               /* prints string |s| */
228
 
    unsigned char *j, *l;       /* current character code position */
229
 
 
230
 
    if (s >= str_ptr) {
231
 
        /* this can't happen */
232
 
        print_char('?');
233
 
        print_char('?');
234
 
        print_char('?');
235
 
        return;
236
 
    } else if (s < STRING_OFFSET) {
237
 
        if (s < 0) {
238
 
            /* can't happen */
239
 
            print_char('?');
240
 
            print_char('?');
241
 
            print_char('?');
242
 
        } else {
243
 
            /* TH not sure about this, disabled for now! */
244
 
            if ((false) && (selector > pseudo)) {
245
 
                print_char(s);
246
 
                return;         /* internal strings are not expanded */
247
 
            }
248
 
            if (s == int_par(new_line_char_code)) {
249
 
                if (selector < pseudo) {
250
 
                    print_ln();
251
 
                    return;
252
 
                }
253
 
            }
254
 
            if (s <= 0x7F) {
255
 
                print_char(s);
256
 
            } else if (s <= 0x7FF) {
257
 
                print_char(0xC0 + (s / 0x40));
258
 
                print_char(0x80 + (s % 0x40));
259
 
            } else if (s <= 0xFFFF) {
260
 
                print_char(0xE0 + (s / 0x1000));
261
 
                print_char(0x80 + ((s % 0x1000) / 0x40));
262
 
                print_char(0x80 + ((s % 0x1000) % 0x40));
263
 
            } else if (s >= 0x110000) {
264
 
                int c = s - 0x110000;
265
 
                if (c >= 256) {
266
 
                    pdf_warning("print", "bad raw byte to print (c=",
267
 
                                true, false);
268
 
                    print_int(c);
269
 
                    tprint("), skipped.");
270
 
                    print_ln();
271
 
                } else {
272
 
                    print_char(c);
273
 
                }
274
 
            } else {
275
 
                print_char(0xF0 + (s / 0x40000));
276
 
                print_char(0x80 + ((s % 0x40000) / 0x1000));
277
 
                print_char(0x80 + (((s % 0x40000) % 0x1000) / 0x40));
278
 
                print_char(0x80 + (((s % 0x40000) % 0x1000) % 0x40));
279
 
            }
280
 
        }
281
 
        return;
282
 
    }
283
 
    if (selector == new_string) {
284
 
        append_string(str_string(s), str_length(s));
285
 
        return;
286
 
    }
287
 
    j = str_string(s);
288
 
    l = j + str_length(s);
289
 
    while (j < l) {
290
 
        /* 0x110000 in utf=8: 0xF4 0x90 0x80 0x80  */
291
 
        /* I don't bother checking the last two bytes explicitly */
292
 
        if ((j < l - 4) && (*j == 0xF4) && (*(j + 1) == 0x90)) {
293
 
            int c = (*(j + 2) - 128) * 64 + (*(j + 3) - 128);
294
 
            assert(c >= 0 && c < 256);
295
 
            print_char(c);
296
 
            j = j + 4;
297
 
        } else {
298
 
            print_char(*j);
299
 
            incr(j);
300
 
        }
301
 
    }
302
 
}
303
 
 
304
 
/*
305
 
The procedure |print_nl| is like |print|, but it makes sure that the
306
 
string appears at the beginning of a new line. 
307
 
*/
308
 
 
309
 
void print_nlp(void)
310
 
{                               /* move to beginning of a line */
311
 
    if (((term_offset > 0) && (odd(selector))) ||
312
 
        ((file_offset > 0) && (selector >= log_only)))
313
 
        print_ln();
314
 
}
315
 
 
316
 
void print_nl(str_number s)
317
 
{                               /* prints string |s| at beginning of line */
318
 
    print_nlp();
319
 
    print(s);
320
 
}
321
 
 
322
 
/* char * versions */
323
 
 
324
 
void tprint(char *s)
325
 
{
326
 
    unsigned char *ss = (unsigned char *) s;
327
 
    if (selector == new_string) {
328
 
        append_string(ss, strlen(s));
329
 
        return;
330
 
    }
331
 
    while (*ss)
332
 
        print_char(*ss++);
333
 
}
334
 
 
335
 
void tprint_nl(char *s)
336
 
{
337
 
    print_nlp();
338
 
    tprint(s);
339
 
}
340
 
 
341
 
/* |slow_print| is the same as |print| nowadays, but the name is kept for now. */
342
 
 
343
 
void slow_print(int s)
344
 
{                               /* prints string |s| */
345
 
    print(s);
346
 
}
347
 
 
348
 
/*
349
 
Here is the very first thing that \TeX\ prints: a headline that identifies
350
 
the version number and format package. The |term_offset| variable is temporarily
351
 
incorrect, but the discrepancy is not serious since we assume that the banner
352
 
and format identifier together will occupy at most |max_print_line|
353
 
character positions.
354
 
*/
355
 
 
356
 
void print_banner(char *v, int e)
357
 
{
358
 
    boolean res;
359
 
    int callback_id;
360
 
    callback_id = callback_defined(start_run_callback);
361
 
    if (callback_id == 0) {
362
 
        fprintf(term_out, "This is LuaTeX, Version %s-%d", v, e);
363
 
        if (format_ident > 0)
364
 
            slow_print(format_ident);
365
 
        print_ln();
366
 
        if (shellenabledp) {
367
 
            wterm(' ');
368
 
            if (restrictedshell)
369
 
                fprintf(term_out, "restricted ");
370
 
            fprintf(term_out, "\\write18 enabled.\n");
371
 
        }
372
 
    } else if (callback_id > 0) {
373
 
        res = run_callback(callback_id, "->");
374
 
    }
375
 
}
376
 
 
377
 
void log_banner(char *v, int e)
378
 
{
379
 
    char *months[] = { "   ",
380
 
        "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
381
 
        "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
382
 
    };
383
 
    unsigned month = (unsigned) int_par(month_code);
384
 
    if (month > 12)
385
 
        month = 0;
386
 
    fprintf(log_file, "This is LuaTeX, Version %s-%d", v, e);
387
 
    slow_print(format_ident);
388
 
    print_char(' ');
389
 
    print_char(' ');
390
 
    print_int(int_par(day_code));
391
 
    print_char(' ');
392
 
    fprintf(log_file, months[month]);
393
 
    print_char(' ');
394
 
    print_int(int_par(year_code));
395
 
    print_char(' ');
396
 
    print_two(int_par(time_code) / 60);
397
 
    print_char(':');
398
 
    print_two(int_par(time_code) % 60);
399
 
    if (shellenabledp) {
400
 
        wlog_cr();
401
 
        wlog(' ');
402
 
        if (restrictedshell)
403
 
            fprintf(log_file, "restricted ");
404
 
        fprintf(log_file, "\\write18 enabled.");
405
 
    }
406
 
    if (filelineerrorstylep) {
407
 
        wlog_cr();
408
 
        fprintf(log_file, " file:line:error style messages enabled.");
409
 
    }
410
 
    if (parsefirstlinep) {
411
 
        wlog_cr();
412
 
        fprintf(log_file, " %%&-line parsing enabled.");
413
 
    }
414
 
}
415
 
 
416
 
void print_version_banner(void)
417
 
{
418
 
    fprintf(term_out, ptexbanner);      /* todo: get the extra info in here */
419
 
    /* write_svnversion(luatex_svnversion); */
420
 
}
421
 
 
422
 
/*
423
 
The procedure |print_esc| prints a string that is preceded by
424
 
the user's escape character (which is usually a backslash).
425
 
*/
426
 
 
427
 
void print_esc(str_number s)
428
 
{                               /* prints escape character, then |s| */
429
 
    int c;                      /* the escape character code */
430
 
    /* Set variable |c| to the current escape character */
431
 
    c = int_par(escape_char_code);
432
 
    if (c >= 0 && c < STRING_OFFSET)
433
 
        print(c);
434
 
    print(s);
435
 
}
436
 
 
437
 
void tprint_esc(char *s)
438
 
{                               /* prints escape character, then |s| */
439
 
    int c;                      /* the escape character code */
440
 
    /* Set variable |c| to the current escape character */
441
 
    c = int_par(escape_char_code);
442
 
    if (c >= 0 && c < STRING_OFFSET)
443
 
        print(c);
444
 
    tprint(s);
445
 
}
446
 
 
447
 
/* An array of digits in the range |0..15| is printed by |print_the_digs|.*/
448
 
 
449
 
void print_the_digs(eight_bits k)
450
 
{
451
 
    /* prints |dig[k-1]|$\,\ldots\,$|dig[0]| */
452
 
    while (k-- > 0) {
453
 
        if (dig[k] < 10)
454
 
            print_char('0' + dig[k]);
455
 
        else
456
 
            print_char('A' - 10 + dig[k]);
457
 
    }
458
 
}
459
 
 
460
 
/*
461
 
The following procedure, which prints out the decimal representation of a
462
 
given integer |n|, has been written carefully so that it works properly
463
 
if |n=0| or if |(-n)| would cause overflow. It does not apply |mod| or |div|
464
 
to negative arguments, since such operations are not implemented consistently
465
 
by all \PASCAL\ compilers.
466
 
*/
467
 
 
468
 
void print_int(longinteger n)
469
 
{                               /* prints an integer in decimal form */
470
 
    int k;                      /* index to current digit; we assume that $|n|<10^{23}$ */
471
 
    longinteger m;              /* used to negate |n| in possibly dangerous cases */
472
 
    k = 0;
473
 
    if (n < 0) {
474
 
        print_char('-');
475
 
        if (n > -100000000) {
476
 
            n = -n;
477
 
        } else {
478
 
            m = -1 - n;
479
 
            n = m / 10;
480
 
            m = (m % 10) + 1;
481
 
            k = 1;
482
 
            if (m < 10)
483
 
                dig[0] = m;
484
 
            else {
485
 
                dig[0] = 0;
486
 
                incr(n);
487
 
            }
488
 
        }
489
 
    }
490
 
    do {
491
 
        dig[k] = n % 10;
492
 
        n = n / 10;
493
 
        incr(k);
494
 
    } while (n != 0);
495
 
    print_the_digs(k);
496
 
}
497
 
 
498
 
/*
499
 
Here is a trivial procedure to print two digits; it is usually called with
500
 
a parameter in the range |0<=n<=99|.
501
 
*/
502
 
 
503
 
void print_two(int n)
504
 
{                               /* prints two least significant digits */
505
 
    n = abs(n) % 100;
506
 
    print_char('0' + (n / 10));
507
 
    print_char('0' + (n % 10));
508
 
}
509
 
 
510
 
/*
511
 
Hexadecimal printing of nonnegative integers is accomplished by |print_hex|.
512
 
*/
513
 
 
514
 
void print_hex(int n)
515
 
{                               /* prints a positive integer in hexadecimal form */
516
 
    int k;                      /* index to current digit; we assume that $0\L n<16^{22}$ */
517
 
    k = 0;
518
 
    print_char('"');
519
 
    do {
520
 
        dig[k] = n % 16;
521
 
        n = n / 16;
522
 
        incr(k);
523
 
    } while (n != 0);
524
 
    print_the_digs(k);
525
 
}
526
 
 
527
 
/*
528
 
Roman numerals are produced by the |print_roman_int| routine.  Readers
529
 
who like puzzles might enjoy trying to figure out how this tricky code
530
 
works; therefore no explanation will be given. Notice that 1990 yields
531
 
\.{mcmxc}, not \.{mxm}.
532
 
*/
533
 
 
534
 
void print_roman_int(int n)
535
 
{
536
 
    char *j, *k;                /* mysterious indices */
537
 
    nonnegative_integer u, v;   /* mysterious numbers */
538
 
    char mystery[] = "m2d5c2l5x2v5i";
539
 
    j = (char *) mystery;
540
 
    v = 1000;
541
 
    while (1) {
542
 
        while (n >= (int) v) {
543
 
            print_char(*j);
544
 
            n = n - v;
545
 
        }
546
 
        if (n <= 0)
547
 
            return;             /* nonpositive input produces no output */
548
 
        k = j + 2;
549
 
        u = v / (*(k - 1) - '0');
550
 
        if (*(k - 1) == '2') {
551
 
            k = k + 2;
552
 
            u = u / (*(k - 1) - '0');
553
 
        }
554
 
        if (n + u >= v) {
555
 
            print_char(*k);
556
 
            n = n + u;
557
 
        } else {
558
 
            j = j + 2;
559
 
            v = v / (*(j - 1) - '0');
560
 
        }
561
 
    }
562
 
}
563
 
 
564
 
/*
565
 
The |print| subroutine will not print a string that is still being
566
 
created. The following procedure will.
567
 
*/
568
 
 
569
 
void print_current_string(void)
570
 
{                               /* prints a yet-unmade string */
571
 
    unsigned j = 0;             /* points to current character code */
572
 
    while (j < cur_length)
573
 
        print_char(cur_string[j++]);
574
 
}
575
 
 
576
 
/*
577
 
The procedure |print_cs| prints the name of a control sequence, given
578
 
a pointer to its address in |eqtb|. A space is printed after the name
579
 
unless it is a single nonletter or an active character. This procedure
580
 
might be invoked with invalid data, so it is ``extra robust.'' The
581
 
individual characters must be printed one at a time using |print|, since
582
 
they may be unprintable.
583
 
*/
584
 
 
585
 
void print_cs(int p)
586
 
{                               /* prints a purported control sequence */
587
 
    str_number t = cs_text(p);
588
 
    if (p < hash_base) {        /* nullcs */
589
 
        if (p == null_cs) {
590
 
            tprint_esc("csname");
591
 
            tprint_esc("endcsname");
592
 
        } else {
593
 
            tprint_esc("IMPOSSIBLE.");
594
 
        }
595
 
    } else if ((p >= undefined_control_sequence) &&
596
 
               ((p <= eqtb_size) || p > eqtb_size + hash_extra)) {
597
 
        tprint_esc("IMPOSSIBLE.");
598
 
    } else if (t >= str_ptr) {
599
 
        tprint_esc("NONEXISTENT.");
600
 
    } else {
601
 
        if (is_active_cs(t)) {
602
 
            print(active_cs_value(t));
603
 
        } else {
604
 
            print_esc(t);
605
 
            if (single_letter(t)) {
606
 
                if (get_cat_code(int_par(cat_code_table_code),
607
 
                                 pool_to_unichar(str_string(t))) == letter_cmd)
608
 
                    print_char(' ');
609
 
            } else {
610
 
                print_char(' ');
611
 
            }
612
 
        }
613
 
    }
614
 
}
615
 
 
616
 
/*
617
 
Here is a similar procedure; it avoids the error checks, and it never
618
 
prints a space after the control sequence.
619
 
*/
620
 
 
621
 
void sprint_cs(pointer p)
622
 
{                               /* prints a control sequence */
623
 
    str_number t;
624
 
    if (p == null_cs) {
625
 
        tprint_esc("csname");
626
 
        tprint_esc("endcsname");
627
 
    } else {
628
 
        t = cs_text(p);
629
 
        if (is_active_cs(t))
630
 
            print(active_cs_value(t));
631
 
        else
632
 
            print_esc(t);
633
 
    }
634
 
}
635
 
 
636
 
 
637
 
/* This procedure is never called when |interaction<scroll_mode|. */
638
 
 
639
 
void prompt_input(char *s)
640
 
{
641
 
    wake_up_terminal();
642
 
    tprint(s);
643
 
    term_input();
644
 
}
645
 
 
646
 
/*
647
 
Then there is a subroutine that prints glue stretch and shrink, possibly
648
 
followed by the name of finite units:
649
 
*/
650
 
 
651
 
void print_glue(scaled d, int order, char *s)
652
 
{                               /* prints a glue component */
653
 
    print_scaled(d);
654
 
    if ((order < normal) || (order > filll)) {
655
 
        tprint("foul");
656
 
    } else if (order > normal) {
657
 
        tprint("fi");
658
 
        while (order > sfi) {
659
 
            print_char('l');
660
 
            decr(order);
661
 
        }
662
 
    } else if (s != NULL) {
663
 
        tprint(s);
664
 
    }
665
 
}
666
 
 
667
 
/*  The next subroutine prints a whole glue specification */
668
 
 
669
 
void print_spec(int p, char *s)
670
 
{                               /* prints a glue specification */
671
 
    if (p < 0) {
672
 
        print_char('*');
673
 
    } else {
674
 
        print_scaled(width(p));
675
 
        if (s != NULL)
676
 
            tprint(s);
677
 
        if (stretch(p) != 0) {
678
 
            tprint(" plus ");
679
 
            print_glue(stretch(p), stretch_order(p), s);
680
 
        }
681
 
        if (shrink(p) != 0) {
682
 
            tprint(" minus ");
683
 
            print_glue(shrink(p), shrink_order(p), s);
684
 
        }
685
 
    }
686
 
}
687
 
 
688
 
/*
689
 
We can reinforce our knowledge of the data structures just introduced
690
 
by considering two procedures that display a list in symbolic form.
691
 
The first of these, called |short_display|, is used in ``overfull box''
692
 
messages to give the top-level description of a list. The other one,
693
 
called |show_node_list|, prints a detailed description of exactly what
694
 
is in the data structure.
695
 
 
696
 
The philosophy of |short_display| is to ignore the fine points about exactly
697
 
what is inside boxes, except that ligatures and discretionary breaks are
698
 
expanded. As a result, |short_display| is a recursive procedure, but the
699
 
recursion is never more than one level deep.
700
 
@^recursion@>
701
 
 
702
 
A global variable |font_in_short_display| keeps track of the font code that
703
 
is assumed to be present when |short_display| begins; deviations from this
704
 
font will be printed.
705
 
*/
706
 
 
707
 
int font_in_short_display;      /* an internal font number */
708
 
 
709
 
/*
710
 
Boxes, rules, inserts, whatsits, marks, and things in general that are
711
 
sort of ``complicated'' are indicated only by printing `\.{[]}'.
712
 
*/
713
 
 
714
 
void print_font_identifier(internal_font_number f)
715
 
{
716
 
    str_number fonttext;
717
 
    if (pdf_font_blink(f) == null_font)
718
 
        fonttext = font_id_text(f);
719
 
    else
720
 
        fonttext = font_id_text(pdf_font_blink(f));
721
 
    if (fonttext > 0) {
722
 
        print_esc(fonttext);
723
 
    } else {
724
 
        tprint_esc("FONT");
725
 
        if (pdf_font_blink(f) == null_font)
726
 
            print_int(f);
727
 
        else
728
 
            print_int(pdf_font_blink(f));
729
 
    }
730
 
    if (int_par(pdf_tracing_fonts_code) > 0) {
731
 
        tprint(" (");
732
 
        print_font_name(f);
733
 
        if (font_size(f) != font_dsize(f)) {
734
 
            tprint("@@");
735
 
            print_scaled(font_size(f));
736
 
            tprint("pt");
737
 
        }
738
 
        print_char(')');
739
 
    } else if (pdf_font_expand_ratio(f) != 0) {
740
 
        tprint(" (");
741
 
        if (pdf_font_expand_ratio(f) > 0)
742
 
            print_char('+');
743
 
        print_int(pdf_font_expand_ratio(f));
744
 
        print_char(')');
745
 
    }
746
 
}
747
 
 
748
 
void short_display(int p)
749
 
{                               /* prints highlights of list |p| */
750
 
    while (p != null) {
751
 
        if (is_char_node(p)) {
752
 
            if (lig_ptr(p) != null) {
753
 
                short_display(lig_ptr(p));
754
 
            } else {
755
 
                if (font(p) != font_in_short_display) {
756
 
                    if (!is_valid_font(font(p)))
757
 
                        print_char('*');
758
 
                    else
759
 
                        print_font_identifier(font(p));
760
 
                    print_char(' ');
761
 
                    font_in_short_display = font(p);
762
 
                }
763
 
                print(character(p));
764
 
            }
765
 
        } else {
766
 
            /* Print a short indication of the contents of node |p| */
767
 
            print_short_node_contents(p);
768
 
        }
769
 
        p = vlink(p);
770
 
    }
771
 
}
772
 
 
773
 
/*
774
 
The |show_node_list| routine requires some auxiliary subroutines: one to
775
 
print a font-and-character combination, one to print a token list without
776
 
its reference count, and one to print a rule dimension.
777
 
*/
778
 
 
779
 
void print_font_and_char(int p)
780
 
{                               /* prints |char_node| data */
781
 
    if (!is_valid_font(font(p)))
782
 
        print_char('*');
783
 
    else
784
 
        print_font_identifier(font(p));
785
 
    print_char(' ');
786
 
    print(character(p));
787
 
}
788
 
 
789
 
void print_mark(int p)
790
 
{                               /* prints token list data in braces */
791
 
    print_char('{');
792
 
    if ((p < fix_mem_min) || (p > fix_mem_end))
793
 
        tprint_esc("CLOBBERED.");
794
 
    else
795
 
        show_token_list(token_link(p), null, max_print_line - 10);
796
 
    print_char('}');
797
 
}
798
 
 
799
 
void print_rule_dimen(scaled d)
800
 
{                               /* prints dimension in rule node */
801
 
    if (is_running(d))
802
 
        print_char('*');
803
 
    else
804
 
        print_scaled(d);
805
 
}
806
 
 
807
 
/*
808
 
Since boxes can be inside of boxes, |show_node_list| is inherently recursive,
809
 
@^recursion@>
810
 
up to a given maximum number of levels.  The history of nesting is indicated
811
 
by the current string, which will be printed at the beginning of each line;
812
 
the length of this string, namely |cur_length|, is the depth of nesting.
813
 
 
814
 
@ A global variable called |depth_threshold| is used to record the maximum
815
 
depth of nesting for which |show_node_list| will show information.  If we
816
 
have |depth_threshold=0|, for example, only the top level information will
817
 
be given and no sublists will be traversed. Another global variable, called
818
 
|breadth_max|, tells the maximum number of items to show at each level;
819
 
|breadth_max| had better be positive, or you won't see anything.
820
 
*/
821
 
 
822
 
int depth_threshold;            /* maximum nesting depth in box displays */
823
 
int breadth_max;                /* maximum number of items shown at the same list level */
824
 
 
825
 
 
826
 
/* The recursive machinery is started by calling |show_box|. */
827
 
 
828
 
void show_box(halfword p)
829
 
{
830
 
    /* Assign the values |depth_threshold:=show_box_depth| and
831
 
       |breadth_max:=show_box_breadth| */
832
 
    depth_threshold = int_par(show_box_depth_code);
833
 
    breadth_max = int_par(show_box_breadth_code);
834
 
 
835
 
    if (breadth_max <= 0)
836
 
        breadth_max = 5;
837
 
    show_node_list(p);          /* the show starts at |p| */
838
 
    print_ln();
839
 
}
840
 
 
841
 
 
842
 
/* Helper for debugging purposes */
843
 
 
844
 
void short_display_n(int p, int m)
845
 
{                               /* prints highlights of list |p| */
846
 
    int i = 0;
847
 
    font_in_short_display = null_font;
848
 
    if (p == null)
849
 
        return;
850
 
    while (p != null) {
851
 
        if (is_char_node(p)) {
852
 
            if (p <= max_halfword) {
853
 
                if (font(p) != font_in_short_display) {
854
 
                    if (!is_valid_font(font(p)))
855
 
                        print_char('*');
856
 
                    else
857
 
                        print_font_identifier(font(p));
858
 
                    print_char(' ');
859
 
                    font_in_short_display = font(p);
860
 
                }
861
 
                print(character(p));
862
 
            }
863
 
        } else {
864
 
            if ((type(p) == glue_node) ||
865
 
                (type(p) == disc_node) ||
866
 
                (type(p) == penalty_node) ||
867
 
                ((type(p) == kern_node) && (subtype(p) == explicit)))
868
 
                incr(i);
869
 
            if (i >= m)
870
 
                return;
871
 
            if (type(p) == disc_node) {
872
 
                print_char('|');
873
 
                short_display(vlink(pre_break(p)));
874
 
                print_char('|');
875
 
                short_display(vlink(post_break(p)));
876
 
                print_char('|');
877
 
            } else {
878
 
                /* Print a short indication of the contents of node |p| */
879
 
                print_short_node_contents(p);
880
 
            }
881
 
        }
882
 
        p = vlink(p);
883
 
        if (p == null)
884
 
            return;
885
 
    }
886
 
    update_terminal();
887
 
}
888
 
 
889
 
/*
890
 
When debugging a macro package, it can be useful to see the exact
891
 
control sequence names in the format file.  For example, if ten new
892
 
csnames appear, it's nice to know what they are, to help pinpoint where
893
 
they came from.  (This isn't a truly ``basic'' printing procedure, but
894
 
that's a convenient module in which to put it.)
895
 
*/
896
 
 
897
 
void print_csnames(int hstart, int hfinish)
898
 
{
899
 
    int h;
900
 
    unsigned char *c, *l;
901
 
    fprintf(stderr, "fmtdebug:csnames from %d to %d:", (int) hstart,
902
 
            (int) hfinish);
903
 
    for (h = hstart; h <= hfinish; h++) {
904
 
        if (cs_text(h) > 0) {   /* if have anything at this position */
905
 
            c = str_string(cs_text(h));
906
 
            l = c + str_length(cs_text(h));
907
 
            while (c < l) {
908
 
                fputc(*c++, stderr);    /* print the characters */
909
 
            }
910
 
            fprintf(stderr, "|");
911
 
        }
912
 
    }
913
 
}
914
 
 
915
 
/*
916
 
A helper for printing file:line:error style messages.  Look for a
917
 
filename in |full_source_filename_stack|, and if we fail to find
918
 
one fall back on the non-file:line:error style.
919
 
*/
920
 
 
921
 
void print_file_line(void)
922
 
{
923
 
    int level;
924
 
    level = in_open;
925
 
    while ((level > 0) && (full_source_filename_stack[level] == 0))
926
 
        decr(level);
927
 
    if (level == 0) {
928
 
        tprint_nl("! ");
929
 
    } else {
930
 
        tprint_nl("");
931
 
        tprint(full_source_filename_stack[level]);
932
 
        print_char(':');
933
 
        if (level == in_open)
934
 
            print_int(line);
935
 
        else
936
 
            print_int(line_stack[iindex + 1 - (in_open - level)]);
937
 
        tprint(": ");
938
 
    }
939
 
}
940
 
 
941
 
/*
942
 
 \TeX\ is occasionally supposed to print diagnostic information that
943
 
goes only into the transcript file, unless |tracing_online| is positive.
944
 
Here are two routines that adjust the destination of print commands:
945
 
*/
946
 
 
947
 
void begin_diagnostic(void)
948
 
{                               /* prepare to do some tracing */
949
 
    global_old_setting = selector;
950
 
    if ((int_par(tracing_online_code) <= 0) && (selector == term_and_log)) {
951
 
        decr(selector);
952
 
        if (history == spotless)
953
 
            history = warning_issued;
954
 
    }
955
 
}
956
 
 
957
 
 
958
 
void end_diagnostic(boolean blank_line)
959
 
{                               /* restore proper conditions after tracing */
960
 
    tprint_nl("");
961
 
    if (blank_line)
962
 
        print_ln();
963
 
    selector = global_old_setting;
964
 
}
965
 
 
966
 
/*
967
 
Of course we had better declare another global variable, if the previous
968
 
routines are going to work.
969
 
*/
970
 
 
971
 
int global_old_setting;