1 /* luatex.c: Hand-coded routines for TeX or Metafont in C. Originally
2 written by Tim Morgan, drawing from other Unix ports of TeX. This is
3 a collection of miscellany, everything that's easier (or only
6 This file is public domain. */
8 /* This file is used to create texextra.c etc., with this line
9 changed to include texd.h or mfd.h. The ?d.h file is what
10 #defines TeX or MF, which avoids the need for a special
13 /* We |#define DLLPROC| in order to build LuaTeX and LuajitTeX as DLL
16 #define DLLPROC dllluajittexmain
18 #define DLLPROC dllluatexmain
23 #include "lua/luatex-api.h"
25 #include "luatex_svnversion.h"
31 int luatex_version
= 100; /* \.{\\luatexversion} */
32 int luatex_revision
= '3'; /* \.{\\luatexrevision} */
33 int luatex_date_info
= 2017021514; /* the compile date is now hardwired :YEAR MONTH DAY HOUR*/
34 const char *luatex_version_string
= "1.0.3";
35 const char *engine_name
= my_name
; /* the name of this engine */
37 #include <kpathsea/c-ctype.h>
38 #include <kpathsea/line.h>
39 #include <kpathsea/readable.h>
40 #include <kpathsea/variable.h>
41 #include <kpathsea/absolute.h>
43 #include <kpathsea/concatn.h>
50 #include <time.h> /* For `struct tm'. */
51 #if defined (HAVE_SYS_TIME_H)
52 # include <sys/time.h>
53 #elif defined (HAVE_SYS_TIMEB_H)
54 # include <sys/timeb.h>
61 #include <signal.h> /* Catch interrupts. */
67 If shellenabledp == 0, all shell escapes are forbidden.
68 If (shellenabledp == 1 && restrictedshell == 0), any command
69 is allowed for a shell escape.
70 If (shellenabledp == 1 && restrictedshell == 1), only commands
71 given in the configuration file as
72 shell_escape_commands = kpsewhich,ebb,extractbb,mpost,metafun,...
73 (no spaces between commands) in texmf.cnf are allowed for a shell
74 escape in a restricted form: command name and arguments should be
75 separated by a white space. The first word should be a command
76 name. The quotation character for an argument with spaces,
77 including a pathname, should be ". ' should not be used.
79 Internally, all arguments are quoted by ' (Unix) or " (Windows)
80 before calling the system() function in order to forbid execution
81 of any embedded command.
83 If the --shell-escape option is given, we set
84 shellenabledp = 1 and restrictedshell = 0, i.e., any command is allowed.
85 If the --shell-restricted option is given, we set
86 shellenabledp = 1 and restrictedshell = 1, i.e., only given cmds allowed.
87 If the --no-shell-escape option is given, we set
88 shellenabledp = -1 (and restrictedshell is irrelevant).
89 If none of these option are given, there are three cases:
94 it becomes shellenabledp = 1 and restrictedshell = 0,
95 that is, any command is allowed.
98 it becomes shellenabledp = 1 and restrictedshell = 1,
99 that is, restricted shell escape is allowed.
100 (3) In all other cases, shellenabledp = 0, that is, shell
101 escape is forbidden. The value of restrictedshell is
102 irrelevant if shellenabledp == 0.
107 /* cmdlist is a list of allowed commands which are given like this:
108 shell_escape_commands = kpsewhich,ebb,extractbb,mpost,metafun
111 static char **cmdlist
= NULL
;
113 void mk_shellcmdlist(char *v
)
122 /* analyze the variable shell_escape_commands = foo,bar,...
123 spaces before and after (,) are not allowed. */
125 while ((r
= strchr(q
, ',')) != 0) {
131 cmdlist
= (char **) xmalloc(n
* sizeof (char *));
134 while ((r
= strchr(q
, ',')) != 0) {
144 /* Called from maininit. Not static because also called from
145 luatexdir/lua/luainit.c. */
148 In order to avoid all kind of time code in the backend code we use a function.
149 The start time can be overloaded in several ways:
151 (1) By setting the environmment variable SOURCE_DATE_EPOCH. This will influence
152 the tex parameters, random seed, pdf timestamp and pdf id that is derived
153 from the time. This variable is consulted when the kpse library is enabled
154 which is analogue to other properties.
156 (2) By setting the texconfig.start_time variable (as with other variables
157 we use the internal name there). This has the same effect as (1) and is
158 provided for when kpse is not used to set these variables or when an overloaded
159 is wanted. This is analogue to other properties.
161 When an utc time is needed one can provide the flag --utc. This property is
162 independent of this time hackery. This flag has a corresponding texconfig
165 To some extend a cleaner solution would be to have a flag that disables all
166 variable data in one go (like filenames and so) but we just follow the method
167 implemented in pdftex where primitives are used tod disable it.
171 static int start_time
= -1;
173 int get_start_time(void) {
174 if (start_time
< 0) {
175 start_time
= time((time_t *) NULL
);
181 This one is called as part of the kpse initialization which only happens
182 when this library is enabled.
184 #if defined(_MSC_VER)
185 #define strtoull _strtoui64
188 void init_start_time(void) {
189 if (start_time
< 0) {
190 unsigned long long epoch
;
193 We don't really care how kpse sets up this variable but we prefer to
194 just use its abstract interface.
196 /* char *source_date_epoch = getenv("SOURCE_DATE_EPOCH"); */
197 char *source_date_epoch
= kpse_var_value("SOURCE_DATE_EPOCH");
198 if (source_date_epoch
&& source_date_epoch
!= '\0' ) {
200 epoch
= strtoull(source_date_epoch
, &endptr
, 10);
201 if (*endptr
!= '\0' || errno
!= 0) {
204 #if defined(_MSC_VER)
205 /* We avoid to crash if users test a large value which is not
206 * supported by Visual Studio 2010:
207 * a later time than 3001/01/01 20:59:59.
209 if (epoch
> 32535291599ULL)
210 epoch
= 32535291599ULL;
218 This one is used to fetch a value from texconfig which can also be used to
219 set properties. This might come in handy when one has other ways to get date
220 info in the pdf file.
223 void set_start_time(int s
) {
229 void init_shell_escape(void)
231 if (shellenabledp
< 0) { /* --no-shell-escape on cmd line */
235 if (shellenabledp
== 0) { /* no shell options on cmd line, check cnf */
236 char *v1
= kpse_var_value("shell_escape");
238 if (*v1
== 't' || *v1
== 'y' || *v1
== '1') {
240 } else if (*v1
== 'p') {
248 /* If shell escapes are restricted, get allowed cmds from cnf. */
249 if (shellenabledp
&& restrictedshell
== 1) {
250 char *v2
= kpse_var_value("shell_escape_commands");
267 static int char_needs_quote(int c
)
269 /* special characters of cmd.exe */
271 return (c
== '&' || c
== '|' || c
== '%' || c
== '<' ||
272 c
== '>' || c
== ';' || c
== ',' || c
== '(' || c
== ')');
277 static int Isspace(char c
)
279 return (c
== ' ' || c
== '\t');
283 -1 : invalid quotation of an argument
284 0 : command is not allowed
285 2 : restricted shell escape, CMD is allowed.
287 We set *SAFECMD to a safely-quoted version of *CMD; this is what
288 should get executed. And we set CMDNAME to its first word; this is
289 what is checked against the shell_escape_commands list. */
291 int shell_cmd_is_allowed(const char *cmd
, char **safecmd
, char **cmdname
)
301 /* pre == 1 means that the previous character is a white space
302 pre == 0 means that the previous character is not a white space */
303 buf
= xmalloc(strlen(cmd
) + 1);
309 while (!Isspace(*d
) && *d
)
313 /* *cmdname is the first word of the command line. For example,
314 *cmdname == "kpsewhich" for
315 \write18{kpsewhich --progname=dvipdfm --format="other text files" config}
317 *cmdname
= xstrdup(c
);
320 /* Is *cmdname listed in a texmf.cnf vriable as
321 shell_escape_commands = foo,bar,... ? */
325 if (strcmp(*p
, *cmdname
) == 0) {
326 /* *cmdname is found in the list, so restricted shell escape
336 for (s
= cmd
; *s
; s
++) {
341 /* allocate enough memory (too much?) */
343 *safecmd
= xmalloc(2 * strlen(cmd
) + 3 + 2 * spaces
);
345 *safecmd
= xmalloc(strlen(cmd
) + 3 + 2 * spaces
);
348 /* make a safe command line *safecmd */
353 while (!Isspace(*s
) && *s
)
358 /* Quotation given by a user. " should always be used; we
359 transform it below. On Unix, if ' is used, simply immediately
360 return a quotation error. */
366 /* All arguments are quoted as 'foo' (Unix) or "foo" (Windows)
367 before calling system(). Therefore closing QUOTE is necessary
368 if the previous character is not a white space.
370 --format="other text files" becomes
371 '--format=''other text files' (Unix)
372 "--format"="other text files" (Windows) */
388 /* output the quotation mark for the quoted argument */
393 /* Illegal use of ', or closing quotation mark is missing */
394 if (*s
== '\'' || *s
== '\0')
398 if (char_needs_quote(*s
))
405 /* Closing quotation mark will be output afterwards, so
406 we do nothing here */
409 /* The character after the closing quotation mark
410 should be a white space or NULL */
411 if (!Isspace(*s
) && *s
)
414 /* Beginning of a usual argument */
415 } else if (pre
== 1 && !Isspace(*s
)) {
420 if (char_needs_quote(*s
))
425 /* Ending of a usual argument */
427 } else if (pre
== 0 && Isspace(*s
)) {
429 /* Closing quotation mark */
433 /* Copy a character from cmd to *safecmd. */
436 if (char_needs_quote(*s
))
443 /* End of the command line */
452 if (strlen (p
) > 2 && p
[1] == ':' && !IS_DIR_SEP (p
[2])) {
453 q
= xmalloc (strlen (p
) + 2);
461 } else if (!IS_DIR_SEP (p
[0]) && !(p
[1] == ':' && IS_DIR_SEP (p
[2]))) {
462 p
= kpse_var_value ("SELFAUTOLOC");
465 while (*r
&& !Isspace(*r
))
468 q
= concatn ("\"", p
, "/", *safecmd
, "\"", NULL
);
472 while (*r
&& Isspace(*r
))
475 q
= concatn ("\"", p
, "/", *safecmd
, "\" ", r
, NULL
);
477 q
= concatn ("\"", p
, "/", *safecmd
, "\"", NULL
);
494 /* What we were invoked as and with. */
498 /* The C version of what might wind up in |TEX_format_default|. */
501 /* The C version of the jobname, if given. */
502 const_string c_job_name
;
504 const char *luatex_banner
;
507 /* Invalid parameter handler */
508 static void myInvalidParameterHandler(const wchar_t * expression
,
509 const wchar_t * function
,
510 const wchar_t * file
,
515 printf(L"Invalid parameter detected in function %s."
516 L" File: %s Line: %d\n", function, file, line);
517 printf(L"Expression: %s\n", expression);
520 I return silently to avoid an exit with the error 0xc0000417
521 (invalid parameter) when we use non-embedded fonts in luatex-ja,
522 which works without any problem on Unix systems.
523 I hope it is not dangerous.
529 /* The entry point: set up for reading the command line, which will
530 happen in `topenin', then call the main body. */
534 DLLPROC (int ac
, string
*av
)
536 main (int ac
, string
*av
)
546 _set_invalid_parameter_handler(myInvalidParameterHandler
);
548 av
[0] = kpse_program_basename (av
[0]);
551 * We choose to crash for fatal errors
552 SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
554 setmode(fileno(stdin
), _O_BINARY
);
557 lua_initialize(ac
, av
);
562 if ((strlen(av
[ac
-1]) > 2) &&
563 isalpha(av
[ac
-1][0]) &&
564 (av
[ac
-1][1] == ':') &&
565 (av
[ac
-1][2] == '\\')) {
566 for (pp
=av
[ac
-1]+2; *pp
; pp
++) {
578 /* Call the real main program. */
585 /* This is supposed to ``open the terminal for input'', but what we
586 really do is copy command line arguments into TeX's or Metafont's
587 buffer, so they can handle them. If nothing is available, or we've
588 been called already (and hence, argc==0), we return with
596 buffer
[first
] = 0; /* In case there are no arguments. */
598 if (optind
< argc
) { /* We have command line arguments. */
600 for (i
= optind
; i
< argc
; i
++) {
601 char *ptr
= &(argv
[i
][0]);
602 /* Don't use strcat, since in Aleph the buffer elements aren't
605 buffer
[k
++] = (packed_ASCII_code
) * (ptr
++);
609 argc
= 0; /* Don't do this again. */
613 /* Find the end of the buffer. */
614 for (last
= first
; buffer
[last
]; ++last
);
616 /* Make `last' be one past the last non-blank character in `buffer'. */
617 /* ??? The test for '\r' should not be necessary. */
618 for (--last
; last
>= first
619 && ISBLANK(buffer
[last
]) && buffer
[last
] != '\r'; --last
);
622 /* One more time, this time converting to TeX's internal character
626 /* IPC for TeX. By Tom Rokicki for the NeXT; it makes TeX ship out the
627 DVI file in a pipe to TeXView so that the output can be displayed
628 incrementally. Shamim Mohamed adapted it for Web2c. */
629 #if defined (TeX) && defined (IPC)
633 #include <winsock2.h>
635 #include <sys/socket.h>
637 #ifndef O_NONBLOCK /* POSIX */
638 #ifdef O_NDELAY /* BSD */
639 #define O_NONBLOCK O_NDELAY
640 #elif defined(O_FNDELAY) /* NeXT */
641 #define O_NONBLOCK O_FNDELAY
643 what the fcntl
? cannot implement IPC without equivalent
for O_NONBLOCK
.
645 #endif /* no O_NONBLOCK */
649 # define IPC_AF AF_INET
650 # ifndef IPC_LOCAL_HOST
651 # define IPC_LOCAL_HOST "127.0.0.1"
652 # define FIXED_PORT (unsigned short)4242
655 # define IPC_AF AF_UNIX
656 # ifndef IPC_PIPE_NAME /* $HOME is prepended to this. */
657 # define IPC_PIPE_NAME "/.TeXview_Pipe"
660 #ifndef IPC_SERVER_CMD /* Command to run to start the server. */
662 # define IPC_SERVER_CMD "texview.exe"
664 # define IPC_SERVER_CMD "open `which TeXview`"
670 int namelength
; /* length of auxiliary data */
671 int eof
; /* new eof for dvi file */
672 #if 0 /* see usage of struct msg below */
673 char more_data
[0]; /* where the rest of the stuff goes */
677 static struct sockaddr
*ipc_addr
;
678 static int ipc_addr_len
;
683 if (ipc_addr_len
== 0) {
685 unsigned long remote_addr
= inet_addr(IPC_LOCAL_HOST
);
686 if (remote_addr
!= INADDR_NONE
) {
687 struct sockaddr_in
*ipc_sin_addr
= xmalloc (sizeof (struct sockaddr_in
));
688 ipc_sin_addr
->sin_family
= AF_INET
;
689 ipc_sin_addr
->sin_addr
.s_addr
= remote_addr
;
690 ipc_sin_addr
->sin_port
= htons (FIXED_PORT
);
691 ipc_addr
= ((struct sockaddr
*) ipc_sin_addr
);
692 ipc_addr_len
= sizeof(struct sockaddr_in
);
695 string s
= getenv ("HOME");
698 ipc_addr
= xmalloc (strlen (s
) + 40);
699 ipc_addr
->sa_family
= 0;
700 ipc_name
= ipc_addr
->sa_data
;
701 strcpy (ipc_name
, s
);
702 strcat (ipc_name
, IPC_PIPE_NAME
);
703 ipc_addr_len
= strlen (ipc_name
) + 3;
710 static int sock
= -1;
713 # define CLOSE_SOCKET(s) closesocket (s); WSACleanup ()
715 # define CLOSE_SOCKET(s) close (s)
725 ipc_open_out (void) {
727 struct WSAData wsaData
;
729 unsigned long mode
= 1;
732 fputs ("tex: Opening socket for IPC output ...\n", stderr
);
739 if ((nCode
= WSAStartup(MAKEWORD(1, 1), &wsaData
)) != 0) {
740 fprintf(stderr
,"WSAStartup() returned error code %d.\n", nCode
);
745 if (ipc_make_name () <= 0)
748 sock
= socket (IPC_AF
, SOCK_STREAM
, 0);
751 fprintf(stderr
, "tex: Socket handle is %d\n", sock
);
753 fprintf(stderr
, "tex: Socket is invalid.\n");
757 if (connect (sock
, ipc_addr
, ipc_addr_len
) != 0 ||
759 ioctlsocket (sock
, FIONBIO
, &mode
) < 0
761 fcntl (sock
, F_SETFL
, O_NONBLOCK
) < 0
767 fputs ("tex: IPC socket cannot be connected.\n", stderr
);
768 fputs ("tex: Socket is closed.\n", stderr
);
773 fputs ("tex: Successfully opened IPC socket.\n", stderr
);
782 fputs ("tex: Closing output socket ...\n", stderr
);
784 if (ipc_is_open ()) {
791 ipc_snd (int n
, int is_eof
, char *data
)
796 char more_data
[1024];
799 if (!ipc_is_open ()) {
804 fprintf(stderr
, "%d\t%d\n", ourmsg
.msg
.namelength
, ourmsg
.msg
.eof
);
805 fputs ("tex: Sending message to socket ...\n", stderr
);
807 ourmsg
.msg
.namelength
= n
;
808 ourmsg
.msg
.eof
= is_eof
;
810 strcpy (ourmsg
.more_data
, data
);
812 n
+= sizeof (struct msg
);
814 fprintf(stderr
, "%d\t%d\n", ourmsg
.msg
.namelength
, ourmsg
.msg
.eof
);
815 fputs ("tex: Writing to socket...\n", stderr
);
818 if (send (sock
, (char *)&ourmsg
, n
, 0) != n
) {
820 if (write (sock
, &ourmsg
, n
) != n
) {
825 fputs ("tex: IPC message sent.\n", stderr
);
829 /* This routine notifies the server if there is an eof, or the filename
830 if a new DVI file is starting. This is the routine called by TeX.
831 Aleph defines str_start(#) as str_start_ar[# - too_big_char], with
832 too_big_char = biggest_char + 1 = 65536 (omstr.ch). */
837 static boolean begun
= false;
842 string name
; /* Just the filename. */
843 string cwd
= xgetcwd ();
847 /* Have to pass whole filename to the other end, since it may have
848 been started up and running as a daemon, e.g., as with the NeXT
850 name
= static_pdf
->file_name
;
851 p
= concat3 (cwd
, DIR_SEP_STRING
, name
);
857 for (q
= p
; *q
; q
++) {
860 else if (IS_KANJI(q
))
868 ipc_snd (len
, is_eof
, p
);
873 #endif /* TeX && IPC */
875 /* Normalize quoting of filename -- that is, only quote if there is a space,
876 and always use the quote-name-quote style. */
877 string
normalize_quotes(const_string name
, const_string mesg
)
879 boolean quoted
= false;
880 boolean must_quote
= (strchr(name
, ' ') != NULL
);
881 /* Leave room for quotes and NUL. */
882 string ret
= (string
) xmalloc((unsigned) strlen(name
) + 3);
888 for (q
= name
; *q
; q
++) {
898 fprintf(stderr
, "! Unbalanced quotes in %s %s\n", mesg
, name
);
905 /* All our interrupt handler has to do is set TeX's or Metafont's global
906 variable `interrupt'; then they will do everything needed. */
908 /* Win32 doesn't set SIGINT ... */
909 static BOOL WINAPI
catch_interrupt(DWORD arg
)
913 case CTRL_BREAK_EVENT
:
917 /* No need to set interrupt as we are exiting anyway */
921 #else /* not WIN32 */
922 static RETSIGTYPE
catch_interrupt(int arg
)
927 (void) signal(SIGINT
, SIG_ACK
);
929 (void) signal(SIGINT
, catch_interrupt
);
930 # endif /* not OS2 */
932 #endif /* not WIN32 */
934 /* Besides getting the date and time here, we also set up the interrupt
935 handler, for no particularly good reason. It's just that since the
936 `fix_date_and_time' routine is called early on (section 1337 in TeX,
937 ``Get the first line of input and prepare to start''), this is as
938 good a place as any. */
940 void get_date_and_time(int *minutes
, int *day
, int *month
, int *year
)
942 time_t myclock
= get_start_time();
945 tmptr
= gmtime(&myclock
);
947 tmptr
= localtime(&myclock
);
950 *minutes
= tmptr
->tm_hour
* 60 + tmptr
->tm_min
;
951 *day
= tmptr
->tm_mday
;
952 *month
= tmptr
->tm_mon
+ 1;
953 *year
= tmptr
->tm_year
+ 1900;
957 /* Under SunOS 4.1.x, the default action after return from the
958 signal handler is to restart the I/O if nothing has been
959 transferred. The effect on TeX is that interrupts are ignored if
960 we are waiting for input. The following tells the system to
961 return EINTR from read() in this case. From ken@cs.toronto.edu. */
963 struct sigaction a
, oa
;
965 a
.sa_handler
= catch_interrupt
;
966 sigemptyset(&a
.sa_mask
);
967 sigaddset(&a
.sa_mask
, SIGINT
);
968 a
.sa_flags
= SA_INTERRUPT
;
969 sigaction(SIGINT
, &a
, &oa
);
970 if (oa
.sa_handler
!= SIG_DFL
)
971 sigaction(SIGINT
, &oa
, (struct sigaction
*) 0);
972 #else /* no SA_INTERRUPT */
974 SetConsoleCtrlHandler(catch_interrupt
, TRUE
);
975 # else /* not WIN32 */
976 RETSIGTYPE(*old_handler
) (int);
978 old_handler
= signal(SIGINT
, catch_interrupt
);
979 if (old_handler
!= SIG_DFL
)
980 signal(SIGINT
, old_handler
);
981 # endif /* not WIN32 */
982 #endif /* no SA_INTERRUPT */
987 Getting a high resolution time.
989 void get_seconds_and_micros(int *seconds
, int *micros
)
991 #if defined (HAVE_GETTIMEOFDAY)
993 gettimeofday(&tv
, NULL
);
994 *seconds
= (int)tv
.tv_sec
;
995 *micros
= (int)tv
.tv_usec
;
996 #elif defined (HAVE_FTIME)
1000 *micros
= tb
.millitm
* 1000;
1002 time_t myclock
= time((time_t *) NULL
);
1003 *seconds
= (int) myclock
;
1009 Generating a better seed numbers
1011 int getrandomseed(void)
1013 #if defined (HAVE_GETTIMEOFDAY)
1015 gettimeofday(&tv
, NULL
);
1016 return (int)(tv
.tv_usec
+ 1000000 * tv
.tv_usec
);
1017 #elif defined (HAVE_FTIME)
1020 return (tb
.millitm
+ 1000 * tb
.time
);
1022 time_t myclock
= get_start_time((time_t *) NULL
);
1025 tmptr
= gmtime(&myclock
);
1027 tmptr
= localtime(&myclock
);
1029 return (tmptr
->tm_sec
+ 60 * (tmptr
->tm_min
+ 60 * tmptr
->tm_hour
));
1033 /* Read a line of input as efficiently as possible while still looking
1034 like Pascal. We set `last' to `first' and return `false' if we get
1035 to eof. Otherwise, we return `true' and set last = first +
1036 length(line except trailing whitespace). */
1038 boolean
input_line(FILE * f
)
1043 if (f
!= Poptr
&& fileno (f
) != fileno (stdin
)) {
1044 long position
= ftell (f
);
1046 if (position
== 0L) { /* Detect and skip Byte order marks. */
1049 if (k1
!= 0xff && k1
!= 0xfe && k1
!= 0xef)
1054 if (k2
!= 0xff && k2
!= 0xfe && k2
!= 0xbb)
1056 else if ((k1
== 0xff && k2
== 0xfe) || /* UTF-16(LE) */
1057 (k1
== 0xfe && k2
== 0xff)) /* UTF-16(BE) */
1062 if (k1
== 0xef && k2
== 0xbb && k3
== 0xbf) /* UTF-8 */
1071 /* Recognize either LF or CR as a line terminator. */
1073 while (last
< buf_size
&& (i
= getc(f
)) != EOF
&& i
!= '\n' && i
!= '\r')
1074 buffer
[last
++] = (packed_ASCII_code
) i
;
1076 if (i
== EOF
&& errno
!= EINTR
&& last
== first
)
1079 /* We didn't get the whole line because our buffer was too small. */
1080 if (i
!= EOF
&& i
!= '\n' && i
!= '\r') {
1081 fprintf(stderr
, "! Unable to read an entire line---bufsize=%u.\n",
1082 (unsigned) buf_size
);
1083 fputs("Please increase buf_size in texmf.cnf.\n", stderr
);
1088 if (last
>= max_buf_stack
)
1089 max_buf_stack
= last
;
1091 /* If next char is LF of a CRLF, read it. */
1093 while ((i
= getc(f
)) == EOF
&& errno
== EINTR
);
1098 /* Trim trailing whitespace. */
1099 while (last
> first
&& ISBLANK(buffer
[last
- 1]))
1102 /* Don't bother using xord if we don't need to. */
1110 /* Get the job name to be used, which may have been set from the
1112 str_number
getjobname(str_number name
)
1114 str_number ret
= name
;
1115 if (c_job_name
!= NULL
)
1116 ret
= maketexstring(c_job_name
);