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
20 /* openinout.c: open input and output files. */
27 extern char * dvi_directory;
28 extern char * log_directory;
29 extern char * aux_directory;
30 extern char * fmt_directory;
31 extern char * pdf_directory;
34 #define PATH_SEP_STRING "/"
36 #define BUILDNAMEDIRECT
38 extern int shorten_file_name;
40 #ifdef FUNNY_CORE_DUMP
41 extern void funny_core_dump(void);
45 #ifdef BUILDNAMEDIRECT
46 char * xconcat (char *buffer, char *s1, char *s2)
53 memmove(buffer + n1, buffer, n2 + 1);
54 strncpy(buffer, s1, n1);
59 strcat(buffer + n1, s2);
64 char * xconcat3 (char *buffer, char *s1, char *s2, char *s3)
72 memmove(buffer + n1 + n2, buffer, n3 + 1);
73 strncpy(buffer, s1, n1);
74 strncpy(buffer + n1, s2, n2);
79 strcat(buffer + n1, s2);
80 strcat(buffer + n1 + n2, s3);
87 // assumes path does not end in PATH_SEP
88 void patch_in_path (unsigned char *buffer, unsigned char *name, unsigned char *path)
91 strcpy((char *) buffer, (char *) name);
93 xconcat3((char *) buffer, (char *) path, PATH_SEP_STRING, (char *) name);
96 int qualified (unsigned char * name)
98 if (strchr((char *) name, PATH_SEP) != NULL ||
99 strchr((char *) name, '\\') != NULL ||
100 strchr((char *) name, ':') != NULL)
107 (ii) name not qualified
110 int prepend_path_if (unsigned char *buffer, unsigned char *name, char *ext, unsigned char *path)
121 if (strstr((char *) name, ext) == NULL)
124 patch_in_path(buffer, name, path);
129 // Following works on null-terminated strings
130 void check_short_name (unsigned char *s)
132 unsigned char *star, *sdot;
135 if ((star = (unsigned char *) strrchr((char *) s, '\\')) != NULL)
137 else if ((star = (unsigned char *) strrchr((char *) s, '/')) != NULL)
139 else if ((star = (unsigned char *) strchr((char *) s, ':')) != NULL)
144 if ((sdot = (unsigned char *) strchr((char *) star, '.')) != NULL)
147 n = strlen((char *) star);
150 strcpy((char *) star + 8, (char *) star + n);
152 if ((sdot = (unsigned char *) strchr((char *) star, '.')) != NULL)
156 n = strlen((char *) star);
163 /* Following works on both null-terminated names */
164 /* reconvert 254 to '~' in file name 95/Sep/26 */
165 /* reconvert 255 to ' ' in file name 95/Sep/26 */
166 /* we do this in tex3.c start_input() -> scan_file_name() now 95/Sep/26 */
167 /* kpathsea/tilde.c */
168 void retwiddle (unsigned char *s)
172 if (*s == (unsigned char) pseudo_tilde)
174 else if (*s == (unsigned char) pseudo_space)
180 /* in lib/openclose.c */
181 boolean open_input (FILE **f, path_constant_type path_index, char *fopen_mode)
183 boolean openable = false;
184 char * file_name = NULL;
186 #if defined (FUNNY_CORE_DUMP) && !defined (BibTeX)
187 if (path_index == TEXINPUTPATH &&
188 strncmp(name_of_file + 1, "HackyInputFileNameForCoreDump.tex", 33) == 0)
194 if (strcmp(fopen_mode, "r") == 0)
198 name_of_file[name_length + 1] = '\0';
200 /* reinsert '~' and ' ' in file names - 95/June/5 */
201 /* done late to prevent problems with null_terminate / space_terminate */
202 if (pseudo_tilde != 0 || pseudo_space != 0)
203 retwiddle(name_of_file + 1);
205 if (shorten_file_name)
206 check_short_name(name_of_file + 1);
210 sprintf(log_line, " Open `%s' for input ", name_of_file + 1);
211 show_line(log_line, 0);
217 file_name = kpse_find_file((const_string) name_of_file + 1, kpse_tex_format, 0);
221 file_name = kpse_find_file((const_string) name_of_file + 1, kpse_fmt_format, 0);
225 file_name = kpse_find_file((const_string) name_of_file + 1, kpse_tfm_format, 0);
229 if (file_name != NULL)
231 strcpy ((char *) name_of_file + 1, file_name);
232 *f = xfopen((char *) file_name, fopen_mode);
235 if (name_of_file[1] == '.' && (name_of_file[2] == PATH_SEP || name_of_file[2] == '\\'))
237 if (name_of_file[1] == '.' && name_of_file[2] == PATH_SEP)
242 while (name_of_file[i + 2] != '\0')
244 name_of_file[i] = name_of_file[i + 2];
248 name_of_file[i] = '\0';
252 name_length = strlen((char *) name_of_file + 1);
254 if (path_index == TFMFILEPATH)
259 if (strstr((char *) name_of_file + 1, ".fmt") != NULL)
261 if (format_file == NULL)
263 format_file = xstrdup((char *) name_of_file + 1);
267 gz_fmt_file = gzdopen(fileno(*f), "rb9");
270 else if (strstr((char *)name_of_file + 1, ".tfm") != NULL)
272 if (show_tfm_flag && log_opened)
275 n = strlen((char *) name_of_file + 1);
277 if (file_offset + n > max_print_line)
279 putc('\n', log_file);
285 fprintf(log_file, "(%s)", name_of_file + 1);
286 file_offset += n + 3;
289 /* code added 98/Sep/29 to catch first file input */
290 /* is there a problem if this file bombs ? */
291 else if (source_direct == NULL)
295 source_direct = xstrdup((char *) name_of_file + 1);
299 sprintf(log_line, "Methinks the source %s is `%s'\n", "file", source_direct);
300 show_line(log_line, 0);
303 if ((s = strrchr(source_direct, '/')) == NULL)
304 *source_direct = '\0';
310 sprintf(log_line, "Methinks the source %s is `%s'\n", "directory", source_direct);
311 show_line(log_line, 0);
319 unsigned temp_length = strlen((char *) name_of_file + 1);
320 name_of_file[temp_length + 1] = ' ';
326 /* At least check for I/O error (such as disk full) when closing */
327 /* Would be better to check while writing - but this is better than nothing */
328 /* This is used for both input and output files, but never mind ... */
330 /* now a_close returns -1 on error --- which could be used by caller */
331 /* probably want to ignore on input files ... */
333 // check_fclose not used by anything
334 int check_fclose (FILE * f)
339 if (ferror(f) || fclose (f))
341 perrormod("\n! I/O Error");
348 // open_output moved down here to avoid potential pragma problem
349 boolean open_output (FILE **f, char *fopen_mode)
351 unsigned temp_length;
353 name_of_file[name_length + 1] = '\0';
355 if (pseudo_tilde != 0 || pseudo_space != 0)
357 retwiddle(name_of_file + 1);
360 /* 8 + 3 file names on Windows NT 95/Feb/20 */
361 if (shorten_file_name)
363 check_short_name(name_of_file + 1);
366 if (prepend_path_if(name_of_file + 1, name_of_file + 1, ".dvi", (unsigned char *) dvi_directory) ||
367 prepend_path_if(name_of_file + 1, name_of_file + 1, ".log", (unsigned char *) log_directory) ||
368 prepend_path_if(name_of_file + 1, name_of_file + 1, ".aux", (unsigned char *) aux_directory) ||
369 prepend_path_if(name_of_file + 1, name_of_file + 1, ".fmt", (unsigned char *) fmt_directory) ||
370 prepend_path_if(name_of_file + 1, name_of_file + 1, ".pdf", (unsigned char *) pdf_directory))
373 printf("After prepend %s\n", name_of_file + 1);
377 printf(" Open `%s' for output ", name_of_file + 1);
379 *f = fopen((char *) name_of_file + 1, fopen_mode);
381 /* Can't open as given. Try the envvar. */
384 string temp_dir = kpse_var_value("TEXMFOUTPUT");
386 if (temp_dir != NULL)
388 #ifdef BUILDNAMEDIRECT
389 unsigned char temp_name[file_name_size];
390 xconcat3((char *) temp_name, temp_dir, PATH_SEP_STRING, (char *) name_of_file + 1);
392 string temp_name = concat3 (temp_dir, PATH_SEP_STRING, name_of_file + 1);
396 unixify((char *) temp_name);
398 /* but we can assume this is opening here for *output* */
399 *f = fopen((char*)temp_name, fopen_mode);
400 /* If this succeeded, change name_of_file accordingly. */
402 strcpy((char*) name_of_file + 1, (char *) temp_name);
403 #ifndef BUILDNAMEDIRECT
410 if (strstr((char *) name_of_file + 1, ".fmt") != NULL)
411 gz_fmt_file = gzdopen(fileno(*f), "wb9");
414 if (strstr((char *) name_of_file + 1, ".dvi") != NULL)
416 if (qualified(name_of_file + 1))
420 (void) getcwd(log_line, sizeof(log_line));
421 strcat(log_line, PATH_SEP_STRING);
424 strcat(log_line, (char*) name_of_file + 1);
426 dvi_file_name = xstrdup(log_line);
428 else if (strstr((char *) name_of_file + 1, ".pdf") != NULL)
430 if (qualified(name_of_file + 1))
434 (void) getcwd(log_line, sizeof(log_line));
435 strcat(log_line, PATH_SEP_STRING);
438 strcat(log_line, (char*) name_of_file + 1);
440 pdf_file_name = xstrdup(log_line);
442 else if (strstr((char *)name_of_file + 1, ".log") != NULL)
444 if (qualified(name_of_file + 1))
448 (void) getcwd(log_line, sizeof(log_line));
449 strcat(log_line, PATH_SEP_STRING);
452 strcat(log_line, (char *) name_of_file + 1);
454 log_file_name = xstrdup(log_line);
457 temp_length = strlen ((char *)name_of_file + 1);
458 name_of_file[temp_length+1] = ' ';
461 name_length = temp_length;