]> git.saurik.com Git - bison.git/blob - src/files.c
* src/files.c (open_files): Yipee! We no longer need all the code
[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 # ifndef BISON_SIMPLE
26 # define BISON_SIMPLE "GNU_BISON:[000000]BISON.SIMPLE"
27 # endif
28 # ifndef BISON_HAIRY
29 # define BISON_HARIRY "GNU_BISON:[000000]BISON.HAIRY"
30 # endif
31 #endif
32
33 #if defined (_MSC_VER)
34 # ifndef BISON_SIMPLE
35 # define BISON_SIMPLE "c:/usr/local/lib/bison.simple"
36 # endif
37 # ifndef BISON_HAIRY
38 # define BISON_HAIRY "c:/usr/local/lib/bison.hairy"
39 # endif
40 #endif
41
42 #include "getargs.h"
43 #include "files.h"
44 #include "xalloc.h"
45 #include "gram.h"
46 #include "complain.h"
47
48 FILE *finput = NULL;
49 FILE *foutput = NULL;
50 FILE *fguard = NULL;
51 FILE *fparser = NULL;
52
53 struct obstack action_obstack;
54 struct obstack attrs_obstack;
55 struct obstack table_obstack;
56 struct obstack defines_obstack;
57
58 /* File name specified with -o for the output file, or 0 if no -o. */
59 char *spec_outfile;
60
61 char *infile;
62 char *attrsfile;
63
64 static char *outfile;
65 static char *defsfile;
66 static char *tabfile;
67 static char *guardfile;
68 static char *actfile;
69 \f
70 /*-----------------------------------------------------------------.
71 | Return a newly allocated string composed of the concatenation of |
72 | the END1 first chars of STRING1, and STRING2. |
73 `-----------------------------------------------------------------*/
74
75 static char *
76 stringappend (const char *string1, int end1, const char *string2)
77 {
78 char *res;
79 char *cp;
80 const char *cp1;
81 int i;
82
83 cp1 = string2;
84 i = 0;
85 while (*cp1++)
86 i++;
87
88 res = XCALLOC (char, i + end1 + 1);
89
90 cp = res;
91 cp1 = string1;
92 for (i = 0; i < end1; i++)
93 *cp++ = *cp1++;
94
95 cp1 = string2;
96 while ((*cp++ = *cp1++))
97 ;
98
99 return res;
100 }
101
102 /*-----------------------------------------------------------------.
103 | Try to open file NAME with mode MODE, and print an error message |
104 | if fails. |
105 `-----------------------------------------------------------------*/
106
107 static FILE *
108 xfopen (const char *name, const char *mode)
109 {
110 FILE *ptr;
111
112 ptr = fopen (name, mode);
113 if (!ptr)
114 error (2, errno, _("cannot open file `%s'"), name);
115
116 return ptr;
117 }
118
119 /*-------------------------------------------------------------.
120 | Try to close file PTR, and print an error message if fails. |
121 `-------------------------------------------------------------*/
122
123 static int
124 xfclose (FILE *ptr)
125 {
126 int result;
127
128 if (ptr == NULL)
129 return 0;
130
131 result = fclose (ptr);
132 if (result == EOF)
133 error (2, errno, _("cannot close file"));
134
135 return result;
136 }
137
138 /*--------------------------------------------------.
139 | Save the content of the obstack OBS in FILENAME. |
140 `--------------------------------------------------*/
141
142 static void
143 obstack_save (struct obstack *obs, const char *filename)
144 {
145 FILE *out = xfopen (filename, "w");
146 size_t size = obstack_object_size (obs);
147 fwrite (obstack_finish (obs), 1, size, out);
148 xfclose (out);
149 }
150
151
152 static const char *
153 skeleton_find (const char *envvar, const char *skeleton)
154 {
155 const char *res = getenv (envvar);
156
157 #ifdef MSDOS
158 const char *cp;
159
160 /* File doesn't exist in current directory; try in INIT directory. */
161 if (!res && (cp = getenv ("INIT")))
162 {
163 res = XMALLOC (char, strlen (cp) + strlen (skeleton) + 2);
164 sprintf (res, "%s%c%s", cp, '/', skeleton);
165 }
166 #endif /* !MSDOS */
167
168 if (!res)
169 res = skeleton;
170
171 return res;
172 }
173
174 \f
175 /*-----------------------------------------------------------------.
176 | Open the input file. Look for the skeletons. Find the names of |
177 | the output files. Prepare the obstacks. |
178 `-----------------------------------------------------------------*/
179
180 void
181 open_files (void)
182 {
183 char *name_base;
184 #ifdef MSDOS
185 register char *cp;
186 #endif
187 int base_length;
188 int short_base_length;
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 strcat (name_base, EXT_TAB);
220 #ifdef MSDOS
221 strlwr (name_base);
222 #endif /* MSDOS */
223 }
224 else
225 {
226 /* -o was not specified; compute output file name from input
227 or use y.tab.c, etc., if -y was specified. */
228
229 static char FIXED_NAME_BASE[] = "y.y";
230
231 name_base = yacc_flag ? FIXED_NAME_BASE : infile;
232
233 /* BASE_LENGTH gets length of NAME_BASE, sans ".y" suffix if any. */
234
235 base_length = strlen (name_base);
236 if (!strcmp (name_base + base_length - 2, ".y"))
237 base_length -= 2;
238 short_base_length = base_length;
239
240 name_base = stringappend (name_base, short_base_length, EXT_TAB);
241 base_length = short_base_length + 4;
242 }
243
244 finput = xfopen (infile, "r");
245
246 if (!no_parser_flag)
247 fparser = xfopen (skeleton_find ("BISON_SIMPLE", BISON_SIMPLE), "r");
248
249 if (verbose_flag)
250 {
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, EXT_OUTPUT);
254 foutput = xfopen (outfile, "w");
255 }
256
257 if (no_parser_flag)
258 {
259 /* use permanent name for actions file */
260 actfile = stringappend (name_base, short_base_length, ".act");
261 }
262
263 if (defines_flag)
264 {
265 defsfile = stringappend (name_base, base_length, ".h");
266 }
267
268 /* These are opened by `done' or `open_extra_files', if at all */
269 if (spec_outfile)
270 tabfile = spec_outfile;
271 else
272 tabfile = stringappend (name_base, base_length, ".c");
273
274 attrsfile = stringappend (name_base, short_base_length, EXT_STYPE_H);
275 guardfile = stringappend (name_base, short_base_length, EXT_GUARD_C);
276
277 /* Initialize the obstacks. */
278 obstack_init (&action_obstack);
279 obstack_init (&attrs_obstack);
280 obstack_init (&table_obstack);
281 obstack_init (&defines_obstack);
282 }
283
284
285
286 /*--------------------------------------------------------------------.
287 | Open the output files needed only for the semantic parser. This |
288 | is done when %semantic_parser is seen in the declarations section. |
289 `--------------------------------------------------------------------*/
290
291 void
292 open_extra_files (void)
293 {
294 xfclose (fparser);
295
296 if (!no_parser_flag)
297 fparser = xfopen (skeleton_find ("BISON_HAIRY", BISON_HAIRY), "r");
298 fguard = xfopen (guardfile, "w");
299 }
300
301
302 /*-----------------------------------------------------.
303 | Close the open files, produce all the output files. |
304 `-----------------------------------------------------*/
305
306 void
307 output_files (void)
308 {
309 xfclose (fguard);
310 xfclose (finput);
311 xfclose (fparser);
312 xfclose (foutput);
313
314 /* Output the main file. */
315 obstack_save (&table_obstack, tabfile);
316
317 /* Output the header file if wanted. */
318 if (defines_flag)
319 obstack_save (&defines_obstack, defsfile);
320
321 /* If we output only the table, dump the actions in ACTFILE.
322 */
323 if (no_parser_flag)
324 obstack_save (&action_obstack, actfile);
325
326 /* If we produced a semantic parser ATTRS_OBSTACK must be dumped
327 into its own file, ATTTRSFILE. */
328 if (semantic_parser)
329 obstack_save (&attrs_obstack, attrsfile);
330 }