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