]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/ocaml/contrib/yacc/main.c
update
[l4.git] / l4 / pkg / ocaml / contrib / yacc / main.c
1 /***********************************************************************/
2 /*                                                                     */
3 /*                           Objective Caml                            */
4 /*                                                                     */
5 /*            Xavier Leroy, projet Cristal, INRIA Rocquencourt         */
6 /*                                                                     */
7 /*  Copyright 1996 Institut National de Recherche en Informatique et   */
8 /*  en Automatique.  All rights reserved.  This file is distributed    */
9 /*  under the terms of the Q Public License version 1.0.               */
10 /*                                                                     */
11 /***********************************************************************/
12
13 /* Based on public-domain code from Berkeley Yacc */
14
15 /* $Id: main.c 7382 2006-04-16 23:28:22Z doligez $ */
16
17 #include <signal.h>
18 #include <string.h>
19 #include "defs.h"
20 #ifdef HAS_UNISTD
21 #include <unistd.h>
22 #endif
23
24 #include "version.h"
25
26 char dflag;
27 char lflag;
28 char rflag;
29 char tflag;
30 char vflag;
31 char qflag;
32 char sflag;
33 char big_endian;
34
35 char *file_prefix = 0;
36 char *myname = "yacc";
37 #ifdef NO_UNIX
38 char temp_form[] = "yacc.X";
39 #else
40 char temp_form[] = "yacc.XXXXXXX";
41 #endif
42
43 int lineno;
44 char *virtual_input_file_name = NULL;
45 int outline;
46
47 char *action_file_name;
48 char *entry_file_name;
49 char *code_file_name;
50 char *interface_file_name;
51 char *defines_file_name;
52 char *input_file_name = "";
53 char *output_file_name;
54 char *text_file_name;
55 char *union_file_name;
56 char *verbose_file_name;
57
58 FILE *action_file;      /*  a temp file, used to save actions associated    */
59                         /*  with rules until the parser is written          */
60 FILE *entry_file;
61 FILE *code_file;        /*  y.code.c (used when the -r option is specified) */
62 FILE *defines_file;     /*  y.tab.h                                         */
63 FILE *input_file;       /*  the input file                                  */
64 FILE *output_file;      /*  y.tab.c                                         */
65 FILE *text_file;        /*  a temp file, used to save text until all        */
66                         /*  symbols have been defined                       */
67 FILE *union_file;       /*  a temp file, used to save the union             */
68                         /*  definition until all symbol have been           */
69                         /*  defined                                         */
70 FILE *verbose_file;     /*  y.output                                        */
71 FILE *interface_file;
72
73 int nitems;
74 int nrules;
75 int ntotalrules;
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 char **symbol_tag;
86 char *symbol_true_token;
87
88 short *ritem;
89 short *rlhs;
90 short *rrhs;
91 short *rprec;
92 char  *rassoc;
93 short **derives;
94 char *nullable;
95
96 extern char *mktemp(char *);
97 extern char *getenv(const char *);
98
99
100 void done(int k)
101 {
102     if (action_file) { fclose(action_file); unlink(action_file_name); }
103     if (entry_file) { fclose(entry_file); unlink(entry_file_name); }
104     if (text_file) { fclose(text_file); unlink(text_file_name); }
105     if (union_file) { fclose(union_file); unlink(union_file_name); }
106     if (output_file && k > 0) {
107       fclose(output_file); unlink(output_file_name);
108     }
109     if (interface_file && k > 0) {
110       fclose(interface_file); unlink(interface_file_name);
111     }
112     exit(k);
113 }
114
115
116 void onintr(int dummy)
117 {
118     done(1);
119 }
120
121
122 void set_signals(void)
123 {
124 #ifdef SIGINT
125     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
126         signal(SIGINT, onintr);
127 #endif
128 #ifdef SIGTERM
129     if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
130         signal(SIGTERM, onintr);
131 #endif
132 #ifdef SIGHUP
133     if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
134         signal(SIGHUP, onintr);
135 #endif
136 }
137
138
139 void usage(void)
140 {
141     fprintf(stderr, "usage: %s [-v] [-q] [-b file_prefix] filename\n",
142             myname);
143     exit(1);
144 }
145
146 void getargs(int argc, char **argv)
147 {
148     register int i;
149     register char *s;
150
151     if (argc > 0) myname = argv[0];
152     for (i = 1; i < argc; ++i)
153     {
154         s = argv[i];
155         if (*s != '-') break;
156         switch (*++s)
157         {
158         case '\0':
159             input_file = stdin;
160             file_prefix = "stdin";
161             if (i + 1 < argc) usage();
162             return;
163
164         case '-':
165             ++i;
166             goto no_more_options;
167
168         case 'v':
169             if (!strcmp (argv[i], "-version")){
170               printf ("The Objective Caml parser generator, version "
171                       OCAML_VERSION "\n");
172               exit (0);
173             }else{
174               vflag = 1;
175             }
176             break;
177
178         case 'q':
179             qflag = 1;
180             break;
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         default:
192             usage();
193         }
194
195         for (;;)
196         {
197             switch (*++s)
198             {
199             case '\0':
200                 goto end_of_option;
201
202             case 'v':
203                 vflag = 1;
204                 break;
205
206             case 'q':
207                 qflag = 1;
208                 break;
209
210             default:
211                 usage();
212             }
213         }
214 end_of_option:;
215     }
216
217 no_more_options:;
218     if (i + 1 != argc) usage();
219     input_file_name = argv[i];
220     if (file_prefix == 0) {
221       int len;
222       len = strlen(argv[i]);
223       file_prefix = malloc(len + 1);
224       if (file_prefix == 0) no_space();
225       strcpy(file_prefix, argv[i]);
226       while (len > 0) {
227         len--;
228         if (file_prefix[len] == '.') {
229           file_prefix[len] = 0;
230           break;
231         }
232       }
233     }
234 }
235
236
237 char *
238 allocate(unsigned int n)
239 {
240     register char *p;
241
242     p = NULL;
243     if (n)
244     {
245         p = CALLOC(1, n);
246         if (!p) no_space();
247     }
248     return (p);
249 }
250
251
252 void create_file_names(void)
253 {
254     int i, len;
255     char *tmpdir;
256
257 #ifdef NO_UNIX
258     len = 0;
259     i = sizeof(temp_form);
260 #else
261     tmpdir = getenv("TMPDIR");
262     if (tmpdir == 0) tmpdir = "/tmp";
263     len = strlen(tmpdir);
264     i = len + sizeof(temp_form);
265     if (len && tmpdir[len-1] != '/')
266         ++i;
267 #endif
268
269     action_file_name = MALLOC(i);
270     if (action_file_name == 0) no_space();
271     entry_file_name = MALLOC(i);
272     if (entry_file_name == 0) no_space();
273     text_file_name = MALLOC(i);
274     if (text_file_name == 0) no_space();
275     union_file_name = MALLOC(i);
276     if (union_file_name == 0) no_space();
277
278 #ifndef NO_UNIX
279     strcpy(action_file_name, tmpdir);
280     strcpy(entry_file_name, tmpdir);
281     strcpy(text_file_name, tmpdir);
282     strcpy(union_file_name, tmpdir);
283
284     if (len && tmpdir[len - 1] != '/')
285     {
286         action_file_name[len] = '/';
287         entry_file_name[len] = '/';
288         text_file_name[len] = '/';
289         union_file_name[len] = '/';
290         ++len;
291     }
292 #endif
293
294     strcpy(action_file_name + len, temp_form);
295     strcpy(entry_file_name + len, temp_form);
296     strcpy(text_file_name + len, temp_form);
297     strcpy(union_file_name + len, temp_form);
298
299     action_file_name[len + 5] = 'a';
300     entry_file_name[len + 5] = 'e';
301     text_file_name[len + 5] = 't';
302     union_file_name[len + 5] = 'u';
303
304 #ifndef NO_UNIX
305     mktemp(action_file_name);
306     mktemp(entry_file_name);
307     mktemp(text_file_name);
308     mktemp(union_file_name);
309 #endif
310
311     len = strlen(file_prefix);
312
313     output_file_name = MALLOC(len + 7);
314     if (output_file_name == 0)
315         no_space();
316     strcpy(output_file_name, file_prefix);
317     strcpy(output_file_name + len, OUTPUT_SUFFIX);
318
319     code_file_name = output_file_name;
320
321     if (vflag)
322     {
323         verbose_file_name = MALLOC(len + 8);
324         if (verbose_file_name == 0)
325             no_space();
326         strcpy(verbose_file_name, file_prefix);
327         strcpy(verbose_file_name + len, VERBOSE_SUFFIX);
328     }
329
330     interface_file_name = MALLOC(len + 8);
331     if (interface_file_name == 0)
332         no_space();
333     strcpy(interface_file_name, file_prefix);
334     strcpy(interface_file_name + len, INTERFACE_SUFFIX);
335
336 }
337
338
339 void open_files(void)
340 {
341     create_file_names();
342
343     if (input_file == 0)
344     {
345         input_file = fopen(input_file_name, "r");
346         if (input_file == 0)
347             open_error(input_file_name);
348     }
349
350     action_file = fopen(action_file_name, "w");
351     if (action_file == 0)
352         open_error(action_file_name);
353
354     entry_file = fopen(entry_file_name, "w");
355     if (entry_file == 0)
356         open_error(entry_file_name);
357
358     text_file = fopen(text_file_name, "w");
359     if (text_file == 0)
360         open_error(text_file_name);
361
362     if (vflag)
363     {
364         verbose_file = fopen(verbose_file_name, "w");
365         if (verbose_file == 0)
366             open_error(verbose_file_name);
367     }
368
369     if (dflag)
370     {
371         defines_file = fopen(defines_file_name, "w");
372         if (defines_file == 0)
373             open_error(defines_file_name);
374         union_file = fopen(union_file_name, "w");
375         if (union_file ==  0)
376             open_error(union_file_name);
377     }
378
379     output_file = fopen(output_file_name, "w");
380     if (output_file == 0)
381         open_error(output_file_name);
382
383     if (rflag)
384     {
385         code_file = fopen(code_file_name, "w");
386         if (code_file == 0)
387             open_error(code_file_name);
388     }
389     else
390         code_file = output_file;
391
392
393     interface_file = fopen(interface_file_name, "w");
394     if (interface_file == 0)
395       open_error(interface_file_name);
396 }
397
398 int main(int argc, char **argv)
399 {
400     set_signals();
401     getargs(argc, argv);
402     open_files();
403     reader();
404     lr0();
405     lalr();
406     make_parser();
407     verbose();
408     output();
409     done(0);
410     /*NOTREACHED*/
411     return 0;
412 }