Fix problems with overlong directory names: phase #1
[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
80 int   start_symbol;
81 char  **symbol_name;
82 short *symbol_value;
83 short *symbol_prec;
84 char  *symbol_assoc;
85
86 short *ritem;
87 short *rlhs;
88 short *rrhs;
89 short *rprec;
90 char  *rassoc;
91 short **derives;
92 char *nullable;
93
94 #if defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
95 extern char* mktemp();
96 #define mkstemp mktemp
97 #endif
98
99 extern char *getenv();
100
101 done(k)
102 int k;
103 {
104     if (action_file) { fclose(action_file); unlink(action_file_name); }
105     if (prolog_file) { fclose(prolog_file); unlink(prolog_file_name); }
106     if (local_file) { fclose(local_file); unlink(local_file_name); }
107     exit(k);
108 }
109
110
111 void
112 onintr(signo)
113         int signo;
114 {
115     done(1);
116 }
117
118
119 set_signals()
120 {
121 #ifdef SIGINT
122     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
123         signal(SIGINT, onintr);
124 #endif
125 #ifdef SIGTERM
126     if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
127         signal(SIGTERM, onintr);
128 #endif
129 #ifdef SIGHUP
130     if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
131         signal(SIGHUP, onintr);
132 #endif
133 }
134
135
136 usage()
137 {
138     fprintf(stderr, "usage: %s [-tvcp] [-b file_prefix] filename\n", myname);
139     exit(1);
140 }
141
142 void
143 print_skel_dir(void)
144 {
145     printf ("%s\n", SKEL_DIRECTORY);
146     exit (0);
147 }
148
149 getargs(argc, argv)
150 int argc;
151 char *argv[];
152 {
153     register int i;
154     register char *s;
155
156     if (argc > 0) myname = argv[0];
157     for (i = 1; i < argc; ++i)
158     {
159         s = argv[i];
160         if (*s != '-') break;
161         switch (*++s)
162         {
163         case '\0':
164             input_file = stdin;
165             if (i + 1 < argc) usage();
166             return;
167
168         case '-':
169             ++i;
170             goto no_more_options;
171
172         case 'b':
173             if (*++s)
174                  file_prefix = s;
175             else if (++i < argc)
176                 file_prefix = argv[i];
177             else
178                 usage();
179             continue;
180
181         case 't':
182             tflag = 1;
183             break;
184
185         case 'p':
186             print_skel_dir ();
187             break;
188
189         case 'c':
190             csharp = 1;
191             line_format = "#line %d \"%s\"\n";
192             default_line_format = "#line default\n";
193             break;
194             
195         case 'v':
196             vflag = 1;
197             break;
198
199         default:
200             usage();
201         }
202
203         for (;;)
204         {
205             switch (*++s)
206             {
207             case '\0':
208                 goto end_of_option;
209
210             case 't':
211                 tflag = 1;
212                 break;
213
214             case 'v':
215                 vflag = 1;
216                 break;
217
218             case 'p':
219                 print_skel_dir ();
220                 break;
221
222             case 'c':
223                 csharp = 1;
224                 line_format = "#line %d \"%s\"\n";
225                 default_line_format = "#line default\n";
226
227                 break;
228
229             default:
230                 usage();
231             }
232         }
233 end_of_option:;
234     }
235
236 no_more_options:;
237     if (i + 1 != argc) usage();
238     input_file_name = argv[i];
239 }
240
241
242 char *
243 allocate(n)
244 unsigned n;
245 {
246     register char *p;
247
248     p = NULL;
249     if (n)
250     {
251         p = CALLOC(1, n);
252         if (!p) no_space();
253     }
254     return (p);
255 }
256
257
258 create_file_names()
259 {
260     int i, len;
261     char *tmpdir;
262
263 #if defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
264     tmpdir = ".";
265 #else
266     tmpdir = getenv("TMPDIR");
267     if (tmpdir == 0) tmpdir = getenv ("TMP");
268     if (tmpdir == 0) tmpdir = getenv ("TEMP");
269     if (tmpdir == 0) tmpdir = "/tmp";
270 #endif
271
272     len = strlen(tmpdir);
273     i = len + 13;
274     if (len && tmpdir[len-1] != '/')
275         ++i;
276
277     action_file_name = MALLOC(i);
278     if (action_file_name == 0) no_space();
279     prolog_file_name = MALLOC(i);
280     if (prolog_file_name == 0) no_space();
281     local_file_name = MALLOC(i);
282     if (local_file_name == 0) no_space();
283
284     strcpy(action_file_name, tmpdir);
285     strcpy(prolog_file_name, tmpdir);
286     strcpy(local_file_name, tmpdir);
287
288     if (len && tmpdir[len - 1] != '/')
289     {
290         action_file_name[len] = '/';
291         prolog_file_name[len] = '/';
292         local_file_name[len] = '/';
293         ++len;
294     }
295
296     strcpy(action_file_name + len, temp_form);
297     strcpy(prolog_file_name + len, temp_form);
298     strcpy(local_file_name + len, temp_form);
299
300     action_file_name[len + 5] = 'a';
301     prolog_file_name[len + 5] = 'p';
302     local_file_name[len + 5] = 'l';
303
304     mkstemp(action_file_name);
305     mkstemp(prolog_file_name);
306     mkstemp(local_file_name);
307
308     len = strlen(file_prefix);
309
310     if (vflag)
311     {
312         verbose_file_name = MALLOC(len + 8);
313         if (verbose_file_name == 0)
314             no_space();
315         strcpy(verbose_file_name, file_prefix);
316         strcpy(verbose_file_name + len, VERBOSE_SUFFIX);
317     }
318 }
319
320
321 open_files()
322 {
323     create_file_names();
324
325     if (input_file == 0)
326     {
327         input_file = fopen(input_file_name, "r");
328         if (input_file == 0)
329             open_error(input_file_name);
330     }
331
332     action_file = fopen(action_file_name, "w");
333     if (action_file == 0)
334         open_error(action_file_name);
335
336     prolog_file = fopen(prolog_file_name, "w");
337     if (prolog_file == 0)
338         open_error(prolog_file_name);
339
340     local_file = fopen(local_file_name, "w");
341     if (local_file == 0)
342         open_error(local_file_name);
343
344     if (vflag)
345     {
346         verbose_file = fopen(verbose_file_name, "w");
347         if (verbose_file == 0)
348             open_error(verbose_file_name);
349     }
350 }
351
352
353 int
354 main(argc, argv)
355 int argc;
356 char *argv[];
357 {
358     set_signals();
359     getargs(argc, argv);
360     open_files();
361     reader();
362     lr0();
363     lalr();
364     make_parser();
365     verbose();
366     output();
367     done(0);
368     /*NOTREACHED*/
369 }