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