OSDN Git Service

removed libmd5.
[putex/putex.git] / src / texsourc / openinou.c
1 /* Copyright 1992 Karl Berry\r
2    Copyright 2007 TeX Users Group\r
3    Copyright 2014 Clerk Ma\r
4 \r
5    This program is free software; you can redistribute it and/or modify\r
6    it under the terms of the GNU General Public License as published by\r
7    the Free Software Foundation; either version 2 of the License, or\r
8    (at your option) any later version.\r
9 \r
10    This program is distributed in the hope that it will be useful, but\r
11    WITHOUT ANY WARRANTY; without even the implied warranty of\r
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
13    General Public License for more details.\r
14 \r
15    You should have received a copy of the GNU General Public License\r
16    along with this program; if not, write to the Free Software\r
17    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\r
18    02110-1301 USA.  */\r
19 \r
20 #define EXTERN extern\r
21 \r
22 #include "yandytex.h"\r
23 #undef name\r
24 \r
25 #define PATH_SEP        '/'\r
26 #define PATH_SEP_STRING "/"\r
27 \r
28 #define BUILDNAMEDIRECT\r
29 \r
30 extern int shorten_file_name;\r
31 \r
32 #ifdef FUNNY_CORE_DUMP\r
33   extern void funny_core_dump(void);\r
34 #endif\r
35 \r
36 #ifdef BUILDNAMEDIRECT\r
37 char * xconcat (char * buffer, char * s1, char * s2)\r
38 {\r
39   int n1 = strlen(s1);\r
40   int n2 = strlen(s2);\r
41 \r
42   if (buffer == s2)\r
43   {\r
44     memmove(buffer + n1, buffer, n2 + 1);\r
45     strncpy(buffer, s1, n1);\r
46   }\r
47   else\r
48   {\r
49     strcpy(buffer, s1);\r
50     strcat(buffer + n1, s2);\r
51   }\r
52 \r
53   return buffer;\r
54 }\r
55 char * xconcat3 (char *buffer, char *s1, char *s2, char *s3)\r
56 {\r
57   int n1 = strlen(s1);\r
58   int n2 = strlen(s2);\r
59   int n3 = strlen(s3);\r
60 \r
61   if (buffer == s3)\r
62   {\r
63     memmove(buffer + n1 + n2, buffer, n3 + 1);\r
64     strncpy(buffer, s1, n1);\r
65     strncpy(buffer + n1, s2, n2);\r
66   }\r
67   else\r
68   {\r
69     strcpy(buffer, s1);\r
70     strcat(buffer + n1, s2);\r
71     strcat(buffer + n1 + n2, s3);\r
72   }\r
73 \r
74   return buffer;\r
75 }\r
76 #endif\r
77 \r
78 void patch_in_path (ASCII_code * buffer, ASCII_code *name, ASCII_code * path)\r
79 {\r
80   if (*path == '\0')\r
81     strcpy((char *) buffer, (char *) name);\r
82   else\r
83     xconcat3((char *) buffer, (char *) path, "/", (char *) name);\r
84 }\r
85 \r
86 int qualified (ASCII_code * name)\r
87 {\r
88   if (strchr((char *) name, '/') != NULL ||\r
89       strchr((char *) name, '\\') != NULL ||\r
90       strchr((char *) name, ':') != NULL)\r
91     return 1;\r
92   else\r
93     return 0;\r
94 }\r
95 /* patch path if \r
96     (i)   path not empty\r
97     (ii)  name not qualified\r
98     (iii) ext match\r
99 */\r
100 int prepend_path_if(ASCII_code * buffer, ASCII_code * name, const char * ext, char *path)\r
101 {\r
102   if (path == NULL)\r
103     return 0;\r
104 \r
105   if (*path == '\0')\r
106     return 0;\r
107 \r
108   if (qualified(name))\r
109     return 0;\r
110 \r
111   if (strstr((char *) name, ext) == NULL)\r
112     return 0;\r
113 \r
114   patch_in_path(buffer, name, (ASCII_code *)path);\r
115 \r
116   return 1;\r
117 }\r
118 \r
119 //  Following works on null-terminated strings\r
120 void check_short_name (unsigned char *s)\r
121 {\r
122   unsigned char *star, *sdot;\r
123   int n;\r
124 \r
125   if ((star = (unsigned char *) strrchr((char *) s, '\\')) != NULL)\r
126     star++;\r
127   else if ((star = (unsigned char *) strrchr((char *) s, '/')) != NULL)\r
128     star++;\r
129   else if ((star = (unsigned char *) strchr((char *) s, ':')) != NULL)\r
130     star++;\r
131   else\r
132     star = s;\r
133 \r
134   if ((sdot = (unsigned char *) strchr((char *) star, '.')) != NULL)\r
135     n = sdot - star;\r
136   else\r
137     n = strlen((char *) star);\r
138 \r
139   if (n > 8)\r
140     strcpy((char *) star + 8, (char *) star + n);\r
141 \r
142   if ((sdot = (unsigned char *) strchr((char *) star, '.')) != NULL)\r
143   {\r
144     star = sdot + 1;\r
145 \r
146     n = strlen((char *) star);\r
147 \r
148     if (n > 3)\r
149       *(star + 3) = '\0';\r
150   }\r
151 }\r
152 \r
153 /* Following works on both null-terminated names */\r
154 \r
155 void retwiddle (unsigned char *s)\r
156 {\r
157   while (*s != '\0')\r
158   {\r
159     if (*s == (unsigned char) pseudo_tilde)\r
160       *s = '~';\r
161     else if (*s == (unsigned char) pseudo_space)\r
162       *s = ' ';\r
163 \r
164     s++;\r
165   }\r
166 }\r
167 \r
168 boolean open_input (FILE ** f, kpse_file_format_type file_fmt, const char * fopen_mode)\r
169 {\r
170   boolean openable = false;\r
171   char * file_name = NULL;\r
172 \r
173 #if defined (FUNNY_CORE_DUMP) && !defined (BibTeX)\r
174   if (file_fmt == kpse_tex_format &&\r
175     strncmp(name_of_file + 1, "HackyInputFileNameForCoreDump.tex", 33) == 0)\r
176     funny_core_dump();\r
177 #endif\r
178 \r
179   if (return_flag)\r
180   {\r
181     if (strcmp(fopen_mode, "r") == 0)\r
182       fopen_mode = "rb";\r
183   }\r
184 \r
185   name_of_file[name_length + 1] = '\0';\r
186 \r
187   /* reinsert '~' and ' ' in file names */  \r
188   if (pseudo_tilde != 0 || pseudo_space != 0)\r
189     retwiddle(name_of_file + 1);\r
190 \r
191   if (shorten_file_name)\r
192     check_short_name(name_of_file + 1);\r
193   \r
194   if (open_trace_flag)\r
195     printf(" Open `%s' for input ", name_of_file + 1);\r
196 \r
197   file_name = kpse_find_file((const_string) name_of_file + 1, file_fmt, false);\r
198 \r
199   if (file_name != NULL)\r
200   {\r
201     strcpy ((char *) name_of_file + 1, file_name);\r
202     *f = xfopen((char *) file_name, fopen_mode);\r
203 \r
204 #ifdef _WIN32\r
205     if (name_of_file[1] == '.' && (name_of_file[2] == PATH_SEP || name_of_file[2] == '\\'))\r
206 #else\r
207     if (name_of_file[1] == '.' && name_of_file[2] == PATH_SEP)\r
208 #endif\r
209     {\r
210       unsigned i = 1;\r
211 \r
212       while (name_of_file[i + 2] != '\0')\r
213       {\r
214         name_of_file[i] = name_of_file[i + 2];\r
215         i++;\r
216       }\r
217 \r
218       name_of_file[i] = '\0';\r
219       name_length = i - 1;\r
220     }\r
221     else\r
222       name_length = strlen((char *) name_of_file + 1);\r
223       \r
224     if (file_fmt == kpse_tfm_format)\r
225     {\r
226       fbyte = getc(*f);\r
227     } \r
228 \r
229     if (strstr((char *) name_of_file + 1, ".fmt") != NULL)\r
230     {\r
231       if (format_file == NULL)\r
232         format_file = xstrdup((char *) name_of_file + 1);\r
233 \r
234 #ifdef COMPACTFORMAT\r
235       gz_fmt_file = gzdopen(fileno(*f), "rb9");\r
236 #endif\r
237     }\r
238     else if (strstr((char *) name_of_file + 1, ".tfm") != NULL)\r
239     {\r
240       if (show_tfm_flag && log_opened)\r
241       {\r
242         int n; \r
243         n = strlen((char *) name_of_file + 1);\r
244 \r
245         if (file_offset + n > max_print_line)\r
246         {\r
247           (void) putc('\n', log_file);\r
248           file_offset = 0;\r
249         }\r
250         else\r
251           (void) putc(' ', log_file);\r
252 \r
253         fprintf(log_file, "(%s)", name_of_file + 1);\r
254         file_offset += n + 3;\r
255       }\r
256     }\r
257     else if (source_direct == NULL)\r
258     {\r
259       char *s;\r
260 \r
261       source_direct = xstrdup((char *) name_of_file + 1);\r
262 \r
263       if (trace_flag)\r
264         printf("Methinks the source %s is `%s'\n", "file", source_direct);\r
265 \r
266       if ((s = strrchr(source_direct, '/')) == NULL)\r
267         *source_direct = '\0';\r
268       else\r
269         *(s + 1) = '\0';\r
270 \r
271       if (trace_flag)\r
272         printf("Methinks the source %s is `%s'\n", "directory", source_direct);\r
273     }\r
274 \r
275     openable = true;\r
276   }\r
277 \r
278   {\r
279     unsigned temp_length = strlen((char *) name_of_file + 1);\r
280     name_of_file[temp_length + 1] = ' ';\r
281   }\r
282 \r
283   return openable;\r
284 }\r
285 \r
286 /* At least check for I/O error (such as disk full) when closing */\r
287 /* Would be better to check while writing - but this is better than nothing */\r
288 /* This is used for both input and output files, but never mind ... */\r
289 \r
290 /* now a_close returns -1 on error --- which could be used by caller */\r
291 /* probably want to ignore on input files ... */\r
292 \r
293 // check_fclose not used by anything\r
294 int check_fclose (FILE * f)\r
295 {\r
296   if (f == NULL)\r
297     return 0;\r
298 \r
299   if (ferror(f) || fclose (f))\r
300   {\r
301     perrormod("\n! I/O Error");\r
302     uexit(EXIT_FAILURE);\r
303   }\r
304 \r
305   return 0;\r
306 }\r
307 \r
308 char * xstrdup_name (void)\r
309 {\r
310   if (qualified(name_of_file + 1))\r
311     *log_line = '\0';\r
312   else\r
313   {\r
314     (void) getcwd(log_line, sizeof(log_line));\r
315     strcat(log_line, PATH_SEP_STRING);\r
316   }\r
317 \r
318   strcat(log_line, (char *) name_of_file + 1);\r
319   unixify(log_line);\r
320   return xstrdup(log_line);\r
321 }\r
322 \r
323 boolean open_output (FILE ** f, const char * fopen_mode)\r
324 {\r
325   unsigned temp_length;\r
326 \r
327   name_of_file[name_length + 1] = '\0';\r
328 \r
329   if (pseudo_tilde != 0 || pseudo_space !=  0)\r
330     retwiddle(name_of_file + 1);\r
331 \r
332   /* 8 + 3 file names on Windows NT 95/Feb/20 */\r
333   if (shorten_file_name)\r
334     check_short_name(name_of_file + 1);\r
335 \r
336   if (prepend_path_if(name_of_file + 1, name_of_file + 1, ".dvi", dvi_directory) ||\r
337       prepend_path_if(name_of_file + 1, name_of_file + 1, ".log", log_directory) ||\r
338       prepend_path_if(name_of_file + 1, name_of_file + 1, ".aux", aux_directory) ||\r
339       prepend_path_if(name_of_file + 1, name_of_file + 1, ".fmt", fmt_directory) ||\r
340       prepend_path_if(name_of_file + 1, name_of_file + 1, ".pdf", pdf_directory))\r
341   {\r
342     if (open_trace_flag)\r
343       printf("After prepend %s\n", name_of_file + 1);\r
344   }\r
345 \r
346   if (open_trace_flag)\r
347     printf(" Open `%s' for output ", name_of_file + 1);\r
348 \r
349   *f = fopen((char *) name_of_file + 1, fopen_mode);\r
350 \r
351   if (*f == NULL)\r
352   {\r
353     string temp_dir = kpse_var_value("TEXMFOUTPUT");\r
354 \r
355     if (temp_dir != NULL)\r
356     {\r
357 #ifdef BUILDNAMEDIRECT\r
358       unsigned char temp_name[file_name_size];\r
359       xconcat3((char *) temp_name, temp_dir, PATH_SEP_STRING, (char *) name_of_file + 1);\r
360 #else\r
361       string temp_name = concat3(temp_dir, PATH_SEP_STRING, name_of_file + 1);\r
362 #endif\r
363 \r
364       if (deslash)\r
365         unixify((char *) temp_name);\r
366       \r
367       /* but we can assume this is opening here for *output* */\r
368       *f = fopen((char *) temp_name, fopen_mode);\r
369       /* If this succeeded, change name_of_file accordingly. */\r
370       if (*f)\r
371         strcpy((char *) name_of_file + 1, (char *) temp_name);\r
372 \r
373 #ifndef BUILDNAMEDIRECT\r
374       free (temp_name);\r
375 #endif\r
376     }\r
377   }\r
378 \r
379 #ifdef COMPACTFORMAT\r
380   if (strstr((char *) name_of_file + 1, ".fmt") != NULL)\r
381     gz_fmt_file = gzdopen(fileno(*f), "wb9");\r
382 #endif\r
383 \r
384   if (strstr((char *) name_of_file + 1, ".dvi") != NULL)\r
385     dvi_file_name = xstrdup_name();\r
386   else if (strstr((char *) name_of_file + 1, ".pdf") != NULL)\r
387     pdf_file_name = xstrdup_name();\r
388   else if (strstr((char *) name_of_file + 1, ".log") != NULL)\r
389     log_file_name = xstrdup_name();\r
390 \r
391   temp_length = strlen((char *) name_of_file + 1);\r
392   name_of_file[temp_length + 1] = ' ';\r
393 \r
394   if (*f)\r
395     name_length = temp_length;\r
396   \r
397   return (*f != NULL);\r
398 }