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