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