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