Merge branch 'master' of github.com:mono/mono
[mono.git] / mcs / jay / main.c
1 /*
2  * Copyright (c) 1989 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Robert Paul Corbett.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36
37 #ifndef lint
38 char copyright[] =
39 "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
40  All rights reserved.\n";
41 #endif /* not lint */
42
43 #ifndef lint
44 static char sccsid[] = "@(#)main.c      5.5 (Berkeley) 5/24/93";
45 #endif /* not lint */
46
47 #include <signal.h>
48 #include "defs.h"
49
50 char tflag;
51 char vflag;
52 int csharp = 0;
53
54 char *file_prefix = "y";
55 char *myname = "yacc";
56 char *temp_form = "yacc.XXXXXXX";
57
58 int lineno;
59 int outline;
60
61 char *action_file_name;
62 char *input_file_name = "";
63 char *prolog_file_name;
64 char *local_file_name;
65 char *verbose_file_name;
66
67 FILE *action_file;      /*  a temp file, used to save actions associated    */
68                         /*  with rules until the parser is written          */
69 FILE *input_file;       /*  the input file                                  */
70 FILE *prolog_file;      /*  temp files, used to save text until all         */
71 FILE *local_file;       /*  symbols have been defined                       */
72 FILE *verbose_file;     /*  y.output                                        */
73
74 int nitems;
75 int nrules;
76 int nsyms;
77 int ntokens;
78 int nvars;
79 int nmethods;
80
81 int   start_symbol;
82 char  **symbol_name;
83 short *symbol_value;
84 short *symbol_prec;
85 char  *symbol_assoc;
86 char  **methods;
87
88 short *ritem;
89 short *rlhs;
90 short *rrhs;
91 short *rprec;
92 char  *rassoc;
93 short **derives;
94 char *nullable;
95
96 #if defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
97 extern char* mktemp();
98 #define mkstemp mktemp
99 #endif
100
101 extern char *getenv();
102
103 done(k)
104 int k;
105 {
106     if (action_file) { fclose(action_file); unlink(action_file_name); }
107     if (prolog_file) { fclose(prolog_file); unlink(prolog_file_name); }
108     if (local_file) { fclose(local_file); unlink(local_file_name); }
109     exit(k);
110 }
111
112
113 void
114 onintr(signo)
115         int signo;
116 {
117     done(1);
118 }
119
120
121 set_signals()
122 {
123 #ifdef SIGINT
124     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
125         signal(SIGINT, onintr);
126 #endif
127 #ifdef SIGTERM
128     if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
129         signal(SIGTERM, onintr);
130 #endif
131 #ifdef SIGHUP
132     if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
133         signal(SIGHUP, onintr);
134 #endif
135 }
136
137
138 usage()
139 {
140     fprintf(stderr, "usage: %s [-tvcp] [-b file_prefix] filename\n", myname);
141     exit(1);
142 }
143
144 void
145 print_skel_dir(void)
146 {
147     printf ("%s\n", SKEL_DIRECTORY);
148     exit (0);
149 }
150
151 getargs(argc, argv)
152 int argc;
153 char *argv[];
154 {
155     register int i;
156     register char *s;
157
158     if (argc > 0) myname = argv[0];
159     for (i = 1; i < argc; ++i)
160     {
161         s = argv[i];
162         if (*s != '-') break;
163         switch (*++s)
164         {
165         case '\0':
166             input_file = stdin;
167             if (i + 1 < argc) usage();
168             return;
169
170         case '-':
171             ++i;
172             goto no_more_options;
173
174         case 'b':
175             if (*++s)
176                  file_prefix = s;
177             else if (++i < argc)
178                 file_prefix = argv[i];
179             else
180                 usage();
181             continue;
182
183         case 't':
184             tflag = 1;
185             break;
186
187         case 'p':
188             print_skel_dir ();
189             break;
190
191         case 'c':
192             csharp = 1;
193             line_format = "#line %d \"%s\"\n";
194             default_line_format = "#line default\n";
195             break;
196             
197         case 'v':
198             vflag = 1;
199             break;
200
201         default:
202             usage();
203         }
204
205         for (;;)
206         {
207             switch (*++s)
208             {
209             case '\0':
210                 goto end_of_option;
211
212             case 't':
213                 tflag = 1;
214                 break;
215
216             case 'v':
217                 vflag = 1;
218                 break;
219
220             case 'p':
221                 print_skel_dir ();
222                 break;
223
224             case 'c':
225                 csharp = 1;
226                 line_format = "#line %d \"%s\"\n";
227                 default_line_format = "#line default\n";
228
229                 break;
230
231             default:
232                 usage();
233             }
234         }
235 end_of_option:;
236     }
237
238 no_more_options:;
239     if (i + 1 != argc) usage();
240     input_file_name = argv[i];
241 }
242
243
244 char *
245 allocate(n)
246 unsigned n;
247 {
248     register char *p;
249
250     p = NULL;
251     if (n)
252     {
253         p = CALLOC(1, n);
254         if (!p) no_space();
255     }
256     return (p);
257 }
258
259
260 create_file_names()
261 {
262     int i, len;
263     char *tmpdir;
264
265 #if defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
266     tmpdir = ".";
267 #else
268     tmpdir = getenv("TMPDIR");
269     if (tmpdir == 0) tmpdir = getenv ("TMP");
270     if (tmpdir == 0) tmpdir = getenv ("TEMP");
271     if (tmpdir == 0) tmpdir = "/tmp";
272 #endif
273
274     len = strlen(tmpdir);
275     i = len + 13;
276     if (len && tmpdir[len-1] != '/')
277         ++i;
278
279     action_file_name = MALLOC(i);
280     if (action_file_name == 0) no_space();
281     prolog_file_name = MALLOC(i);
282     if (prolog_file_name == 0) no_space();
283     local_file_name = MALLOC(i);
284     if (local_file_name == 0) no_space();
285
286     strcpy(action_file_name, tmpdir);
287     strcpy(prolog_file_name, tmpdir);
288     strcpy(local_file_name, tmpdir);
289
290     if (len && tmpdir[len - 1] != '/')
291     {
292         action_file_name[len] = '/';
293         prolog_file_name[len] = '/';
294         local_file_name[len] = '/';
295         ++len;
296     }
297
298     strcpy(action_file_name + len, temp_form);
299     strcpy(prolog_file_name + len, temp_form);
300     strcpy(local_file_name + len, temp_form);
301
302     action_file_name[len + 5] = 'a';
303     prolog_file_name[len + 5] = 'p';
304     local_file_name[len + 5] = 'l';
305
306     mkstemp(action_file_name);
307     mkstemp(prolog_file_name);
308     mkstemp(local_file_name);
309
310     len = strlen(file_prefix);
311
312     if (vflag)
313     {
314         verbose_file_name = MALLOC(len + 8);
315         if (verbose_file_name == 0)
316             no_space();
317         strcpy(verbose_file_name, file_prefix);
318         strcpy(verbose_file_name + len, VERBOSE_SUFFIX);
319     }
320 }
321
322
323 open_files()
324 {
325     create_file_names();
326
327     if (input_file == 0)
328     {
329         input_file = fopen(input_file_name, "r");
330         if (input_file == 0)
331             open_error(input_file_name);
332     }
333
334     action_file = fopen(action_file_name, "w");
335     if (action_file == 0)
336         open_error(action_file_name);
337
338     prolog_file = fopen(prolog_file_name, "w");
339     if (prolog_file == 0)
340         open_error(prolog_file_name);
341
342     local_file = fopen(local_file_name, "w");
343     if (local_file == 0)
344         open_error(local_file_name);
345
346     if (vflag)
347     {
348         verbose_file = fopen(verbose_file_name, "w");
349         if (verbose_file == 0)
350             open_error(verbose_file_name);
351     }
352 }
353
354
355 int
356 main(argc, argv)
357 int argc;
358 char *argv[];
359 {
360     set_signals();
361     getargs(argc, argv);
362     open_files();
363     reader();
364     lr0();
365     lalr();
366     make_parser();
367     verbose();
368     output();
369     done(0);
370     /*NOTREACHED*/
371 }