don't bother resolving onbld python module deps
[unleashed.git] / bin / yacc / main.c
blob3d9f6add5c89e06a5b30964338d24d8fbb62324a
1 /* $OpenBSD: main.c,v 1.29 2017/05/25 20:11:03 tedu Exp $ */
2 /* $NetBSD: main.c,v 1.5 1996/03/19 03:21:38 jtc Exp $ */
4 /*
5 * Copyright (c) 1989 The Regents of the University of California.
6 * All rights reserved.
8 * This code is derived from software contributed to Berkeley by
9 * Robert Paul Corbett.
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. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
36 #include <sys/types.h>
37 #include <fcntl.h>
38 #include <paths.h>
39 #include <signal.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include "defs.h"
44 char dflag;
45 char lflag;
46 char rflag;
47 char tflag;
48 char vflag;
50 char *symbol_prefix;
51 char *file_prefix = "y";
53 int lineno;
54 int outline;
56 int explicit_file_name;
58 char *action_file_name;
59 char *code_file_name;
60 char *defines_file_name;
61 char *input_file_name = "";
62 char *output_file_name;
63 char *text_file_name;
64 char *union_file_name;
65 char *verbose_file_name;
67 FILE *action_file; /* a temp file, used to save actions associated */
68 /* with rules until the parser is written */
69 FILE *code_file; /* y.code.c (used when the -r option is specified) */
70 FILE *defines_file; /* y.tab.h */
71 FILE *input_file; /* the input file */
72 FILE *output_file; /* y.tab.c */
73 FILE *text_file; /* a temp file, used to save text until all */
74 /* symbols have been defined */
75 FILE *union_file; /* a temp file, used to save the union */
76 /* definition until all symbol have been */
77 /* defined */
78 FILE *verbose_file; /* y.output */
80 int nitems;
81 int nrules;
82 int nsyms;
83 int ntokens;
84 int nvars;
86 int start_symbol;
87 char **symbol_name;
88 short *symbol_value;
89 short *symbol_prec;
90 char *symbol_assoc;
92 short *ritem;
93 short *rlhs;
94 short *rrhs;
95 short *rprec;
96 char *rassoc;
97 short **derives;
98 char *nullable;
100 void onintr(int);
101 void set_signals(void);
102 void usage(void);
103 void getargs(int, char *[]);
104 void create_file_names(void);
105 void open_files(void);
107 volatile sig_atomic_t sigdie;
109 void
110 done(int k)
112 if (action_file)
113 unlink(action_file_name);
114 if (text_file)
115 unlink(text_file_name);
116 if (union_file)
117 unlink(union_file_name);
118 if (sigdie)
119 _exit(k);
120 exit(k);
124 void
125 onintr(__unused int signo)
127 sigdie = 1;
128 done(1);
132 void
133 set_signals(void)
135 #ifdef SIGINT
136 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
137 signal(SIGINT, onintr);
138 #endif
139 #ifdef SIGTERM
140 if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
141 signal(SIGTERM, onintr);
142 #endif
143 #ifdef SIGHUP
144 if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
145 signal(SIGHUP, onintr);
146 #endif
150 void
151 usage(void)
153 fprintf(stderr, "usage: %s [-dlrtv] [-b file_prefix] [-o output_file] [-p symbol_prefix] file\n", __progname);
154 exit(1);
158 void
159 getargs(int argc, char *argv[])
161 int ch;
163 while ((ch = getopt(argc, argv, "b:dlo:p:rtv")) != -1) {
164 switch (ch) {
165 case 'b':
166 file_prefix = optarg;
167 break;
169 case 'd':
170 dflag = 1;
171 break;
173 case 'l':
174 lflag = 1;
175 break;
177 case 'o':
178 output_file_name = optarg;
179 explicit_file_name = 1;
180 break;
182 case 'p':
183 symbol_prefix = optarg;
184 break;
186 case 'r':
187 rflag = 1;
188 break;
190 case 't':
191 tflag = 1;
192 break;
194 case 'v':
195 vflag = 1;
196 break;
198 default:
199 usage();
202 argc -= optind;
203 argv += optind;
205 if (argc != 1)
206 usage();
207 if (strcmp(*argv, "-") == 0)
208 input_file = stdin;
209 else
210 input_file_name = *argv;
214 void *
215 allocate(size_t n)
217 void *v;
219 v = NULL;
220 if (n) {
221 v = calloc(1, n);
222 if (!v)
223 no_space();
225 return (v);
228 #define TEMPNAME(s, c, d, l) \
229 (asprintf(&(s), "%.*s/yacc.%xXXXXXXXXXX", (int)(l), (d), (c)))
231 void
232 create_file_names(void)
234 size_t len;
235 char *tmpdir;
237 tmpdir = _PATH_TMP;
239 len = strlen(tmpdir);
240 if (tmpdir[len - 1] == '/')
241 len--;
243 if (TEMPNAME(action_file_name, 'a', tmpdir, len) == -1 ||
244 TEMPNAME(text_file_name, 'r', tmpdir, len) == -1 ||
245 TEMPNAME(union_file_name, 'u', tmpdir, len) == -1)
246 no_space();
248 if (output_file_name == NULL) {
249 if (asprintf(&output_file_name, "%s%s", file_prefix, OUTPUT_SUFFIX)
250 == -1)
251 no_space();
253 if (rflag) {
254 if (asprintf(&code_file_name, "%s%s", file_prefix, CODE_SUFFIX) == -1)
255 no_space();
256 } else
257 code_file_name = output_file_name;
259 if (dflag) {
260 if (explicit_file_name) {
261 char *suffix;
263 defines_file_name = strdup(output_file_name);
264 if (defines_file_name == 0)
265 no_space();
267 /* does the output_file_name have a known suffix */
268 if ((suffix = strrchr(output_file_name, '.')) != 0 &&
269 (!strcmp(suffix, ".c") || /* good, old-fashioned C */
270 !strcmp(suffix, ".C") || /* C++, or C on Windows */
271 !strcmp(suffix, ".cc") || /* C++ */
272 !strcmp(suffix, ".cxx") || /* C++ */
273 !strcmp(suffix, ".cpp"))) {/* C++ (Windows) */
274 strncpy(defines_file_name, output_file_name,
275 suffix - output_file_name + 1);
276 defines_file_name[suffix - output_file_name + 1] = 'h';
277 defines_file_name[suffix - output_file_name + 2] = '\0';
278 } else {
279 fprintf(stderr, "%s: suffix of output file name %s"
280 " not recognized, no -d file generated.\n",
281 __progname, output_file_name);
282 dflag = 0;
283 free(defines_file_name);
284 defines_file_name = 0;
286 } else {
287 if (asprintf(&defines_file_name, "%s%s", file_prefix,
288 DEFINES_SUFFIX) == -1)
289 no_space();
292 if (vflag) {
293 if (asprintf(&verbose_file_name, "%s%s", file_prefix,
294 VERBOSE_SUFFIX) == -1)
295 no_space();
300 void
301 open_files(void)
303 int fd;
305 create_file_names();
307 if (input_file == 0) {
308 input_file = fopen(input_file_name, "r");
309 if (input_file == 0)
310 open_error(input_file_name);
312 fd = mkstemp(action_file_name);
313 if (fd == -1 || (action_file = fdopen(fd, "w")) == NULL)
314 open_error(action_file_name);
316 fd = mkstemp(text_file_name);
317 if (fd == -1 || (text_file = fdopen(fd, "w")) == NULL)
318 open_error(text_file_name);
320 if (vflag) {
321 verbose_file = fopen(verbose_file_name, "w");
322 if (verbose_file == 0)
323 open_error(verbose_file_name);
325 if (dflag) {
326 defines_file = fopen(defines_file_name, "w");
327 if (defines_file == NULL)
328 open_write_error(defines_file_name);
329 fd = mkstemp(union_file_name);
330 if (fd == -1 || (union_file = fdopen(fd, "w")) == NULL)
331 open_error(union_file_name);
333 output_file = fopen(output_file_name, "w");
334 if (output_file == 0)
335 open_error(output_file_name);
337 if (rflag) {
338 code_file = fopen(code_file_name, "w");
339 if (code_file == 0)
340 open_error(code_file_name);
341 } else
342 code_file = output_file;
347 main(int argc, char *argv[])
349 if (pledge("stdio rpath wpath cpath", NULL) == -1)
350 fatal("pledge: invalid arguments");
352 set_signals();
353 getargs(argc, argv);
354 open_files();
355 reader();
356 lr0();
357 lalr();
358 make_parser();
359 verbose();
360 output();
361 done(0);
362 /* NOTREACHED */
363 return (0);