OSDN Git Service

binding with libharu.
[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 #ifdef _WINDOWS
21   #define NOCOMM
22   #define NOSOUND
23   #define NODRIVERS
24   #define STRICT
25   #pragma warning(disable:4115) // kill rpcasync.h complaint
26   #include <windows.h>
27   #define MYLIBAPI __declspec(dllexport)
28 #endif
29
30 #include "texwin.h"
31
32 #pragma warning(disable:4996)
33 #pragma warning(disable:4131)   // old style declarator
34 #pragma warning(disable:4135)   // conversion between different integral types 
35 #pragma warning(disable:4127)   // conditional expression is constant
36
37 #include <setjmp.h>
38
39 #include <direct.h>                                             /* for _getcwd() */
40
41 #define EXTERN extern
42
43 #include "texd.h"
44
45 #define PATH_SEP        '/'
46 #define PATH_SEP_STRING "/"
47
48 /* openinout.c: open input and output files.  These routines used by
49    TeX, Metafont, and BibTeX.  */
50
51 /* #include <sys\stat.h> */                             /* debugging 94/Mar/2 */
52 /* #include <sys\types.h> */                    /* debugging 94/Mar/2 */
53 /* #include <conio.h>   */                              /* for getch */
54
55 // #include "config.h"
56 // #include "c-namemx.h"
57 // #include "c-pathch.h"
58
59 #define BUILDNAMEDIRECT                                 /* avoid malloc for string concat */
60
61 bool test_read_access (unsigned char *, int);   /* in ourpaths.c - bkph */
62 /* bool test_read_access (char *, int, int); */ /* in ourpaths.c - bkph */
63
64 extern char *unixify (char *);                  /* in pathsrch.c bkph */
65
66 extern void try_and_open (char *);              /* in local.c bkph */
67
68 extern int shorten_file_name;                           /* in local.c bkph */
69
70 #ifdef FUNNY_CORE_DUMP
71 /* This is defined in ./texmf.c.  */
72 extern void funny_core_dump();
73 #endif /* FUNNY_CORE_DUMP */
74
75
76 \f
77 #ifdef MSDOS
78
79 #ifdef BUILDNAMEDIRECT
80 /* similar to concat, but AVOIDS using malloc, pass in place to put result */
81 char *xconcat (char *buffer, char *s1, char *s2)
82 {
83         int n1 = strlen(s1);
84         int n2 = strlen(s2);
85         if (buffer == s2) {                     /* treat special case of overlap */
86                 memmove (buffer + n1, buffer, n2 + 1); /* trailing null ! */
87                 strncpy (buffer, s1, n1);
88         }
89         else {
90                 strcpy(buffer, s1);
91                 strcat(buffer + n1, s2);
92         }
93         return buffer;
94 }
95 /* similar to concat3, but avoids using malloc, pass in place to put result */
96 char *xconcat3 (char *buffer, char *s1, char *s2, char *s3)
97 {
98         int n1 = strlen(s1);
99         int n2 = strlen(s2);
100         int n3 = strlen(s3);
101         if (buffer == s3) {                     /* treat special case of overlap */
102                 memmove (buffer + n1 + n2, buffer, n3 + 1); /* trailing null ! */
103                 strncpy (buffer, s1, n1);
104                 strncpy (buffer + n1, s2, n2);
105         }
106         else {
107                 strcpy(buffer, s1);
108                 strcat(buffer + n1, s2);
109                 strcat(buffer + n1 + n2, s3);
110         }
111         return buffer;
112 }
113 #endif /* end of BUILDNAMEDIRECT  */
114
115 #endif  /* end of ifdef MSDOS ??? */
116
117 #ifdef MSDOS
118 /* separated out 1996/Jan/20 to make easier to read */
119 /* assumes path does not end in PATH_SEP */
120 void patch_in_path (unsigned char *buffer, unsigned char *name, unsigned char *path)
121 {
122 #ifdef BUILDNAMEDIRECT
123         if (*path == '\0') strcpy((char *)buffer, (char *)name);
124         else xconcat3((char *)buffer, (char *)path, PATH_SEP_STRING, (char *)name);
125 #else
126         string temp_name;
127         temp_name = concat3 (path, PATH_SEP_STRING, name);
128         strcpy (buffer, temp_name);
129         free (temp_name);
130 #endif
131 }
132 int qualified (unsigned char *name)
133 {
134         if (strchr((char *)name, PATH_SEP) != NULL ||
135                 strchr((char *)name, '\\') != NULL ||
136                 strchr((char *)name, ':') != NULL)
137                 return 1;
138         else
139                 return 0;
140 }
141 /* patch path if (i) path not empty (ii) name not qualified (iii) ext match */
142 int prepend_path_if (unsigned char *buffer, unsigned char *name, char *ext, unsigned char *path)
143 {
144         if (path == NULL) return 0;
145         if (*path == '\0') return 0;
146         if (qualified(name)) return 0;
147         if (strstr((char *)name, ext) == NULL) return 0;
148         patch_in_path(buffer, name, path);
149         return 1;
150 }
151 #endif                  /* end of MSDOS */
152
153 /*  Following works on null-terminated strings */
154
155 /* void check_short_name(void) { */                             /* 1995/Feb/20 */
156 void check_short_name (unsigned char *s)
157 {                                       /* 1995/Sep/26 */
158         unsigned char *star, *sdot;
159         int n;
160
161 /*      if ((star = strrchr(name_of_file+1, '\\')) != NULL) star++;
162         else if ((star = strrchr(name_of_file+1, '/')) != NULL) star++;
163         else if ((star = strchr(name_of_file+1, ':')) != NULL) star++;
164         else star = name_of_file+1; */                          /* 1995/Sep/26 */
165         if ((star = (unsigned char *) strrchr((char *)s, '\\')) != NULL) star++;
166         else if ((star = (unsigned char *) strrchr((char *)s, '/')) != NULL) star++;
167         else if ((star = (unsigned char *) strchr((char *)s, ':')) != NULL) star++;
168         else star = s;
169         if ((sdot = (unsigned char *) strchr((char *)star, '.')) != NULL) n = sdot - star;
170         else n = strlen((char *)star);
171         if (n > 8) strcpy((char *)star+8, (char *)star+n);
172         if ((sdot = (unsigned char *)strchr((char *)star, '.')) != NULL) {
173                 star = sdot+1;
174                 n = strlen((char *)star);
175                 if (n > 3) *(star+3) = '\0';
176         }
177 }
178
179 /* Following works on both null-terminated names */
180 /* reconvert 254 to '~' in file name 95/Sep/26 */
181 /* reconvert 255 to ' ' in file name 95/Sep/26 */
182 /* we do this in tex3.c start_input() -> scan_file_name() now 95/Sep/26 */
183
184 void retwiddle (unsigned char *s)
185 {       /* assumes null terminated - 97/June/5 */
186 /*      while (*s != '\0' && *s != ' ') { */
187         while (*s != '\0') {
188                 if (*s == (unsigned char) pseudo_tilde) *s = '~';
189                 else if (*s == (unsigned char) pseudo_space) *s = ' ';
190                 s++;
191         }
192
193
194 /* #endif */ /* ??? */
195
196 /* Open an input file F, using the path PATHSPEC and passing
197    FOPEN_MODE to fopen.  The filename is in `name_of_file', as a Pascal
198    string. We return whether or not the open succeeded.  If it did, we
199    also set `name_length' to the length of the full pathname that we
200    opened.  */
201
202 bool open_input (FILE **f, path_constant_type path_index, char *fopen_mode)
203 {
204         bool openable = false;
205
206 #if defined (FUNNY_CORE_DUMP) && !defined (BibTeX)
207 /*      This only applies if a preloaded TeX (or Metafont) is being made;
208         it allows for automatic creation of the core dump (typing ^\
209         requires manual intervention).  */
210         if (path_index == TEXINPUTPATH
211       && strncmp (name_of_file+1, "HackyInputFileNameForCoreDump.tex", 33) == 0)
212                 funny_core_dump();
213 #endif /* FUNNY_CORE_DUMP and not BibTeX */
214
215 #ifdef MSDOS
216         if (return_flag) {
217                 if (strcmp(fopen_mode, "r") == 0)
218                         fopen_mode = "rb";              /* so can catch `return' bkph */
219         }
220 #endif /* MSDOS */
221
222 /*      null_terminate (name_of_file + 1);  */  /* moved here 97/June/5 */
223         name_of_file[name_length + 1] = '\0';   /* null terminate */
224
225 /* reinsert '~' and ' ' in file names -  95/June/5 */
226 /* done late to prevent problems with  null_terminate / space_terminate */  
227         if (pseudo_tilde != 0 || pseudo_space != 0) {
228                 retwiddle(name_of_file + 1);
229         }
230
231 #ifdef MSDOS
232         if (shorten_file_name) {        /* 8 + 3 file names on Windows NT 95/Feb/20 */
233 /*              null_terminate (name_of_file + 1); */
234                 check_short_name(name_of_file + 1);                                             /* 95/Sep/26 */
235 /*              space_terminate (name_of_file + 1); */
236         }
237 #endif  /* MSDOS */
238
239 #ifdef BibTeX
240         if (path_index == NO_FILE_PATH) {
241                 unsigned temp_length;
242
243 /*      null_terminate (name_of_file + 1); */
244 /*  if share_flag is non-zero and we are opening for reading use fsopen */
245 /*      but we can assume here that we are opening for *input* */
246 /*      *f = fopen (name_of_file + 1, fopen_mode); */
247                 if (share_flag == 0)  *f = fopen (name_of_file + 1, fopen_mode);
248                 else *f = _fsopen (name_of_file + 1, fopen_mode, share_flag);
249                 temp_length = strlen (name_of_file + 1);
250 /*      space_terminate (name_of_file + 1); */
251
252                 if (*f != NULL) {
253                         name_length = temp_length;
254                         openable = true;
255                 }
256         }
257
258         else
259 #endif /* BibTeX */
260   
261         if (open_trace_flag) {
262 /*      null_terminate (name_of_file + 1); */
263                 sprintf(log_line, " Open `%s' for input ", name_of_file+1);     /* Pascal */
264                 show_line(log_line, 0);
265 /*      space_terminate (name_of_file + 1); */
266         }               // debugging only
267
268         if (test_read_access(name_of_file+1, path_index)) { 
269 /*      if (test_read_access(name_of_file, name_length, path_index)) */
270
271 /*              We can assume `name_of_file' is openable, */
272 /*              since `test_read_access' just returned true.  */
273 /*              *f = xfopen_pas (name_of_file, fopen_mode); */
274                 *f = xfopen((char *)name_of_file+1, fopen_mode);
275
276 //              should we check *f == NULL ??? (should be OK because of test_read_access)
277
278 /*              If we found the file in the current directory, don't leave the
279         `./' at the beginning of `name_of_file', since it looks dumb when
280         TeX says `(./foo.tex ...)', and analogously for Metafont.  */
281 #ifdef MSDOS
282                 if (name_of_file[1] == '.' &&                                   /* 1994/Mar/1 */
283                         (name_of_file[2] == PATH_SEP || name_of_file[2] == '\\'))
284 #else
285                 if (name_of_file[1] == '.' && name_of_file[2] == PATH_SEP) 
286 #endif
287                 {
288                         unsigned i = 1;
289 /*                              while (name_of_file[i + 2] != ' ') */
290                         while (name_of_file[i + 2] != '\0')
291                         {
292                                 name_of_file[i] = name_of_file[i + 2];
293                                 i++;
294                         }
295 /*                      name_of_file[i] = ' '; */
296                         name_of_file[i] = '\0';
297                         name_length = i - 1;
298                 }
299                 else
300 /*                      name_length = strchr(name_of_file + 1, ' ') - (name_of_file + 1); */
301                         name_length = strlen((char *)name_of_file + 1);
302       
303 #ifdef TeX
304 /*              If we just opened a TFM file, we have to read the first byte,
305         since TeX wants to look at it.  What a kludge.  */
306                 if (path_index == TFMFILEPATH)
307                 { /* See comments in ctex.ch for why we need this.  */
308 /*          extern integer tfm_temp; */ /* see texd.h for definition */
309                         tfm_temp = getc (*f);
310                 }
311 #endif /* TeX */  
312
313 #ifdef MSDOS
314 /*              code added 94/June/21 to show 'fmt' file opening in log */
315 /*              if (show_fmt_flag && strstr(name_of_file+1, ".fmt") != NULL) { */
316                 if (strstr((char *)name_of_file + 1, ".fmt") != NULL) {
317                         if (format_file == NULL) {
318 /*                              null_terminate (name_of_file + 1); */
319                                 format_file = xstrdup((char *)name_of_file + 1);
320 /*                              space_terminate (name_of_file + 1); */
321                         }
322                 }       /* remember full format file name with path */
323 /*              if (showpoolflag && strstr(name_of_file+1, ".poo") != NULL) { */
324                 else if (strstr((char *)name_of_file+1, ".poo") != NULL) {
325                         if (string_file == NULL) {
326 /*                              null_terminate (name_of_file + 1); */
327                                 string_file = xstrdup((char *)name_of_file + 1);
328 /*                              space_terminate (name_of_file + 1); */
329                         }
330                 }       /* remember full pool file name with path */
331 /*              else if (show_tfm_flag && strstr(name_of_file+1, ".tfm") != NULL) { */
332                 else if (strstr((char *)name_of_file+1, ".tfm") != NULL) {
333                         if (show_tfm_flag && log_opened) {
334 #ifdef WRAPLINES
335                                 int old_setting = selector;
336                                 char *s = name_of_file + 1;
337                                 selector = 18;                  /* log file only */
338                                 print_char (' ');
339                                 print_char (40);                        /*(*/
340 /*                              while (*s > ' ') print_char (*s++); */
341                                 while (*s != '\0') print_char (*s++);
342                                 print_char (41);                        /*)*/
343                                 selector = old_setting;
344 #else
345                                 int n; 
346 /*                              null_terminate (name_of_file + 1); */
347                                 n = strlen((char *)name_of_file+1);
348                                 if (file_offset + n > max_print_line) {
349                                         putc('\n', log_file);
350                                         file_offset = 0;
351                                 }       /* somewhat risky ? */
352                                 else putc(' ', log_file);
353                                 fprintf(log_file, "(%s)", name_of_file+1);
354                                 file_offset += n+3;
355 /*                              space_terminate (name_of_file + 1);  */
356 #endif  /*  end of WRAPLINES */
357                         }
358                 }
359 /*              code added 98/Sep/29 to catch first file input */
360 /*              is there a problem if this file bombs ? */
361                 else if (source_direct == NULL) {                       /* 98/Sep/29 */
362                         char *s;
363 /*                      null_terminate (name_of_file + 1); */
364                         source_direct = xstrdup((char *)name_of_file + 1);
365 /*                      space_terminate (name_of_file + 1); */
366                         if (trace_flag) {
367                                 sprintf(log_line, "Methinks the source %s is `%s'\n", "file", source_direct);
368                                 show_line(log_line, 0);
369                         }
370                         if ((s = strrchr(source_direct, '/')) == NULL) *source_direct='\0';
371                         else *(s+1) = '\0';
372                         if (trace_flag) {
373                                 sprintf(log_line, "Methinks the source %s is `%s'\n", "directory", source_direct);
374                                 show_line(log_line, 0);
375                         }
376                 }
377
378 #endif  /* end of MSDOS */
379                 openable = true;
380         }
381 /*      space_terminate (name_of_file + 1); */
382         {
383                 unsigned temp_length = strlen((char *)name_of_file + 1);
384                 name_of_file[temp_length+1] = ' ';      /* space terminate */
385 /*              set up name_length ??? */
386         }
387         return openable;
388 }
389
390 /* Call the external program PROGRAM, passing it `name_of_file'.  */
391 /* This nonsense probably only works for Unix anyway. bkph */
392 /* For one thing, MakeTeXTFM etc is more than 8 characters ! */
393
394 #ifdef MSDOS
395   #define NO_MAKETEX
396 #endif
397
398 /* the string program is unreferenced in DOS NO_MAKETEX */
399
400 static bool
401 make_tex_file (string program)
402 {
403 #ifdef NO_MAKETEX
404   return 0;
405 #else
406   char cmd[NAME_MAX + 1 + PATH_MAX + 1];
407   unsigned cmd_len;
408   int ret;
409   unsigned i = 1; /* For copying from `name_of_file'.  */
410
411   /* Wrap another sh around the invocation of the MakeTeX program, so we
412      can avoid `sh: MakeTeXTFM: not found' errors confusing the user.
413      We don't use fork/exec ourselves, since we'd have to call sh anyway
414      to interpret the script.  */
415 #ifdef MSDOS
416   strcpy (cmd, "command.com ");
417 #else
418   strcpy (cmd, "sh -c ");
419 #endif
420   
421 /*  strcat (cmd, program); */   /* shrouded 93/Nov/20 */
422   strcat (cmd, "Make");
423 #ifndef MSDOS
424   strcat (cmd, "TeX");
425 #endif
426   strcat (cmd, program);
427   cmd_len = strlen (cmd);
428   cmd[cmd_len++] = ' ';
429
430   while (name_of_file[i] != ' ')
431     cmd[cmd_len++] = name_of_file[i++];
432
433   /* Add terminating null.  */
434   cmd[cmd_len] = 0;
435
436   /* Don't show any output.  */
437 #ifdef MSDOS
438   strcat (cmd, "> nul");        /* ? 93/Nov/20 */
439 #else
440   strcat (cmd, ">/dev/null 2>&1");
441 #endif
442
443 /* Run the command, and return whether or not it succeeded.  */
444   ret = system (cmd);
445   return ret == EXIT_SUCCESS_CODE;
446 #endif /* not NO_MAKE_TEX */
447 }
448
449 #define TEXONLY
450
451 /* This is called by TeX if an \input resp. TFM file can't be opened.  */
452
453 bool maketextex (void)                                  /* called in tex3.c and tex8.c */
454 {
455 /*  return make_tex_file ("MakeTeXTeX"); */
456   return make_tex_file ("TeX"); 
457 }
458
459 bool maketextfm (void)                                  /* called in tex3.c */
460 {
461 /*  return make_tex_file ("MakeTeXTFM"); */
462   return make_tex_file ("TFM");
463 }
464
465 #ifndef TEXONLY
466 bool maketexmf (void)
467 {
468 /*  return make_tex_file ("MakeTeXMF"); */
469   return make_tex_file ("MF");
470 }
471 #endif /* ifndef TEXONLY */
472 \f
473
474 char *get_env_shroud (char *);          /* defined in texmf.c */
475
476 /* char outputdirectory[PATH_MAX]; */                           /* defined in local.c */
477
478 extern char *dvi_directory;                             /* defined in local.c */
479 extern char *log_directory;                             /* defined in local.c */
480 extern char *aux_directory;                             /* defined in local.c */
481
482 #ifdef IGNORED
483 /* Try and figure out if can write to current directory */
484 bool isitsafe (char *name)
485 {
486 /*  struct stat statbuf; */                                     /* debugging 94/Mar/2 */
487 /*      Can't test access on file, since fails if not exist */
488 /*      Can't test access on `nul', since always fails */ 
489 /*      Can   test access on `.', but its true on locked diskette! */
490 /*      stat on directory always says read an write permission */
491         return true;                            /* for now */
492 }
493 #endif
494
495 /* open_output moved to end to avoid pragma problems 96/Sep/15 */
496
497 \f
498 /* used only in start_input in tex3.c, and in open_or_close_in in tex8.c */
499 /* modified 97/June/5 to take null terminated (C) string */
500
501 #ifdef IGNORED
502 bool extensionirrelevantaux (char *base, char *suffix)
503
504   bool ret;
505 /*  make_c_string (&base);  */
506 /*  base[nlen+1] = '\0'; */                     /* null terminate */
507 #ifdef MSDOS
508 /*      In DOS, an extension is irrelevant if there already is an extension ! */
509 /*      MAY NEED TO REVISE IN WIN32 where we can have foo.bar.chomp.tex ??? */
510   {                                                             /* simplification 1996/Jan/20 ??? */
511           char *s, *t;
512           if ((s = strrchr (base, '.')) == NULL) ret = 0;       /* no extension */
513           else {
514                   if ((t = strrchr (base, PATH_SEP)) != NULL ||
515                           (t = strrchr (base, '\\')) != NULL ||
516                           (t = strrchr (base, ':')) != NULL) {
517                           if (t > s) ret = 0;   /* last dot occurs in path - no extension */
518                           else ret = 1;                 /* last dot occurs in file name itself */
519                   }
520                   else ret = 1;                         /* name not qualified and has dot */
521           }
522   }
523 #else   /*  not MSDOS */
524   {
525           char temp[PATH_MAX];
526           strcpy (temp, base);
527           strcat (temp, ".");
528           strcat (temp, suffix);
529           ret = same_file_p (base, temp);
530   }
531 #endif /* end of not MSDOS */
532 /*  make_pascal_string (&base); */
533 /*  base[nlen+1] = ' '; */                      /* space terminate */
534   return ret;
535 }
536 #endif /* IGNORED */
537
538 /* Test if the Pascal string BASE concatenated with the extension
539    `.SUFFIX' is the same file as just BASE.  SUFFIX is a C string.  */
540
541 /* used in `start_input' (tex3.c) and open_or_close_in (tex8.c) */
542 /* used to always return true, since in DOS can have only one extension */
543 /* modified 98/Feb/7 to always return false */
544
545 bool extensionirrelevantp (unsigned char *base, int nlen, char *suffix)
546
547 #ifdef IGNORED
548   bool ret;
549   base[nlen+1] = '\0';                  /* null terminate */
550   ret = extensionirrelevantaux(base+1, suffix);
551   base[nlen+1] = ' ';                   /* space terminate */
552   return ret;
553 #endif
554   return false;
555 }
556 \f
557
558 /* #define a_close(f) if (f) { if (ferror (f)) {perror(""); exit(1);} } if (f) (void) fclose (f) */
559 /* #define a_close(f)   if (f) (void) check_fclose (f) */
560
561 /* At least check for I/O error (such as disk full) when closing */
562 /* Would be better to check while writing - but this is better than nothing */
563 /* This is used for both input and output files, but never mind ... */
564
565 /* now a_close returns -1 on error --- which could be used by caller */
566 /* probably want to ignore on input files ... */
567
568 void perrormod (char *s);                               /* in local.c */
569
570 // check_fclose not used by anything
571
572 int check_fclose (FILE *f)
573 {                               /* 1993/Nov/20 - bkph */
574         if (f == NULL) return 0;                        // sanity check
575         if (ferror(f) || fclose (f)) {
576                 perrormod("\n! I/O Error");
577                 uexit (1);              // ???
578         }
579         return 0;
580 }
581
582 /* open_output moved down here to avoid potential pragma problem */
583
584 /* #pragma optimize ("g", off) *//* try and avoid compiler bug here */
585
586 /* Open an output file F either in the current directory or in
587    $TEXMFOUTPUT/F, if the environment variable `TEXMFOUTPUT' exists.
588    (Actually, this applies to the BibTeX output files, also, but
589    `TEXMFBIBOUTPUT' was just too long.)  The filename is in the global
590    `name_of_file', as a Pascal string.  We return whether or not the open
591    succeeded.  If it did, the global `name_length' is set to the length
592    of the actual filename.  */
593
594 bool open_output (FILE **f, char *fopen_mode)
595 {
596         unsigned temp_length;
597
598 /*      null_terminate (name_of_file + 1);      */      /* moved here 95/Sep/26  */
599         name_of_file[name_length+1] = '\0';     /* null terminate */
600
601 /* reinsert '~' and ' ' in file names -  95/June/5 */
602 /* done late to prevent problems with  null_terminate / space_terminate */  
603         if (pseudo_tilde != 0 || pseudo_space !=  0) {
604                 retwiddle(name_of_file + 1);
605         }
606
607 #ifdef MSDOS
608         if (shorten_file_name) {        /* 8 + 3 file names on Windows NT 95/Feb/20 */
609 /*              null_terminate (name_of_file + 1);  */
610 /*              check_short_name(); */
611                 check_short_name(name_of_file + 1);                                     /* 95/Sep/26 */
612 /*              space_terminate (name_of_file + 1); */
613         }
614 #endif
615
616 /*  null_terminate (name_of_file + 1); */ /* Make the filename into a C string.  */
617
618 /*  if (debug_flag) try_and_open(name_of_file+1); */    /* debugging 94/Mar/20 */
619
620 #ifdef MSDOS
621 /* write into user specified output directory if given on command line */
622 /* following code added 1993/Dec/12 */ /* separated 1996/Jan/20 */
623         if (prepend_path_if (name_of_file+1, name_of_file+1, ".dvi", (unsigned char *)dvi_directory) ||
624                 prepend_path_if (name_of_file+1, name_of_file+1, ".log", (unsigned char *)log_directory) ||
625                 prepend_path_if (name_of_file+1, name_of_file+1, ".aux", (unsigned char *)aux_directory)) {
626                 if (open_trace_flag) {
627                         sprintf(log_line, "After prepend %s\n", name_of_file+1);
628                         show_line(log_line, 0);
629                 }
630         }
631 #endif
632
633 /* name_length recomputed below so don't need to do it yet */
634
635         if (open_trace_flag) {
636 /*      null_terminate (name_of_file + 1); */
637                 sprintf(log_line, " Open `%s' for output ", name_of_file+1); /* C string */
638                 show_line(log_line, 0);
639 /*      space_terminate (name_of_file + 1); */
640         }               // debugging only
641
642 /* Is the filename openable as given?  */
643
644 /*  if share_flag is non-zero and we are opening for reading use fsopen */
645 /*      but we can assume this is opening here for *output* */
646         *f = fopen((char *)name_of_file + 1, fopen_mode);
647
648         if (*f == NULL)    { /* Can't open as given.  Try the envvar.  */
649 /*    string temp_dir = getenv ("TEXMFOUTPUT"); */      /* 93/Nov/20 */
650 /*    string temp_dir = getenv ("TEXMFOUT"); */ /* 93/Nov/20 */
651 /*      string temp_dir = get_env_shroud ("UFYNGPVUQVU"); */
652                 string temp_dir = get_env_shroud ("UFYNGPVU");
653
654 /*              if (deslash) unixify(temp_dir); */              /* deslashify 93/Dec/28 */
655
656                 if (temp_dir != NULL) {
657 #ifdef BUILDNAMEDIRECT
658                         unsigned char temp_name[PATH_MAX];
659                         xconcat3((char *)temp_name, temp_dir, PATH_SEP_STRING, (char *)name_of_file + 1);
660 #else
661 /*          string temp_name = concat3 (temp_dir, "/", name_of_file + 1); */
662                         string temp_name = concat3 (temp_dir, PATH_SEP_STRING, name_of_file + 1);
663 #endif
664                         if (deslash) unixify((char *) temp_name);               /* deslashify 93/Dec/28 */
665 /*      If share_flag is non-zero and we are opening for reading use fsopen */
666 /*      but we can assume this is opening here for *output* */
667                         *f = fopen((char*)temp_name, fopen_mode);
668 /*      If this succeeded, change name_of_file accordingly.  */
669                         if (*f) strcpy((char*)name_of_file + 1, (char *)temp_name);
670 #ifndef BUILDNAMEDIRECT
671                         free (temp_name);
672 #endif
673                 }
674         }
675
676 //      show_line(name_of_file+1, 1);           // debugging only
677 //      New code to remember complete dvi_file name and log_file_name
678 //      To remember for output at the end 2000 June 18
679         if (strstr((char *)name_of_file + 1, ".dvi") != NULL) {
680                 if (qualified(name_of_file+1)) *log_line = '\0';
681                 else {
682                         (void) _getcwd(log_line, sizeof(log_line));
683                         strcat(log_line, PATH_SEP_STRING);
684                 }
685                 strcat(log_line, (char*)name_of_file+1);
686                 unixify(log_line);
687                 dvi_file_name = xstrdup(log_line);
688 //              show_line(dvi_file_name, 1);    // debugging only
689         }
690         else if (strstr((char *)name_of_file + 1, ".log") != NULL) {
691                 if (qualified(name_of_file+1)) *log_line = '\0';
692                 else {
693                         (void) _getcwd(log_line, sizeof(log_line));
694                         strcat(log_line, PATH_SEP_STRING);
695                 }
696                 strcat(log_line, (char *)name_of_file+1);
697                 unixify(log_line);
698                 log_file_name = xstrdup(log_line);
699 //              show_line(log_file_name, 1);    // debugging only
700         }
701 /* Back into a Pascal string, but first get its length.  */
702         temp_length = strlen ((char *)name_of_file + 1);
703 /*      space_terminate (name_of_file + 1); */
704         name_of_file[temp_length+1] = ' ';      /* space terminate */
705
706 /* Only set `name_length' if we succeeded.  I'm not sure why.  */
707         if (*f)                                                         /* TEST ? 94/MAR/2 */
708                 name_length = temp_length;
709   
710         return *f != NULL;
711 }
712
713
714 /* #pragma optimize ("g",)*/    /* try and avoid compiler bug here */
715 /* #pragma optimize ("", on) */         /* try and avoid compiler bug here */
716