1 /* Copyright 1992 Karl Berry
2 Copyright 2007 TeX Users Group
3 Copyright 2014 Clerk Ma
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 #define dump_ext_length 4
25 #define edit_value tex_edit_value
27 extern char * replacement[];
35 int main (int ac, char *av[])
37 int flag = 0, ret = 0;
42 if (main_init(gargc, gargv))
45 TEX_format_default = " plain.fmt";
46 format_default_length = strlen(TEX_format_default + 1);
50 ret = setjmp(jumpbuffer);
54 flag = main_program();
57 printf("EXITING at %s: flag = %d, ret = %d, jump_used = %d\n", "main", flag, ret, jump_used);
62 printf("EXITING at %s: flag = %d, ret = %d, jump_used = %d\n", "jump_out", flag, ret, jump_used);
66 flag = 1; /* do final clean up in local.c */
74 /* texk/web2c/lib/texmfmp.c */
81 if (gargc > optind && optind > 0)
83 for (i = optind; i < gargc; i++)
85 if (allow_quoted_names && strchr(gargv[i], ' ') != NULL)
87 (void) strcat ((char *) &buffer[first], "\"");
88 (void) strcat ((char *) &buffer[first], gargv[i]);
89 (void) strcat ((char *) &buffer[first], "\"");
92 (void) strcat ((char *) &buffer[first], gargv[i]);
94 (void) strcat ((char *) &buffer[first], " ");
100 /* Find the end of the buffer. */
101 for (last = first; buffer[last]; ++last)
104 for (--last; last >= first && ISBLANK (buffer[last]) && buffer[last] != '\r'; --last)
109 /* One more time, this time converting to TeX's internal character
110 representation. */ /* for command line input in this case */
113 for (i = first; i < last; i++)
114 buffer[i] = xord[buffer[i]];
118 static void catch_interrupt (int err)
121 (void) signal(SIGINT, SIG_IGN);
123 if (interrupt++ >= 3)
126 (void) signal(SIGINT, catch_interrupt);
129 void fix_date_and_time (void)
137 printf("The time is %lld\n", (long long)clock);
140 puts("Time not available!");
142 tmptr = localtime (&clock);
146 printf("Cannot convert time (%0lld)!\n", (long long)clock);
150 tex_time = 22 * 60 + 14;
154 tex_time = tmptr->tm_hour * 60 + tmptr->tm_min;
155 day = tmptr->tm_mday;
156 month = tmptr->tm_mon + 1;
157 year = tmptr->tm_year + 1900;
160 printf("%d-%d-%d %d:%d\n",
161 tmptr->tm_year + 1900,
170 if (signal(SIGINT, catch_interrupt) == SIG_ERR)
172 puts(" CTRL-C handler not installed");
176 void (*old_handler)();
178 old_handler = signal(SIGINT, catch_interrupt);
180 if (old_handler != SIG_DFL)
181 (void) signal(SIGINT, old_handler);
186 /* I/O for TeX and Metafont. */
187 void complain_line (FILE * output)
191 #ifdef ALLOCATEBUFFER
192 sprintf(log_line, "! Unable to read an entire line---buf_size=%d.\n", current_buf_size);
194 sprintf(log_line, "! Unable to read an entire line---buf_size=%d.\n", buf_size);
197 fputs(log_line, output);
198 puts(" (File may have a line termination problem.)");
201 void show_bad_line (FILE * output, int first, int last)
206 for (i = first; i <= last; i++)
210 if (show_in_hex && (ch > 127))
235 *s++ = (char) (ch + 64);
241 *s++ = (char) (ch - 64);
252 fputs(log_line, output); // log_file
255 boolean input_line_finish (void)
262 if (last >= max_buf_stack)
263 max_buf_stack = last;
267 i = buffer[last - 1];
269 if (i == ' ' || i == '\t')
275 if (restrict_to_ascii)
279 for (i = first; i <= last; i++)
283 if (ch > 126 || (ch < ' ' && ch != '\t' && ch != '\f' && ch != '\r' && ch != '\n'))
285 sprintf(log_line, "\n! non ASCII char (%d) in line: ", ch);
286 show_line(log_line, 1);
289 fprintf(log_file, "\n! non ASCII char (%d) in line: ", ch);
298 show_bad_line(errout, first, last);
301 show_bad_line(log_file, first, last);
307 for (i = first; i <= last; i++)
308 buffer[i] = xord[buffer[i]];
314 /* Read a line of input into buffer as efficiently as possible (ha ha)
315 while still looking like Pascal.
316 We set `last' to `first' and return `false' if we get to eof.
317 Otherwise, we return `true' and set last = first +
318 length(line except trailing whitespace). */
320 boolean input_line (FILE * f)
322 char * u; /* 1994/July/3 for key_replace */
326 /* following is new version with tab expansion and key replacement */
327 /* may want to expand out separately for speed 1994/July/3 */
328 /* different versions depending on return_flag / tabexpand / key_replace */
329 /* while (last < buf_size && (i = getc (f)) != EOF) */
330 #ifdef ALLOCATEBUFFER
333 while (last < buf_size)
340 if (i == EOF || i == '\n' || (i == '\r' && return_flag))
342 else if (i == '\t' && tab_step != 0)
344 buffer[last++] = (ASCII_code) ' ';
346 #ifdef ALLOCATEBUFFER
347 if (last >= current_buf_size)
349 buffer = realloc_buffer(increment_buf_size);
351 if (last >= current_buf_size)
356 #ifdef ALLOCATEBUFFER
357 while ((last - first) % tab_step != 0)
359 while (last < buf_size && (last - first) % tab_step != 0)
363 buffer[last++] = (ASCII_code) ' ';
365 #ifdef ALLOCATEBUFFER
366 if (last >= current_buf_size)
368 buffer = realloc_buffer(increment_buf_size);
370 if (last >= current_buf_size)
380 if (key_replace && (u = replacement[i]) != NULL)
382 #ifdef ALLOCATEBUFFER
385 while (last < buf_size && *u != '\0')
388 buffer[last++] = (ASCII_code) *u++;
390 #ifdef ALLOCATEBUFFER
391 if (last >= current_buf_size)
393 buffer = realloc_buffer(increment_buf_size);
395 if (last >= current_buf_size)
401 else /* normal case */
403 buffer[last++] = (ASCII_code) i;
405 #ifdef ALLOCATEBUFFER
406 if (last >= current_buf_size)
408 buffer = realloc_buffer(increment_buf_size);
410 if (last >= current_buf_size)
417 if (return_flag) /* let return terminate line as well as newline */
419 if (i == '\r') /* see whether return followed by newline */
421 i = getc (f); /* in which case throw away the newline */
428 /* else buffer[last-1] = (ASCII_code) i; */
432 // Turn Ctrl-Z at end of file into newline 2000 June 22
433 if (i == EOF && trimeof && buffer[last - 1] == 26)
438 if (i == EOF && last == first)
441 /* Didn't get the whole line because buffer was too small? */
442 /* This shouldn't happen anymore 99/Jan/23 */
443 if (i != EOF && i != '\n' && i != '\r')
445 complain_line(errout);
448 complain_line(log_file);
450 /* This may no longer be needed ... now that we grow it */
451 if (truncate_long_lines)
453 while (i != EOF && i != '\n' && i != '\r')
455 i = getc (f); // discard rest of line
458 last--; /* just in case */
461 uexit(EXIT_FAILURE); /* line too long */
464 return input_line_finish();
467 /* This string specifies what the `e' option does in response to an
470 static char * edit_value = "c:\\yandy\\WinEdt\\WinEdt.exe [Open('%s');SelLine(%d,7)]";
472 static int Isspace (char c)
474 return (c == ' ' || c == '\t');
477 void call_edit (ASCII_code * filename, pool_pointer fnstart, integer fnlength, integer linenumber)
479 char *temp, *command, *fullcmd;
484 char *fp, *ffp, *env, editorname[256], buffer[256];
492 /* Close any open input files, since we're going to kill the job. */
493 for (i = 1; i <= in_open; i++)
495 xfclose (input_file[i]->f, "inputfile");
497 xfclose (input_file[i], "inputfile");
500 /* Replace the default with the value of the appropriate environment
501 variable or config file value, if it's set. */
502 temp = kpse_var_value("TEXEDIT");
507 /* Construct the command string. The `11' is the maximum length an
509 command = (char *) xmalloc (strlen (edit_value) + fnlength + 11);
511 /* So we can construct it as we go. */
516 if ((isalpha(*edit_value) && *(edit_value + 1) == ':'
517 && IS_DIR_SEP (*(edit_value + 2)))
518 || (*edit_value == '"' && isalpha(*(edit_value + 1))
519 && *(edit_value + 2) == ':'
520 && IS_DIR_SEP (*(edit_value + 3)))
525 while ((c = *edit_value++) != 0)
529 switch (c = *edit_value++)
533 FATAL ("call_edit: `%%d' appears twice in editor command");
534 sprintf (temp, "%ld", (long int)linenumber);
535 while (*temp != '\0')
542 FATAL ("call_edit: `%%s' appears twice in editor command");
543 for (i = 0; i < fnlength; i++)
544 *temp++ = xchr[(filename[i])];
550 /* Back up to the null to force termination. */
567 if(Isspace(c) && cnt == 0)
574 else if(!Isspace(c) && cnt == 0)
592 if (dontchange == 0) {
593 if(editorname[0] == '.' ||
594 editorname[0] == '/' ||
595 editorname[0] == '\\') {
596 fprintf(stderr, "%s is not allowed to execute.\n", editorname);
599 env = (char *)getenv("PATH");
600 if(SearchPath(env, editorname, ".exe", 256, buffer, &ffp)==0) {
601 if(SearchPath(env, editorname, ".bat", 256, buffer, &ffp)==0) {
602 fprintf(stderr, "I cannot find %s in the PATH.\n", editorname);
606 fullcmd = (char *)xmalloc(strlen(buffer)+strlen(command)+5);
607 strcpy(fullcmd, "\"");
608 strcat(fullcmd, buffer);
609 strcat(fullcmd, "\"");
610 strcat(fullcmd, command);
615 /* Execute the command. */
616 if (system (fullcmd) != 0)
617 fprintf(stderr, "! Trouble executing `%s'.\n", command);
619 /* Quit, since we found an error. */
624 #if !defined (WORDS_BIGENDIAN) && !defined (NO_FMTBASE_SWAP)
626 /* We don't REALLY care what `endian' the machine is after all ! */
629 // char swapmarkerstring="ERROR: SWAPPING - NOT BigEndian AND NOT NoFmtBaseSwap";
632 /* This macro is always invoked as a statement. It assumes a variable
635 #define SWAP(x, y) temp = (x); (x) = (y); (y) = temp;
638 /* Make the NITEMS items pointed at by P, each of size SIZE, be the
639 opposite-endianness of whatever they are now. */
641 static int swap_items (char *p, int nitems, int size)
645 /* Since `size' does not change, we can write a while loop for each
646 case, and avoid testing `size' for each time. */
683 sprintf(log_line, "! I can't (un)dump a %d byte item.\n", size);
684 show_line(log_line, 1);
689 #endif /* not WORDS_BIGENDIAN and not NO_FMTBASE_SWAP */
692 int do_dump (char *p, int item_size, int nitems, gzFile out_file)
694 int do_dump (char *p, int item_size, int nitems, FILE *out_file)
697 #if !defined (WORDS_BIGENDIAN) && !defined (NO_FMTBASE_SWAP)
698 swap_items (p, nitems, item_size);
702 if (gzwrite(out_file, p, (item_size * nitems)) != (item_size * nitems))
704 if ((int) fwrite(p, item_size, nitems, out_file) != nitems)
707 printf("\n! Could not write %d %d-byte item%s.\n",
708 nitems, item_size, (nitems > 1) ? "s" : "");
712 /* Have to restore the old contents of memory, since some of it might get used again. */
713 #if !defined (WORDS_BIGENDIAN) && !defined (NO_FMTBASE_SWAP)
714 swap_items (p, nitems, item_size);
721 int do_undump (char *p, int item_size, int nitems, gzFile in_file)
723 int do_undump (char *p, int item_size, int nitems, FILE *in_file)
727 if (gzread(in_file, (void *) p, (unsigned int) (item_size * nitems)) <= 0)
729 if ((int) fread((void *) p, item_size, nitems, in_file) != nitems)
732 printf("\n! Could not read %d %d-byte item%s.\n",
733 nitems, item_size, (nitems > 1) ? "s" : "");
737 #if !defined (WORDS_BIGENDIAN) && !defined (NO_FMTBASE_SWAP)
738 swap_items (p, nitems, item_size);
744 #ifdef FUNNY_CORE_DUMP
746 void funny_core_dump (void)
751 switch (pid = vfork ())
758 (void) signal (SIGQUIT, SIG_DFL);
759 (void) kill (getpid (), SIGQUIT);
760 (void) write (2, "how did we get here?\n", 21);
764 while ((w = wait (&status)) != pid && w != -1)
767 if (status.w_coredump)
770 (void) write (2, "attempt to dump core failed\n", 28);
774 #endif /* FUNNY_CORE_DUMP */