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