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