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

« back to all changes in this revision

Viewing changes to source/texk/web2c/luatexdir/tex/texfileio.w

  • 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
% texfileio.w
 
2
 
3
% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
 
4
 
 
5
% This file is part of LuaTeX.
 
6
 
 
7
% LuaTeX is free software; you can redistribute it and/or modify it under
 
8
% the terms of the GNU General Public License as published by the Free
 
9
% Software Foundation; either version 2 of the License, or (at your
 
10
% option) any later version.
 
11
 
 
12
% LuaTeX is distributed in the hope that it will be useful, but WITHOUT
 
13
% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
14
% FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 
15
% License for more details.
 
16
 
 
17
% You should have received a copy of the GNU General Public License along
 
18
% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
 
19
 
 
20
@ @c
 
21
#include <string.h>
 
22
#include "ptexlib.h"
 
23
#include <kpathsea/absolute.h>
 
24
 
 
25
static const char _svn_version[] =
 
26
    "$Id: texfileio.w 3612 2010-04-13 09:29:42Z taco $"
 
27
    "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.1/source/texk/web2c/luatexdir/tex/texfileio.w $";
 
28
 
 
29
@ @c
 
30
#define end_line_char int_par(end_line_char_code)
 
31
 
 
32
@ The bane of portability is the fact that different operating systems treat
 
33
input and output quite differently, perhaps because computer scientists
 
34
have not given sufficient attention to this problem. People have felt somehow
 
35
that input and output are not part of ``real'' programming. Well, it is true
 
36
that some kinds of programming are more fun than others. With existing
 
37
input/output conventions being so diverse and so messy, the only sources of
 
38
joy in such parts of the code are the rare occasions when one can find a
 
39
way to make the program a little less bad than it might have been. We have
 
40
two choices, either to attack I/O now and get it over with, or to postpone
 
41
I/O until near the end. Neither prospect is very attractive, so let's
 
42
get it over with.
 
43
 
 
44
The basic operations we need to do are (1)~inputting and outputting of
 
45
text, to or from a file or the user's terminal; (2)~inputting and
 
46
outputting of eight-bit bytes, to or from a file; (3)~instructing the
 
47
operating system to initiate (``open'') or to terminate (``close'') input or
 
48
output from a specified file; (4)~testing whether the end of an input
 
49
file has been reached.
 
50
 
 
51
\TeX\ needs to deal with two kinds of files.
 
52
We shall use the term |alpha_file| for a file that contains textual data,
 
53
and the term |byte_file| for a file that contains eight-bit binary information.
 
54
These two types turn out to be the same on many computers, but
 
55
sometimes there is a significant distinction, so we shall be careful to
 
56
distinguish between them. Standard protocols for transferring
 
57
such files from computer to computer, via high-speed networks, are
 
58
now becoming available to more and more communities of users.
 
59
 
 
60
The program actually makes use also of a third kind of file, called a
 
61
|word_file|, when dumping and reloading base information for its own
 
62
initialization.  We shall define a word file later; but it will be possible
 
63
for us to specify simple operations on word files before they are defined.
 
64
 
 
65
@ We finally did away with |nameoffile| and |namelength|, but the variables
 
66
have to be kept otherwise there will be link errors from |openclose.c| in
 
67
the web2c library 
 
68
 
 
69
@c
 
70
char *nameoffile;
 
71
int namelength;
 
72
 
 
73
 
 
74
@ When input files are opened via a callback, they will also be read using
 
75
callbacks. for that purpose, the |open_read_file_callback| returns an
 
76
integer to uniquely identify a callback table. This id replaces the file
 
77
point |f| in this case, because the input does not have to be a file
 
78
in the traditional sense.
 
79
 
 
80
Signalling this fact is achieved by having two arrays of integers.
 
81
 
 
82
@c
 
83
int *input_file_callback_id;
 
84
int read_file_callback_id[17];
 
85
 
 
86
@ Handle -output-directory.
 
87
 
 
88
We assume that it is OK to look here first.  Possibly it
 
89
would be better to replace lookups in "." with lookups in the
 
90
|output_directory| followed by "." but to do this requires much more
 
91
invasive surgery in libkpathsea.  
 
92
 
 
93
@c
 
94
static char *find_in_output_directory(const char *s)
 
95
{
 
96
    if (output_directory && !kpse_absolute_p(s, false)) {
 
97
        FILE *f_ptr;
 
98
        char *ftemp = concat3(output_directory, DIR_SEP_STRING, s);
 
99
        f_ptr = fopen(ftemp, "rb");     /* this code is used for input files only */
 
100
        if (f_ptr) {
 
101
            fclose(f_ptr);
 
102
            return ftemp;
 
103
        } else {
 
104
            free(ftemp);
 
105
 
 
106
        }
 
107
    }
 
108
    return NULL;
 
109
}
 
110
 
 
111
@ find an \.{\\input} or \.{\\read} file. |n| differentiates between those case. 
 
112
 
 
113
@c
 
114
char *luatex_find_read_file(const char *s, int n, int callback_index)
 
115
{
 
116
    char *ftemp = NULL;
 
117
    int callback_id = callback_defined(callback_index);
 
118
    if (callback_id > 0) {
 
119
        (void) run_callback(callback_id, "dS->S", n, s, &ftemp);
 
120
    } else {
 
121
        /* use kpathsea here */
 
122
        ftemp = find_in_output_directory(s);
 
123
        if (!ftemp)
 
124
            ftemp = kpse_find_file(s, kpse_tex_format, 1);
 
125
    }
 
126
    if (ftemp) {
 
127
        if (fullnameoffile)
 
128
            free(fullnameoffile);
 
129
        fullnameoffile = xstrdup(ftemp);
 
130
    }
 
131
    return ftemp;
 
132
}
 
133
 
 
134
@ find other files types
 
135
@c
 
136
char *luatex_find_file(const char *s, int callback_index)
 
137
{
 
138
    char *ftemp = NULL;
 
139
    int callback_id = callback_defined(callback_index);
 
140
    if (callback_id > 0) {
 
141
        (void) run_callback(callback_id, "S->S", s, &ftemp);
 
142
 
 
143
    } else {
 
144
        /* use kpathsea here */
 
145
        switch (callback_index) {
 
146
        case find_enc_file_callback:
 
147
            ftemp = kpse_find_file(s, kpse_enc_format, 0);
 
148
            break;
 
149
        case find_sfd_file_callback:
 
150
            ftemp = kpse_find_file(s, kpse_sfd_format, 0);
 
151
            break;
 
152
        case find_map_file_callback:
 
153
            ftemp = kpse_find_file(s, kpse_fontmap_format, 0);
 
154
            break;
 
155
        case find_type1_file_callback:
 
156
            ftemp = kpse_find_file(s, kpse_type1_format, 0);
 
157
            break;
 
158
        case find_truetype_file_callback:
 
159
            ftemp = kpse_find_file(s, kpse_truetype_format, 0);
 
160
            break;
 
161
        case find_opentype_file_callback:
 
162
            ftemp = kpse_find_file(s, kpse_opentype_format, 0);
 
163
            if (ftemp == NULL)
 
164
                ftemp = kpse_find_file(s, kpse_truetype_format, 0);
 
165
            break;
 
166
        case find_ocp_file_callback:
 
167
            ftemp = kpse_find_file(s, kpse_ocp_format, 0);
 
168
            break;
 
169
        case find_data_file_callback:
 
170
            ftemp = find_in_output_directory(s);
 
171
            if (!ftemp)
 
172
                ftemp = kpse_find_file(s, kpse_tex_format, 0);
 
173
            break;
 
174
        case find_font_file_callback:
 
175
            ftemp = kpse_find_file(s, kpse_ofm_format, 0);
 
176
            if (ftemp == NULL)
 
177
                ftemp = kpse_find_file(s, kpse_tfm_format, 0);
 
178
            break;
 
179
        case find_vf_file_callback:
 
180
            ftemp = kpse_find_file(s, kpse_ovf_format, 0);
 
181
            if (ftemp == NULL)
 
182
                ftemp = kpse_find_file(s, kpse_vf_format, 0);
 
183
            break;
 
184
        default:
 
185
            printf
 
186
                ("luatex_find_file(): do not know how to handle file %s of type %d\n",
 
187
                 s, callback_index);
 
188
            break;
 
189
        }
 
190
    }
 
191
    return ftemp;
 
192
}
 
193
 
 
194
 
 
195
@  Open an input file F, using the kpathsea format FILEFMT and passing
 
196
   |FOPEN_MODE| to fopen.  The filename is in `fn'.  We return whether or 
 
197
   not the open succeeded.
 
198
 
 
199
@c
 
200
boolean
 
201
luatex_open_input(FILE ** f_ptr, const char *fn, int filefmt,
 
202
                  const_string fopen_mode, boolean must_exist)
 
203
{
 
204
    string fname = NULL;
 
205
    /* We havent found anything yet. */
 
206
    *f_ptr = NULL;
 
207
    if (fullnameoffile)
 
208
        free(fullnameoffile);
 
209
    fullnameoffile = NULL;
 
210
    fname = kpse_find_file(fn, (kpse_file_format_type) filefmt, must_exist);
 
211
    if (fname) {
 
212
        fullnameoffile = xstrdup(fname);
 
213
        /* If we found the file in the current directory, don't leave
 
214
           the `./' at the beginning of `fn', since it looks
 
215
           dumb when `tex foo' says `(./foo.tex ... )'.  On the other
 
216
           hand, if the user said `tex ./foo', and that's what we
 
217
           opened, then keep it -- the user specified it, so we
 
218
           shouldn't remove it.  */
 
219
        if (fname[0] == '.' && IS_DIR_SEP(fname[1])
 
220
            && (fn[0] != '.' || !IS_DIR_SEP(fn[1]))) {
 
221
            unsigned i = 0;
 
222
            while (fname[i + 2] != 0) {
 
223
                fname[i] = fname[i + 2];
 
224
                i++;
 
225
            }
 
226
            fname[i] = 0;
 
227
        }
 
228
        /* This fopen is not allowed to fail. */
 
229
        *f_ptr = xfopen(fname, fopen_mode);
 
230
    }
 
231
    if (*f_ptr) {
 
232
        recorder_record_input(fname);
 
233
    }
 
234
    return *f_ptr != NULL;
 
235
}
 
236
 
 
237
@ @c
 
238
boolean luatex_open_output(FILE ** f_ptr, const char *fn,
 
239
                           const_string fopen_mode)
 
240
{
 
241
    char *fname;
 
242
    boolean absolute = kpse_absolute_p(fn, false);
 
243
 
 
244
    /* If we have an explicit output directory, use it. */
 
245
    if (output_directory && !absolute) {
 
246
        fname = concat3(output_directory, DIR_SEP_STRING, fn);
 
247
    } else {
 
248
        fname = xstrdup(fn);
 
249
    }
 
250
 
 
251
    /* Is the filename openable as given?  */
 
252
    *f_ptr = fopen(fname, fopen_mode);
 
253
 
 
254
    if (!*f_ptr) {
 
255
        /* Can't open as given.  Try the envvar.  */
 
256
        string texmfoutput = kpse_var_value("TEXMFOUTPUT");
 
257
 
 
258
        if (texmfoutput && *texmfoutput && !absolute) {
 
259
            fname = concat3(texmfoutput, DIR_SEP_STRING, fn);
 
260
            *f_ptr = fopen(fname, fopen_mode);
 
261
        }
 
262
    }
 
263
    if (*f_ptr) {
 
264
        recorder_record_output(fname);
 
265
    }
 
266
    free(fname);
 
267
    return *f_ptr != NULL;
 
268
}
 
269
 
 
270
 
 
271
@ @c
 
272
boolean lua_a_open_in(alpha_file * f, char *fn, int n)
 
273
{
 
274
    int k;
 
275
    char *fnam;                 /* string returned by find callback */
 
276
    int callback_id;
 
277
    boolean ret = true;         /* return value */
 
278
    boolean file_ok = true;     /* the status so far  */
 
279
    if (n == 0) {
 
280
        input_file_callback_id[iindex] = 0;
 
281
    } else {
 
282
        read_file_callback_id[n] = 0;
 
283
    }
 
284
    fnam = luatex_find_read_file(fn, n, find_read_file_callback);
 
285
    if (!fnam)
 
286
        return false;
 
287
    callback_id = callback_defined(open_read_file_callback);
 
288
    if (callback_id > 0) {
 
289
        k = run_and_save_callback(callback_id, "S->", fnam);
 
290
        if (k > 0) {
 
291
            ret = true;
 
292
            if (n == 0)
 
293
                input_file_callback_id[iindex] = k;
 
294
            else
 
295
                read_file_callback_id[n] = k;
 
296
        } else {
 
297
            file_ok = false;    /* read failed */
 
298
        }
 
299
    } else {                    /* no read callback */
 
300
        if (openinnameok(fnam)) {
 
301
            ret =
 
302
                open_in_or_pipe(f, fnam, kpse_tex_format, FOPEN_RBIN_MODE,
 
303
                                (n == 0 ? true : false));
 
304
        } else {
 
305
            file_ok = false;    /* open failed */
 
306
        }
 
307
    }
 
308
    if (!file_ok) {
 
309
        ret = false;
 
310
    }
 
311
    return ret;
 
312
}
 
313
 
 
314
@ @c
 
315
boolean lua_a_open_out(alpha_file * f, char *fn, int n)
 
316
{
 
317
    boolean test;
 
318
    str_number fnam;
 
319
    int callback_id;
 
320
    boolean ret = false;
 
321
    callback_id = callback_defined(find_write_file_callback);
 
322
    if (callback_id > 0) {
 
323
        fnam = 0;
 
324
        test = run_callback(callback_id, "dS->s", n, fn, &fnam);
 
325
        if ((test) && (fnam != 0) && (str_length(fnam) > 0)) {
 
326
            ret = open_outfile(f, fn, FOPEN_W_MODE);
 
327
        }
 
328
    } else {
 
329
        if (openoutnameok(fn)) {
 
330
            ret = open_out_or_pipe(f, fn, FOPEN_W_MODE);
 
331
        }
 
332
    }
 
333
    return ret;
 
334
}
 
335
 
 
336
@ @c
 
337
boolean lua_b_open_out(alpha_file * f, char *fn)
 
338
{
 
339
    boolean test;
 
340
    str_number fnam;
 
341
    int callback_id;
 
342
    boolean ret = false;
 
343
    callback_id = callback_defined(find_output_file_callback);
 
344
    if (callback_id > 0) {
 
345
        fnam = 0;
 
346
        test = run_callback(callback_id, "S->s", fn, &fnam);
 
347
        if ((test) && (fnam != 0) && (str_length(fnam) > 0)) {
 
348
            ret = open_outfile(f, fn, FOPEN_WBIN_MODE);
 
349
        }
 
350
    } else {
 
351
        if (openoutnameok(fn)) {
 
352
            ret = luatex_open_output(f, fn, FOPEN_WBIN_MODE);
 
353
        }
 
354
    }
 
355
    return ret;
 
356
}
 
357
 
 
358
@ @c
 
359
void lua_a_close_in(alpha_file f, int n)
 
360
{                               /* close a text file */
 
361
    boolean ret;
 
362
    int callback_id;
 
363
    if (n == 0)
 
364
        callback_id = input_file_callback_id[iindex];
 
365
    else
 
366
        callback_id = read_file_callback_id[n];
 
367
    if (callback_id > 0) {
 
368
        ret = run_saved_callback(callback_id, "close", "->");
 
369
        destroy_saved_callback(callback_id);
 
370
        if (n == 0)
 
371
            input_file_callback_id[iindex] = 0;
 
372
        else
 
373
            read_file_callback_id[n] = 0;
 
374
    } else {
 
375
        close_file_or_pipe(f);
 
376
    }
 
377
}
 
378
 
 
379
@ @c
 
380
void lua_a_close_out(alpha_file f)
 
381
{                               /* close a text file */
 
382
    close_file_or_pipe(f);
 
383
}
 
384
 
 
385
 
 
386
@ Binary input and output are done with C's ordinary 
 
387
procedures, so we don't have to make any other special arrangements for
 
388
binary~I/O. Text output is also easy to do with standard routines.
 
389
The treatment of text input is more difficult, however, because
 
390
of the necessary translation to |ASCII_code| values.
 
391
\TeX's conventions should be efficient, and they should
 
392
blend nicely with the user's operating environment.
 
393
 
 
394
Input from text files is read one line at a time, using a routine called
 
395
|lua_input_ln|. This function is defined in terms of global variables called
 
396
|buffer|, |first|, and |last| that will be described in detail later; for
 
397
now, it suffices for us to know that |buffer| is an array of |ASCII_code|
 
398
values, and that |first| and |last| are indices into this array
 
399
representing the beginning and ending of a line of text.
 
400
 
 
401
@c
 
402
packed_ASCII_code *buffer;      /* lines of characters being read */
 
403
int first;                      /* the first unused position in |buffer| */
 
404
int last;                       /* end of the line just input to |buffer| */
 
405
int max_buf_stack;              /* largest index used in |buffer| */
 
406
 
 
407
 
 
408
@ The |lua_input_ln| function brings the next line of input from the specified
 
409
file into available positions of the buffer array and returns the value
 
410
|true|, unless the file has already been entirely read, in which case it
 
411
returns |false| and sets |last:=first|.  In general, the |ASCII_code|
 
412
numbers that represent the next line of the file are input into
 
413
|buffer[first]|, |buffer[first+1]|, \dots, |buffer[last-1]|; and the
 
414
global variable |last| is set equal to |first| plus the length of the
 
415
line. Trailing blanks are removed from the line; thus, either |last=first|
 
416
(in which case the line was entirely blank) or |buffer[last-1]<>" "|.
 
417
 
 
418
An overflow error is given, however, if the normal actions of |lua_input_ln|
 
419
would make |last>=buf_size|; this is done so that other parts of \TeX\
 
420
can safely look at the contents of |buffer[last+1]| without overstepping
 
421
the bounds of the |buffer| array. Upon entry to |lua_input_ln|, the condition
 
422
|first<buf_size| will always hold, so that there is always room for an
 
423
``empty'' line.
 
424
 
 
425
The variable |max_buf_stack|, which is used to keep track of how large
 
426
the |buf_size| parameter must be to accommodate the present job, is
 
427
also kept up to date by |lua_input_ln|.
 
428
 
 
429
If the |bypass_eoln| parameter is |true|, |lua_input_ln| will do a |get|
 
430
before looking at the first character of the line; this skips over
 
431
an |eoln| that was in |f^|. The procedure does not do a |get| when it
 
432
reaches the end of the line; therefore it can be used to acquire input
 
433
from the user's terminal as well as from ordinary text files.
 
434
 
 
435
Since the inner loop of |lua_input_ln| is part of \TeX's ``inner loop''---each
 
436
character of input comes in at this place---it is wise to reduce system
 
437
overhead by making use of special routines that read in an entire array
 
438
of characters at once, if such routines are available. 
 
439
@^inner loop@>
 
440
 
 
441
@c
 
442
boolean lua_input_ln(alpha_file f, int n, boolean bypass_eoln)
 
443
{
 
444
    boolean lua_result;
 
445
    int last_ptr;
 
446
    int callback_id;
 
447
    (void) bypass_eoln;         /* todo: variable can be removed */
 
448
    if (n == 0)
 
449
        callback_id = input_file_callback_id[iindex];
 
450
    else
 
451
        callback_id = read_file_callback_id[n];
 
452
    if (callback_id > 0) {
 
453
        last = first;
 
454
        last_ptr = first;
 
455
        lua_result =
 
456
            run_saved_callback(callback_id, "reader", "->l", &last_ptr);
 
457
        if ((lua_result == true) && (last_ptr != 0)) {
 
458
            last = last_ptr;
 
459
            if (last > max_buf_stack)
 
460
                max_buf_stack = last;
 
461
        } else {
 
462
            lua_result = false;
 
463
        }
 
464
    } else {
 
465
        lua_result = input_ln(f, bypass_eoln);
 
466
    }
 
467
    if (lua_result == true) {
 
468
        /* Fix up the input buffer using callbacks */
 
469
        if (last >= first) {
 
470
            callback_id = callback_defined(process_input_buffer_callback);
 
471
            if (callback_id > 0) {
 
472
                last_ptr = first;
 
473
                lua_result =
 
474
                    run_callback(callback_id, "l->l", (last - first),
 
475
                                 &last_ptr);
 
476
                if ((lua_result == true) && (last_ptr != 0)) {
 
477
                    last = last_ptr;
 
478
                    if (last > max_buf_stack)
 
479
                        max_buf_stack = last;
 
480
                }
 
481
            }
 
482
        }
 
483
        return true;
 
484
    }
 
485
    return false;
 
486
}
 
487
 
 
488
 
 
489
@ We need a special routine to read the first line of \TeX\ input from
 
490
the user's terminal. This line is different because it is read before we
 
491
have opened the transcript file; there is sort of a ``chicken and
 
492
egg'' problem here. If the user types `\.{\\input paper}' on the first
 
493
line, or if some macro invoked by that line does such an \.{\\input},
 
494
the transcript file will be named `\.{paper.log}'; but if no \.{\\input}
 
495
commands are performed during the first line of terminal input, the transcript
 
496
file will acquire its default name `\.{texput.log}'. (The transcript file
 
497
will not contain error messages generated by the first line before the
 
498
first \.{\\input} command.)
 
499
@.texput@>
 
500
 
 
501
The first line is special also because it may be read before \TeX\ has
 
502
input a format file. In such cases, normal error messages cannot yet
 
503
be given. The following code uses concepts that will be explained later.
 
504
 
 
505
@ Different systems have different ways to get started. But regardless of
 
506
what conventions are adopted, the routine that initializes the terminal
 
507
should satisfy the following specifications:
 
508
 
 
509
\yskip\textindent{1)}It should open file |term_in| for input from the
 
510
  terminal. (The file |term_out| will already be open for output to the
 
511
  terminal.)
 
512
 
 
513
\textindent{2)}If the user has given a command line, this line should be
 
514
  considered the first line of terminal input. Otherwise the
 
515
  user should be prompted with `\.{**}', and the first line of input
 
516
  should be whatever is typed in response.
 
517
 
 
518
\textindent{3)}The first line of input, which might or might not be a
 
519
  command line, should appear in locations |first| to |last-1| of the
 
520
  |buffer| array.
 
521
 
 
522
\textindent{4)}The global variable |loc| should be set so that the
 
523
  character to be read next by \TeX\ is in |buffer[loc]|. This
 
524
  character should not be blank, and we should have |loc<last|.
 
525
 
 
526
\yskip\noindent(It may be necessary to prompt the user several times
 
527
before a non-blank line comes in. The prompt is `\.{**}' instead of the
 
528
later `\.*' because the meaning is slightly different: `\.{\\input}' need
 
529
not be typed immediately after~`\.{**}'.)
 
530
 
 
531
The following program does the required initialization.
 
532
Iff anything has been specified on the command line, then |t_open_in|
 
533
will return with |last > first|.
 
534
@^system dependencies@>
 
535
 
 
536
@c
 
537
boolean init_terminal(void)
 
538
{                               /* gets the terminal input started */
 
539
    t_open_in();
 
540
    if (last > first) {
 
541
        iloc = first;
 
542
        while ((iloc < last) && (buffer[iloc] == ' '))
 
543
            incr(iloc);
 
544
        if (iloc < last) {
 
545
            return true;
 
546
        }
 
547
    }
 
548
    while (1) {
 
549
        wake_up_terminal();
 
550
        fputs("**", term_out);
 
551
        update_terminal();
 
552
        if (!input_ln(term_in, true)) {
 
553
            /* this shouldn't happen */
 
554
            fputs("\n! End of file on the terminal... why?\n", term_out);
 
555
            return false;
 
556
        }
 
557
        iloc = first;
 
558
        while ((iloc < last) && (buffer[iloc] == ' '))
 
559
            incr(iloc);
 
560
        if (iloc < last) {
 
561
            return true;        /* return unless the line was all blank */
 
562
        }
 
563
        fputs("Please type the name of your input file.\n", term_out);
 
564
    }
 
565
}
 
566
 
 
567
 
 
568
@ Here is a procedure that asks the user to type a line of input,
 
569
assuming that the |selector| setting is either |term_only| or |term_and_log|.
 
570
The input is placed into locations |first| through |last-1| of the
 
571
|buffer| array, and echoed on the transcript file if appropriate.
 
572
 
 
573
@c
 
574
void term_input(void)
 
575
{                               /* gets a line from the terminal */
 
576
    int k;                      /* index into |buffer| */
 
577
    update_terminal();          /* now the user sees the prompt for sure */
 
578
    if (!input_ln(term_in, true))
 
579
        fatal_error("End of file on the terminal!");
 
580
    term_offset = 0;            /* the user's line ended with \.{<return>} */
 
581
    decr(selector);             /* prepare to echo the input */
 
582
    if (last != first) {
 
583
        for (k = first; k <= last - 1; k++)
 
584
            print_char(buffer[k]);
 
585
    }
 
586
    print_ln();
 
587
    incr(selector);             /* restore previous status */
 
588
}
 
589
 
 
590
 
 
591
@ It's time now to fret about file names.  Besides the fact that different
 
592
operating systems treat files in different ways, we must cope with the
 
593
fact that completely different naming conventions are used by different
 
594
groups of people. The following programs show what is required for one
 
595
particular operating system; similar routines for other systems are not
 
596
difficult to devise.
 
597
@^fingers@>
 
598
@^system dependencies@>
 
599
 
 
600
\TeX\ assumes that a file name has three parts: the name proper; its
 
601
``extension''; and a ``file area'' where it is found in an external file
 
602
system.  The extension of an input file or a write file is assumed to be
 
603
`\.{.tex}' unless otherwise specified; it is `\.{.log}' on the
 
604
transcript file that records each run of \TeX; it is `\.{.tfm}' on the font
 
605
metric files that describe characters in the fonts \TeX\ uses; it is
 
606
`\.{.dvi}' on the output files that specify typesetting information; and it
 
607
is `\.{.fmt}' on the format files written by \.{INITEX} to initialize \TeX.
 
608
The file area can be arbitrary on input files, but files are usually
 
609
output to the user's current area.  If an input file cannot be
 
610
found on the specified area, \TeX\ will look for it on a special system
 
611
area; this special area is intended for commonly used input files like
 
612
\.{webmac.tex}.
 
613
 
 
614
Simple uses of \TeX\ refer only to file names that have no explicit
 
615
extension or area. For example, a person usually says `\.{\\input} \.{paper}'
 
616
or `\.{\\font\\tenrm} \.= \.{helvetica}' instead of `\.{\\input}
 
617
\.{paper.new}' or `\.{\\font\\tenrm} \.= \.{<csd.knuth>test}'. Simple file
 
618
names are best, because they make the \TeX\ source files portable;
 
619
whenever a file name consists entirely of letters and digits, it should be
 
620
treated in the same way by all implementations of \TeX. However, users
 
621
need the ability to refer to other files in their environment, especially
 
622
when responding to error messages concerning unopenable files; therefore
 
623
we want to let them use the syntax that appears in their favorite
 
624
operating system.
 
625
 
 
626
The following procedures don't allow spaces to be part of
 
627
file names; but some users seem to like names that are spaced-out.
 
628
System-dependent changes to allow such things should probably
 
629
be made with reluctance, and only when an entire file name that
 
630
includes spaces is ``quoted'' somehow.
 
631
 
 
632
Here are the global values that file names will be scanned into.
 
633
 
 
634
@c
 
635
str_number cur_name;            /* name of file just scanned */
 
636
str_number cur_area;            /* file area just scanned, or \.{""} */
 
637
str_number cur_ext;             /* file extension just scanned, or \.{""} */
 
638
 
 
639
 
 
640
@ The file names we shall deal with have the
 
641
following structure:  If the name contains `\./' or `\.:'
 
642
(for Amiga only), the file area
 
643
consists of all characters up to and including the final such character;
 
644
otherwise the file area is null.  If the remaining file name contains
 
645
`\..', the file extension consists of all such characters from the last
 
646
`\..' to the end, otherwise the file extension is null.
 
647
 
 
648
We can scan such file names easily by using two global variables that keep track
 
649
of the occurrences of area and extension delimiters:
 
650
 
 
651
@c
 
652
pool_pointer area_delimiter;    /* the most recent `\./', if any */
 
653
pool_pointer ext_delimiter;     /* the relevant `\..', if any */
 
654
 
 
655
 
 
656
@ Input files that can't be found in the user's area may appear in a standard
 
657
system area called |TEX_area|. Font metric files whose areas are not given
 
658
explicitly are assumed to appear in a standard system area called
 
659
|TEX_font_area|.  $\Omega$'s compiled translation process files whose areas
 
660
are not given explicitly are assumed to appear in a standard system area. 
 
661
These system area names will, of course, vary from place to place.
 
662
 
 
663
@c
 
664
#define append_to_fn(A) do {                                    \
 
665
        c=(A);                                                  \
 
666
        if (c!='"') {                                           \
 
667
            if (k<file_name_size) fn[k++]=(unsigned char)(c);   \
 
668
        }                                                       \
 
669
    } while (0)
 
670
 
 
671
 
 
672
char *pack_file_name(str_number n, str_number a, str_number e)
 
673
{
 
674
    ASCII_code c;               /* character being packed */
 
675
    unsigned char *j;           /* index into |str_pool| */
 
676
    int k = 0;                  /* number of positions filled in |fn| */
 
677
    unsigned char *fn = xmallocarray(packed_ASCII_code,
 
678
                                     str_length(a) + str_length(n) +
 
679
                                     str_length(e) + 1);
 
680
    for (j = str_string(a); j < str_string(a) + str_length(a); j++)
 
681
        append_to_fn(*j);
 
682
    for (j = str_string(n); j < str_string(n) + str_length(n); j++)
 
683
        append_to_fn(*j);
 
684
    for (j = str_string(e); j < str_string(e) + str_length(e); j++)
 
685
        append_to_fn(*j);
 
686
    fn[k] = 0;
 
687
    return (char *) fn;
 
688
}
 
689
 
 
690
 
 
691
 
 
692
@ A messier routine is also needed, since format file names must be scanned
 
693
before \TeX's string mechanism has been initialized. We shall use the
 
694
global variable |TEX_format_default| to supply the text for default system areas
 
695
and extensions related to format files.
 
696
@^system dependencies@>
 
697
 
 
698
Under {\mc UNIX} we don't give the area part, instead depending
 
699
on the path searching that will happen during file opening.  Also, the
 
700
length will be set in the main program.
 
701
 
 
702
@c
 
703
char *TEX_format_default;
 
704
 
 
705
 
 
706
@ This part of the program becomes active when a ``virgin'' \TeX\ is trying to get going, 
 
707
just after the preliminary initialization, or when the user is substituting another
 
708
format file by typing `\.\&' after the initial `\.{**}' prompt.  The buffer
 
709
contains the first line of input in |buffer[loc..(last-1)]|, where
 
710
|loc<last| and |buffer[loc]<>" "|.
 
711
 
 
712
@c
 
713
char *open_fmt_file(void)
 
714
{
 
715
    int j;                      /* the first space after the format file name */
 
716
    char *fmt = NULL;
 
717
    int dist;
 
718
    j = iloc;
 
719
    if (buffer[iloc] == '&') {
 
720
        incr(iloc);
 
721
        j = iloc;
 
722
        buffer[last] = ' ';
 
723
        while (buffer[j] != ' ')
 
724
            incr(j);
 
725
        fmt = xmalloc((unsigned) (j - iloc + 1));
 
726
        strncpy(fmt, (char *) (buffer + iloc), (size_t) (j - iloc));
 
727
        fmt[j - iloc] = 0;
 
728
        dist = (int) (strlen(fmt) - strlen(DUMP_EXT));
 
729
        if (!(strstr(fmt, DUMP_EXT) == fmt + dist))
 
730
            fmt = concat(fmt, DUMP_EXT);
 
731
        if (zopen_w_input(&fmt_file, fmt, DUMP_FORMAT, FOPEN_RBIN_MODE))
 
732
            goto FOUND;
 
733
        wake_up_terminal();
 
734
        fprintf(stdout, "Sorry, I can't find the format `%s'; will try `%s'.\n",
 
735
                fmt, TEX_format_default);
 
736
        update_terminal();
 
737
    }
 
738
    /* now pull out all the stops: try for the system \.{plain} file */
 
739
    fmt = TEX_format_default;
 
740
    if (!zopen_w_input(&fmt_file, fmt, DUMP_FORMAT, FOPEN_RBIN_MODE)) {
 
741
        wake_up_terminal();
 
742
        fprintf(stdout, "I can't find the format file `%s'!\n",
 
743
                TEX_format_default);
 
744
        return NULL;
 
745
    }
 
746
  FOUND:
 
747
    iloc = j;
 
748
    return fmt;
 
749
}
 
750
 
 
751
 
 
752
@ The global variable |name_in_progress| is used to prevent recursive
 
753
use of |scan_file_name|, since the |begin_name| and other procedures
 
754
communicate via global variables. Recursion would arise only by
 
755
devious tricks like `\.{\\input\\input f}'; such attempts at sabotage
 
756
must be thwarted. Furthermore, |name_in_progress| prevents \.{\\input}
 
757
@^recursion@>
 
758
from being initiated when a font size specification is being scanned.
 
759
 
 
760
Another global variable, |job_name|, contains the file name that was first
 
761
\.{\\input} by the user. This name is extended by `\.{.log}' and `\.{.dvi}'
 
762
and `\.{.fmt}' in the names of \TeX's output files.
 
763
 
 
764
@c
 
765
boolean name_in_progress;       /* is a file name being scanned? */
 
766
str_number job_name;            /* principal file name */
 
767
boolean log_opened;             /* has the transcript file been opened? */
 
768
 
 
769
 
 
770
@ Initially |job_name=0|; it becomes nonzero as soon as the true name is known.
 
771
We have |job_name=0| if and only if the `\.{log}' file has not been opened,
 
772
except of course for a short time just after |job_name| has become nonzero.
 
773
 
 
774
@c
 
775
unsigned char *texmf_log_name;  /* full name of the log file */
 
776
 
 
777
 
 
778
@ The |open_log_file| routine is used to open the transcript file and to help
 
779
it catch up to what has previously been printed on the terminal.
 
780
 
 
781
@c
 
782
void open_log_file(void)
 
783
{
 
784
    int old_setting;            /* previous |selector| setting */
 
785
    int k;                      /* index into |buffer| */
 
786
    int l;                      /* end of first input line */
 
787
    char *fn;
 
788
    old_setting = selector;
 
789
    if (job_name == 0)
 
790
        job_name = getjobname(maketexstring("texput")); /* TODO */
 
791
    fn = pack_job_name(".fls");
 
792
    recorder_change_filename(fn);
 
793
    fn = pack_job_name(".log");
 
794
    while (!lua_a_open_out(&log_file, fn, 0)) {
 
795
        /* Try to get a different log file name */
 
796
        /* Sometimes |open_log_file| is called at awkward moments when \TeX\ is
 
797
           unable to print error messages or even to |show_context|.
 
798
           The |prompt_file_name| routine can result in a |fatal_error|, but the |error|
 
799
           routine will not be invoked because |log_opened| will be false.
 
800
 
 
801
           The normal idea of |batch_mode| is that nothing at all should be written
 
802
           on the terminal. However, in the unusual case that
 
803
           no log file could be opened, we make an exception and allow
 
804
           an explanatory message to be seen.
 
805
 
 
806
           Incidentally, the program always refers to the log file as a `\.{transcript
 
807
           file}', because some systems cannot use the extension `\.{.log}' for
 
808
           this file.
 
809
         */
 
810
        selector = term_only;
 
811
        fn = prompt_file_name("transcript file name", ".log");
 
812
    }
 
813
    texmf_log_name = (unsigned char *) xstrdup(fn);
 
814
    selector = log_only;
 
815
    log_opened = true;
 
816
    if (callback_defined(start_run_callback) == 0) {
 
817
        /* Print the banner line, including the date and time */
 
818
        log_banner(luatex_version_string, luatex_date_info, luatex_svn);
 
819
 
 
820
        input_stack[input_ptr] = cur_input;     /* make sure bottom level is in memory */
 
821
        tprint_nl("**");
 
822
        l = input_stack[0].limit_field; /* last position of first line */
 
823
        if (buffer[l] == end_line_char)
 
824
            decr(l);            /* TODO: multichar endlinechar */
 
825
        for (k = 1; k <= l; k++)
 
826
            print_char(buffer[k]);
 
827
        print_ln();             /* now the transcript file contains the first line of input */
 
828
    }
 
829
    flush_loggable_info();      /* should be done always */
 
830
    selector = old_setting + 2; /* |log_only| or |term_and_log| */
 
831
}
 
832
 
 
833
 
 
834
@ Let's turn now to the procedure that is used to initiate file reading
 
835
when an `\.{\\input}' command is being processed.
 
836
 
 
837
@c
 
838
void start_input(void)
 
839
{                               /* \TeX\ will \.{\\input} something */
 
840
    str_number temp_str;
 
841
    char *fn;
 
842
    do {
 
843
        get_x_token();
 
844
    } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
 
845
 
 
846
    back_input();
 
847
    if (cur_cmd != left_brace_cmd) {
 
848
        scan_file_name();       /* set |cur_name| to desired file name */
 
849
    } else {
 
850
        scan_file_name_toks();
 
851
    }
 
852
    fn = pack_file_name(cur_name, cur_area, cur_ext);
 
853
    while (1) {
 
854
        begin_file_reading();   /* set up |cur_file| and new level of input */
 
855
        if (lua_a_open_in(&cur_file, fn, 0))
 
856
            break;
 
857
        end_file_reading();     /* remove the level that didn't work */
 
858
        fn = prompt_file_name("input file name", "");
 
859
    }
 
860
    iname = maketexstring(fullnameoffile);
 
861
    source_filename_stack[in_open] = iname;
 
862
    full_source_filename_stack[in_open] = xstrdup(fullnameoffile);
 
863
    /* we can try to conserve string pool space now */
 
864
    temp_str = search_string(iname);
 
865
    if (temp_str > 0) {
 
866
        flush_str(iname);
 
867
        iname = temp_str;
 
868
    }
 
869
    if (job_name == 0) {
 
870
        job_name = getjobname(cur_name);
 
871
        open_log_file();
 
872
    }
 
873
    /* |open_log_file| doesn't |show_context|, so |limit|
 
874
       and |loc| needn't be set to meaningful values yet */
 
875
    if (tracefilenames) {
 
876
        if (term_offset + (int) str_length(iname) > max_print_line - 2)
 
877
            print_ln();
 
878
        else if ((term_offset > 0) || (file_offset > 0))
 
879
            print_char(' ');
 
880
        print_char('(');
 
881
        tprint_file_name(NULL, (unsigned char *) fullnameoffile, NULL);
 
882
    }
 
883
    incr(open_parens);
 
884
    update_terminal();
 
885
    istate = new_line;
 
886
    /* Prepare new file {\sl Sync\TeX} information */
 
887
    synctexstartinput();        /* Give control to the {\sl Sync\TeX} controller */
 
888
 
 
889
    /* Read the first line of the new file */
 
890
    /* Here we have to remember to tell the |lua_input_ln| routine not to
 
891
       start with a |get|. If the file is empty, it is considered to
 
892
       contain a single blank line. */
 
893
 
 
894
    line = 1;
 
895
    if (lua_input_ln(cur_file, 0, false)) {
 
896
        ;
 
897
    }
 
898
    firm_up_the_line();
 
899
    if (end_line_char_inactive())
 
900
        decr(ilimit);
 
901
    else
 
902
        buffer[ilimit] = (packed_ASCII_code) end_line_char;
 
903
    first = ilimit + 1;
 
904
    iloc = istart;
 
905
}
 
906
 
 
907
@ Read and write dump files through zlib
 
908
 
 
909
@ Earlier versions recast |*f| from |FILE *| to |gzFile|, but there is
 
910
no guarantee that these have the same size, so a static variable 
 
911
is needed.
 
912
 
 
913
@c
 
914
static gzFile gz_fmtfile = NULL;
 
915
 
 
916
@ @c
 
917
void do_zdump(char *p, int item_size, int nitems, FILE * out_file)
 
918
{
 
919
    int err;
 
920
    (void) out_file;
 
921
    if (nitems == 0)
 
922
        return;
 
923
#if !defined (WORDS_BIGENDIAN) && !defined (NO_DUMP_SHARE)
 
924
    swap_items(p, nitems, item_size);
 
925
#endif
 
926
    if (gzwrite(gz_fmtfile, (void *) p, (unsigned) (item_size * nitems)) !=
 
927
        item_size * nitems) {
 
928
        fprintf(stderr, "! Could not write %d %d-byte item(s): %s.\n", nitems,
 
929
                item_size, gzerror(gz_fmtfile, &err));
 
930
        uexit(1);
 
931
    }
 
932
}
 
933
 
 
934
@ @c
 
935
void do_zundump(char *p, int item_size, int nitems, FILE * in_file)
 
936
{
 
937
    int err;
 
938
    (void) in_file;
 
939
    if (nitems == 0)
 
940
        return;
 
941
    if (gzread(gz_fmtfile, (void *) p, (unsigned) (item_size * nitems)) <= 0) {
 
942
        fprintf(stderr, "Could not undump %d %d-byte item(s): %s.\n",
 
943
                nitems, item_size, gzerror(gz_fmtfile, &err));
 
944
        uexit(1);
 
945
    }
 
946
#if !defined (WORDS_BIGENDIAN) && !defined (NO_DUMP_SHARE)
 
947
    swap_items(p, nitems, item_size);
 
948
#endif
 
949
}
 
950
 
 
951
@ @c
 
952
#define COMPRESSION "R3"
 
953
 
 
954
boolean zopen_w_input(FILE ** f, const char *fname, int format,
 
955
                      const_string fopen_mode)
 
956
{
 
957
    int callbackid;
 
958
    int res;
 
959
    char *fnam;
 
960
    callbackid = callback_defined(find_format_file_callback);
 
961
    if (callbackid > 0) {
 
962
        res = run_callback(callbackid, "S->S", fname, &fnam);
 
963
        if (res && fnam && strlen(fnam) > 0) {
 
964
            *f = xfopen(fnam, fopen_mode);
 
965
            if (*f == NULL) {
 
966
                return 0;
 
967
            }
 
968
        } else {
 
969
            return 0;
 
970
        }
 
971
    } else {
 
972
        res = luatex_open_input(f, fname, format, fopen_mode, true);
 
973
    }
 
974
    if (res) {
 
975
        gz_fmtfile = gzdopen(fileno(*f), "rb" COMPRESSION);
 
976
    }
 
977
    return res;
 
978
}
 
979
 
 
980
@ @c
 
981
boolean zopen_w_output(FILE ** f, const char *s, const_string fopen_mode)
 
982
{
 
983
    int res = 1;
 
984
    if (luainit) {
 
985
        *f = fopen(s, fopen_mode);
 
986
        if (*f == NULL) {
 
987
            return 0;
 
988
        }
 
989
    } else {
 
990
        res = luatex_open_output(f, s, fopen_mode);
 
991
    }
 
992
    if (res) {
 
993
        gz_fmtfile = gzdopen(fileno(*f), "wb" COMPRESSION);
 
994
    }
 
995
    return res;
 
996
}
 
997
 
 
998
@ @c
 
999
void zwclose(FILE * f)
 
1000
{
 
1001
    (void) f;
 
1002
    gzclose(gz_fmtfile);
 
1003
}
 
1004
 
 
1005
@  create the dvi or pdf file 
 
1006
@c
 
1007
int open_outfile(FILE ** f, const char *name, const char *mode)
 
1008
{
 
1009
    FILE *res;
 
1010
    res = fopen(name, mode);
 
1011
    if (res != NULL) {
 
1012
        *f = res;
 
1013
        return 1;
 
1014
    }
 
1015
    return 0;
 
1016
}
 
1017
 
 
1018
 
 
1019
@ the caller should set |tfm_buffer=NULL| and |tfm_size=0|
 
1020
@c
 
1021
int readbinfile(FILE * f, unsigned char **tfm_buffer, int *tfm_size)
 
1022
{
 
1023
    void *buf;
 
1024
    int size;
 
1025
    if (fseek(f, 0, SEEK_END) == 0) {
 
1026
        size = (int) ftell(f);
 
1027
        if (size > 0) {
 
1028
            buf = xmalloc((unsigned) size);
 
1029
            if (fseek(f, 0, SEEK_SET) == 0) {
 
1030
                if (fread((void *) buf, (size_t) size, 1, f) == 1) {
 
1031
                    *tfm_buffer = (unsigned char *) buf;
 
1032
                    *tfm_size = size;
 
1033
                    return 1;
 
1034
                }
 
1035
            }
 
1036
        } else {
 
1037
            *tfm_buffer = NULL;
 
1038
            *tfm_size = 0;
 
1039
            return 1;
 
1040
        }
 
1041
    }                           /* seek failed, or zero-sized file */
 
1042
    return 0;
 
1043
}
 
1044
 
 
1045
 
 
1046
@ Like |runsystem()|, the |runpopen()| function is called only when
 
1047
   |shellenabledp == 1|.   Unlike |runsystem()|, here we write errors to
 
1048
   stderr, since we have nowhere better to use; and of course we return
 
1049
   a file handle (or NULL) instead of a status indicator. 
 
1050
 
 
1051
@c
 
1052
static FILE *runpopen(char *cmd, const char *mode)
 
1053
{
 
1054
    FILE *f = NULL;
 
1055
    char *safecmd = NULL;
 
1056
    char *cmdname = NULL;
 
1057
    int allow;
 
1058
 
 
1059
    /* If restrictedshell == 0, any command is allowed. */
 
1060
    if (restrictedshell == 0) {
 
1061
        allow = 1;
 
1062
    } else {
 
1063
        const char *thecmd = cmd;
 
1064
        allow = shell_cmd_is_allowed(&thecmd, &safecmd, &cmdname);
 
1065
    }
 
1066
    if (allow == 1)
 
1067
        f = popen(cmd, mode);
 
1068
    else if (allow == 2)
 
1069
        f = popen(safecmd, mode);
 
1070
    else if (allow == -1)
 
1071
        fprintf(stderr, "\nrunpopen quotation error in command line: %s\n",
 
1072
                cmd);
 
1073
    else
 
1074
        fprintf(stderr, "\nrunpopen command not allowed: %s\n", cmdname);
 
1075
 
 
1076
    if (safecmd)
 
1077
        free(safecmd);
 
1078
    if (cmdname)
 
1079
        free(cmdname);
 
1080
    return f;
 
1081
}
 
1082
 
 
1083
@ Return true if FNAME is acceptable as a name for \.{\\openout}, \.{\\openin}, or
 
1084
   \.{\\input}.  
 
1085
 
 
1086
@c
 
1087
typedef enum ok_type {
 
1088
    ok_reading,
 
1089
    ok_writing
 
1090
} ok_type;
 
1091
 
 
1092
static const_string ok_type_name[] = {
 
1093
    "reading",
 
1094
    "writing"
 
1095
};
 
1096
 
 
1097
static boolean
 
1098
opennameok(const_string fname, const_string check_var,
 
1099
           const_string default_choice, ok_type action)
 
1100
{
 
1101
    /* We distinguish three cases:
 
1102
       'a' (any)        allows any file to be opened.
 
1103
       'r' (restricted) means disallowing special file names.
 
1104
       'p' (paranoid)   means being really paranoid: disallowing special file
 
1105
       names and restricting output files to be in or below
 
1106
       the working directory or $TEXMFOUTPUT, while input files
 
1107
       must be below the current directory, $TEXMFOUTPUT, or
 
1108
       (implicitly) in the system areas.
 
1109
       We default to "paranoid".  The error messages from TeX will be somewhat
 
1110
       puzzling...
 
1111
       This function contains several return statements...  */
 
1112
 
 
1113
    const_string open_choice = kpse_var_value(check_var);
 
1114
 
 
1115
    if (!open_choice)
 
1116
        open_choice = default_choice;
 
1117
 
 
1118
    if (*open_choice == 'a' || *open_choice == 'y' || *open_choice == '1')
 
1119
        return true;
 
1120
 
 
1121
#if defined (unix) && !defined (MSDOS)
 
1122
    {
 
1123
        const_string base = xbasename(fname);
 
1124
        /* Disallow .rhosts, .login, etc.  Allow .tex (for LaTeX).  */
 
1125
        if (base[0] == 0 ||
 
1126
            (base[0] == '.' && !IS_DIR_SEP(base[1]) && !STREQ(base, ".tex"))) {
 
1127
            fprintf(stderr, "%s: Not %s to %s (%s = %s).\n",
 
1128
                    program_invocation_name, ok_type_name[action], fname,
 
1129
                    check_var, open_choice);
 
1130
            return false;
 
1131
        }
 
1132
    }
 
1133
#else
 
1134
    /* Other OSs don't have special names? */
 
1135
#endif
 
1136
 
 
1137
    if (*open_choice == 'r' || *open_choice == 'n' || *open_choice == '0')
 
1138
        return true;
 
1139
 
 
1140
    /* Paranoia supplied by Charles Karney...  */
 
1141
    if (kpse_absolute_p(fname, false)) {
 
1142
        const_string texmfoutput = kpse_var_value("TEXMFOUTPUT");
 
1143
        /* Absolute pathname is only OK if TEXMFOUTPUT is set, it's not empty,
 
1144
           fname begins the TEXMFOUTPUT, and is followed by / */
 
1145
        if (!texmfoutput || *texmfoutput == '\0'
 
1146
            || fname != strstr(fname, texmfoutput)
 
1147
            || !IS_DIR_SEP(fname[strlen(texmfoutput)])) {
 
1148
            fprintf(stderr, "%s: Not %s to %s (%s = %s).\n",
 
1149
                    program_invocation_name, ok_type_name[action], fname,
 
1150
                    check_var, open_choice);
 
1151
            return false;
 
1152
        }
 
1153
    }
 
1154
    /* For all pathnames, we disallow "../" at the beginning or "/../"
 
1155
       anywhere.  */
 
1156
    if (fname[0] == '.' && fname[1] == '.' && IS_DIR_SEP(fname[2])) {
 
1157
        fprintf(stderr, "%s: Not %s to %s (%s = %s).\n",
 
1158
                program_invocation_name, ok_type_name[action], fname,
 
1159
                check_var, open_choice);
 
1160
        return false;
 
1161
    } else {
 
1162
        /* Check for "/../".  Since more than one characted can be matched
 
1163
           by |IS_DIR_SEP|, we cannot use "/../" itself. */
 
1164
        const_string dotpair = strstr(fname, "..");
 
1165
        while (dotpair) {
 
1166
            /* If dotpair[2] == |DIR_SEP|, then dotpair[-1] is well-defined,
 
1167
               because the "../" case was handled above. */
 
1168
            if (IS_DIR_SEP(dotpair[2]) && IS_DIR_SEP(dotpair[-1])) {
 
1169
                fprintf(stderr, "%s: Not %s to %s (%s = %s).\n",
 
1170
                        program_invocation_name, ok_type_name[action], fname,
 
1171
                        check_var, open_choice);
 
1172
                return false;
 
1173
            }
 
1174
            /* Continue after the dotpair. */
 
1175
            dotpair = strstr(dotpair + 2, "..");
 
1176
        }
 
1177
    }
 
1178
 
 
1179
    /* We passed all tests.  */
 
1180
    return true;
 
1181
}
 
1182
 
 
1183
boolean openinnameok(const_string fname)
 
1184
{
 
1185
    /* For input default to all. */
 
1186
    return opennameok(fname, "openin_any", "a", ok_reading);
 
1187
}
 
1188
 
 
1189
#if defined(WIN32) || defined(__MINGW32__) || defined(__CYGWIN__)
 
1190
 
 
1191
static int Isspace(char c)
 
1192
{
 
1193
    return (c == ' ' || c == '\t');
 
1194
}
 
1195
 
 
1196
static boolean executable_filep(const_string fname)
 
1197
{
 
1198
    string p, q, base;
 
1199
    string *pp;
 
1200
 
 
1201
    /*  check |openout_any| */
 
1202
    p = kpse_var_value("openout_any");
 
1203
    if (p && *p == 'p') {
 
1204
        free(p);
 
1205
/* get base name
 
1206
   we cannot use xbasename() for abnormal names.
 
1207
*/
 
1208
        base = xstrdup(fname);
 
1209
        p = strrchr(fname, '/');
 
1210
        if (p) {
 
1211
            p++;
 
1212
            strcpy(base, p);
 
1213
        }
 
1214
        p = strrchr(base, '\\');
 
1215
        if (p) {
 
1216
            p++;
 
1217
            strcpy(base, p);
 
1218
        }
 
1219
#  if defined(__CYGWIN__)
 
1220
        for (p = base; *p; p++)
 
1221
            *p = tolower(*p);
 
1222
        p = base;
 
1223
#  else
 
1224
        p = (char *) strlwr(base);
 
1225
#  endif
 
1226
        for (q = p + strlen(p) - 1;
 
1227
             (q >= p) && ((*q == '.') || (Isspace(*q))); q--) {
 
1228
            *q = '\0';          /* remove trailing '.' , ' ' and '\t' */
 
1229
        }
 
1230
        q = strrchr(p, '.');    /* get extension part */
 
1231
        pp = suffixlist;
 
1232
        if (pp && q) {
 
1233
            while (*pp) {
 
1234
                if (strchr(fname, ':') || !strcmp(q, *pp)) {
 
1235
                    fprintf(stderr,
 
1236
                            "\nThe name %s is forbidden to open for writing.\n",
 
1237
                            fname);
 
1238
                    free(base);
 
1239
                    return true;
 
1240
                }
 
1241
                pp++;
 
1242
            }
 
1243
        }
 
1244
        free(base);
 
1245
    } else if (p) {
 
1246
        free(p);
 
1247
    }
 
1248
    return false;
 
1249
}
 
1250
#endif
 
1251
 
 
1252
boolean openoutnameok(const_string fname)
 
1253
{
 
1254
#if defined(WIN32) || defined(__MINGW32__) || defined(__CYGWIN__)
 
1255
    /* Output of an executable file is restricted on Windows */
 
1256
    if (executable_filep(fname))
 
1257
        return false;
 
1258
#endif
 
1259
    /* For output, default to paranoid. */
 
1260
    return opennameok(fname, "openout_any", "p", ok_writing);
 
1261
}
 
1262
 
 
1263
 
 
1264
@  piped I/O
 
1265
 
 
1266
 
 
1267
@ The code that implements |popen()| needs an array for tracking 
 
1268
   possible pipe file pointers, because these need to be
 
1269
   closed using |pclose()|.
 
1270
 
 
1271
@c
 
1272
static FILE *pipes[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
1273
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 
1274
};
 
1275
 
 
1276
boolean open_in_or_pipe(FILE ** f_ptr, char *fn, int filefmt,
 
1277
                        const_string fopen_mode, boolean must_exist)
 
1278
{
 
1279
    string fname = NULL;
 
1280
    int i;                      /* iterator */
 
1281
 
 
1282
    /* opening a read pipe is straightforward, only have to
 
1283
       skip past the pipe symbol in the file name. filename
 
1284
       quoting is assumed to happen elsewhere (it does :-)) */
 
1285
 
 
1286
    if (shellenabledp && *fn == '|') {
 
1287
        /* the user requested a pipe */
 
1288
        *f_ptr = NULL;
 
1289
        fname = (string) xmalloc((unsigned) (strlen(fn) + 1));
 
1290
        strcpy(fname, fn);
 
1291
        if (fullnameoffile)
 
1292
            free(fullnameoffile);
 
1293
        fullnameoffile = xstrdup(fname);
 
1294
        recorder_record_input(fname + 1);
 
1295
        *f_ptr = runpopen(fname + 1, "r");
 
1296
        free(fname);
 
1297
        for (i = 0; i <= 15; i++) {
 
1298
            if (pipes[i] == NULL) {
 
1299
                pipes[i] = *f_ptr;
 
1300
                break;
 
1301
            }
 
1302
        }
 
1303
        if (*f_ptr)
 
1304
            setvbuf(*f_ptr, (char *) NULL, _IOLBF, 0);
 
1305
 
 
1306
        return *f_ptr != NULL;
 
1307
    }
 
1308
 
 
1309
    return luatex_open_input(f_ptr, fn, filefmt, fopen_mode, must_exist);
 
1310
}
 
1311
 
 
1312
 
 
1313
boolean open_out_or_pipe(FILE ** f_ptr, char *fn, const_string fopen_mode)
 
1314
{
 
1315
    string fname;
 
1316
    int i;                      /* iterator */
 
1317
 
 
1318
    /* opening a write pipe takes a little bit more work, because TeX
 
1319
       will perhaps have appended ".tex".  To avoid user confusion as
 
1320
       much as possible, this extension is stripped only when the command
 
1321
       is a bare word.  Some small string trickery is needed to make
 
1322
       sure the correct number of bytes is free()-d afterwards */
 
1323
 
 
1324
    if (shellenabledp && *fn == '|') {
 
1325
        /* the user requested a pipe */
 
1326
        fname = (string) xmalloc((unsigned) (strlen(fn) + 1));
 
1327
        strcpy(fname, fn);
 
1328
        if (strchr(fname, ' ') == NULL && strchr(fname, '>') == NULL) {
 
1329
            /* mp and mf currently do not use this code, but it 
 
1330
               is better to be prepared */
 
1331
            if (STREQ((fname + strlen(fname) - 3), "tex"))
 
1332
                *(fname + strlen(fname) - 4) = 0;
 
1333
            *f_ptr = runpopen(fname + 1, "w");
 
1334
            *(fname + strlen(fname)) = '.';
 
1335
        } else {
 
1336
            *f_ptr = runpopen(fname + 1, "w");
 
1337
        }
 
1338
        recorder_record_output(fname + 1);
 
1339
        free(fname);
 
1340
 
 
1341
        for (i = 0; i <= 15; i++) {
 
1342
            if (pipes[i] == NULL) {
 
1343
                pipes[i] = *f_ptr;
 
1344
                break;
 
1345
            }
 
1346
        }
 
1347
 
 
1348
        if (*f_ptr)
 
1349
            setvbuf(*f_ptr, (char *) NULL, _IOLBF, 0);
 
1350
 
 
1351
        return *f_ptr != NULL;
 
1352
    }
 
1353
 
 
1354
    return luatex_open_output(f_ptr, fn, fopen_mode);
 
1355
}
 
1356
 
 
1357
 
 
1358
void close_file_or_pipe(FILE * f)
 
1359
{
 
1360
    int i;                      /* iterator */
 
1361
 
 
1362
    if (shellenabledp) {
 
1363
        for (i = 0; i <= 15; i++) {
 
1364
        /* if this file was a pipe, |pclose()| it and return */
 
1365
            if (pipes[i] == f) {
 
1366
                if (f)
 
1367
                    pclose(f);
 
1368
                pipes[i] = NULL;
 
1369
                return;
 
1370
            }
 
1371
        }
 
1372
    }
 
1373
    close_file(f);
 
1374
}