OSDN Git Service

removed unused flag.
[putex/putex.git] / src / texsourc / openinou.c
1 /* Copyright 1992 Karl Berry
2    Copyright 2007 TeX Users Group
3    Copyright 2014 Clerk Ma
4
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.
9
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.
14
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
18    02110-1301 USA.  */
19
20 #define EXTERN extern
21
22 #include "texd.h"
23
24 #define PATH_SEP        '/'
25 #define PATH_SEP_STRING "/"
26
27 /* openinout.c: open input and output files. */
28
29 #define BUILDNAMEDIRECT         /* avoid malloc for string concat */
30  
31 extern char *unixify (char *);      /* in pathsrch.c bkph */
32
33 extern int shorten_file_name;       /* in local.c bkph */
34
35 #ifdef FUNNY_CORE_DUMP
36   extern void funny_core_dump();
37 #endif
38
39
40 #ifdef BUILDNAMEDIRECT
41 char * xconcat (char *buffer, char *s1, char *s2)
42 {
43   int n1 = strlen(s1);
44   int n2 = strlen(s2);
45
46   if (buffer == s2)
47   {
48     memmove (buffer + n1, buffer, n2 + 1);
49     strncpy (buffer, s1, n1);
50   }
51   else
52   {
53     strcpy(buffer, s1);
54     strcat(buffer + n1, s2);
55   }
56
57   return buffer;
58 }
59 char * xconcat3 (char *buffer, char *s1, char *s2, char *s3)
60 {
61   int n1 = strlen(s1);
62   int n2 = strlen(s2);
63   int n3 = strlen(s3);
64
65   if (buffer == s3)
66   {
67     memmove (buffer + n1 + n2, buffer, n3 + 1);
68     strncpy (buffer, s1, n1);
69     strncpy (buffer + n1, s2, n2);
70   }
71   else
72   {
73     strcpy(buffer, s1);
74     strcat(buffer + n1, s2);
75     strcat(buffer + n1 + n2, s3);
76   }
77
78   return buffer;
79 }
80 #endif
81
82 // separated out 1996/Jan/20 to make easier to read
83 // assumes path does not end in PATH_SEP
84 void patch_in_path (unsigned char *buffer, unsigned char *name, unsigned char *path)
85 {
86   if (*path == '\0')
87     strcpy((char *) buffer, (char *) name);
88   else
89     xconcat3((char *) buffer, (char *) path, PATH_SEP_STRING, (char *) name);
90 }
91
92 int qualified (unsigned char * name)
93 {
94   if (strchr((char *) name, PATH_SEP) != NULL ||
95       strchr((char *) name, '\\') != NULL ||
96       strchr((char *) name, ':') != NULL)
97     return 1;
98   else
99     return 0;
100 }
101 /* patch path if 
102     (i)   path not empty
103     (ii)  name not qualified
104     (iii) ext match
105 */
106 int prepend_path_if (unsigned char *buffer, unsigned char *name, char *ext, unsigned char *path)
107 {
108   if (path == NULL)
109     return 0;
110
111   if (*path == '\0')
112     return 0;
113
114   if (qualified(name))
115     return 0;
116
117   if (strstr((char *)name, ext) == NULL)
118     return 0;
119
120   patch_in_path(buffer, name, path);
121
122   return 1;
123 }
124
125
126 //  Following works on null-terminated strings
127 void check_short_name (unsigned char *s)
128 {
129   unsigned char *star, *sdot;
130   int n;
131
132   if ((star = (unsigned char *) strrchr((char *) s, '\\')) != NULL)
133     star++;
134   else if ((star = (unsigned char *) strrchr((char *) s, '/')) != NULL)
135     star++;
136   else if ((star = (unsigned char *) strchr((char *) s, ':')) != NULL)
137     star++;
138   else
139     star = s;
140
141   if ((sdot = (unsigned char *) strchr((char *) star, '.')) != NULL)
142     n = sdot - star;
143   else
144     n = strlen((char *) star);
145
146   if (n > 8)
147     strcpy((char *) star + 8, (char *) star + n);
148
149   if ((sdot = (unsigned char *) strchr((char *) star, '.')) != NULL)
150   {
151     star = sdot + 1;
152
153     n = strlen((char *) star);
154
155     if (n > 3)
156       *(star + 3) = '\0';
157   }
158 }
159
160 /* Following works on both null-terminated names */
161 /* reconvert 254 to '~' in file name 95/Sep/26 */
162 /* reconvert 255 to ' ' in file name 95/Sep/26 */
163 /* we do this in tex3.c start_input() -> scan_file_name() now 95/Sep/26 */
164 /* kpathsea/tilde.c */
165 void retwiddle (unsigned char *s)
166 {
167 /* assumes null terminated - 97/June/5 */
168 /*  while (*s != '\0' && *s != ' ') { */
169   while (*s != '\0')
170   {
171     if (*s == (unsigned char) pseudo_tilde)
172       *s = '~';
173     else if (*s == (unsigned char) pseudo_space)
174       *s = ' ';
175     s++;
176   }
177 }
178
179 /* in lib/openclose.c */
180 bool open_input (FILE **f, path_constant_type path_index, char *fopen_mode)
181 {
182   bool openable = false;
183   char * file_name = NULL;
184
185 #if defined (FUNNY_CORE_DUMP) && !defined (BibTeX)
186   if (path_index == TEXINPUTPATH &&
187     strncmp (name_of_file + 1, "HackyInputFileNameForCoreDump.tex", 33) == 0)
188     funny_core_dump();
189 #endif
190
191   if (return_flag)
192   {
193     if (strcmp(fopen_mode, "r") == 0)
194       fopen_mode = "rb";
195   }
196
197   name_of_file[name_length + 1] = '\0';
198
199 /* reinsert '~' and ' ' in file names -  95/June/5 */
200 /* done late to prevent problems with  null_terminate / space_terminate */  
201   if (pseudo_tilde != 0 || pseudo_space != 0)
202     retwiddle(name_of_file + 1);
203
204   if (shorten_file_name)
205   {
206     check_short_name(name_of_file + 1);
207   }
208   
209   if (open_trace_flag)
210   {
211     sprintf(log_line, " Open `%s' for input ", name_of_file + 1);
212     show_line(log_line, 0);
213   }
214
215   switch (path_index)
216   {
217     case TEXINPUTPATH:
218       file_name = kpse_find_file((const_string) name_of_file + 1, kpse_tex_format, 0);
219       break;
220
221     case TEXFORMATPATH:
222       file_name = kpse_find_file((const_string) name_of_file + 1, kpse_fmt_format, 0);
223       break;
224
225     case TFMFILEPATH:
226       file_name = kpse_find_file((const_string) name_of_file + 1, kpse_tfm_format, 0);
227       break;
228   }
229
230   if (file_name != NULL)
231   {
232     strcpy ((char *) name_of_file + 1, file_name);
233     *f = xfopen((char *) file_name, fopen_mode);
234
235 #ifdef _WIN32
236     if (name_of_file[1] == '.' && (name_of_file[2] == PATH_SEP || name_of_file[2] == '\\'))
237 #else
238     if (name_of_file[1] == '.' && name_of_file[2] == PATH_SEP)
239 #endif
240     {
241       unsigned i = 1;
242
243       while (name_of_file[i + 2] != '\0')
244       {
245         name_of_file[i] = name_of_file[i + 2];
246         i++;
247       }
248
249       name_of_file[i] = '\0';
250       name_length = i - 1;
251     }
252     else
253       name_length = strlen((char *) name_of_file + 1);
254       
255     if (path_index == TFMFILEPATH)
256     {
257       tfm_temp = getc (*f);
258     } 
259
260     if (strstr((char *) name_of_file + 1, ".fmt") != NULL)
261     {
262       if (format_file == NULL)
263       {
264         format_file = xstrdup((char *) name_of_file + 1);
265       }
266     }
267     else if (strstr((char *)name_of_file+1, ".tfm") != NULL)
268     {
269       if (show_tfm_flag && log_opened)
270       {
271         int n; 
272         n = strlen((char *) name_of_file + 1);
273
274         if (file_offset + n > max_print_line)
275         {
276           putc('\n', log_file);
277           file_offset = 0;
278         }
279         else
280           putc(' ', log_file);
281
282         fprintf(log_file, "(%s)", name_of_file + 1);
283         file_offset += n + 3;
284       }
285     }
286 /*    code added 98/Sep/29 to catch first file input */
287 /*    is there a problem if this file bombs ? */
288     else if (source_direct == NULL)
289     {
290       char *s;
291
292       source_direct = xstrdup((char *) name_of_file + 1);
293
294       if (trace_flag)
295       {
296         sprintf(log_line, "Methinks the source %s is `%s'\n", "file", source_direct);
297         show_line(log_line, 0);
298       }
299
300       if ((s = strrchr(source_direct, '/')) == NULL)
301         *source_direct = '\0';
302       else
303         *(s + 1) = '\0';
304
305       if (trace_flag)
306       {
307         sprintf(log_line, "Methinks the source %s is `%s'\n", "directory", source_direct);
308         show_line(log_line, 0);
309       }
310     }
311
312     openable = true;
313   }
314
315   {
316     unsigned temp_length = strlen((char *) name_of_file + 1);
317     name_of_file[temp_length + 1] = ' ';
318   }
319
320   return openable;
321 }
322
323 /* Call the external program PROGRAM, passing it `name_of_file'.  */
324 /* This nonsense probably only works for Unix anyway. bkph */
325 /* For one thing, MakeTeXTFM etc is more than 8 characters ! */
326
327 char *get_env_shroud (char *);    /* defined in texmf.c */
328
329 extern char * dvi_directory;
330 extern char * log_directory;
331 extern char * aux_directory;
332 extern char * fmt_directory;
333 extern char * pdf_directory;
334
335 /* At least check for I/O error (such as disk full) when closing */
336 /* Would be better to check while writing - but this is better than nothing */
337 /* This is used for both input and output files, but never mind ... */
338
339 /* now a_close returns -1 on error --- which could be used by caller */
340 /* probably want to ignore on input files ... */
341
342 extern void perrormod (char *s);       /* in local.c */
343
344 // check_fclose not used by anything
345 int check_fclose (FILE * f)
346 {
347   if (f == NULL)
348     return 0;      // sanity check
349
350   if (ferror(f) || fclose (f))
351   {
352     perrormod("\n! I/O Error");
353     uexit (1);
354   }
355
356   return 0;
357 }
358
359 // open_output moved down here to avoid potential pragma problem
360 bool open_output (FILE **f, char *fopen_mode)
361 {
362   unsigned temp_length;
363
364   name_of_file[name_length + 1] = '\0';
365
366   if (pseudo_tilde != 0 || pseudo_space !=  0)
367   {
368     retwiddle(name_of_file + 1);
369   }
370
371 /* 8 + 3 file names on Windows NT 95/Feb/20 */
372   if (shorten_file_name)
373   {
374     check_short_name(name_of_file + 1);
375   }
376
377   if (prepend_path_if (name_of_file + 1, name_of_file + 1, ".dvi", (unsigned char *) dvi_directory) ||
378       prepend_path_if (name_of_file + 1, name_of_file + 1, ".log", (unsigned char *) log_directory) ||
379       prepend_path_if (name_of_file + 1, name_of_file + 1, ".aux", (unsigned char *) aux_directory) ||
380       prepend_path_if (name_of_file + 1, name_of_file + 1, ".fmt", (unsigned char *) fmt_directory) ||
381       prepend_path_if (name_of_file + 1, name_of_file + 1, ".pdf", (unsigned char *) pdf_directory))
382   {
383     if (open_trace_flag)
384     {
385       sprintf(log_line, "After prepend %s\n", name_of_file + 1);
386       show_line(log_line, 0);
387     }
388   }
389
390   if (open_trace_flag)
391   {
392     sprintf(log_line, " Open `%s' for output ", name_of_file + 1);
393     show_line(log_line, 0);
394   }
395
396 /*  but we can assume this is opening here for *output* */
397   *f = fopen((char *) name_of_file + 1, fopen_mode);
398
399 /* Can't open as given.  Try the envvar.  */
400   if (*f == NULL)
401   {
402     string temp_dir = get_env_shroud ("UFYNGPVU");
403
404     if (temp_dir != NULL)
405     {
406 #ifdef BUILDNAMEDIRECT
407       unsigned char temp_name[PATH_MAX];
408       xconcat3((char *) temp_name, temp_dir, PATH_SEP_STRING, (char *) name_of_file + 1);
409 #else
410 /*    string temp_name = concat3 (temp_dir, "/", name_of_file + 1); */
411       string temp_name = concat3 (temp_dir, PATH_SEP_STRING, name_of_file + 1);
412 #endif
413
414       if (deslash)
415         unixify((char *) temp_name);
416
417 /*  but we can assume this is opening here for *output* */
418       *f = fopen((char*)temp_name, fopen_mode);
419 /*  If this succeeded, change name_of_file accordingly.  */
420       if (*f)
421         strcpy((char*) name_of_file + 1, (char *) temp_name);
422 #ifndef BUILDNAMEDIRECT
423       free (temp_name);
424 #endif
425     }
426   }
427
428   if (strstr((char *) name_of_file + 1, ".dvi") != NULL)
429   {
430     if (qualified(name_of_file + 1))
431       *log_line = '\0';
432     else
433     {
434       (void) getcwd(log_line, sizeof(log_line));
435       strcat(log_line, PATH_SEP_STRING);
436     }
437
438     strcat(log_line, (char*) name_of_file + 1);
439     unixify(log_line);
440     dvi_file_name = xstrdup(log_line);
441   }
442   else if (strstr((char *) name_of_file + 1, ".pdf") != NULL)
443   {
444     if (qualified(name_of_file + 1))
445       *log_line = '\0';
446     else
447     {
448       (void) getcwd(log_line, sizeof(log_line));
449       strcat(log_line, PATH_SEP_STRING);
450     }
451
452     strcat(log_line, (char*) name_of_file + 1);
453     unixify(log_line);
454     pdf_file_name = xstrdup(log_line);
455   }
456   else if (strstr((char *)name_of_file + 1, ".log") != NULL)
457   {
458     if (qualified(name_of_file + 1))
459       *log_line = '\0';
460     else
461     {
462       (void) getcwd(log_line, sizeof(log_line));
463       strcat(log_line, PATH_SEP_STRING);
464     }
465
466     strcat(log_line, (char *) name_of_file + 1);
467     unixify(log_line);
468     log_file_name = xstrdup(log_line);
469   }
470
471   temp_length = strlen ((char *)name_of_file + 1);
472   name_of_file[temp_length+1] = ' ';
473
474   if (*f)
475     name_length = temp_length;
476   
477   return *f != NULL;
478 }