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