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