]> git.saurik.com Git - bison.git/blob - src/files.c
Introduce obstacks.
[bison.git] / src / files.c
1 /* Open and close files for bison,
2 Copyright 1984, 1986, 1989, 1992, 2000 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 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.
10
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.
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 the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
20
21
22 #include "system.h"
23
24 #if defined (VMS) & !defined (__VMS_POSIX)
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
33 #endif
34
35 #if defined (_MSC_VER)
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
42 #endif
43
44 #include "getargs.h"
45 #include "files.h"
46 #include "xalloc.h"
47 #include "gram.h"
48 #include "complain.h"
49
50 FILE *finput = NULL;
51 FILE *foutput = NULL;
52 FILE *fdefines = NULL;
53 FILE *ftable = NULL;
54 FILE *fattrs = NULL;
55 FILE *fguard = NULL;
56 FILE *fparser = NULL;
57
58 struct obstack action_obstack;
59
60 /* File name specified with -o for the output file, or 0 if no -o. */
61 char *spec_outfile;
62
63 char *infile;
64 char *attrsfile;
65
66 static char *outfile;
67 static char *defsfile;
68 static char *tabfile;
69 static char *guardfile;
70 static char *actfile;
71 static char *tmpattrsfile;
72 static char *tmptabfile;
73 static char *tmpdefsfile;
74
75 extern char *mktemp (); /* So the compiler won't complain */
76 extern char *getenv ();
77
78 extern char *program_name;
79 \f
80
81 static char *
82 stringappend (const char *string1, int end1, const char *string2)
83 {
84 register char *ostring;
85 register char *cp;
86 register const char *cp1;
87 register int i;
88
89 cp1 = string2;
90 i = 0;
91 while (*cp1++)
92 i++;
93
94 ostring = XCALLOC (char, i + end1 + 1);
95
96 cp = ostring;
97 cp1 = string1;
98 for (i = 0; i < end1; i++)
99 *cp++ = *cp1++;
100
101 cp1 = string2;
102 while ((*cp++ = *cp1++))
103 ;
104
105 return ostring;
106 }
107
108 /*-----------------------------------------------------------------.
109 | Try to open file NAME with mode MODE, and print an error message |
110 | if fails. |
111 `-----------------------------------------------------------------*/
112
113 static FILE *
114 xfopen (const char *name, const char *mode)
115 {
116 FILE *ptr;
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
129 static int
130 xfclose (FILE *ptr)
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
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 */
146 void
147 open_files (void)
148 {
149 char *name_base;
150 #ifdef MSDOS
151 register char *cp;
152 #endif
153 char *filename;
154 int base_length;
155 int short_base_length;
156
157 #if defined (VMS) & !defined (__VMS_POSIX)
158 const char *tmp_base = "sys$scratch:b_";
159 #else
160 const char *tmp_base = "/tmp/b.";
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
171 #if (defined(_WIN32) && !defined(__CYGWIN32__))
172 tmp_base = getenv ("TEMP"); /* Windows95 defines this ... */
173 if (tmp_base == 0)
174 tmp_base = getenv ("Temp"); /* ... while NT prefers this */
175 if (tmp_base == 0)
176 tmp_base = "";
177 strlwr (infile);
178 #endif /* _WIN32 && !__CYGWIN32__ */
179
180 #if (defined(unix) || defined(__unix) || defined(__unix__) || defined(__EMX__))
181 {
182 char *tmp_ptr = getenv ("TMPDIR");
183
184 if (tmp_ptr != 0)
185 tmp_base = stringappend (tmp_ptr, strlen (tmp_ptr), "/b.");
186 }
187 #endif /* unix || __unix || __unix__ */
188
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.
194 For other output files, remove the ".c" or ".tab.c" suffix. */
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;
217 name_base = XMALLOC (char, base_length + 1);
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
232 or use y.tab.c, etc., if -y was specified. */
233
234 static char FIXED_NAME_BASE[] = "y.y";
235
236 name_base = yacc_flag ? FIXED_NAME_BASE : infile;
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
246 name_base = stringappend (name_base, short_base_length, "_tab");
247 #else
248 #ifdef MSDOS
249 name_base = stringappend (name_base, short_base_length, "_tab");
250 #else
251 name_base = stringappend (name_base, short_base_length, ".tab");
252 #endif /* not MSDOS */
253 #endif
254 base_length = short_base_length + 4;
255 }
256
257 finput = xfopen (infile, "r");
258
259 if (!no_parser_flag)
260 {
261 filename = getenv ("BISON_SIMPLE");
262 #ifdef MSDOS
263 /* File doesn't exist in current directory; try in INIT directory. */
264 cp = getenv ("INIT");
265 if (filename == 0 && cp != NULL)
266 {
267 filename = XMALLOC (char, strlen (cp) + strlen (PFILE) + 2);
268 strcpy (filename, cp);
269 cp = filename + strlen (filename);
270 *cp++ = '/';
271 strcpy (cp, PFILE);
272 }
273 #endif /* MSDOS */
274 fparser = xfopen (filename ? filename : PFILE, "r");
275 }
276
277 if (verbose_flag)
278 {
279 #ifdef MSDOS
280 outfile = stringappend (name_base, short_base_length, ".out");
281 #else
282 /* We used to use just .out if spec_name_prefix (-p) was used,
283 but that conflicts with Posix. */
284 outfile = stringappend (name_base, short_base_length, ".output");
285 #endif
286 foutput = xfopen (outfile, "w");
287 }
288
289 if (no_parser_flag)
290 {
291 /* use permanent name for actions file */
292 actfile = stringappend (name_base, short_base_length, ".act");
293 }
294
295 #ifdef MSDOS
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"));
299 #else
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"));
303 #endif /* not MSDOS */
304
305 fattrs = xfopen (tmpattrsfile, "w+");
306 ftable = xfopen (tmptabfile, "w+");
307
308 if (defines_flag)
309 {
310 defsfile = stringappend (name_base, base_length, ".h");
311 fdefines = xfopen (tmpdefsfile, "w+");
312 }
313
314 #if !(defined (MSDOS) || (defined(_WIN32) && !defined(__CYGWIN32__)))
315 unlink (tmpattrsfile);
316 unlink (tmptabfile);
317 unlink (tmpdefsfile);
318 #endif /* MSDOS || (_WIN32 && !__CYGWIN32__) */
319
320 /* These are opened by `done' or `open_extra_files', if at all */
321 if (spec_outfile)
322 tabfile = spec_outfile;
323 else
324 tabfile = stringappend (name_base, base_length, ".c");
325
326 #ifdef VMS
327 attrsfile = stringappend (name_base, short_base_length, "_stype.h");
328 guardfile = stringappend (name_base, short_base_length, "_guard.c");
329 #else
330 #ifdef MSDOS
331 attrsfile = stringappend (name_base, short_base_length, ".sth");
332 guardfile = stringappend (name_base, short_base_length, ".guc");
333 #else
334 attrsfile = stringappend (name_base, short_base_length, ".stype.h");
335 guardfile = stringappend (name_base, short_base_length, ".guard.c");
336 #endif /* not MSDOS */
337 #endif /* not VMS */
338
339 /* Setup the action obstack. */
340 obstack_init (&action_obstack);
341 }
342
343
344
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 `--------------------------------------------------------------------*/
349
350 void
351 open_extra_files (void)
352 {
353 FILE *ftmp;
354 int c;
355 char *filename;
356 #ifdef MSDOS
357 char *cp;
358 #endif
359
360 xfclose (fparser);
361
362 if (!no_parser_flag)
363 {
364 filename = (char *) getenv ("BISON_HAIRY");
365 #ifdef MSDOS
366 /* File doesn't exist in current directory; try in INIT directory. */
367 cp = getenv ("INIT");
368 if (filename == 0 && cp != NULL)
369 {
370 filename = XMALLOC (char, strlen (cp) + strlen (PFILE1) + 2);
371 strcpy (filename, cp);
372 cp = filename + strlen (filename);
373 *cp++ = '/';
374 strcpy (cp, PFILE1);
375 }
376 #endif
377 fparser = xfopen (filename ? filename : PFILE1, "r");
378 }
379
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;
387
388 fguard = xfopen (guardfile, "w");
389
390 }
391
392 void
393 done (void)
394 {
395 xfclose (fattrs);
396 xfclose (fguard);
397 xfclose (finput);
398 xfclose (fparser);
399 xfclose (foutput);
400
401 /* JF write out the output file */
402 if (!complain_message_count && ftable)
403 {
404 FILE *ftmp;
405 register int c;
406
407 ftmp = xfopen (tabfile, "w");
408 rewind (ftable);
409 while ((c = getc (ftable)) != EOF)
410 putc (c, ftmp);
411 xfclose (ftmp);
412 xfclose (ftable);
413
414 if (defines_flag)
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 }
424 }
425
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 }
433 #if defined (VMS) & !defined (__VMS_POSIX)
434 if (fattrs)
435 delete (tmpattrsfile);
436 if (ftable)
437 delete (tmptabfile);
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); */
442 #else
443 #if (defined (MSDOS) || (defined(_WIN32) && !defined(__CYGWIN32__)))
444 if (tmpattrsfile)
445 unlink (tmpattrsfile);
446 if (tmptabfile)
447 unlink (tmptabfile);
448 if (tmpdefsfile)
449 unlink (tmpdefsfile);
450 #endif /* MSDOS || (_WIN32 && !__CYGWIN32__) */
451 /* Don't call exit again, we're in atexit ().
452 exit (complain_message_count ? 1 : 0); */
453 #endif /* not VMS, or __VMS_POSIX */
454 }