]> git.saurik.com Git - bison.git/blame - src/files.c
First set of tests: use the `calc' example from the documentation.
[bison.git] / src / files.c
CommitLineData
54bd0db4 1/* Open and close files for bison,
28683c54 2 Copyright (C) 1984, 1986, 1989, 1992 Free Software Foundation, Inc.
54bd0db4
RS
3
4This file is part of Bison, the GNU Compiler Compiler.
5
6Bison is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11Bison is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with Bison; see the file COPYING. If not, write to
c49a8e71
JT
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
54bd0db4
RS
20
21
9eceb6c6
JT
22#include "system.h"
23
fcca25ad 24#if defined (VMS) & !defined (__VMS_POSIX)
54bd0db4
RS
25#include <ssdef.h>
26#define unlink delete
27#ifndef XPFILE
28#define XPFILE "GNU_BISON:[000000]BISON.SIMPLE"
29#endif
30#ifndef XPFILE1
31#define XPFILE1 "GNU_BISON:[000000]BISON.HAIRY"
32#endif
33#endif
34
6a5705cf
RS
35#if defined (_MSC_VER)
36#ifndef XPFILE
37#define XPFILE "c:/usr/local/lib/bison.simple"
38#endif
39#ifndef XPFILE1
40#define XPFILE1 "c:/usr/local/lib/bison.hairy"
41#endif
42#endif
43
54bd0db4 44#include <stdio.h>
dad49092
JT
45
46#ifdef HAVE_UNISTD_H
47#include <unistd.h>
48#endif
49
54bd0db4 50#include "files.h"
7612000c 51#include "alloc.h"
54bd0db4 52#include "gram.h"
a0f6b076 53#include "complain.h"
54bd0db4
RS
54
55FILE *finput = NULL;
56FILE *foutput = NULL;
57FILE *fdefines = NULL;
58FILE *ftable = NULL;
59FILE *fattrs = NULL;
60FILE *fguard = NULL;
61FILE *faction = NULL;
62FILE *fparser = NULL;
63
64/* File name specified with -o for the output file, or 0 if no -o. */
65char *spec_outfile;
66
67char *infile;
54bd0db4 68char *attrsfile;
4a120d45
JT
69
70static char *outfile;
71static char *defsfile;
72static char *tabfile;
73static char *guardfile;
74static char *actfile;
75static char *tmpattrsfile;
76static char *tmptabfile;
77static char *tmpdefsfile;
54bd0db4 78
28683c54
RS
79extern int noparserflag;
80
54bd0db4
RS
81extern char *mktemp(); /* So the compiler won't complain */
82extern char *getenv();
bd088c91 83
4a120d45
JT
84extern char *stringappend PARAMS((const char *, int, const char *));
85extern void openfiles PARAMS((void));
86extern void open_extra_files PARAMS((void));
87
88int fixed_outfiles = 0;
54bd0db4
RS
89
90extern char *program_name;
91extern int verboseflag;
92extern int definesflag;
54bd0db4
RS
93\f
94
bd088c91 95char *
4a120d45 96stringappend (const char *string1, int end1, const char *string2)
54bd0db4
RS
97{
98 register char *ostring;
4a120d45
JT
99 register char *cp;
100 register const char *cp1;
54bd0db4
RS
101 register int i;
102
4a120d45
JT
103 cp1 = string2;
104 i = 0;
105 while (*cp1++) i++;
54bd0db4
RS
106
107 ostring = NEW2(i+end1+1, char);
108
109 cp = ostring;
110 cp1 = string1;
111 for (i = 0; i < end1; i++)
112 *cp++ = *cp1++;
113
114 cp1 = string2;
bd088c91
JT
115 while ((*cp++ = *cp1++))
116 ;
54bd0db4
RS
117
118 return ostring;
119}
120
cfe5fbc0
AD
121/*-----------------------------------------------------------------.
122| Try to open file NAME with mode MODE, and print an error message |
123| if fails. |
124`-----------------------------------------------------------------*/
54bd0db4 125
cfe5fbc0 126static FILE *
4a120d45 127tryopen (const char *name, const char *mode)
cfe5fbc0
AD
128{
129 FILE *ptr;
130
131 ptr = fopen (name, mode);
132 if (!ptr)
133 error (2, errno, _("cannot open file `%s'"), name);
134
135 return ptr;
136}
137
138/*-------------------------------------------------------------.
139| Try to close file PTR, and print an error message if fails. |
140`-------------------------------------------------------------*/
141
142static int
143tryclose (FILE *ptr)
144{
145 int result;
146
147 if (ptr == NULL)
148 return 0;
149
150 result = fclose (ptr);
151 if (result == EOF)
152 error (2, errno, _("cannot close file"));
153
154 return result;
155}
156\f
54bd0db4
RS
157/* JF this has been hacked to death. Nowaday it sets up the file names for
158 the output files, and opens the tmp files and the parser */
159void
bd088c91 160openfiles (void)
54bd0db4
RS
161{
162 char *name_base;
a693bf18 163#ifdef MSDOS
54bd0db4 164 register char *cp;
a693bf18 165#endif
54bd0db4
RS
166 char *filename;
167 int base_length;
168 int short_base_length;
169
fcca25ad 170#if defined (VMS) & !defined (__VMS_POSIX)
4a120d45 171 const char *tmp_base = "sys$scratch:b_";
54bd0db4 172#else
4a120d45 173 const char *tmp_base = "/tmp/b.";
54bd0db4
RS
174#endif
175 int tmp_len;
176
177#ifdef MSDOS
178 tmp_base = getenv ("TMP");
179 if (tmp_base == 0)
180 tmp_base = "";
181 strlwr (infile);
182#endif /* MSDOS */
183
e0672a61
RS
184#if (defined(_WIN32) && !defined(__CYGWIN32__))
185 tmp_base = getenv ("TEMP"); /* Windows95 defines this ... */
186 if (tmp_base == 0)
187 tmp_base = getenv ("Temp"); /* ... while NT prefers this */
188 if (tmp_base == 0)
189 tmp_base = "";
190 strlwr (infile);
191#endif /* _WIN32 && !__CYGWIN32__ */
192
5191ef24 193#if (defined(unix) || defined(__unix) || defined(__unix__) || defined(__EMX__))
bd088c91
JT
194 {
195 char *tmp_ptr = getenv("TMPDIR");
196
197 if (tmp_ptr != 0)
198 tmp_base = stringappend (tmp_ptr, strlen (tmp_ptr), "/b.");
199 }
200#endif /* unix || __unix || __unix__ */
201
54bd0db4
RS
202 tmp_len = strlen (tmp_base);
203
204 if (spec_outfile)
205 {
206 /* -o was specified. The precise -o name will be used for ftable.
207 For other output files, remove the ".c" or ".tab.c" suffix. */
208 name_base = spec_outfile;
209#ifdef MSDOS
210 strlwr (name_base);
211#endif /* MSDOS */
212 /* BASE_LENGTH includes ".tab" but not ".c". */
213 base_length = strlen (name_base);
214 if (!strcmp (name_base + base_length - 2, ".c"))
215 base_length -= 2;
216 /* SHORT_BASE_LENGTH includes neither ".tab" nor ".c". */
217 short_base_length = base_length;
218 if (!strncmp (name_base + short_base_length - 4, ".tab", 4))
219 short_base_length -= 4;
220 else if (!strncmp (name_base + short_base_length - 4, "_tab", 4))
221 short_base_length -= 4;
222 }
223 else if (spec_file_prefix)
224 {
225 /* -b was specified. Construct names from it. */
226 /* SHORT_BASE_LENGTH includes neither ".tab" nor ".c". */
227 short_base_length = strlen (spec_file_prefix);
228 /* Count room for `.tab'. */
229 base_length = short_base_length + 4;
40675e7c 230 name_base = (char *) xmalloc (base_length + 1);
54bd0db4
RS
231 /* Append `.tab'. */
232 strcpy (name_base, spec_file_prefix);
233#ifdef VMS
234 strcat (name_base, "_tab");
235#else
236 strcat (name_base, ".tab");
237#endif
238#ifdef MSDOS
239 strlwr (name_base);
240#endif /* MSDOS */
241 }
242 else
243 {
244 /* -o was not specified; compute output file name from input
245 or use y.tab.c, etc., if -y was specified. */
246
4a120d45
JT
247 static char FIXED_NAME_BASE[] = "y.y";
248
249 name_base = fixed_outfiles ? FIXED_NAME_BASE : infile;
54bd0db4
RS
250
251 /* BASE_LENGTH gets length of NAME_BASE, sans ".y" suffix if any. */
252
253 base_length = strlen (name_base);
254 if (!strcmp (name_base + base_length - 2, ".y"))
255 base_length -= 2;
256 short_base_length = base_length;
257
258#ifdef VMS
259 name_base = stringappend(name_base, short_base_length, "_tab");
260#else
261#ifdef MSDOS
262 name_base = stringappend(name_base, short_base_length, "_tab");
263#else
264 name_base = stringappend(name_base, short_base_length, ".tab");
265#endif /* not MSDOS */
266#endif
267 base_length = short_base_length + 4;
268 }
269
270 finput = tryopen(infile, "r");
271
a0f6b076 272 if (! noparserflag)
54bd0db4 273 {
28683c54
RS
274 filename = getenv("BISON_SIMPLE");
275#ifdef MSDOS
276 /* File doesn't exist in current directory; try in INIT directory. */
277 cp = getenv("INIT");
278 if (filename == 0 && cp != NULL)
279 {
280 filename = xmalloc(strlen(cp) + strlen(PFILE) + 2);
281 strcpy(filename, cp);
282 cp = filename + strlen(filename);
283 *cp++ = '/';
284 strcpy(cp, PFILE);
285 }
54bd0db4 286#endif /* MSDOS */
28683c54
RS
287 fparser = tryopen(filename ? filename : PFILE, "r");
288 }
54bd0db4
RS
289
290 if (verboseflag)
291 {
292#ifdef MSDOS
293 outfile = stringappend(name_base, short_base_length, ".out");
294#else
295 /* We used to use just .out if spec_name_prefix (-p) was used,
296 but that conflicts with Posix. */
297 outfile = stringappend(name_base, short_base_length, ".output");
298#endif
299 foutput = tryopen(outfile, "w");
300 }
301
28683c54
RS
302 if (noparserflag)
303 {
304 /* use permanent name for actions file */
305 actfile = stringappend(name_base, short_base_length, ".act");
306 faction = tryopen(actfile, "w");
a0f6b076 307 }
28683c54 308
54bd0db4 309#ifdef MSDOS
28683c54
RS
310 if (! noparserflag)
311 actfile = mktemp(stringappend(tmp_base, tmp_len, "acXXXXXX"));
54bd0db4
RS
312 tmpattrsfile = mktemp(stringappend(tmp_base, tmp_len, "atXXXXXX"));
313 tmptabfile = mktemp(stringappend(tmp_base, tmp_len, "taXXXXXX"));
314 tmpdefsfile = mktemp(stringappend(tmp_base, tmp_len, "deXXXXXX"));
315#else
28683c54
RS
316 if (! noparserflag)
317 actfile = mktemp(stringappend(tmp_base, tmp_len, "act.XXXXXX"));
54bd0db4
RS
318 tmpattrsfile = mktemp(stringappend(tmp_base, tmp_len, "attrs.XXXXXX"));
319 tmptabfile = mktemp(stringappend(tmp_base, tmp_len, "tab.XXXXXX"));
320 tmpdefsfile = mktemp(stringappend(tmp_base, tmp_len, "defs.XXXXXX"));
321#endif /* not MSDOS */
322
28683c54
RS
323 if (! noparserflag)
324 faction = tryopen(actfile, "w+");
54bd0db4
RS
325 fattrs = tryopen(tmpattrsfile,"w+");
326 ftable = tryopen(tmptabfile, "w+");
327
328 if (definesflag)
329 {
330 defsfile = stringappend(name_base, base_length, ".h");
331 fdefines = tryopen(tmpdefsfile, "w+");
332 }
333
e0672a61 334#if !(defined (MSDOS) || (defined(_WIN32) && !defined(__CYGWIN32__)))
28683c54
RS
335 if (! noparserflag)
336 unlink(actfile);
54bd0db4
RS
337 unlink(tmpattrsfile);
338 unlink(tmptabfile);
339 unlink(tmpdefsfile);
e0672a61 340#endif /* MSDOS || (_WIN32 && !__CYGWIN32__) */
54bd0db4
RS
341
342 /* These are opened by `done' or `open_extra_files', if at all */
343 if (spec_outfile)
344 tabfile = spec_outfile;
345 else
346 tabfile = stringappend(name_base, base_length, ".c");
347
348#ifdef VMS
349 attrsfile = stringappend(name_base, short_base_length, "_stype.h");
350 guardfile = stringappend(name_base, short_base_length, "_guard.c");
351#else
352#ifdef MSDOS
353 attrsfile = stringappend(name_base, short_base_length, ".sth");
354 guardfile = stringappend(name_base, short_base_length, ".guc");
355#else
356 attrsfile = stringappend(name_base, short_base_length, ".stype.h");
357 guardfile = stringappend(name_base, short_base_length, ".guard.c");
358#endif /* not MSDOS */
359#endif /* not VMS */
360}
361
362
363
0d533154
AD
364/*--------------------------------------------------------------------.
365| Open the output files needed only for the semantic parser. This |
366| is done when %semantic_parser is seen in the declarations section. |
367`--------------------------------------------------------------------*/
54bd0db4
RS
368
369void
bd088c91 370open_extra_files (void)
54bd0db4
RS
371{
372 FILE *ftmp;
373 int c;
a693bf18
JT
374 char *filename;
375#ifdef MSDOS
376 char *cp;
377#endif
54bd0db4 378
a693bf18 379 tryclose(fparser);
54bd0db4 380
a0f6b076 381 if (! noparserflag)
54bd0db4 382 {
28683c54
RS
383 filename = (char *) getenv ("BISON_HAIRY");
384#ifdef MSDOS
385 /* File doesn't exist in current directory; try in INIT directory. */
386 cp = getenv("INIT");
387 if (filename == 0 && cp != NULL)
388 {
389 filename = xmalloc(strlen(cp) + strlen(PFILE1) + 2);
390 strcpy(filename, cp);
391 cp = filename + strlen(filename);
392 *cp++ = '/';
393 strcpy(cp, PFILE1);
394 }
54bd0db4 395#endif
28683c54
RS
396 fparser= tryopen(filename ? filename : PFILE1, "r");
397 }
54bd0db4
RS
398
399 /* JF change from inline attrs file to separate one */
400 ftmp = tryopen(attrsfile, "w");
401 rewind(fattrs);
402 while((c=getc(fattrs))!=EOF) /* Thank god for buffering */
403 putc(c,ftmp);
a693bf18 404 tryclose(fattrs);
54bd0db4
RS
405 fattrs=ftmp;
406
407 fguard = tryopen(guardfile, "w");
408
409}
410
a693bf18 411void
a0f6b076 412done (void)
a693bf18
JT
413{
414 tryclose(faction);
415 tryclose(fattrs);
416 tryclose(fguard);
417 tryclose(finput);
418 tryclose(fparser);
419 tryclose(foutput);
54bd0db4 420
a0f6b076
AD
421 /* JF write out the output file */
422 if (!complain_message_count && ftable)
54bd0db4
RS
423 {
424 FILE *ftmp;
425 register int c;
426
427 ftmp=tryopen(tabfile, "w");
428 rewind(ftable);
429 while((c=getc(ftable)) != EOF)
430 putc(c,ftmp);
a693bf18
JT
431 tryclose(ftmp);
432 tryclose(ftable);
54bd0db4
RS
433
434 if (definesflag)
435 {
436 ftmp = tryopen(defsfile, "w");
437 fflush(fdefines);
438 rewind(fdefines);
439 while((c=getc(fdefines)) != EOF)
440 putc(c,ftmp);
a693bf18
JT
441 tryclose(ftmp);
442 tryclose(fdefines);
54bd0db4
RS
443 }
444 }
445
fcca25ad 446#if defined (VMS) & !defined (__VMS_POSIX)
28683c54 447 if (faction && ! noparserflag)
54bd0db4
RS
448 delete(actfile);
449 if (fattrs)
450 delete(tmpattrsfile);
451 if (ftable)
452 delete(tmptabfile);
a0f6b076
AD
453/* Don't call exit again, we're in atexit ().
454 if (!complain_message_count)
455 sys$exit(SS$_NORMAL);
456 sys$exit(SS$_ABORT); */
54bd0db4 457#else
e0672a61 458#if (defined (MSDOS) || (defined(_WIN32) && !defined(__CYGWIN32__)))
28683c54 459 if (actfile && ! noparserflag) unlink(actfile);
54bd0db4
RS
460 if (tmpattrsfile) unlink(tmpattrsfile);
461 if (tmptabfile) unlink(tmptabfile);
462 if (tmpdefsfile) unlink(tmpdefsfile);
e0672a61 463#endif /* MSDOS || (_WIN32 && !__CYGWIN32__) */
a0f6b076
AD
464/* Don't call exit again, we're in atexit ().
465 exit (complain_message_count ? 1 : 0); */
fcca25ad 466#endif /* not VMS, or __VMS_POSIX */
54bd0db4 467}