1 #include "defs.h"
2 #include <signal.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 
6 char dflag;
7 char lflag;
8 char rflag;
9 char tflag;
10 char vflag;
11 int Eflag = 0;
12 
13 char *symbol_prefix = "yy";
14 char *myname = "yacc";
15 #if defined(__MSDOS__) || defined(_WIN32)
16 #define DIR_CHAR '\\'
17 #define DEFAULT_TMPDIR "."
18 char *file_prefix = "y";
19 #else  /* Unix */
20 #define DIR_CHAR '/'
21 #define DEFAULT_TMPDIR "/tmp"
22 char *file_prefix = 0;
23 #endif
24 char *temp_form = "yacc_t_XXXXXX";
25 
26 int outline;
27 
28 char *action_file_name;
29 char *code_file_name;
30 char *defines_file_name;
31 char include_defines;
32 char *output_file_name;
33 char *text_file_name;
34 char *union_file_name;
35 char *verbose_file_name;
36 
37 FILE *action_file;	/*  a temp file, used to save actions associated    */
38 			/*  with rules until the parser is written	    */
39 FILE *code_file;	/*  y.code.c (used when the -r option is specified) */
40 FILE *defines_file;	/*  y.tab.h					    */
41 FILE *output_file;	/*  y.tab.c					    */
42 FILE *text_file;	/*  a temp file, used to save text until all	    */
43 			/*  symbols have been defined			    */
44 FILE *union_file;	/*  a temp file, used to save the union		    */
45 			/*  definition until all symbol have been	    */
46 			/*  defined					    */
47 FILE *verbose_file;	/*  y.output					    */
48 
49 int nitems;
50 int nrules;
51 int nsyms;
52 int ntokens;
53 int nvars;
54 
55 int   start_symbol;
56 char  **symbol_name;
57 Yshort *symbol_value;
58 Yshort *symbol_prec;
59 char  *symbol_assoc;
60 
61 Yshort *ritem;
62 Yshort *rlhs;
63 Yshort *rrhs;
64 Yshort *rprec;
65 char  *rassoc;
66 Yshort **derives;
67 char *nullable;
68 
69 
done(int k)70 void done(int k)
71 {
72     if (action_file) { fclose(action_file); unlink(action_file_name); }
73     if (text_file) { fclose(text_file); unlink(text_file_name); }
74     if (union_file) { fclose(union_file); unlink(union_file_name); }
75     exit(k);
76 }
77 
78 
onintr(int ignore)79 void onintr(int ignore)
80 {
81     done(1);
82 }
83 
84 
set_signals()85 void set_signals()
86 {
87 #ifdef SIGINT
88     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
89 	signal(SIGINT, onintr);
90 #endif
91 #ifdef SIGTERM
92     if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
93 	signal(SIGTERM, onintr);
94 #endif
95 #ifdef SIGHUP
96     if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
97 	signal(SIGHUP, onintr);
98 #endif
99 }
100 
101 
usage()102 void usage()
103 {
104     fprintf(stderr, "usage: %s [-dlrtv] [-b file_prefix] [-S skeleton file] "
105 		    "[-p symbol_prefix] filename\n", myname);
106     exit(1);
107 }
108 
109 
getargs(int argc,char ** argv)110 void getargs(int argc, char **argv)
111 {
112     register int i;
113     register char *s;
114 
115     if (argc > 0) myname = argv[0];
116     for (i = 1; i < argc; ++i)
117     {
118 	s = argv[i];
119 	if (*s != '-') break;
120 	switch (*++s)
121 	{
122 	case '\0':
123 	    read_from_file("-");
124 	    if (i + 1 < argc) usage();
125 	    return;
126 
127 	case '-':
128 	    ++i;
129 	    goto no_more_options;
130 
131 	case 'b':
132 	    if (*++s)
133 		 file_prefix = s;
134 	    else if (++i < argc)
135 		file_prefix = argv[i];
136 	    else
137 		usage();
138 	    continue;
139 
140 	case 'p':
141 	    if (*++s)
142 		 symbol_prefix = s;
143 	    else if (++i < argc)
144 		symbol_prefix = argv[i];
145 	    else
146 		usage();
147 	    continue;
148 
149 	case 'd':
150 	    dflag = 1;
151 	    break;
152 
153 	case 'D':
154 	    /* Find the preprocessor variable */
155 	    { char **ps;
156 	      char *var_name = s + 1;
157 	      extern char *defd_vars[];
158 	      for(ps=&defd_vars[0]; *ps; ps++) {
159 		if(strcmp(*ps,var_name)==0) {
160 		  error(input_file->lineno, 0, 0,
161 		        "Preprocessor variable %s already defined", var_name);
162 		}
163 	      }
164 	      *ps = MALLOC(strlen(var_name)+1);
165 	      strcpy(*ps, var_name);
166 	      *++ps = NULL;
167 	    }
168 	    continue;
169 
170 	case 'E':
171 	    Eflag = 1;
172 	    break;
173 
174 	case 'l':
175 	    lflag = 1;
176 	    break;
177 
178 	case 'r':
179 	    rflag = 1;
180 	    break;
181 
182 	case 't':
183 	    tflag = 1;
184 	    break;
185 
186 	case 'v':
187 	    vflag = 1;
188 	    break;
189 
190 	case 'y':
191 	    file_prefix = "y";
192 	    break;
193 
194 	case 'S':
195 	    if (*++s)
196 		read_skel(s);
197 	    else if (++i < argc)
198 		read_skel(argv[i]);
199 	    else
200 		usage();
201 	    continue;
202 
203 	default:
204 	    usage();
205 	}
206 
207 	for (;;)
208 	{
209 	    switch (*++s)
210 	    {
211 	    case '\0':
212 		goto end_of_option;
213 
214 	    case 'd':
215 		dflag = 1;
216 		break;
217 
218 	    case 'l':
219 		lflag = 1;
220 		break;
221 
222 	    case 'r':
223 		rflag = 1;
224 		break;
225 
226 	    case 't':
227 		tflag = 1;
228 		break;
229 
230 	    case 'v':
231 		vflag = 1;
232 		break;
233 
234 	    case 'y':
235 		file_prefix = "y";
236 		break;
237 
238 	    default:
239 		usage();
240 	    }
241 	}
242 end_of_option:;
243     }
244 
245 no_more_options:;
246     if (i + 1 != argc) usage();
247     read_from_file(argv[i]);
248 
249     if (!file_prefix) {
250       if (input_file && input_file->name) {
251 	file_prefix = strdup(input_file->name);
252 	if ((s = strrchr(file_prefix, '.')))
253 	  *s = 0;
254       } else {
255 	file_prefix = "y";
256       }
257     }
258 
259     /* Replace symbol prefix in the skeleton */
260     if (strcmp(symbol_prefix, "yy")) {
261       struct section *s;
262       char **l, *q, *n, *p;
263 
264       for (s = section_list; s->name; s++)
265         for (l = s->ptr; *l; l++) {
266 	  /* Very conservative estimate */
267 	  p = n = malloc(strlen(*l) * strlen(symbol_prefix));
268 	  for (q = *l; *q; q++)
269 	    if (q[0] == 'y' && q[1] == 'y') {
270 	      strcpy(p, symbol_prefix);
271 	      p += strlen(symbol_prefix);
272 	      q++;
273 	    } else
274 	      *p++ = *q;
275 	  *p = 0;
276 	  *l = realloc(n ,strlen(n) + 1);
277         }
278     }
279 }
280 
allocate(unsigned n)281 char *allocate(unsigned n)
282 {
283     register char *p;
284 
285     p = NULL;
286     if (n)
287     {
288         /* VM: add a few bytes here, cause
289          * Linux calloc does not like sizes like 32768 */
290 	p = CALLOC(1, n+10);
291 	if (!p) no_space();
292     }
293     return (p);
294 }
295 
296 
create_file_names()297 void create_file_names()
298 {
299     int i, len;
300     char *tmpdir;
301 
302     tmpdir = getenv("TMPDIR");
303     if (tmpdir == 0) tmpdir = DEFAULT_TMPDIR;
304 
305     len = strlen(tmpdir);
306     i = len + 13;
307     if (len && tmpdir[len-1] != DIR_CHAR)
308 	++i;
309 
310     action_file_name = MALLOC(i);
311     if (action_file_name == 0) no_space();
312     text_file_name = MALLOC(i);
313     if (text_file_name == 0) no_space();
314     union_file_name = MALLOC(i);
315     if (union_file_name == 0) no_space();
316 
317     strcpy(action_file_name, tmpdir);
318     strcpy(text_file_name, tmpdir);
319     strcpy(union_file_name, tmpdir);
320 
321     if (len && tmpdir[len - 1] != DIR_CHAR)
322     {
323 	action_file_name[len] = DIR_CHAR;
324 	text_file_name[len] = DIR_CHAR;
325 	union_file_name[len] = DIR_CHAR;
326 	++len;
327     }
328 
329     strcpy(action_file_name + len, temp_form);
330     strcpy(text_file_name + len, temp_form);
331     strcpy(union_file_name + len, temp_form);
332 
333     action_file_name[len + 5] = 'a';
334     text_file_name[len + 5] = 't';
335     union_file_name[len + 5] = 'u';
336 
337     if(mktemp(action_file_name)==NULL) {
338       fprintf(stderr, "btyacc: Cannot create temporary file\n");
339       exit(1);
340     }
341     if(mktemp(text_file_name)==NULL) {
342       fprintf(stderr, "btyacc: Cannot create temporary file\n");
343       exit(1);
344     }
345     if(mktemp(union_file_name)==NULL) {
346       fprintf(stderr, "btyacc: Cannot create temporary file\n");
347       exit(1);
348     }
349 
350     len = strlen(file_prefix);
351 
352     output_file_name = MALLOC(len + 7);
353     if (output_file_name == 0)
354 	no_space();
355     strcpy(output_file_name, file_prefix);
356     strcpy(output_file_name + len, OUTPUT_SUFFIX);
357 
358     if (rflag)
359     {
360 	code_file_name = MALLOC(len + 8);
361 	if (code_file_name == 0)
362 	    no_space();
363 	strcpy(code_file_name, file_prefix);
364 	strcpy(code_file_name + len, CODE_SUFFIX);
365     }
366     else
367 	code_file_name = output_file_name;
368 
369     if (dflag)
370     {
371 	defines_file_name = MALLOC(len + 7);
372 	if (defines_file_name == 0)
373 	    no_space();
374 	strcpy(defines_file_name, file_prefix);
375 	strcpy(defines_file_name + len, DEFINES_SUFFIX);
376     }
377 
378     if (vflag)
379     {
380 	verbose_file_name = MALLOC(len + 8);
381 	if (verbose_file_name == 0)
382 	    no_space();
383 	strcpy(verbose_file_name, file_prefix);
384 	strcpy(verbose_file_name + len, VERBOSE_SUFFIX);
385     }
386 }
387 
388 
open_files()389 void open_files()
390 {
391     create_file_names();
392 
393     action_file = fopen(action_file_name, "w");
394     if (action_file == 0)
395 	open_error(action_file_name);
396 
397     text_file = fopen(text_file_name, "w");
398     if (text_file == 0)
399 	open_error(text_file_name);
400 
401     if (vflag)
402     {
403 	verbose_file = fopen(verbose_file_name, "w");
404 	if (verbose_file == 0)
405 	    open_error(verbose_file_name);
406     }
407 
408     if (dflag)
409     {
410 	defines_file = fopen(defines_file_name, "w");
411 	if (defines_file == 0)
412 	    open_error(defines_file_name);
413 	union_file = fopen(union_file_name, "w");
414 	if (union_file ==  0)
415 	    open_error(union_file_name);
416     }
417 
418     output_file = fopen(output_file_name, "w");
419     if (output_file == 0)
420 	open_error(output_file_name);
421 
422     if (rflag)
423     {
424 	code_file = fopen(code_file_name, "w");
425 	if (code_file == 0)
426 	    open_error(code_file_name);
427     }
428     else
429 	code_file = output_file;
430 }
431 
432 
main(int argc,char ** argv)433 int main(int argc, char **argv)
434 {
435     set_signals();
436     getargs(argc, argv);
437     open_files();
438     reader();
439     lr0();
440     lalr();
441     make_parser();
442     verbose();
443     output();
444     done(0);
445     return 0;
446 }
447