Annotation of src/usr.bin/yacc/main.c, Revision 1.4
1.3 deraadt 1: /* $NetBSD: main.c,v 1.5 1996/03/19 03:21:38 jtc Exp $ */
2:
3: /*
4: * Copyright (c) 1989 The Regents of the University of California.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to Berkeley by
8: * Robert Paul Corbett.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed by the University of
21: * California, Berkeley and its contributors.
22: * 4. Neither the name of the University nor the names of its contributors
23: * may be used to endorse or promote products derived from this software
24: * without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36: * SUCH DAMAGE.
37: */
38:
39: #ifndef lint
40: char copyright[] =
41: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
42: All rights reserved.\n";
43: #endif /* not lint */
44:
1.1 deraadt 45: #ifndef lint
1.3 deraadt 46: #if 0
47: static char sccsid[] = "@(#)main.c 5.5 (Berkeley) 5/24/93";
48: #else
49: static char rcsid[] = "$NetBSD: main.c,v 1.5 1996/03/19 03:21:38 jtc Exp $";
50: #endif
1.1 deraadt 51: #endif /* not lint */
52:
1.4 ! deraadt 53: #include <sys/types.h>
! 54: #include <sys/file.h>
! 55: #include <stdlib.h>
1.1 deraadt 56: #include <signal.h>
57: #include "defs.h"
58:
59: char dflag;
60: char lflag;
61: char rflag;
62: char tflag;
63: char vflag;
64:
65: char *symbol_prefix;
66: char *file_prefix = "y";
67: char *myname = "yacc";
68: char *temp_form = "yacc.XXXXXXX";
69:
70: int lineno;
71: int outline;
72:
1.2 niklas 73: int explicit_file_name;
74:
1.1 deraadt 75: char *action_file_name;
76: char *code_file_name;
77: char *defines_file_name;
78: char *input_file_name = "";
79: char *output_file_name;
80: char *text_file_name;
81: char *union_file_name;
82: char *verbose_file_name;
83:
84: FILE *action_file; /* a temp file, used to save actions associated */
85: /* with rules until the parser is written */
86: FILE *code_file; /* y.code.c (used when the -r option is specified) */
87: FILE *defines_file; /* y.tab.h */
88: FILE *input_file; /* the input file */
89: FILE *output_file; /* y.tab.c */
90: FILE *text_file; /* a temp file, used to save text until all */
91: /* symbols have been defined */
92: FILE *union_file; /* a temp file, used to save the union */
93: /* definition until all symbol have been */
94: /* defined */
95: FILE *verbose_file; /* y.output */
96:
97: int nitems;
98: int nrules;
99: int nsyms;
100: int ntokens;
101: int nvars;
102:
103: int start_symbol;
104: char **symbol_name;
105: short *symbol_value;
106: short *symbol_prec;
107: char *symbol_assoc;
108:
109: short *ritem;
110: short *rlhs;
111: short *rrhs;
112: short *rprec;
113: char *rassoc;
114: short **derives;
115: char *nullable;
116:
117: done(k)
118: int k;
119: {
120: if (action_file) { fclose(action_file); unlink(action_file_name); }
121: if (text_file) { fclose(text_file); unlink(text_file_name); }
122: if (union_file) { fclose(union_file); unlink(union_file_name); }
123: exit(k);
124: }
125:
126:
127: void
1.3 deraadt 128: onintr(signo)
129: int signo;
1.1 deraadt 130: {
131: done(1);
132: }
133:
134:
135: set_signals()
136: {
137: #ifdef SIGINT
138: if (signal(SIGINT, SIG_IGN) != SIG_IGN)
139: signal(SIGINT, onintr);
140: #endif
141: #ifdef SIGTERM
142: if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
143: signal(SIGTERM, onintr);
144: #endif
145: #ifdef SIGHUP
146: if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
147: signal(SIGHUP, onintr);
148: #endif
149: }
150:
151:
152: usage()
153: {
1.2 niklas 154: fprintf(stderr, "usage: %s [-dlrtv] [-b file_prefix] [-o outputfile] [-p symbol_prefix] filename\n", myname);
1.1 deraadt 155: exit(1);
156: }
157:
158:
159: getargs(argc, argv)
160: int argc;
161: char *argv[];
162: {
163: register int i;
164: register char *s;
165:
166: if (argc > 0) myname = argv[0];
167: for (i = 1; i < argc; ++i)
168: {
169: s = argv[i];
170: if (*s != '-') break;
171: switch (*++s)
172: {
173: case '\0':
174: input_file = stdin;
175: if (i + 1 < argc) usage();
176: return;
177:
178: case '-':
179: ++i;
180: goto no_more_options;
181:
182: case 'b':
183: if (*++s)
184: file_prefix = s;
185: else if (++i < argc)
186: file_prefix = argv[i];
187: else
188: usage();
189: continue;
190:
191: case 'd':
192: dflag = 1;
193: break;
194:
195: case 'l':
196: lflag = 1;
197: break;
198:
1.2 niklas 199: case 'o':
200: if (*++s)
201: output_file_name = s;
202: else if (++i < argc)
203: output_file_name = argv[i];
204: else
205: usage();
206: explicit_file_name = 1;
207: continue;
208:
1.1 deraadt 209: case 'p':
210: if (*++s)
211: symbol_prefix = s;
212: else if (++i < argc)
213: symbol_prefix = argv[i];
214: else
215: usage();
216: continue;
217:
218: case 'r':
219: rflag = 1;
220: break;
221:
222: case 't':
223: tflag = 1;
224: break;
225:
226: case 'v':
227: vflag = 1;
228: break;
229:
230: default:
231: usage();
232: }
233:
234: for (;;)
235: {
236: switch (*++s)
237: {
238: case '\0':
239: goto end_of_option;
240:
241: case 'd':
242: dflag = 1;
243: break;
244:
245: case 'l':
246: lflag = 1;
247: break;
248:
249: case 'r':
250: rflag = 1;
251: break;
252:
253: case 't':
254: tflag = 1;
255: break;
256:
257: case 'v':
258: vflag = 1;
259: break;
260:
261: default:
262: usage();
263: }
264: }
265: end_of_option:;
266: }
267:
268: no_more_options:;
269: if (i + 1 != argc) usage();
270: input_file_name = argv[i];
271: }
272:
273:
274: char *
275: allocate(n)
276: unsigned n;
277: {
278: register char *p;
279:
280: p = NULL;
281: if (n)
282: {
283: p = CALLOC(1, n);
284: if (!p) no_space();
285: }
286: return (p);
287: }
288:
289:
290: create_file_names()
291: {
292: int i, len;
293: char *tmpdir;
294:
295: tmpdir = getenv("TMPDIR");
296: if (tmpdir == 0) tmpdir = "/tmp";
297:
298: len = strlen(tmpdir);
299: i = len + 13;
300: if (len && tmpdir[len-1] != '/')
301: ++i;
302:
303: action_file_name = MALLOC(i);
304: if (action_file_name == 0) no_space();
305: text_file_name = MALLOC(i);
306: if (text_file_name == 0) no_space();
307: union_file_name = MALLOC(i);
308: if (union_file_name == 0) no_space();
309:
310: strcpy(action_file_name, tmpdir);
311: strcpy(text_file_name, tmpdir);
312: strcpy(union_file_name, tmpdir);
313:
314: if (len && tmpdir[len - 1] != '/')
315: {
316: action_file_name[len] = '/';
317: text_file_name[len] = '/';
318: union_file_name[len] = '/';
319: ++len;
320: }
321:
322: strcpy(action_file_name + len, temp_form);
323: strcpy(text_file_name + len, temp_form);
324: strcpy(union_file_name + len, temp_form);
325:
326: action_file_name[len + 5] = 'a';
327: text_file_name[len + 5] = 't';
328: union_file_name[len + 5] = 'u';
329:
330: mktemp(action_file_name);
331: mktemp(text_file_name);
332: mktemp(union_file_name);
333:
334: len = strlen(file_prefix);
335:
1.2 niklas 336: if (!output_file_name)
337: {
338: output_file_name = MALLOC(len + 7);
339: if (output_file_name == 0)
340: no_space();
341: strcpy(output_file_name, file_prefix);
342: strcpy(output_file_name + len, OUTPUT_SUFFIX);
343: }
1.1 deraadt 344:
345: if (rflag)
346: {
347: code_file_name = MALLOC(len + 8);
348: if (code_file_name == 0)
349: no_space();
350: strcpy(code_file_name, file_prefix);
351: strcpy(code_file_name + len, CODE_SUFFIX);
352: }
353: else
354: code_file_name = output_file_name;
355:
356: if (dflag)
357: {
1.2 niklas 358: if (explicit_file_name)
359: {
360: defines_file_name = MALLOC(strlen(output_file_name));
361: if (defines_file_name == 0)
362: no_space();
363: strcpy(defines_file_name, output_file_name);
364: if (!strcmp(output_file_name + (strlen(output_file_name)-2), ".c"))
365: defines_file_name [strlen(output_file_name)-1] = 'h';
366: }
367: else
368: {
369: defines_file_name = MALLOC(len + 7);
370: if (defines_file_name == 0)
371: no_space();
372: strcpy(defines_file_name, file_prefix);
373: strcpy(defines_file_name + len, DEFINES_SUFFIX);
374: }
1.1 deraadt 375: }
376:
377: if (vflag)
378: {
379: verbose_file_name = MALLOC(len + 8);
380: if (verbose_file_name == 0)
381: no_space();
382: strcpy(verbose_file_name, file_prefix);
383: strcpy(verbose_file_name + len, VERBOSE_SUFFIX);
384: }
385: }
386:
387:
1.4 ! deraadt 388: FILE *
! 389: fsopen(name, mode)
! 390: char *name;
! 391: char *mode;
! 392: {
! 393: FILE *fp = NULL;
! 394: int fd, mod = O_RDONLY;
! 395:
! 396: if (strchr(mode, 'w'))
! 397: mod = O_RDWR;
! 398: if ((fd = open(name, mod | O_EXCL|O_CREAT, 0666)) == -1 ||
! 399: (fp = fdopen(fd, mode)) == NULL) {
! 400: if (fd != -1)
! 401: close(fd);
! 402: }
! 403: return (fp);
! 404: }
! 405:
! 406:
1.1 deraadt 407: open_files()
408: {
1.4 ! deraadt 409: int fd;
! 410:
1.1 deraadt 411: create_file_names();
412:
413: if (input_file == 0)
414: {
415: input_file = fopen(input_file_name, "r");
416: if (input_file == 0)
417: open_error(input_file_name);
418: }
419:
1.4 ! deraadt 420: action_file = fsopen(action_file_name, "w");
1.1 deraadt 421: if (action_file == 0)
422: open_error(action_file_name);
423:
1.4 ! deraadt 424: text_file = fsopen(text_file_name, "w");
1.1 deraadt 425: if (text_file == 0)
426: open_error(text_file_name);
427:
428: if (vflag)
429: {
430: verbose_file = fopen(verbose_file_name, "w");
431: if (verbose_file == 0)
432: open_error(verbose_file_name);
433: }
434:
435: if (dflag)
436: {
437: defines_file = fopen(defines_file_name, "w");
438: if (defines_file == 0)
439: open_error(defines_file_name);
1.4 ! deraadt 440: union_file = fsopen(union_file_name, "w");
1.1 deraadt 441: if (union_file == 0)
442: open_error(union_file_name);
443: }
444:
445: output_file = fopen(output_file_name, "w");
446: if (output_file == 0)
447: open_error(output_file_name);
448:
449: if (rflag)
450: {
451: code_file = fopen(code_file_name, "w");
452: if (code_file == 0)
453: open_error(code_file_name);
454: }
455: else
456: code_file = output_file;
457: }
458:
459:
460: int
461: main(argc, argv)
462: int argc;
463: char *argv[];
464: {
465: set_signals();
466: getargs(argc, argv);
467: open_files();
468: reader();
469: lr0();
470: lalr();
471: make_parser();
472: verbose();
473: output();
474: done(0);
475: /*NOTREACHED*/
476: }