]> git.saurik.com Git - bison.git/blame - src/files.c
Don't use `atexit'.
[bison.git] / src / files.c
CommitLineData
54bd0db4 1/* Open and close files for bison,
8c7ebe49 2 Copyright 1984, 1986, 1989, 1992, 2000 Free Software Foundation, Inc.
54bd0db4 3
ceed8467 4 This file is part of Bison, the GNU Compiler Compiler.
54bd0db4 5
ceed8467
AD
6 Bison is free software; you can redistribute it and/or modify it
7 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.
54bd0db4 10
ceed8467
AD
11 Bison is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
54bd0db4 15
ceed8467
AD
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 the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
54bd0db4
RS
20
21
9eceb6c6
JT
22#include "system.h"
23
fcca25ad 24#if defined (VMS) & !defined (__VMS_POSIX)
ceed8467
AD
25# include <ssdef.h>
26# define unlink delete
27# ifndef XPFILE
28# define XPFILE "GNU_BISON:[000000]BISON.SIMPLE"
29# endif
30# ifndef XPFILE1
31# define XPFILE1 "GNU_BISON:[000000]BISON.HAIRY"
32# endif
54bd0db4
RS
33#endif
34
6a5705cf 35#if defined (_MSC_VER)
ceed8467
AD
36# ifndef XPFILE
37# define XPFILE "c:/usr/local/lib/bison.simple"
38# endif
39# ifndef XPFILE1
40# define XPFILE1 "c:/usr/local/lib/bison.hairy"
41# endif
dad49092
JT
42#endif
43
ceed8467 44#include "getargs.h"
54bd0db4 45#include "files.h"
d7913476 46#include "xalloc.h"
54bd0db4 47#include "gram.h"
a0f6b076 48#include "complain.h"
54bd0db4
RS
49
50FILE *finput = NULL;
51FILE *foutput = NULL;
54bd0db4 52FILE *fguard = NULL;
54bd0db4
RS
53FILE *fparser = NULL;
54
8c7ebe49 55struct obstack action_obstack;
dd60faec 56struct obstack attrs_obstack;
896fe5c1
AD
57struct obstack table_obstack;
58struct obstack defines_obstack;
8c7ebe49 59
54bd0db4
RS
60/* File name specified with -o for the output file, or 0 if no -o. */
61char *spec_outfile;
62
63char *infile;
54bd0db4 64char *attrsfile;
4a120d45
JT
65
66static char *outfile;
67static char *defsfile;
68static char *tabfile;
69static char *guardfile;
70static char *actfile;
54bd0db4 71
8963a27b 72extern char *getenv ();
4a120d45 73
54bd0db4 74extern char *program_name;
54bd0db4
RS
75\f
76
8963a27b 77static char *
4a120d45 78stringappend (const char *string1, int end1, const char *string2)
54bd0db4
RS
79{
80 register char *ostring;
4a120d45
JT
81 register char *cp;
82 register const char *cp1;
54bd0db4
RS
83 register int i;
84
4a120d45
JT
85 cp1 = string2;
86 i = 0;
8963a27b
AD
87 while (*cp1++)
88 i++;
54bd0db4 89
d7913476 90 ostring = XCALLOC (char, i + end1 + 1);
54bd0db4
RS
91
92 cp = ostring;
93 cp1 = string1;
94 for (i = 0; i < end1; i++)
95 *cp++ = *cp1++;
96
97 cp1 = string2;
bd088c91
JT
98 while ((*cp++ = *cp1++))
99 ;
54bd0db4
RS
100
101 return ostring;
102}
103
cfe5fbc0
AD
104/*-----------------------------------------------------------------.
105| Try to open file NAME with mode MODE, and print an error message |
106| if fails. |
107`-----------------------------------------------------------------*/
54bd0db4 108
cfe5fbc0 109static FILE *
8963a27b 110xfopen (const char *name, const char *mode)
cfe5fbc0 111{
8963a27b 112 FILE *ptr;
cfe5fbc0
AD
113
114 ptr = fopen (name, mode);
115 if (!ptr)
116 error (2, errno, _("cannot open file `%s'"), name);
117
118 return ptr;
119}
120
121/*-------------------------------------------------------------.
122| Try to close file PTR, and print an error message if fails. |
123`-------------------------------------------------------------*/
124
125static int
8963a27b 126xfclose (FILE *ptr)
cfe5fbc0
AD
127{
128 int result;
129
130 if (ptr == NULL)
131 return 0;
132
133 result = fclose (ptr);
134 if (result == EOF)
135 error (2, errno, _("cannot close file"));
136
137 return result;
138}
d8880f69
AD
139
140/*--------------------------------------------------.
141| Save the content of the obstack OBS in FILENAME. |
142`--------------------------------------------------*/
143
144void
145obstack_save (struct obstack *obs, const char *filename)
146{
147 FILE *out = xfopen (filename, "w");
148 size_t size = obstack_object_size (obs);
149 fwrite (obstack_finish (obs), 1, size, out);
150 xfclose (out);
151}
152
cfe5fbc0 153\f
d8880f69
AD
154/*-----------------------------------------------------------------.
155| Open the input file. Look for the skeletons. Find the names of |
156| the output files. Prepare the obstacks. |
157`-----------------------------------------------------------------*/
158
54bd0db4 159void
8963a27b 160open_files (void)
54bd0db4
RS
161{
162 char *name_base;
a693bf18 163#ifdef MSDOS
54bd0db4 164 register char *cp;
a693bf18 165#endif
54bd0db4
RS
166 char *filename;
167 int base_length;
168 int short_base_length;
169
fcca25ad 170#if defined (VMS) & !defined (__VMS_POSIX)
4a120d45 171 const char *tmp_base = "sys$scratch:b_";
54bd0db4 172#else
4a120d45 173 const char *tmp_base = "/tmp/b.";
54bd0db4
RS
174#endif
175 int tmp_len;
176
177#ifdef MSDOS
178 tmp_base = getenv ("TMP");
179 if (tmp_base == 0)
180 tmp_base = "";
181 strlwr (infile);
182#endif /* MSDOS */
183
e0672a61 184#if (defined(_WIN32) && !defined(__CYGWIN32__))
8963a27b 185 tmp_base = getenv ("TEMP"); /* Windows95 defines this ... */
e0672a61 186 if (tmp_base == 0)
8963a27b 187 tmp_base = getenv ("Temp"); /* ... while NT prefers this */
e0672a61
RS
188 if (tmp_base == 0)
189 tmp_base = "";
190 strlwr (infile);
191#endif /* _WIN32 && !__CYGWIN32__ */
192
5191ef24 193#if (defined(unix) || defined(__unix) || defined(__unix__) || defined(__EMX__))
bd088c91 194 {
8963a27b 195 char *tmp_ptr = getenv ("TMPDIR");
bd088c91
JT
196
197 if (tmp_ptr != 0)
198 tmp_base = stringappend (tmp_ptr, strlen (tmp_ptr), "/b.");
199 }
8963a27b 200#endif /* unix || __unix || __unix__ */
bd088c91 201
54bd0db4
RS
202 tmp_len = strlen (tmp_base);
203
204 if (spec_outfile)
205 {
896fe5c1 206 /* -o was specified. The precise -o name will be used for FTABLE.
8963a27b 207 For other output files, remove the ".c" or ".tab.c" suffix. */
54bd0db4
RS
208 name_base = spec_outfile;
209#ifdef MSDOS
210 strlwr (name_base);
211#endif /* MSDOS */
212 /* BASE_LENGTH includes ".tab" but not ".c". */
213 base_length = strlen (name_base);
214 if (!strcmp (name_base + base_length - 2, ".c"))
215 base_length -= 2;
216 /* SHORT_BASE_LENGTH includes neither ".tab" nor ".c". */
217 short_base_length = base_length;
218 if (!strncmp (name_base + short_base_length - 4, ".tab", 4))
219 short_base_length -= 4;
220 else if (!strncmp (name_base + short_base_length - 4, "_tab", 4))
221 short_base_length -= 4;
222 }
223 else if (spec_file_prefix)
224 {
225 /* -b was specified. Construct names from it. */
226 /* SHORT_BASE_LENGTH includes neither ".tab" nor ".c". */
227 short_base_length = strlen (spec_file_prefix);
228 /* Count room for `.tab'. */
229 base_length = short_base_length + 4;
d7913476 230 name_base = XMALLOC (char, base_length + 1);
54bd0db4
RS
231 /* Append `.tab'. */
232 strcpy (name_base, spec_file_prefix);
233#ifdef VMS
234 strcat (name_base, "_tab");
235#else
236 strcat (name_base, ".tab");
237#endif
238#ifdef MSDOS
239 strlwr (name_base);
240#endif /* MSDOS */
241 }
242 else
243 {
244 /* -o was not specified; compute output file name from input
8963a27b 245 or use y.tab.c, etc., if -y was specified. */
54bd0db4 246
4a120d45
JT
247 static char FIXED_NAME_BASE[] = "y.y";
248
89cab50d 249 name_base = yacc_flag ? FIXED_NAME_BASE : infile;
54bd0db4
RS
250
251 /* BASE_LENGTH gets length of NAME_BASE, sans ".y" suffix if any. */
252
253 base_length = strlen (name_base);
254 if (!strcmp (name_base + base_length - 2, ".y"))
255 base_length -= 2;
256 short_base_length = base_length;
257
258#ifdef VMS
8963a27b 259 name_base = stringappend (name_base, short_base_length, "_tab");
54bd0db4
RS
260#else
261#ifdef MSDOS
8963a27b 262 name_base = stringappend (name_base, short_base_length, "_tab");
54bd0db4 263#else
8963a27b 264 name_base = stringappend (name_base, short_base_length, ".tab");
54bd0db4
RS
265#endif /* not MSDOS */
266#endif
267 base_length = short_base_length + 4;
268 }
269
8963a27b 270 finput = xfopen (infile, "r");
54bd0db4 271
89cab50d 272 if (!no_parser_flag)
54bd0db4 273 {
8963a27b 274 filename = getenv ("BISON_SIMPLE");
28683c54
RS
275#ifdef MSDOS
276 /* File doesn't exist in current directory; try in INIT directory. */
8963a27b 277 cp = getenv ("INIT");
28683c54 278 if (filename == 0 && cp != NULL)
8963a27b 279 {
d7913476 280 filename = XMALLOC (char, strlen (cp) + strlen (PFILE) + 2);
8963a27b
AD
281 strcpy (filename, cp);
282 cp = filename + strlen (filename);
283 *cp++ = '/';
284 strcpy (cp, PFILE);
285 }
54bd0db4 286#endif /* MSDOS */
8963a27b 287 fparser = xfopen (filename ? filename : PFILE, "r");
28683c54 288 }
54bd0db4 289
89cab50d 290 if (verbose_flag)
54bd0db4
RS
291 {
292#ifdef MSDOS
8963a27b 293 outfile = stringappend (name_base, short_base_length, ".out");
54bd0db4
RS
294#else
295 /* We used to use just .out if spec_name_prefix (-p) was used,
8963a27b
AD
296 but that conflicts with Posix. */
297 outfile = stringappend (name_base, short_base_length, ".output");
54bd0db4 298#endif
8963a27b 299 foutput = xfopen (outfile, "w");
54bd0db4
RS
300 }
301
89cab50d 302 if (no_parser_flag)
28683c54
RS
303 {
304 /* use permanent name for actions file */
8963a27b 305 actfile = stringappend (name_base, short_base_length, ".act");
a0f6b076 306 }
28683c54 307
89cab50d 308 if (defines_flag)
54bd0db4 309 {
8963a27b 310 defsfile = stringappend (name_base, base_length, ".h");
54bd0db4
RS
311 }
312
8963a27b 313 /* These are opened by `done' or `open_extra_files', if at all */
54bd0db4
RS
314 if (spec_outfile)
315 tabfile = spec_outfile;
316 else
8963a27b 317 tabfile = stringappend (name_base, base_length, ".c");
54bd0db4
RS
318
319#ifdef VMS
8963a27b
AD
320 attrsfile = stringappend (name_base, short_base_length, "_stype.h");
321 guardfile = stringappend (name_base, short_base_length, "_guard.c");
54bd0db4
RS
322#else
323#ifdef MSDOS
8963a27b
AD
324 attrsfile = stringappend (name_base, short_base_length, ".sth");
325 guardfile = stringappend (name_base, short_base_length, ".guc");
54bd0db4 326#else
8963a27b
AD
327 attrsfile = stringappend (name_base, short_base_length, ".stype.h");
328 guardfile = stringappend (name_base, short_base_length, ".guard.c");
54bd0db4
RS
329#endif /* not MSDOS */
330#endif /* not VMS */
8c7ebe49 331
dd60faec 332 /* Initialize the obstacks. */
8c7ebe49 333 obstack_init (&action_obstack);
dd60faec 334 obstack_init (&attrs_obstack);
896fe5c1
AD
335 obstack_init (&table_obstack);
336 obstack_init (&defines_obstack);
54bd0db4
RS
337}
338
339
340
0d533154
AD
341/*--------------------------------------------------------------------.
342| Open the output files needed only for the semantic parser. This |
343| is done when %semantic_parser is seen in the declarations section. |
344`--------------------------------------------------------------------*/
54bd0db4
RS
345
346void
bd088c91 347open_extra_files (void)
54bd0db4 348{
54bd0db4 349 int c;
a693bf18 350 char *filename;
54bd0db4 351
8963a27b 352 xfclose (fparser);
54bd0db4 353
89cab50d 354 if (!no_parser_flag)
54bd0db4 355 {
28683c54
RS
356 filename = (char *) getenv ("BISON_HAIRY");
357#ifdef MSDOS
dd60faec
AD
358 {
359 /* File doesn't exist in current directory; try in INIT
360 directory. */
361 char *cp = getenv ("INIT");
362 if (filename == 0 && cp != NULL)
363 {
364 filename = XMALLOC (char, strlen (cp) + strlen (PFILE1) + 2);
365 strcpy (filename, cp);
366 cp = filename + strlen (filename);
367 *cp++ = '/';
368 strcpy (cp, PFILE1);
369 }
370 }
54bd0db4 371#endif
8963a27b 372 fparser = xfopen (filename ? filename : PFILE1, "r");
28683c54 373 }
54bd0db4 374
8963a27b 375 fguard = xfopen (guardfile, "w");
54bd0db4
RS
376}
377
d8880f69
AD
378
379/*-----------------------------------------------------.
380| Close the open files, produce all the output files. |
381`-----------------------------------------------------*/
382
a693bf18 383void
d8880f69 384output_files (void)
a693bf18 385{
8963a27b
AD
386 xfclose (fguard);
387 xfclose (finput);
388 xfclose (fparser);
389 xfclose (foutput);
54bd0db4 390
d8880f69
AD
391 /* Output the main file. */
392 obstack_save (&table_obstack, tabfile);
393
394 /* Output the header file if wanted. */
395 if (defines_flag)
396 obstack_save (&defines_obstack, defsfile);
54bd0db4 397
d8880f69 398 /* If we output only the table, dump the actions in ACTFILE.
dd60faec 399 */
8c7ebe49 400 if (no_parser_flag)
d8880f69 401 obstack_save (&action_obstack, actfile);
dd60faec
AD
402
403 /* If we produced a semantic parser ATTRS_OBSTACK must be dumped
404 into its own file, ATTTRSFILE. */
405 if (semantic_parser)
d8880f69 406 obstack_save (&attrs_obstack, attrsfile);
54bd0db4 407}