]> git.saurik.com Git - bison.git/blame - src/files.c
Comment wording fix.
[bison.git] / src / files.c
CommitLineData
82129ef5
PE
1/* Open and close files for Bison.
2
592e8d4d 3 Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002
b85810ae 4 Free Software Foundation, Inc.
54bd0db4 5
ceed8467 6 This file is part of Bison, the GNU Compiler Compiler.
54bd0db4 7
ceed8467
AD
8 Bison is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
54bd0db4 12
ceed8467
AD
13 Bison is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
54bd0db4 17
ceed8467
AD
18 You should have received a copy of the GNU General Public License
19 along with Bison; see the file COPYING. If not, write to the Free
20 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
54bd0db4
RS
22
23
9eceb6c6 24#include "system.h"
6d441fc3
PE
25
26#include <error.h>
27#include <get-errno.h>
28
29#include "complain.h"
54bd0db4 30#include "files.h"
6d441fc3 31#include "getargs.h"
54bd0db4
RS
32#include "gram.h"
33
ae404801 34/* From basename.c. Almost a lie, as it returns a char *. */
d33cb3ae 35const char *base_name (char const *name);
ae404801 36
54bd0db4 37FILE *finput = NULL;
54bd0db4 38
0dd1580a
RA
39struct obstack pre_prologue_obstack;
40struct obstack post_prologue_obstack;
8c7ebe49 41
b5b61c61
AD
42/* Initializing some values below (such SPEC_NAME_PREFIX to `yy') is
43 tempting, but don't do that: for the time being our handling of the
44 %directive vs --option leaves precedence to the options by deciding
45 that if a %directive sets a variable which is really set (i.e., not
46 NULL), then the %directive is ignored. As a result, %name-prefix,
47 for instance, will not be honored. */
48
b0ce6046 49char *spec_outfile = NULL; /* for -o. */
f0130d39 50char *spec_file_prefix = NULL; /* for -b. */
b5b61c61 51const char *spec_name_prefix = NULL; /* for -p. */
342b8b6e
AD
52char *spec_verbose_file = NULL; /* for --verbose. */
53char *spec_graph_file = NULL; /* for -g. */
54char *spec_defines_file = NULL; /* for --defines. */
ea52d706 55char *parser_file_name = NULL;
54bd0db4 56
6d441fc3
PE
57uniqstr grammar_file = NULL;
58uniqstr current_file = NULL;
4a120d45 59
ae404801 60static char *full_base_name = NULL;
b85810ae
AD
61
62/* Prefix used to generate output file names. */
9b3add5b 63char *short_base_name = NULL;
27110317 64
f0130d39 65/* C source file extension (the parser source). */
7333d403 66const char *src_extension = NULL;
f0130d39 67/* Header file extension (if option ``-d'' is specified). */
7333d403 68const char *header_extension = NULL;
54bd0db4 69\f
358c15b7
AD
70/*-----------------------------------------------------------------.
71| Return a newly allocated string composed of the concatenation of |
6d441fc3 72| STR1, and STR2. |
358c15b7 73`-----------------------------------------------------------------*/
54bd0db4 74
6d441fc3
PE
75static char *
76concat2 (char const *str1, char const *str2)
54bd0db4 77{
6d441fc3 78 size_t len = strlen (str1) + strlen (str2);
82129ef5 79 char *res = xmalloc (len + 1);
358c15b7 80 char *cp;
6d441fc3
PE
81 cp = stpcpy (res, str1);
82 cp = stpcpy (cp, str2);
358c15b7 83 return res;
54bd0db4
RS
84}
85
cfe5fbc0
AD
86/*-----------------------------------------------------------------.
87| Try to open file NAME with mode MODE, and print an error message |
88| if fails. |
89`-----------------------------------------------------------------*/
54bd0db4 90
ff61dabd 91FILE *
8963a27b 92xfopen (const char *name, const char *mode)
cfe5fbc0 93{
8963a27b 94 FILE *ptr;
cfe5fbc0
AD
95
96 ptr = fopen (name, mode);
97 if (!ptr)
6d441fc3 98 error (EXIT_FAILURE, get_errno (), _("cannot open file `%s'"), name);
cfe5fbc0
AD
99
100 return ptr;
101}
102
103/*-------------------------------------------------------------.
104| Try to close file PTR, and print an error message if fails. |
105`-------------------------------------------------------------*/
106
e63ee1f1 107void
8963a27b 108xfclose (FILE *ptr)
cfe5fbc0 109{
cfe5fbc0 110 if (ptr == NULL)
e63ee1f1 111 return;
cfe5fbc0 112
e63ee1f1
PE
113 if (ferror (ptr))
114 error (EXIT_FAILURE, 0, _("I/O error"));
cfe5fbc0 115
e63ee1f1 116 if (fclose (ptr) != 0)
6d441fc3 117 error (EXIT_FAILURE, get_errno (), _("cannot close file"));
cfe5fbc0
AD
118}
119\f
f0130d39 120
234a3be3
AD
121/*----------------------------------------------------------------.
122| Compute BASE_NAME, SHORT_BASE_NAME and output files extensions. |
123`----------------------------------------------------------------*/
124
b0ce6046 125/* Replace all characters FROM by TO in the string IN.
f0130d39 126 and returns a new allocated string. */
234a3be3 127static char *
f0130d39 128tr (const char *in, char from, char to)
234a3be3
AD
129{
130 char *temp;
82129ef5 131 char *out = xmalloc (strlen (in) + 1);
234a3be3
AD
132
133 for (temp = out; *in; in++, out++)
134 if (*in == from)
135 *out = to;
136 else
137 *out = *in;
138 *out = 0;
139 return (temp);
140}
141
234a3be3
AD
142/* Computes extensions from the grammar file extension. */
143static void
f0130d39 144compute_exts_from_gf (const char *ext)
234a3be3 145{
342b8b6e
AD
146 src_extension = tr (ext, 'y', 'c');
147 src_extension = tr (src_extension, 'Y', 'C');
148 header_extension = tr (ext, 'y', 'h');
149 header_extension = tr (header_extension, 'Y', 'H');
234a3be3
AD
150}
151
152/* Computes extensions from the given c source file extension. */
153static void
f0130d39 154compute_exts_from_src (const char *ext)
234a3be3 155{
4ecbf796
MA
156 /* We use this function when the user specifies `-o' or `--output',
157 so the extenions must be computed unconditionally from the file name
158 given by this option. */
f0130d39
AD
159 src_extension = xstrdup (ext);
160 header_extension = tr (ext, 'c', 'h');
161 header_extension = tr (header_extension, 'C', 'H');
234a3be3 162}
d8880f69 163
ae404801
AD
164
165/* Decompose FILENAME in four parts: *BASE, *TAB, and *EXT, the fourth
166 part, (the directory) is ranging from FILENAME to the char before
167 *BASE, so we don't need an additional parameter.
168
169 *EXT points to the last period in the basename, or NULL if none.
170
171 If there is no *EXT, *TAB is NULL. Otherwise, *TAB points to
172 `.tab' or `_tab' if present right before *EXT, or is NULL. *TAB
173 cannot be equal to *BASE.
174
175 None are allocated, they are simply pointers to parts of FILENAME.
176 Examples:
177
178 '/tmp/foo.tab.c' -> *BASE = 'foo.tab.c', *TAB = '.tab.c', *EXT =
179 '.c'
180
181 'foo.c' -> *BASE = 'foo.c', *TAB = NULL, *EXT = '.c'
182
183 'tab.c' -> *BASE = 'tab.c', *TAB = NULL, *EXT = '.c'
184
185 '.tab.c' -> *BASE = '.tab.c', *TAB = NULL, *EXT = '.c'
186
187 'foo.tab' -> *BASE = 'foo.tab', *TAB = NULL, *EXT = '.tab'
188
189 'foo_tab' -> *BASE = 'foo_tab', *TAB = NULL, *EXT = NULL
190
191 'foo' -> *BASE = 'foo', *TAB = NULL, *EXT = NULL. */
192
193static void
194filename_split (const char *filename,
195 const char **base, const char **tab, const char **ext)
196{
197 *base = base_name (filename);
198
199 /* Look for the extension, i.e., look for the last dot. */
200 *ext = strrchr (*base, '.');
201 *tab = NULL;
202
82129ef5 203 /* If there is an extension, check if there is a `.tab' part right
ae404801 204 before. */
82129ef5
PE
205 if (*ext)
206 {
207 size_t baselen = *ext - *base;
208 size_t dottablen = 4;
209 if (dottablen < baselen
210 && (strncmp (*ext - dottablen, ".tab", dottablen) == 0
211 || strncmp (*ext - dottablen, "_tab", dottablen) == 0))
212 *tab = *ext - dottablen;
213 }
ae404801
AD
214}
215
216
19c50364
AD
217/* FIXME: Should use xstrndup. */
218
219static void
27110317 220compute_base_names (void)
54bd0db4 221{
ae404801 222 const char *base, *tab, *ext;
b0ce6046 223
19c50364
AD
224 /* If --output=foo.c was specified (SPEC_OUTFILE == foo.c),
225 BASE_NAME and SHORT_BASE_NAME are `foo'.
54bd0db4 226
19c50364
AD
227 If --output=foo.tab.c was specified, BASE_NAME is `foo.tab' and
228 SHORT_BASE_NAME is `foo'.
229
230 The precise -o name will be used for FTABLE. For other output
231 files, remove the ".c" or ".tab.c" suffix. */
54bd0db4
RS
232 if (spec_outfile)
233 {
ae404801
AD
234 filename_split (spec_outfile, &base, &tab, &ext);
235
236 /* The full base name goes up the EXT, excluding it. */
237 full_base_name =
238 xstrndup (spec_outfile,
239 (strlen (spec_outfile) - (ext ? strlen (ext) : 0)));
b85810ae 240
ae404801
AD
241 /* The short base name goes up to TAB, excluding it. */
242 short_base_name =
243 xstrndup (spec_outfile,
244 (strlen (spec_outfile)
245 - (tab ? strlen (tab) : (ext ? strlen (ext) : 0))));
246
ae404801
AD
247 if (ext)
248 compute_exts_from_src (ext);
54bd0db4 249 }
19c50364 250
ae404801
AD
251 /* If --file-prefix=foo was specified, FULL_BASE_NAME = `foo.tab'
252 and SHORT_BASE_NAME = `foo'.
19c50364
AD
253
254 Construct names from it. */
ae404801 255 else
54bd0db4 256 {
ae404801
AD
257 if (spec_file_prefix)
258 {
259 /* If --file-prefix=foo was specified, SHORT_BASE_NAME =
260 `foo'. */
261 short_base_name = xstrdup (spec_file_prefix);
262 }
263 else if (yacc_flag)
264 {
265 /* If --yacc, then the output is `y.tab.c'. */
266 short_base_name = xstrdup ("y");
267 }
268 else
269 {
270 /* Otherwise, the short base name is computed from the input
8c165d89 271 grammar: `foo/bar.yy' => `bar'. */
95612cfa 272 filename_split (grammar_file, &base, &tab, &ext);
ae404801 273 short_base_name =
8c165d89
AD
274 xstrndup (base,
275 (strlen (base) - (ext ? strlen (ext) : 0)));
ae404801 276 }
9b3add5b 277
82129ef5 278 full_base_name = xmalloc (strlen (short_base_name)
6d441fc3
PE
279 + strlen (TAB_EXT) + 1);
280 stpcpy (stpcpy (full_base_name, short_base_name), TAB_EXT);
ae404801
AD
281
282 /* Computes the extensions from the grammar file name. */
95612cfa 283 filename_split (grammar_file, &base, &tab, &ext);
5e5d5415 284 if (ext && !yacc_flag)
ae404801 285 compute_exts_from_gf (ext);
54bd0db4 286 }
19c50364
AD
287}
288
342b8b6e
AD
289/*-------------------------------------------------------.
290| Close the open files, compute the output files names. |
291`-------------------------------------------------------*/
292
293void
294compute_output_file_names (void)
295{
296 compute_base_names ();
297
298 /* If not yet done. */
299 if (!src_extension)
300 src_extension = ".c";
301 if (!header_extension)
302 header_extension = ".h";
fdbcd8e2 303
fc6edc45 304 parser_file_name =
6d441fc3 305 spec_outfile ? spec_outfile : concat2 (full_base_name, src_extension);
fdbcd8e2 306
342b8b6e
AD
307 /* It the defines filename if not given, we create it. */
308 if (!spec_defines_file)
6d441fc3 309 spec_defines_file = concat2 (full_base_name, header_extension);
342b8b6e
AD
310
311 /* It the graph filename if not given, we create it. */
312 if (!spec_graph_file)
6d441fc3 313 spec_graph_file = concat2 (short_base_name, ".vcg");
342b8b6e 314
6d441fc3 315 spec_verbose_file = concat2 (short_base_name, OUTPUT_EXT);
342b8b6e 316}