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