]> git.saurik.com Git - bison.git/blame - src/files.c
Introduce obstacks.
[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;
52FILE *fdefines = NULL;
53FILE *ftable = NULL;
54FILE *fattrs = NULL;
55FILE *fguard = NULL;
54bd0db4
RS
56FILE *fparser = NULL;
57
8c7ebe49
AD
58struct obstack action_obstack;
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;
71static char *tmpattrsfile;
72static char *tmptabfile;
73static char *tmpdefsfile;
54bd0db4 74
8963a27b
AD
75extern char *mktemp (); /* So the compiler won't complain */
76extern char *getenv ();
4a120d45 77
54bd0db4 78extern char *program_name;
54bd0db4
RS
79\f
80
8963a27b 81static char *
4a120d45 82stringappend (const char *string1, int end1, const char *string2)
54bd0db4
RS
83{
84 register char *ostring;
4a120d45
JT
85 register char *cp;
86 register const char *cp1;
54bd0db4
RS
87 register int i;
88
4a120d45
JT
89 cp1 = string2;
90 i = 0;
8963a27b
AD
91 while (*cp1++)
92 i++;
54bd0db4 93
d7913476 94 ostring = XCALLOC (char, i + end1 + 1);
54bd0db4
RS
95
96 cp = ostring;
97 cp1 = string1;
98 for (i = 0; i < end1; i++)
99 *cp++ = *cp1++;
100
101 cp1 = string2;
bd088c91
JT
102 while ((*cp++ = *cp1++))
103 ;
54bd0db4
RS
104
105 return ostring;
106}
107
cfe5fbc0
AD
108/*-----------------------------------------------------------------.
109| Try to open file NAME with mode MODE, and print an error message |
110| if fails. |
111`-----------------------------------------------------------------*/
54bd0db4 112
cfe5fbc0 113static FILE *
8963a27b 114xfopen (const char *name, const char *mode)
cfe5fbc0 115{
8963a27b 116 FILE *ptr;
cfe5fbc0
AD
117
118 ptr = fopen (name, mode);
119 if (!ptr)
120 error (2, errno, _("cannot open file `%s'"), name);
121
122 return ptr;
123}
124
125/*-------------------------------------------------------------.
126| Try to close file PTR, and print an error message if fails. |
127`-------------------------------------------------------------*/
128
129static int
8963a27b 130xfclose (FILE *ptr)
cfe5fbc0
AD
131{
132 int result;
133
134 if (ptr == NULL)
135 return 0;
136
137 result = fclose (ptr);
138 if (result == EOF)
139 error (2, errno, _("cannot close file"));
140
141 return result;
142}
143\f
54bd0db4
RS
144/* JF this has been hacked to death. Nowaday it sets up the file names for
145 the output files, and opens the tmp files and the parser */
146void
8963a27b 147open_files (void)
54bd0db4
RS
148{
149 char *name_base;
a693bf18 150#ifdef MSDOS
54bd0db4 151 register char *cp;
a693bf18 152#endif
54bd0db4
RS
153 char *filename;
154 int base_length;
155 int short_base_length;
156
fcca25ad 157#if defined (VMS) & !defined (__VMS_POSIX)
4a120d45 158 const char *tmp_base = "sys$scratch:b_";
54bd0db4 159#else
4a120d45 160 const char *tmp_base = "/tmp/b.";
54bd0db4
RS
161#endif
162 int tmp_len;
163
164#ifdef MSDOS
165 tmp_base = getenv ("TMP");
166 if (tmp_base == 0)
167 tmp_base = "";
168 strlwr (infile);
169#endif /* MSDOS */
170
e0672a61 171#if (defined(_WIN32) && !defined(__CYGWIN32__))
8963a27b 172 tmp_base = getenv ("TEMP"); /* Windows95 defines this ... */
e0672a61 173 if (tmp_base == 0)
8963a27b 174 tmp_base = getenv ("Temp"); /* ... while NT prefers this */
e0672a61
RS
175 if (tmp_base == 0)
176 tmp_base = "";
177 strlwr (infile);
178#endif /* _WIN32 && !__CYGWIN32__ */
179
5191ef24 180#if (defined(unix) || defined(__unix) || defined(__unix__) || defined(__EMX__))
bd088c91 181 {
8963a27b 182 char *tmp_ptr = getenv ("TMPDIR");
bd088c91
JT
183
184 if (tmp_ptr != 0)
185 tmp_base = stringappend (tmp_ptr, strlen (tmp_ptr), "/b.");
186 }
8963a27b 187#endif /* unix || __unix || __unix__ */
bd088c91 188
54bd0db4
RS
189 tmp_len = strlen (tmp_base);
190
191 if (spec_outfile)
192 {
193 /* -o was specified. The precise -o name will be used for ftable.
8963a27b 194 For other output files, remove the ".c" or ".tab.c" suffix. */
54bd0db4
RS
195 name_base = spec_outfile;
196#ifdef MSDOS
197 strlwr (name_base);
198#endif /* MSDOS */
199 /* BASE_LENGTH includes ".tab" but not ".c". */
200 base_length = strlen (name_base);
201 if (!strcmp (name_base + base_length - 2, ".c"))
202 base_length -= 2;
203 /* SHORT_BASE_LENGTH includes neither ".tab" nor ".c". */
204 short_base_length = base_length;
205 if (!strncmp (name_base + short_base_length - 4, ".tab", 4))
206 short_base_length -= 4;
207 else if (!strncmp (name_base + short_base_length - 4, "_tab", 4))
208 short_base_length -= 4;
209 }
210 else if (spec_file_prefix)
211 {
212 /* -b was specified. Construct names from it. */
213 /* SHORT_BASE_LENGTH includes neither ".tab" nor ".c". */
214 short_base_length = strlen (spec_file_prefix);
215 /* Count room for `.tab'. */
216 base_length = short_base_length + 4;
d7913476 217 name_base = XMALLOC (char, base_length + 1);
54bd0db4
RS
218 /* Append `.tab'. */
219 strcpy (name_base, spec_file_prefix);
220#ifdef VMS
221 strcat (name_base, "_tab");
222#else
223 strcat (name_base, ".tab");
224#endif
225#ifdef MSDOS
226 strlwr (name_base);
227#endif /* MSDOS */
228 }
229 else
230 {
231 /* -o was not specified; compute output file name from input
8963a27b 232 or use y.tab.c, etc., if -y was specified. */
54bd0db4 233
4a120d45
JT
234 static char FIXED_NAME_BASE[] = "y.y";
235
89cab50d 236 name_base = yacc_flag ? FIXED_NAME_BASE : infile;
54bd0db4
RS
237
238 /* BASE_LENGTH gets length of NAME_BASE, sans ".y" suffix if any. */
239
240 base_length = strlen (name_base);
241 if (!strcmp (name_base + base_length - 2, ".y"))
242 base_length -= 2;
243 short_base_length = base_length;
244
245#ifdef VMS
8963a27b 246 name_base = stringappend (name_base, short_base_length, "_tab");
54bd0db4
RS
247#else
248#ifdef MSDOS
8963a27b 249 name_base = stringappend (name_base, short_base_length, "_tab");
54bd0db4 250#else
8963a27b 251 name_base = stringappend (name_base, short_base_length, ".tab");
54bd0db4
RS
252#endif /* not MSDOS */
253#endif
254 base_length = short_base_length + 4;
255 }
256
8963a27b 257 finput = xfopen (infile, "r");
54bd0db4 258
89cab50d 259 if (!no_parser_flag)
54bd0db4 260 {
8963a27b 261 filename = getenv ("BISON_SIMPLE");
28683c54
RS
262#ifdef MSDOS
263 /* File doesn't exist in current directory; try in INIT directory. */
8963a27b 264 cp = getenv ("INIT");
28683c54 265 if (filename == 0 && cp != NULL)
8963a27b 266 {
d7913476 267 filename = XMALLOC (char, strlen (cp) + strlen (PFILE) + 2);
8963a27b
AD
268 strcpy (filename, cp);
269 cp = filename + strlen (filename);
270 *cp++ = '/';
271 strcpy (cp, PFILE);
272 }
54bd0db4 273#endif /* MSDOS */
8963a27b 274 fparser = xfopen (filename ? filename : PFILE, "r");
28683c54 275 }
54bd0db4 276
89cab50d 277 if (verbose_flag)
54bd0db4
RS
278 {
279#ifdef MSDOS
8963a27b 280 outfile = stringappend (name_base, short_base_length, ".out");
54bd0db4
RS
281#else
282 /* We used to use just .out if spec_name_prefix (-p) was used,
8963a27b
AD
283 but that conflicts with Posix. */
284 outfile = stringappend (name_base, short_base_length, ".output");
54bd0db4 285#endif
8963a27b 286 foutput = xfopen (outfile, "w");
54bd0db4
RS
287 }
288
89cab50d 289 if (no_parser_flag)
28683c54
RS
290 {
291 /* use permanent name for actions file */
8963a27b 292 actfile = stringappend (name_base, short_base_length, ".act");
a0f6b076 293 }
28683c54 294
54bd0db4 295#ifdef MSDOS
8963a27b
AD
296 tmpattrsfile = mktemp (stringappend (tmp_base, tmp_len, "atXXXXXX"));
297 tmptabfile = mktemp (stringappend (tmp_base, tmp_len, "taXXXXXX"));
298 tmpdefsfile = mktemp (stringappend (tmp_base, tmp_len, "deXXXXXX"));
54bd0db4 299#else
8963a27b
AD
300 tmpattrsfile = mktemp (stringappend (tmp_base, tmp_len, "attrs.XXXXXX"));
301 tmptabfile = mktemp (stringappend (tmp_base, tmp_len, "tab.XXXXXX"));
302 tmpdefsfile = mktemp (stringappend (tmp_base, tmp_len, "defs.XXXXXX"));
54bd0db4
RS
303#endif /* not MSDOS */
304
8963a27b
AD
305 fattrs = xfopen (tmpattrsfile, "w+");
306 ftable = xfopen (tmptabfile, "w+");
54bd0db4 307
89cab50d 308 if (defines_flag)
54bd0db4 309 {
8963a27b
AD
310 defsfile = stringappend (name_base, base_length, ".h");
311 fdefines = xfopen (tmpdefsfile, "w+");
54bd0db4
RS
312 }
313
e0672a61 314#if !(defined (MSDOS) || (defined(_WIN32) && !defined(__CYGWIN32__)))
8963a27b
AD
315 unlink (tmpattrsfile);
316 unlink (tmptabfile);
317 unlink (tmpdefsfile);
e0672a61 318#endif /* MSDOS || (_WIN32 && !__CYGWIN32__) */
54bd0db4 319
8963a27b 320 /* These are opened by `done' or `open_extra_files', if at all */
54bd0db4
RS
321 if (spec_outfile)
322 tabfile = spec_outfile;
323 else
8963a27b 324 tabfile = stringappend (name_base, base_length, ".c");
54bd0db4
RS
325
326#ifdef VMS
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#else
330#ifdef MSDOS
8963a27b
AD
331 attrsfile = stringappend (name_base, short_base_length, ".sth");
332 guardfile = stringappend (name_base, short_base_length, ".guc");
54bd0db4 333#else
8963a27b
AD
334 attrsfile = stringappend (name_base, short_base_length, ".stype.h");
335 guardfile = stringappend (name_base, short_base_length, ".guard.c");
54bd0db4
RS
336#endif /* not MSDOS */
337#endif /* not VMS */
8c7ebe49
AD
338
339 /* Setup the action obstack. */
340 obstack_init (&action_obstack);
54bd0db4
RS
341}
342
343
344
0d533154
AD
345/*--------------------------------------------------------------------.
346| Open the output files needed only for the semantic parser. This |
347| is done when %semantic_parser is seen in the declarations section. |
348`--------------------------------------------------------------------*/
54bd0db4
RS
349
350void
bd088c91 351open_extra_files (void)
54bd0db4
RS
352{
353 FILE *ftmp;
354 int c;
a693bf18
JT
355 char *filename;
356#ifdef MSDOS
357 char *cp;
358#endif
54bd0db4 359
8963a27b 360 xfclose (fparser);
54bd0db4 361
89cab50d 362 if (!no_parser_flag)
54bd0db4 363 {
28683c54
RS
364 filename = (char *) getenv ("BISON_HAIRY");
365#ifdef MSDOS
366 /* File doesn't exist in current directory; try in INIT directory. */
8963a27b 367 cp = getenv ("INIT");
28683c54 368 if (filename == 0 && cp != NULL)
8963a27b 369 {
d7913476 370 filename = XMALLOC (char, strlen (cp) + strlen (PFILE1) + 2);
8963a27b
AD
371 strcpy (filename, cp);
372 cp = filename + strlen (filename);
373 *cp++ = '/';
374 strcpy (cp, PFILE1);
375 }
54bd0db4 376#endif
8963a27b 377 fparser = xfopen (filename ? filename : PFILE1, "r");
28683c54 378 }
54bd0db4 379
8963a27b
AD
380 /* JF change from inline attrs file to separate one */
381 ftmp = xfopen (attrsfile, "w");
382 rewind (fattrs);
383 while ((c = getc (fattrs)) != EOF) /* Thank god for buffering */
384 putc (c, ftmp);
385 xfclose (fattrs);
386 fattrs = ftmp;
54bd0db4 387
8963a27b 388 fguard = xfopen (guardfile, "w");
54bd0db4
RS
389
390}
391
a693bf18 392void
a0f6b076 393done (void)
a693bf18 394{
8963a27b
AD
395 xfclose (fattrs);
396 xfclose (fguard);
397 xfclose (finput);
398 xfclose (fparser);
399 xfclose (foutput);
54bd0db4 400
a0f6b076
AD
401 /* JF write out the output file */
402 if (!complain_message_count && ftable)
54bd0db4
RS
403 {
404 FILE *ftmp;
405 register int c;
406
8963a27b
AD
407 ftmp = xfopen (tabfile, "w");
408 rewind (ftable);
409 while ((c = getc (ftable)) != EOF)
410 putc (c, ftmp);
411 xfclose (ftmp);
412 xfclose (ftable);
54bd0db4 413
89cab50d 414 if (defines_flag)
8963a27b
AD
415 {
416 ftmp = xfopen (defsfile, "w");
417 fflush (fdefines);
418 rewind (fdefines);
419 while ((c = getc (fdefines)) != EOF)
420 putc (c, ftmp);
421 xfclose (ftmp);
422 xfclose (fdefines);
423 }
54bd0db4
RS
424 }
425
8c7ebe49
AD
426 if (no_parser_flag)
427 {
428 FILE *faction = xfopen (actfile, "w");
429 size_t size = obstack_object_size (&action_obstack);
430 fwrite (obstack_finish (&action_obstack), 1, size, faction);
431 fclose (faction);
432 }
fcca25ad 433#if defined (VMS) & !defined (__VMS_POSIX)
54bd0db4 434 if (fattrs)
8963a27b 435 delete (tmpattrsfile);
54bd0db4 436 if (ftable)
8963a27b 437 delete (tmptabfile);
a0f6b076
AD
438/* Don't call exit again, we're in atexit ().
439 if (!complain_message_count)
440 sys$exit(SS$_NORMAL);
441 sys$exit(SS$_ABORT); */
54bd0db4 442#else
e0672a61 443#if (defined (MSDOS) || (defined(_WIN32) && !defined(__CYGWIN32__)))
8963a27b
AD
444 if (tmpattrsfile)
445 unlink (tmpattrsfile);
446 if (tmptabfile)
447 unlink (tmptabfile);
448 if (tmpdefsfile)
449 unlink (tmpdefsfile);
e0672a61 450#endif /* MSDOS || (_WIN32 && !__CYGWIN32__) */
a0f6b076
AD
451/* Don't call exit again, we're in atexit ().
452 exit (complain_message_count ? 1 : 0); */
fcca25ad 453#endif /* not VMS, or __VMS_POSIX */
54bd0db4 454}