updated version.release
[luatex.git] / source / texk / web2c / luatexdir / luatex.c
blob429dcd95dee2c5762a4099d0d56c91e00d0509a6
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
4 possible) to do in C.
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
11 Makefile rule. */
13 /* We |#define DLLPROC| in order to build LuaTeX and LuajitTeX as DLL
14 for W32TeX. */
15 #if defined LuajitTeX
16 #define DLLPROC dllluajittexmain
17 #else
18 #define DLLPROC dllluatexmain
19 #endif
21 #include "ptexlib.h"
22 #include "luatex.h"
23 #include "lua/luatex-api.h"
24 #include "luatex_svnversion.h"
27 #define TeX
29 int luatex_svn = luatex_svn_revision;
30 int luatex_version = 81; /* \.{\\luatexversion} */
31 int luatex_revision = '1'; /* \.{\\luatexrevision} */
32 int luatex_date_info = 2015042200; /* the compile date is now hardwired */
33 const char *luatex_version_string = "beta-0.81.1";
34 const char *engine_name = my_name; /* the name of this engine */
36 #include <kpathsea/c-ctype.h>
37 #include <kpathsea/line.h>
38 #include <kpathsea/readable.h>
39 #include <kpathsea/variable.h>
40 #include <kpathsea/absolute.h>
41 #ifdef WIN32
42 #include <kpathsea/concatn.h>
43 #endif
45 #ifdef _MSC_VER
46 #undef timezone
47 #endif
49 #include <time.h> /* For `struct tm'. */
50 #if defined (HAVE_SYS_TIME_H)
51 # include <sys/time.h>
52 #elif defined (HAVE_SYS_TIMEB_H)
53 # include <sys/timeb.h>
54 #endif
56 #if defined(__STDC__)
57 # include <locale.h>
58 #endif
60 #include <signal.h> /* Catch interrupts. */
63 /* {tex,mf}d.h defines TeX, MF, INI, and other such symbols.
64 Unfortunately there's no way to get the banner into this code, so
65 just repeat the text. */
66 #define edit_var "TEXEDIT"
68 /* Shell escape.
70 If shellenabledp == 0, all shell escapes are forbidden.
71 If (shellenabledp == 1 && restrictedshell == 0), any command
72 is allowed for a shell escape.
73 If (shellenabledp == 1 && restrictedshell == 1), only commands
74 given in the configuration file as
75 shell_escape_commands = kpsewhich,ebb,extractbb,mpost,metafun,...
76 (no spaces between commands) in texmf.cnf are allowed for a shell
77 escape in a restricted form: command name and arguments should be
78 separated by a white space. The first word should be a command
79 name. The quotation character for an argument with spaces,
80 including a pathname, should be ". ' should not be used.
82 Internally, all arguments are quoted by ' (Unix) or " (Windows)
83 before calling the system() function in order to forbid execution
84 of any embedded command. In addition, on Windows, special
85 characters of cmd.exe are escaped by using (^).
87 If the --shell-escape option is given, we set
88 shellenabledp = 1 and restrictedshell = 0, i.e., any command is allowed.
89 If the --shell-restricted option is given, we set
90 shellenabledp = 1 and restrictedshell = 1, i.e., only given cmds allowed.
91 If the --no-shell-escape option is given, we set
92 shellenabledp = -1 (and restrictedshell is irrelevant).
93 If none of these option are given, there are three cases:
94 (1) In the case where
95 shell_escape = y or
96 shell_escape = t or
97 shell_escape = 1
98 it becomes shellenabledp = 1 and restrictedshell = 0,
99 that is, any command is allowed.
100 (2) In the case where
101 shell_escape = p
102 it becomes shellenabledp = 1 and restrictedshell = 1,
103 that is, restricted shell escape is allowed.
104 (3) In all other cases, shellenabledp = 0, that is, shell
105 escape is forbidden. The value of restrictedshell is
106 irrelevant if shellenabledp == 0.
109 #ifdef TeX
111 /* cmdlist is a list of allowed commands which are given like this:
112 shell_escape_commands = kpsewhich,ebb,extractbb,mpost,metafun
113 in texmf.cnf. */
115 static char **cmdlist = NULL;
117 void mk_shellcmdlist(char *v)
119 char **p;
120 char *q, *r;
121 size_t n;
123 q = v;
124 n = 1;
126 /* analyze the variable shell_escape_commands = foo,bar,...
127 spaces before and after (,) are not allowed. */
129 while ((r = strchr(q, ',')) != 0) {
130 n++;
131 q = r + 1;
133 if (*q)
134 n++;
135 cmdlist = (char **) xmalloc(n * sizeof (char *));
136 p = cmdlist;
137 q = v;
138 while ((r = strchr(q, ',')) != 0) {
139 *r = '\0';
140 *p++ = xstrdup (q);
141 q = r + 1;
143 if (*q)
144 *p++ = xstrdup (q);
145 *p = NULL;
148 /* Called from maininit. Not static because also called from
149 luatexdir/lua/luainit.c. */
151 void init_shell_escape(void)
153 if (shellenabledp < 0) { /* --no-shell-escape on cmd line */
154 shellenabledp = 0;
156 } else {
157 if (shellenabledp == 0) { /* no shell options on cmd line, check cnf */
158 char *v1 = kpse_var_value("shell_escape");
159 if (v1) {
160 if (*v1 == 't' || *v1 == 'y' || *v1 == '1') {
161 shellenabledp = 1;
162 } else if (*v1 == 'p') {
163 shellenabledp = 1;
164 restrictedshell = 1;
166 free(v1);
170 /* If shell escapes are restricted, get allowed cmds from cnf. */
171 if (shellenabledp && restrictedshell == 1) {
172 char *v2 = kpse_var_value("shell_escape_commands");
173 if (v2) {
174 mk_shellcmdlist(v2);
175 free(v2);
181 # ifdef WIN32
182 # define QUOTE '"'
183 # else
184 # define QUOTE '\''
185 # endif
187 # ifdef WIN32
188 static int char_needs_quote(int c)
190 /* special characters of cmd.exe */
192 return (c == '&' || c == '|' || c == '%' || c == '<' ||
193 c == '>' || c == ';' || c == ',' || c == '(' || c == ')');
195 # endif
197 static int Isspace(char c)
199 return (c == ' ' || c == '\t');
202 /* return values:
203 -1 : invalid quotation of an argument
204 0 : command is not allowed
205 2 : restricted shell escape, CMD is allowed.
207 We set *SAFECMD to a safely-quoted version of *CMD; this is what
208 should get executed. And we set CMDNAME to its first word; this is
209 what is checked against the shell_escape_commands list. */
211 int shell_cmd_is_allowed(const char *cmd, char **safecmd, char **cmdname)
213 char **p;
214 char *buf;
215 char *c, *d;
216 const char *s;
217 int pre;
218 unsigned spaces;
219 int allow = 0;
221 /* pre == 1 means that the previous character is a white space
222 pre == 0 means that the previous character is not a white space */
223 buf = xmalloc(strlen(cmd) + 1);
224 strcpy(buf, cmd);
225 c = buf;
226 while (Isspace(*c))
227 c++;
228 d = c;
229 while (!Isspace(*d) && *d)
230 d++;
231 *d = '\0';
233 /* *cmdname is the first word of the command line. For example,
234 *cmdname == "kpsewhich" for
235 \write18{kpsewhich --progname=dvipdfm --format="other text files" config}
237 *cmdname = xstrdup(c);
238 free(buf);
240 /* Is *cmdname listed in a texmf.cnf vriable as
241 shell_escape_commands = foo,bar,... ? */
242 p = cmdlist;
243 if (p) {
244 while (*p) {
245 if (strcmp(*p, *cmdname) == 0) {
246 /* *cmdname is found in the list, so restricted shell escape
247 is allowed */
248 allow = 2;
249 break;
251 p++;
254 if (allow == 2) {
255 spaces = 0;
256 for (s = cmd; *s; s++) {
257 if (Isspace(*s))
258 spaces++;
261 /* allocate enough memory (too much?) */
262 # ifdef WIN32
263 *safecmd = xmalloc(2 * strlen(cmd) + 3 + 2 * spaces);
264 # else
265 *safecmd = xmalloc(strlen(cmd) + 3 + 2 * spaces);
266 # endif
268 /* make a safe command line *safecmd */
269 s = cmd;
270 while (Isspace(*s))
271 s++;
272 d = *safecmd;
273 while (!Isspace(*s) && *s)
274 *d++ = *s++;
276 pre = 1;
277 while (*s) {
278 /* Quotation given by a user. " should always be used; we
279 transform it below. On Unix, if ' is used, simply immediately
280 return a quotation error. */
281 if (*s == '\'') {
282 return -1;
285 if (*s == '"') {
286 /* All arguments are quoted as 'foo' (Unix) or "foo" (Windows)
287 before calling system(). Therefore closing QUOTE is necessary
288 if the previous character is not a white space.
289 example:
290 --format="other text files" becomes
291 '--format=''other text files' (Unix)
292 "--format=""other test files" (Windows) */
294 if (pre == 0)
295 *d++ = QUOTE;
297 pre = 0;
298 /* output the quotation mark for the quoted argument */
299 *d++ = QUOTE;
300 s++;
302 while (*s != '"') {
303 /* Illegal use of ', or closing quotation mark is missing */
304 if (*s == '\'' || *s == '\0')
305 return -1;
306 # ifdef WIN32
307 if (char_needs_quote(*s))
308 *d++ = '^';
309 # endif
310 *d++ = *s++;
313 /* Closing quotation mark will be output afterwards, so
314 we do nothing here */
315 s++;
317 /* The character after the closing quotation mark
318 should be a white space or NULL */
319 if (!Isspace(*s) && *s)
320 return -1;
322 /* Beginning of a usual argument */
323 } else if (pre == 1 && !Isspace(*s)) {
324 pre = 0;
325 *d++ = QUOTE;
326 # ifdef WIN32
327 if (char_needs_quote(*s))
328 *d++ = '^';
329 # endif
330 *d++ = *s++;
331 /* Ending of a usual argument */
333 } else if (pre == 0 && Isspace(*s)) {
334 pre = 1;
335 /* Closing quotation mark */
336 *d++ = QUOTE;
337 *d++ = *s++;
338 } else {
339 /* Copy a character from cmd to *safecmd. */
340 # ifdef WIN32
341 if (char_needs_quote(*s))
342 *d++ = '^';
343 # endif
344 *d++ = *s++;
347 /* End of the command line */
348 if (pre == 0) {
349 *d++ = QUOTE;
351 *d = '\0';
352 #ifdef WIN32
354 char *p, *q, *r;
355 p = *safecmd;
356 if (strlen (p) > 2 && p[1] == ':' && !IS_DIR_SEP (p[2])) {
357 q = xmalloc (strlen (p) + 2);
358 q[0] = p[0];
359 q[1] = p[1];
360 q[2] = '/';
361 q[3] = '\0';
362 strcat (q, (p + 2));
363 free (*safecmd);
364 *safecmd = q;
365 } else if (!IS_DIR_SEP (p[0]) && !(p[1] == ':' && IS_DIR_SEP (p[2]))) {
366 p = kpse_var_value ("SELFAUTOLOC");
367 if (p) {
368 r = *safecmd;
369 while (*r && !Isspace(*r))
370 r++;
371 if (*r == '\0')
372 q = concatn ("\"", p, "/", *safecmd, "\"", NULL);
373 else {
374 *r = '\0';
375 r++;
376 while (*r && Isspace(*r))
377 r++;
378 if (*r)
379 q = concatn ("\"", p, "/", *safecmd, "\" ", r, NULL);
380 else
381 q = concatn ("\"", p, "/", *safecmd, "\"", NULL);
383 free (p);
384 free (*safecmd);
385 *safecmd = q;
389 #endif
392 return allow;
395 /* We should only be called with shellenabledp == 1.
396 Return value:
397 -1 if a quotation syntax error.
398 0 if CMD is not allowed; given shellenabledp==1, this is because
399 shell escapes are restricted and CMD is not allowed.
400 1 if shell escapes are not restricted, hence any command is allowed.
401 2 if shell escapes are restricted and CMD is allowed. */
403 int runsystem(const char *cmd)
405 int allow = 0;
406 char *safecmd = NULL;
407 char *cmdname = NULL;
409 if (shellenabledp <= 0) {
410 return 0;
413 /* If restrictedshell == 0, any command is allowed. */
414 if (restrictedshell == 0)
415 allow = 1;
416 else
417 allow = shell_cmd_is_allowed(cmd, &safecmd, &cmdname);
419 if (allow == 1)
420 (void) system(cmd);
421 else if (allow == 2)
422 (void) system(safecmd);
424 if (safecmd)
425 free(safecmd);
426 if (cmdname)
427 free(cmdname);
429 return allow;
432 #endif
435 /* What we were invoked as and with. */
436 char **argv;
437 int argc;
439 /* The C version of what might wind up in |TEX_format_default|. */
440 string dump_name;
442 /* The C version of the jobname, if given. */
443 const_string c_job_name;
445 const char *luatex_banner;
447 #ifdef _MSC_VER
448 /* Invalid parameter handler */
449 static void myInvalidParameterHandler(const wchar_t * expression,
450 const wchar_t * function,
451 const wchar_t * file,
452 unsigned int line,
453 uintptr_t pReserved)
456 printf(L"Invalid parameter detected in function %s."
457 L" File: %s Line: %d\n", function, file, line);
458 printf(L"Expression: %s\n", expression);
461 I return silently to avoid an exit with the error 0xc0000417
462 (invalid parameter) when we use non-embedded fonts in luatex-ja,
463 which works without any problem on Unix systems.
464 I hope it is not dangerous.
466 return;
468 #endif
470 /* The entry point: set up for reading the command line, which will
471 happen in `topenin', then call the main body. */
474 #if defined(DLLPROC)
475 DLLPROC (int ac, string *av)
476 #else
477 main (int ac, string *av)
478 #endif
480 # ifdef __EMX__
481 _wildcard(&ac, &av);
482 _response(&ac, &av);
483 # endif
485 # ifdef WIN32
486 # ifdef _MSC_VER
487 _set_invalid_parameter_handler(myInvalidParameterHandler);
488 # endif
489 av[0] = kpse_program_basename (av[0]);
490 _setmaxstdio(2048);
491 SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
492 setmode(fileno(stdin), _O_BINARY);
493 # endif
495 lua_initialize(ac, av);
497 # ifdef WIN32
498 if (ac > 1) {
499 char *pp;
500 if ((strlen(av[ac-1]) > 2) &&
501 isalpha(av[ac-1][0]) &&
502 (av[ac-1][1] == ':') &&
503 (av[ac-1][2] == '\\')) {
504 for (pp=av[ac-1]+2; *pp; pp++) {
505 if (IS_KANJI(pp)) {
506 pp++;
507 continue;
509 if (*pp == '\\')
510 *pp = '/';
514 # endif
516 /* Call the real main program. */
517 main_body();
519 return EXIT_SUCCESS;
523 /* This is supposed to ``open the terminal for input'', but what we
524 really do is copy command line arguments into TeX's or Metafont's
525 buffer, so they can handle them. If nothing is available, or we've
526 been called already (and hence, argc==0), we return with
527 `last=first'. */
529 void topenin(void)
531 int i;
534 buffer[first] = 0; /* In case there are no arguments. */
536 if (optind < argc) { /* We have command line arguments. */
537 int k = first;
538 for (i = optind; i < argc; i++) {
539 char *ptr = &(argv[i][0]);
540 /* Don't use strcat, since in Aleph the buffer elements aren't
541 single bytes. */
542 while (*ptr) {
543 buffer[k++] = (packed_ASCII_code) * (ptr++);
545 buffer[k++] = ' ';
547 argc = 0; /* Don't do this again. */
548 buffer[k] = 0;
551 /* Find the end of the buffer. */
552 for (last = first; buffer[last]; ++last);
554 /* Make `last' be one past the last non-blank character in `buffer'. */
555 /* ??? The test for '\r' should not be necessary. */
556 for (--last; last >= first
557 && ISBLANK(buffer[last]) && buffer[last] != '\r'; --last);
558 last++;
560 /* One more time, this time converting to TeX's internal character
561 representation. */
564 /* IPC for TeX. By Tom Rokicki for the NeXT; it makes TeX ship out the
565 DVI file in a pipe to TeXView so that the output can be displayed
566 incrementally. Shamim Mohamed adapted it for Web2c. */
567 #if defined (TeX) && defined (IPC)
569 #ifdef WIN32
570 #undef _WINSOCKAPI_
571 #include <winsock2.h>
572 #else
573 #include <sys/socket.h>
574 #include <fcntl.h>
575 #ifndef O_NONBLOCK /* POSIX */
576 #ifdef O_NDELAY /* BSD */
577 #define O_NONBLOCK O_NDELAY
578 #elif defined(O_FNDELAY) /* NeXT */
579 #define O_NONBLOCK O_FNDELAY
580 #else
581 what the fcntl? cannot implement IPC without equivalent for O_NONBLOCK.
582 #endif
583 #endif /* no O_NONBLOCK */
584 #endif /* !WIN32 */
586 #ifdef WIN32
587 # define IPC_AF AF_INET
588 # ifndef IPC_LOCAL_HOST
589 # define IPC_LOCAL_HOST "127.0.0.1"
590 # define FIXED_PORT (unsigned short)4242
591 # endif
592 #else
593 # define IPC_AF AF_UNIX
594 # ifndef IPC_PIPE_NAME /* $HOME is prepended to this. */
595 # define IPC_PIPE_NAME "/.TeXview_Pipe"
596 # endif
597 #endif
598 #ifndef IPC_SERVER_CMD /* Command to run to start the server. */
599 # ifdef WIN32
600 # define IPC_SERVER_CMD "texview.exe"
601 # else
602 # define IPC_SERVER_CMD "open `which TeXview`"
603 # endif
604 #endif
606 struct msg
608 int namelength; /* length of auxiliary data */
609 int eof; /* new eof for dvi file */
610 #if 0 /* see usage of struct msg below */
611 char more_data[0]; /* where the rest of the stuff goes */
612 #endif
615 static struct sockaddr *ipc_addr;
616 static int ipc_addr_len;
618 static int
619 ipc_make_name (void)
621 if (ipc_addr_len == 0) {
622 #ifdef WIN32
623 unsigned long remote_addr = inet_addr(IPC_LOCAL_HOST);
624 if (remote_addr != INADDR_NONE) {
625 struct sockaddr_in *ipc_sin_addr = xmalloc (sizeof (struct sockaddr_in));
626 ipc_sin_addr->sin_family = AF_INET;
627 ipc_sin_addr->sin_addr.s_addr = remote_addr;
628 ipc_sin_addr->sin_port = htons (FIXED_PORT);
629 ipc_addr = ((struct sockaddr *) ipc_sin_addr);
630 ipc_addr_len = sizeof(struct sockaddr_in);
632 #else
633 string s = getenv ("HOME");
634 if (s) {
635 char *ipc_name;
636 ipc_addr = xmalloc (strlen (s) + 40);
637 ipc_addr->sa_family = 0;
638 ipc_name = ipc_addr->sa_data;
639 strcpy (ipc_name, s);
640 strcat (ipc_name, IPC_PIPE_NAME);
641 ipc_addr_len = strlen (ipc_name) + 3;
643 #endif
645 return ipc_addr_len;
648 static int sock = -1;
650 #ifdef WIN32
651 # define CLOSE_SOCKET(s) closesocket (s); WSACleanup ()
652 #else
653 # define CLOSE_SOCKET(s) close (s)
654 #endif
656 static int
657 ipc_is_open (void)
659 return sock != -1;
662 static void
663 ipc_open_out (void) {
664 #ifdef WIN32
665 struct WSAData wsaData;
666 int nCode;
667 unsigned long mode = 1;
668 #endif
669 #ifdef IPC_DEBUG
670 fputs ("tex: Opening socket for IPC output ...\n", stderr);
671 #endif
672 if (sock != -1) {
673 return;
676 #ifdef WIN32
677 if ((nCode = WSAStartup(MAKEWORD(1, 1), &wsaData)) != 0) {
678 fprintf(stderr,"WSAStartup() returned error code %d.\n", nCode);
679 return;
681 #endif
683 if (ipc_make_name () <= 0)
684 return;
686 sock = socket (IPC_AF, SOCK_STREAM, 0);
687 #ifdef IPC_DEBUG
688 if(sock != -1)
689 fprintf(stderr, "tex: Socket handle is %d\n", sock);
690 else
691 fprintf(stderr, "tex: Socket is invalid.\n");
692 #endif
694 if (sock != -1) {
695 if (connect (sock, ipc_addr, ipc_addr_len) != 0 ||
696 #ifdef WIN32
697 ioctlsocket (sock, FIONBIO, &mode) < 0
698 #else
699 fcntl (sock, F_SETFL, O_NONBLOCK) < 0
700 #endif
702 CLOSE_SOCKET (sock);
703 sock = -1;
704 #ifdef IPC_DEBUG
705 fputs ("tex: IPC socket cannot be connected.\n", stderr);
706 fputs ("tex: Socket is closed.\n", stderr);
707 #endif
708 return;
710 #ifdef IPC_DEBUG
711 fputs ("tex: Successfully opened IPC socket.\n", stderr);
712 #endif
716 static void
717 ipc_close_out (void)
719 #ifdef IPC_DEBUG
720 fputs ("tex: Closing output socket ...\n", stderr);
721 #endif
722 if (ipc_is_open ()) {
723 CLOSE_SOCKET (sock);
724 sock = -1;
728 static void
729 ipc_snd (int n, int is_eof, char *data)
731 struct
733 struct msg msg;
734 char more_data[1024];
735 } ourmsg;
737 if (!ipc_is_open ()) {
738 return;
741 #ifdef IPC_DEBUG
742 fprintf(stderr, "%d\t%d\n", ourmsg.msg.namelength, ourmsg.msg.eof);
743 fputs ("tex: Sending message to socket ...\n", stderr);
744 #endif
745 ourmsg.msg.namelength = n;
746 ourmsg.msg.eof = is_eof;
747 if (n) {
748 strcpy (ourmsg.more_data, data);
750 n += sizeof (struct msg);
751 #ifdef IPC_DEBUG
752 fprintf(stderr, "%d\t%d\n", ourmsg.msg.namelength, ourmsg.msg.eof);
753 fputs ("tex: Writing to socket...\n", stderr);
754 #endif
755 #if defined(WIN32)
756 if (send (sock, (char *)&ourmsg, n, 0) != n) {
757 #else
758 if (write (sock, &ourmsg, n) != n) {
759 #endif
760 ipc_close_out ();
762 #ifdef IPC_DEBUG
763 fputs ("tex: IPC message sent.\n", stderr);
764 #endif
767 /* This routine notifies the server if there is an eof, or the filename
768 if a new DVI file is starting. This is the routine called by TeX.
769 Aleph defines str_start(#) as str_start_ar[# - too_big_char], with
770 too_big_char = biggest_char + 1 = 65536 (omstr.ch). */
772 void
773 ipcpage (int is_eof)
775 static boolean begun = false;
776 unsigned len = 0;
777 string p = NULL;
779 if (!begun) {
780 string name; /* Just the filename. */
781 string cwd = xgetcwd ();
783 ipc_open_out ();
785 /* Have to pass whole filename to the other end, since it may have
786 been started up and running as a daemon, e.g., as with the NeXT
787 preview program. */
788 name = static_pdf->file_name;
789 p = concat3 (cwd, DIR_SEP_STRING, name);
790 free (cwd);
791 free (name);
793 #if defined (WIN32)
794 { char *q;
795 for (q = p; *q; q++) {
796 if (*q == '\\')
797 *q = '/';
798 else if (IS_KANJI(q))
799 q++;
802 #endif
803 len = strlen(p);
804 begun = true;
806 ipc_snd (len, is_eof, p);
808 if (p)
809 free (p);
811 #endif /* TeX && IPC */
813 /* Normalize quoting of filename -- that is, only quote if there is a space,
814 and always use the quote-name-quote style. */
815 string normalize_quotes(const_string name, const_string mesg)
817 boolean quoted = false;
818 boolean must_quote = (strchr(name, ' ') != NULL);
819 /* Leave room for quotes and NUL. */
820 string ret = (string) xmalloc((unsigned) strlen(name) + 3);
821 string p;
822 const_string q;
823 p = ret;
824 if (must_quote)
825 *p++ = '"';
826 for (q = name; *q; q++) {
827 if (*q == '"')
828 quoted = !quoted;
829 else
830 *p++ = *q;
832 if (must_quote)
833 *p++ = '"';
834 *p = '\0';
835 if (quoted) {
836 fprintf(stderr, "! Unbalanced quotes in %s %s\n", mesg, name);
837 uexit(1);
839 return ret;
843 /* All our interrupt handler has to do is set TeX's or Metafont's global
844 variable `interrupt'; then they will do everything needed. */
845 #ifdef WIN32
846 /* Win32 doesn't set SIGINT ... */
847 static BOOL WINAPI catch_interrupt(DWORD arg)
849 switch (arg) {
850 case CTRL_C_EVENT:
851 case CTRL_BREAK_EVENT:
852 interrupt = 1;
853 return TRUE;
854 default:
855 /* No need to set interrupt as we are exiting anyway */
856 return FALSE;
859 #else /* not WIN32 */
860 static RETSIGTYPE catch_interrupt(int arg)
862 (void) arg;
863 interrupt = 1;
864 # ifdef OS2
865 (void) signal(SIGINT, SIG_ACK);
866 # else
867 (void) signal(SIGINT, catch_interrupt);
868 # endif /* not OS2 */
870 #endif /* not WIN32 */
872 /* Besides getting the date and time here, we also set up the interrupt
873 handler, for no particularly good reason. It's just that since the
874 `fix_date_and_time' routine is called early on (section 1337 in TeX,
875 ``Get the first line of input and prepare to start''), this is as
876 good a place as any. */
878 void get_date_and_time(int *minutes, int *day, int *month, int *year)
880 time_t myclock = time((time_t *) 0);
881 struct tm *tmptr = localtime(&myclock);
883 *minutes = tmptr->tm_hour * 60 + tmptr->tm_min;
884 *day = tmptr->tm_mday;
885 *month = tmptr->tm_mon + 1;
886 *year = tmptr->tm_year + 1900;
889 #ifdef SA_INTERRUPT
890 /* Under SunOS 4.1.x, the default action after return from the
891 signal handler is to restart the I/O if nothing has been
892 transferred. The effect on TeX is that interrupts are ignored if
893 we are waiting for input. The following tells the system to
894 return EINTR from read() in this case. From ken@cs.toronto.edu. */
896 struct sigaction a, oa;
898 a.sa_handler = catch_interrupt;
899 sigemptyset(&a.sa_mask);
900 sigaddset(&a.sa_mask, SIGINT);
901 a.sa_flags = SA_INTERRUPT;
902 sigaction(SIGINT, &a, &oa);
903 if (oa.sa_handler != SIG_DFL)
904 sigaction(SIGINT, &oa, (struct sigaction *) 0);
905 #else /* no SA_INTERRUPT */
906 # ifdef WIN32
907 SetConsoleCtrlHandler(catch_interrupt, TRUE);
908 # else /* not WIN32 */
909 RETSIGTYPE(*old_handler) (int);
911 old_handler = signal(SIGINT, catch_interrupt);
912 if (old_handler != SIG_DFL)
913 signal(SIGINT, old_handler);
914 # endif /* not WIN32 */
915 #endif /* no SA_INTERRUPT */
920 Getting a high resolution time.
922 void get_seconds_and_micros(int *seconds, int *micros)
924 #if defined (HAVE_GETTIMEOFDAY)
925 struct timeval tv;
926 gettimeofday(&tv, NULL);
927 *seconds = (int)tv.tv_sec;
928 *micros = (int)tv.tv_usec;
929 #elif defined (HAVE_FTIME)
930 struct timeb tb;
931 ftime(&tb);
932 *seconds = tb.time;
933 *micros = tb.millitm * 1000;
934 #else
935 time_t myclock = time((time_t *) NULL);
936 *seconds = (int) myclock;
937 *micros = 0;
938 #endif
942 Generating a better seed numbers
944 int getrandomseed(void)
946 #if defined (HAVE_GETTIMEOFDAY)
947 struct timeval tv;
948 gettimeofday(&tv, NULL);
949 return (int)(tv.tv_usec + 1000000 * tv.tv_usec);
950 #elif defined (HAVE_FTIME)
951 struct timeb tb;
952 ftime(&tb);
953 return (tb.millitm + 1000 * tb.time);
954 #else
955 time_t myclock = time((time_t *) NULL);
956 struct tm *tmptr = localtime(&myclock);
957 return (tmptr->tm_sec + 60 * (tmptr->tm_min + 60 * tmptr->tm_hour));
958 #endif
961 /* Read a line of input as efficiently as possible while still looking
962 like Pascal. We set `last' to `first' and return `false' if we get
963 to eof. Otherwise, we return `true' and set last = first +
964 length(line except trailing whitespace). */
966 boolean input_line(FILE * f)
968 int i = EOF;
970 #ifdef WIN32
971 if (f != Poptr && fileno (f) != fileno (stdin)) {
972 long position = ftell (f);
974 if (position == 0L) { /* Detect and skip Byte order marks. */
975 int k1 = getc (f);
977 if (k1 != 0xff && k1 != 0xfe && k1 != 0xef)
978 rewind (f);
979 else {
980 int k2 = getc (f);
982 if (k2 != 0xff && k2 != 0xfe && k2 != 0xbb)
983 rewind (f);
984 else if ((k1 == 0xff && k2 == 0xfe) || /* UTF-16(LE) */
985 (k1 == 0xfe && k2 == 0xff)) /* UTF-16(BE) */
987 else {
988 int k3 = getc (f);
990 if (k1 == 0xef && k2 == 0xbb && k3 == 0xbf) /* UTF-8 */
992 else
993 rewind (f);
998 #endif
999 /* Recognize either LF or CR as a line terminator. */
1000 last = first;
1001 while (last < buf_size && (i = getc(f)) != EOF && i != '\n' && i != '\r')
1002 buffer[last++] = (packed_ASCII_code) i;
1004 if (i == EOF && errno != EINTR && last == first)
1005 return false;
1007 /* We didn't get the whole line because our buffer was too small. */
1008 if (i != EOF && i != '\n' && i != '\r') {
1009 fprintf(stderr, "! Unable to read an entire line---bufsize=%u.\n",
1010 (unsigned) buf_size);
1011 fputs("Please increase buf_size in texmf.cnf.\n", stderr);
1012 uexit(1);
1015 buffer[last] = ' ';
1016 if (last >= max_buf_stack)
1017 max_buf_stack = last;
1019 /* If next char is LF of a CRLF, read it. */
1020 if (i == '\r') {
1021 while ((i = getc(f)) == EOF && errno == EINTR);
1022 if (i != '\n')
1023 ungetc(i, f);
1026 /* Trim trailing whitespace. */
1027 while (last > first && ISBLANK(buffer[last - 1]))
1028 --last;
1030 /* Don't bother using xord if we don't need to. */
1032 return true;
1038 /* Get the job name to be used, which may have been set from the
1039 command line. */
1040 str_number getjobname(str_number name)
1042 str_number ret = name;
1043 if (c_job_name != NULL)
1044 ret = maketexstring(c_job_name);
1045 return ret;