]> git.saurik.com Git - bison.git/blob - src/files.c
Honor TMPDIR on Unix hosts.
[bison.git] / src / files.c
1 /* Open and close files for bison,
2 Copyright (C) 1984, 1986, 1989, 1992 Free Software Foundation, Inc.
3
4 This file is part of Bison, the GNU Compiler Compiler.
5
6 Bison is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 Bison is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Bison; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21 #if defined (VMS) & !defined (__VMS_POSIX)
22 #include <ssdef.h>
23 #define unlink delete
24 #ifndef XPFILE
25 #define XPFILE "GNU_BISON:[000000]BISON.SIMPLE"
26 #endif
27 #ifndef XPFILE1
28 #define XPFILE1 "GNU_BISON:[000000]BISON.HAIRY"
29 #endif
30 #endif
31
32 #if defined (_MSC_VER)
33 #ifndef XPFILE
34 #define XPFILE "c:/usr/local/lib/bison.simple"
35 #endif
36 #ifndef XPFILE1
37 #define XPFILE1 "c:/usr/local/lib/bison.hairy"
38 #endif
39 #endif
40
41 #include <stdio.h>
42 #include "system.h"
43 #include "files.h"
44 #include "alloc.h"
45 #include "gram.h"
46
47 FILE *finput = NULL;
48 FILE *foutput = NULL;
49 FILE *fdefines = NULL;
50 FILE *ftable = NULL;
51 FILE *fattrs = NULL;
52 FILE *fguard = NULL;
53 FILE *faction = NULL;
54 FILE *fparser = NULL;
55
56 /* File name specified with -o for the output file, or 0 if no -o. */
57 char *spec_outfile;
58
59 char *infile;
60 char *outfile;
61 char *defsfile;
62 char *tabfile;
63 char *attrsfile;
64 char *guardfile;
65 char *actfile;
66 char *tmpattrsfile;
67 char *tmptabfile;
68 char *tmpdefsfile;
69
70 extern int noparserflag;
71
72 extern char *mktemp(); /* So the compiler won't complain */
73 extern char *getenv();
74 extern void perror();
75
76 char *stringappend PARAMS((char *, int, char *));
77 void openfiles PARAMS((void));
78 void open_extra_files PARAMS((void));
79 FILE *tryopen PARAMS((char *, char *)); /* This might be a good idea */
80 void done PARAMS((int));
81
82 extern char *program_name;
83 extern int verboseflag;
84 extern int definesflag;
85 int fixed_outfiles = 0;
86 \f
87
88 char *
89 stringappend (char *string1, int end1, char *string2)
90 {
91 register char *ostring;
92 register char *cp, *cp1;
93 register int i;
94
95 cp = string2; i = 0;
96 while (*cp++) i++;
97
98 ostring = NEW2(i+end1+1, char);
99
100 cp = ostring;
101 cp1 = string1;
102 for (i = 0; i < end1; i++)
103 *cp++ = *cp1++;
104
105 cp1 = string2;
106 while ((*cp++ = *cp1++))
107 ;
108
109 return ostring;
110 }
111
112
113 /* JF this has been hacked to death. Nowaday it sets up the file names for
114 the output files, and opens the tmp files and the parser */
115 void
116 openfiles (void)
117 {
118 char *name_base;
119 register char *cp;
120 char *filename;
121 int base_length;
122 int short_base_length;
123
124 #if defined (VMS) & !defined (__VMS_POSIX)
125 char *tmp_base = "sys$scratch:b_";
126 #else
127 char *tmp_base = "/tmp/b.";
128 #endif
129 int tmp_len;
130
131 #ifdef MSDOS
132 tmp_base = getenv ("TMP");
133 if (tmp_base == 0)
134 tmp_base = "";
135 strlwr (infile);
136 #endif /* MSDOS */
137
138 #if (defined(_WIN32) && !defined(__CYGWIN32__))
139 tmp_base = getenv ("TEMP"); /* Windows95 defines this ... */
140 if (tmp_base == 0)
141 tmp_base = getenv ("Temp"); /* ... while NT prefers this */
142 if (tmp_base == 0)
143 tmp_base = "";
144 strlwr (infile);
145 #endif /* _WIN32 && !__CYGWIN32__ */
146
147 #if (defined(unix) || defined(__unix) || defined(__unix__))
148 {
149 char *tmp_ptr = getenv("TMPDIR");
150
151 if (tmp_ptr != 0)
152 tmp_base = stringappend (tmp_ptr, strlen (tmp_ptr), "/b.");
153 }
154 #endif /* unix || __unix || __unix__ */
155
156 tmp_len = strlen (tmp_base);
157
158 if (spec_outfile)
159 {
160 /* -o was specified. The precise -o name will be used for ftable.
161 For other output files, remove the ".c" or ".tab.c" suffix. */
162 name_base = spec_outfile;
163 #ifdef MSDOS
164 strlwr (name_base);
165 #endif /* MSDOS */
166 /* BASE_LENGTH includes ".tab" but not ".c". */
167 base_length = strlen (name_base);
168 if (!strcmp (name_base + base_length - 2, ".c"))
169 base_length -= 2;
170 /* SHORT_BASE_LENGTH includes neither ".tab" nor ".c". */
171 short_base_length = base_length;
172 if (!strncmp (name_base + short_base_length - 4, ".tab", 4))
173 short_base_length -= 4;
174 else if (!strncmp (name_base + short_base_length - 4, "_tab", 4))
175 short_base_length -= 4;
176 }
177 else if (spec_file_prefix)
178 {
179 /* -b was specified. Construct names from it. */
180 /* SHORT_BASE_LENGTH includes neither ".tab" nor ".c". */
181 short_base_length = strlen (spec_file_prefix);
182 /* Count room for `.tab'. */
183 base_length = short_base_length + 4;
184 name_base = (char *) xmalloc (base_length + 1);
185 /* Append `.tab'. */
186 strcpy (name_base, spec_file_prefix);
187 #ifdef VMS
188 strcat (name_base, "_tab");
189 #else
190 strcat (name_base, ".tab");
191 #endif
192 #ifdef MSDOS
193 strlwr (name_base);
194 #endif /* MSDOS */
195 }
196 else
197 {
198 /* -o was not specified; compute output file name from input
199 or use y.tab.c, etc., if -y was specified. */
200
201 name_base = fixed_outfiles ? "y.y" : infile;
202
203 /* BASE_LENGTH gets length of NAME_BASE, sans ".y" suffix if any. */
204
205 base_length = strlen (name_base);
206 if (!strcmp (name_base + base_length - 2, ".y"))
207 base_length -= 2;
208 short_base_length = base_length;
209
210 #ifdef VMS
211 name_base = stringappend(name_base, short_base_length, "_tab");
212 #else
213 #ifdef MSDOS
214 name_base = stringappend(name_base, short_base_length, "_tab");
215 #else
216 name_base = stringappend(name_base, short_base_length, ".tab");
217 #endif /* not MSDOS */
218 #endif
219 base_length = short_base_length + 4;
220 }
221
222 finput = tryopen(infile, "r");
223
224 if (! noparserflag)
225 {
226 filename = getenv("BISON_SIMPLE");
227 #ifdef MSDOS
228 /* File doesn't exist in current directory; try in INIT directory. */
229 cp = getenv("INIT");
230 if (filename == 0 && cp != NULL)
231 {
232 filename = xmalloc(strlen(cp) + strlen(PFILE) + 2);
233 strcpy(filename, cp);
234 cp = filename + strlen(filename);
235 *cp++ = '/';
236 strcpy(cp, PFILE);
237 }
238 #endif /* MSDOS */
239 fparser = tryopen(filename ? filename : PFILE, "r");
240 }
241
242 if (verboseflag)
243 {
244 #ifdef MSDOS
245 outfile = stringappend(name_base, short_base_length, ".out");
246 #else
247 /* We used to use just .out if spec_name_prefix (-p) was used,
248 but that conflicts with Posix. */
249 outfile = stringappend(name_base, short_base_length, ".output");
250 #endif
251 foutput = tryopen(outfile, "w");
252 }
253
254 if (noparserflag)
255 {
256 /* use permanent name for actions file */
257 actfile = stringappend(name_base, short_base_length, ".act");
258 faction = tryopen(actfile, "w");
259 }
260
261 #ifdef MSDOS
262 if (! noparserflag)
263 actfile = mktemp(stringappend(tmp_base, tmp_len, "acXXXXXX"));
264 tmpattrsfile = mktemp(stringappend(tmp_base, tmp_len, "atXXXXXX"));
265 tmptabfile = mktemp(stringappend(tmp_base, tmp_len, "taXXXXXX"));
266 tmpdefsfile = mktemp(stringappend(tmp_base, tmp_len, "deXXXXXX"));
267 #else
268 if (! noparserflag)
269 actfile = mktemp(stringappend(tmp_base, tmp_len, "act.XXXXXX"));
270 tmpattrsfile = mktemp(stringappend(tmp_base, tmp_len, "attrs.XXXXXX"));
271 tmptabfile = mktemp(stringappend(tmp_base, tmp_len, "tab.XXXXXX"));
272 tmpdefsfile = mktemp(stringappend(tmp_base, tmp_len, "defs.XXXXXX"));
273 #endif /* not MSDOS */
274
275 if (! noparserflag)
276 faction = tryopen(actfile, "w+");
277 fattrs = tryopen(tmpattrsfile,"w+");
278 ftable = tryopen(tmptabfile, "w+");
279
280 if (definesflag)
281 {
282 defsfile = stringappend(name_base, base_length, ".h");
283 fdefines = tryopen(tmpdefsfile, "w+");
284 }
285
286 #if !(defined (MSDOS) || (defined(_WIN32) && !defined(__CYGWIN32__)))
287 if (! noparserflag)
288 unlink(actfile);
289 unlink(tmpattrsfile);
290 unlink(tmptabfile);
291 unlink(tmpdefsfile);
292 #endif /* MSDOS || (_WIN32 && !__CYGWIN32__) */
293
294 /* These are opened by `done' or `open_extra_files', if at all */
295 if (spec_outfile)
296 tabfile = spec_outfile;
297 else
298 tabfile = stringappend(name_base, base_length, ".c");
299
300 #ifdef VMS
301 attrsfile = stringappend(name_base, short_base_length, "_stype.h");
302 guardfile = stringappend(name_base, short_base_length, "_guard.c");
303 #else
304 #ifdef MSDOS
305 attrsfile = stringappend(name_base, short_base_length, ".sth");
306 guardfile = stringappend(name_base, short_base_length, ".guc");
307 #else
308 attrsfile = stringappend(name_base, short_base_length, ".stype.h");
309 guardfile = stringappend(name_base, short_base_length, ".guard.c");
310 #endif /* not MSDOS */
311 #endif /* not VMS */
312 }
313
314
315
316 /* open the output files needed only for the semantic parser.
317 This is done when %semantic_parser is seen in the declarations section. */
318
319 void
320 open_extra_files (void)
321 {
322 FILE *ftmp;
323 int c;
324 char *filename, *cp;
325
326 if (fparser)
327 fclose(fparser);
328
329 if (! noparserflag)
330 {
331 filename = (char *) getenv ("BISON_HAIRY");
332 #ifdef MSDOS
333 /* File doesn't exist in current directory; try in INIT directory. */
334 cp = getenv("INIT");
335 if (filename == 0 && cp != NULL)
336 {
337 filename = xmalloc(strlen(cp) + strlen(PFILE1) + 2);
338 strcpy(filename, cp);
339 cp = filename + strlen(filename);
340 *cp++ = '/';
341 strcpy(cp, PFILE1);
342 }
343 #endif
344 fparser= tryopen(filename ? filename : PFILE1, "r");
345 }
346
347 /* JF change from inline attrs file to separate one */
348 ftmp = tryopen(attrsfile, "w");
349 rewind(fattrs);
350 while((c=getc(fattrs))!=EOF) /* Thank god for buffering */
351 putc(c,ftmp);
352 fclose(fattrs);
353 fattrs=ftmp;
354
355 fguard = tryopen(guardfile, "w");
356
357 }
358
359 /* JF to make file opening easier. This func tries to open file
360 NAME with mode MODE, and prints an error message if it fails. */
361 FILE *
362 tryopen (char *name, char *mode)
363 {
364 FILE *ptr;
365
366 ptr = fopen(name, mode);
367 if (ptr == NULL)
368 {
369 fprintf(stderr, "%s: ", program_name);
370 perror(name);
371 done(2);
372 }
373 return ptr;
374 }
375
376 void
377 done (int k)
378 {
379 if (faction)
380 fclose(faction);
381
382 if (fattrs)
383 fclose(fattrs);
384
385 if (fguard)
386 fclose(fguard);
387
388 if (finput)
389 fclose(finput);
390
391 if (fparser)
392 fclose(fparser);
393
394 if (foutput)
395 fclose(foutput);
396
397 /* JF write out the output file */
398 if (k == 0 && ftable)
399 {
400 FILE *ftmp;
401 register int c;
402
403 ftmp=tryopen(tabfile, "w");
404 rewind(ftable);
405 while((c=getc(ftable)) != EOF)
406 putc(c,ftmp);
407 fclose(ftmp);
408 fclose(ftable);
409
410 if (definesflag)
411 {
412 ftmp = tryopen(defsfile, "w");
413 fflush(fdefines);
414 rewind(fdefines);
415 while((c=getc(fdefines)) != EOF)
416 putc(c,ftmp);
417 fclose(ftmp);
418 fclose(fdefines);
419 }
420 }
421
422 #if defined (VMS) & !defined (__VMS_POSIX)
423 if (faction && ! noparserflag)
424 delete(actfile);
425 if (fattrs)
426 delete(tmpattrsfile);
427 if (ftable)
428 delete(tmptabfile);
429 if (k==0) sys$exit(SS$_NORMAL);
430 sys$exit(SS$_ABORT);
431 #else
432 #if (defined (MSDOS) || (defined(_WIN32) && !defined(__CYGWIN32__)))
433 if (actfile && ! noparserflag) unlink(actfile);
434 if (tmpattrsfile) unlink(tmpattrsfile);
435 if (tmptabfile) unlink(tmptabfile);
436 if (tmpdefsfile) unlink(tmpdefsfile);
437 #endif /* MSDOS || (_WIN32 && !__CYGWIN32__) */
438 exit(k);
439 #endif /* not VMS, or __VMS_POSIX */
440 }