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