main.c revision 36790
11590Srgrimes/*
21590Srgrimes * Copyright (c) 1989 The Regents of the University of California.
31590Srgrimes * All rights reserved.
41590Srgrimes *
51590Srgrimes * This code is derived from software contributed to Berkeley by
61590Srgrimes * Robert Paul Corbett.
71590Srgrimes *
81590Srgrimes * Redistribution and use in source and binary forms, with or without
91590Srgrimes * modification, are permitted provided that the following conditions
101590Srgrimes * are met:
111590Srgrimes * 1. Redistributions of source code must retain the above copyright
121590Srgrimes *    notice, this list of conditions and the following disclaimer.
131590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
141590Srgrimes *    notice, this list of conditions and the following disclaimer in the
151590Srgrimes *    documentation and/or other materials provided with the distribution.
161590Srgrimes * 3. All advertising materials mentioning features or use of this software
171590Srgrimes *    must display the following acknowledgement:
181590Srgrimes *	This product includes software developed by the University of
191590Srgrimes *	California, Berkeley and its contributors.
201590Srgrimes * 4. Neither the name of the University nor the names of its contributors
211590Srgrimes *    may be used to endorse or promote products derived from this software
221590Srgrimes *    without specific prior written permission.
231590Srgrimes *
241590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
251590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
261590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
271590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
281590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
291590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
301590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
311590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
321590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
331590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
341590Srgrimes * SUCH DAMAGE.
351590Srgrimes */
361590Srgrimes
371590Srgrimes#ifndef lint
3821622Sstevestatic char const copyright[] =
391590Srgrimes"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
401590Srgrimes All rights reserved.\n";
411590Srgrimes#endif /* not lint */
421590Srgrimes
431590Srgrimes#ifndef lint
4428856Scharnier#if 0
4521622Sstevestatic char const sccsid[] = "@(#)main.c	5.5 (Berkeley) 5/24/93";
4628856Scharnier#endif
4728856Scharnierstatic const char rcsid[] =
4836790Simp	"$Id: main.c,v 1.8 1997/08/28 06:33:53 charnier Exp $";
491590Srgrimes#endif /* not lint */
501590Srgrimes
511590Srgrimes#include <signal.h>
5221622Ssteve#include <stdlib.h>
5321622Ssteve#include <string.h>
5421622Ssteve#include <unistd.h>
551590Srgrimes#include "defs.h"
561590Srgrimes
571590Srgrimeschar dflag;
581590Srgrimeschar lflag;
591590Srgrimeschar rflag;
601590Srgrimeschar tflag;
611590Srgrimeschar vflag;
621590Srgrimes
631590Srgrimeschar *symbol_prefix;
641590Srgrimeschar *file_prefix = "y";
651590Srgrimeschar *temp_form = "yacc.XXXXXXX";
661590Srgrimes
671590Srgrimesint lineno;
681590Srgrimesint outline;
691590Srgrimes
701590Srgrimeschar *action_file_name;
711590Srgrimeschar *code_file_name;
721590Srgrimeschar *defines_file_name;
731590Srgrimeschar *input_file_name = "";
741590Srgrimeschar *output_file_name;
751590Srgrimeschar *text_file_name;
761590Srgrimeschar *union_file_name;
771590Srgrimeschar *verbose_file_name;
781590Srgrimes
791590SrgrimesFILE *action_file;	/*  a temp file, used to save actions associated    */
801590Srgrimes			/*  with rules until the parser is written	    */
811590SrgrimesFILE *code_file;	/*  y.code.c (used when the -r option is specified) */
821590SrgrimesFILE *defines_file;	/*  y.tab.h					    */
831590SrgrimesFILE *input_file;	/*  the input file				    */
841590SrgrimesFILE *output_file;	/*  y.tab.c					    */
851590SrgrimesFILE *text_file;	/*  a temp file, used to save text until all	    */
861590Srgrimes			/*  symbols have been defined			    */
871590SrgrimesFILE *union_file;	/*  a temp file, used to save the union		    */
881590Srgrimes			/*  definition until all symbol have been	    */
891590Srgrimes			/*  defined					    */
901590SrgrimesFILE *verbose_file;	/*  y.output					    */
911590Srgrimes
921590Srgrimesint nitems;
931590Srgrimesint nrules;
941590Srgrimesint nsyms;
951590Srgrimesint ntokens;
961590Srgrimesint nvars;
971590Srgrimes
981590Srgrimesint   start_symbol;
991590Srgrimeschar  **symbol_name;
1001590Srgrimesshort *symbol_value;
1011590Srgrimesshort *symbol_prec;
1021590Srgrimeschar  *symbol_assoc;
1031590Srgrimes
1041590Srgrimesshort *ritem;
1051590Srgrimesshort *rlhs;
1061590Srgrimesshort *rrhs;
1071590Srgrimesshort *rprec;
1081590Srgrimeschar  *rassoc;
1091590Srgrimesshort **derives;
1101590Srgrimeschar *nullable;
1111590Srgrimes
11221622Sstevestatic void create_file_names __P((void));
11321622Sstevestatic void getargs __P((int, char **));
11421622Sstevestatic void onintr __P((int));
11521622Sstevestatic void open_files __P((void));
11621622Sstevestatic void set_signals __P((void));
11721622Sstevestatic void usage __P((void));
1181590Srgrimes
1191590Srgrimes
12021622Sstevevoid
1211590Srgrimesdone(k)
1221590Srgrimesint k;
1231590Srgrimes{
1241590Srgrimes    if (action_file) { fclose(action_file); unlink(action_file_name); }
1251590Srgrimes    if (text_file) { fclose(text_file); unlink(text_file_name); }
1261590Srgrimes    if (union_file) { fclose(union_file); unlink(union_file_name); }
1271590Srgrimes    exit(k);
1281590Srgrimes}
1291590Srgrimes
1301590Srgrimes
13121622Sstevestatic void
1321590Srgrimesonintr(signo)
1331590Srgrimes	int signo;
1341590Srgrimes{
1351590Srgrimes    done(1);
1361590Srgrimes}
1371590Srgrimes
1381590Srgrimes
13921622Sstevestatic void
1401590Srgrimesset_signals()
1411590Srgrimes{
1421590Srgrimes#ifdef SIGINT
1431590Srgrimes    if (signal(SIGINT, SIG_IGN) != SIG_IGN)
1441590Srgrimes	signal(SIGINT, onintr);
1451590Srgrimes#endif
1461590Srgrimes#ifdef SIGTERM
1471590Srgrimes    if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
1481590Srgrimes	signal(SIGTERM, onintr);
1491590Srgrimes#endif
1501590Srgrimes#ifdef SIGHUP
1511590Srgrimes    if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
1521590Srgrimes	signal(SIGHUP, onintr);
1531590Srgrimes#endif
1541590Srgrimes}
1551590Srgrimes
1561590Srgrimes
15721622Sstevestatic void
1581590Srgrimesusage()
1591590Srgrimes{
16028856Scharnier    fprintf(stderr, "%s\n%s\n",
16128856Scharnier		"usage: yacc [-dlrtv] [-b file_prefix] [-o output_filename]",
16228856Scharnier		"            [-p symbol_prefix] filename");
1631590Srgrimes    exit(1);
1641590Srgrimes}
1651590Srgrimes
1661590Srgrimes
16721622Sstevestatic void
1681590Srgrimesgetargs(argc, argv)
1691590Srgrimesint argc;
1701590Srgrimeschar *argv[];
1711590Srgrimes{
1721590Srgrimes    register int i;
1731590Srgrimes    register char *s;
1741590Srgrimes
1751590Srgrimes    for (i = 1; i < argc; ++i)
1761590Srgrimes    {
1771590Srgrimes	s = argv[i];
1781590Srgrimes	if (*s != '-') break;
1791590Srgrimes	switch (*++s)
1801590Srgrimes	{
1811590Srgrimes	case '\0':
1821590Srgrimes	    input_file = stdin;
1831590Srgrimes	    if (i + 1 < argc) usage();
1841590Srgrimes	    return;
1851590Srgrimes
1861590Srgrimes	case '-':
1871590Srgrimes	    ++i;
1881590Srgrimes	    goto no_more_options;
1891590Srgrimes
1901590Srgrimes	case 'b':
1911590Srgrimes	    if (*++s)
1921590Srgrimes		 file_prefix = s;
1931590Srgrimes	    else if (++i < argc)
1941590Srgrimes		file_prefix = argv[i];
1951590Srgrimes	    else
1961590Srgrimes		usage();
1971590Srgrimes	    continue;
1981590Srgrimes
1991590Srgrimes	case 'd':
2001590Srgrimes	    dflag = 1;
2011590Srgrimes	    break;
2021590Srgrimes
2031590Srgrimes	case 'l':
2041590Srgrimes	    lflag = 1;
2051590Srgrimes	    break;
2061590Srgrimes
20722776Ssteve	case 'o':
20822776Ssteve	    if (*++s)
20922776Ssteve		output_file_name = s;
21022776Ssteve	    else if (++i < argc)
21122776Ssteve		output_file_name = argv[i];
21222776Ssteve	    else
21322776Ssteve		usage();
21422776Ssteve	    continue;
21522776Ssteve
2161590Srgrimes	case 'p':
2171590Srgrimes	    if (*++s)
2181590Srgrimes		symbol_prefix = s;
2191590Srgrimes	    else if (++i < argc)
2201590Srgrimes		symbol_prefix = argv[i];
2211590Srgrimes	    else
2221590Srgrimes		usage();
2231590Srgrimes	    continue;
2241590Srgrimes
2251590Srgrimes	case 'r':
2261590Srgrimes	    rflag = 1;
2271590Srgrimes	    break;
2281590Srgrimes
2291590Srgrimes	case 't':
2301590Srgrimes	    tflag = 1;
2311590Srgrimes	    break;
2321590Srgrimes
2331590Srgrimes	case 'v':
2341590Srgrimes	    vflag = 1;
2351590Srgrimes	    break;
2361590Srgrimes
2371590Srgrimes	default:
2381590Srgrimes	    usage();
2391590Srgrimes	}
2401590Srgrimes
2411590Srgrimes	for (;;)
2421590Srgrimes	{
2431590Srgrimes	    switch (*++s)
2441590Srgrimes	    {
2451590Srgrimes	    case '\0':
2461590Srgrimes		goto end_of_option;
2471590Srgrimes
2481590Srgrimes	    case 'd':
2491590Srgrimes		dflag = 1;
2501590Srgrimes		break;
2511590Srgrimes
2521590Srgrimes	    case 'l':
2531590Srgrimes		lflag = 1;
2541590Srgrimes		break;
2551590Srgrimes
2561590Srgrimes	    case 'r':
2571590Srgrimes		rflag = 1;
2581590Srgrimes		break;
2591590Srgrimes
2601590Srgrimes	    case 't':
2611590Srgrimes		tflag = 1;
2621590Srgrimes		break;
2631590Srgrimes
2641590Srgrimes	    case 'v':
2651590Srgrimes		vflag = 1;
2661590Srgrimes		break;
2671590Srgrimes
2681590Srgrimes	    default:
2691590Srgrimes		usage();
2701590Srgrimes	    }
2711590Srgrimes	}
2721590Srgrimesend_of_option:;
2731590Srgrimes    }
2741590Srgrimes
2751590Srgrimesno_more_options:;
2761590Srgrimes    if (i + 1 != argc) usage();
2771590Srgrimes    input_file_name = argv[i];
2781590Srgrimes}
2791590Srgrimes
2801590Srgrimes
2811590Srgrimeschar *
2821590Srgrimesallocate(n)
2831590Srgrimesunsigned n;
2841590Srgrimes{
2851590Srgrimes    register char *p;
2861590Srgrimes
2871590Srgrimes    p = NULL;
2881590Srgrimes    if (n)
2891590Srgrimes    {
2901590Srgrimes	p = CALLOC(1, n);
2911590Srgrimes	if (!p) no_space();
2921590Srgrimes    }
2931590Srgrimes    return (p);
2941590Srgrimes}
2951590Srgrimes
2961590Srgrimes
29721622Sstevestatic void
2981590Srgrimescreate_file_names()
2991590Srgrimes{
3001590Srgrimes    int i, len;
3011590Srgrimes    char *tmpdir;
3021590Srgrimes
3031590Srgrimes    tmpdir = getenv("TMPDIR");
3041590Srgrimes    if (tmpdir == 0) tmpdir = "/tmp";
3051590Srgrimes
3061590Srgrimes    len = strlen(tmpdir);
3071590Srgrimes    i = len + 13;
3081590Srgrimes    if (len && tmpdir[len-1] != '/')
3091590Srgrimes	++i;
3101590Srgrimes
3111590Srgrimes    action_file_name = MALLOC(i);
3121590Srgrimes    if (action_file_name == 0) no_space();
3131590Srgrimes    text_file_name = MALLOC(i);
3141590Srgrimes    if (text_file_name == 0) no_space();
3151590Srgrimes    union_file_name = MALLOC(i);
3161590Srgrimes    if (union_file_name == 0) no_space();
3171590Srgrimes
3181590Srgrimes    strcpy(action_file_name, tmpdir);
3191590Srgrimes    strcpy(text_file_name, tmpdir);
3201590Srgrimes    strcpy(union_file_name, tmpdir);
3211590Srgrimes
3221590Srgrimes    if (len && tmpdir[len - 1] != '/')
3231590Srgrimes    {
3241590Srgrimes	action_file_name[len] = '/';
3251590Srgrimes	text_file_name[len] = '/';
3261590Srgrimes	union_file_name[len] = '/';
3271590Srgrimes	++len;
3281590Srgrimes    }
3291590Srgrimes
3301590Srgrimes    strcpy(action_file_name + len, temp_form);
3311590Srgrimes    strcpy(text_file_name + len, temp_form);
3321590Srgrimes    strcpy(union_file_name + len, temp_form);
3331590Srgrimes
3341590Srgrimes    action_file_name[len + 5] = 'a';
3351590Srgrimes    text_file_name[len + 5] = 't';
3361590Srgrimes    union_file_name[len + 5] = 'u';
3371590Srgrimes
33822776Ssteve    if (output_file_name != 0)
33922776Ssteve    {
34022776Ssteve	file_prefix = output_file_name;
34122776Ssteve	len = strlen(file_prefix);
34222776Ssteve    }
34322776Ssteve    else
34422776Ssteve    {
34522776Ssteve	len = strlen(file_prefix);
34622776Ssteve	output_file_name = MALLOC(len + 7);
34722776Ssteve	if (output_file_name == 0)
34822776Ssteve	    no_space();
34922776Ssteve	strcpy(output_file_name, file_prefix);
35022776Ssteve	strcpy(output_file_name + len, OUTPUT_SUFFIX);
35122776Ssteve    }
3521590Srgrimes
3531590Srgrimes    if (rflag)
3541590Srgrimes    {
3551590Srgrimes	code_file_name = MALLOC(len + 8);
3561590Srgrimes	if (code_file_name == 0)
3571590Srgrimes	    no_space();
3581590Srgrimes	strcpy(code_file_name, file_prefix);
35922776Ssteve	if (file_prefix == output_file_name)
36022776Ssteve	{
36122776Ssteve	    /*
36222776Ssteve	     * XXX ".tab.c" here is OUTPUT_SUFFIX, but since its length is
36322776Ssteve	     * in various magic numbers, don't bother using the macro.
36422776Ssteve	     */
36522776Ssteve	    if (len >= 6 && strcmp(code_file_name + len - 6, ".tab.c") == 0)
36622776Ssteve		strcpy(code_file_name + len - 6, CODE_SUFFIX);
36722776Ssteve	    else if (len >= 2 && strcmp(code_file_name + len - 2, ".c") == 0)
36822776Ssteve		strcpy(code_file_name + len - 2, CODE_SUFFIX);
36922776Ssteve	    else
37022776Ssteve		strcpy(code_file_name + len, CODE_SUFFIX);
37122776Ssteve	}
37222776Ssteve	else
37322776Ssteve	    strcpy(code_file_name + len, CODE_SUFFIX);
3741590Srgrimes    }
3751590Srgrimes    else
3761590Srgrimes	code_file_name = output_file_name;
3771590Srgrimes
3781590Srgrimes    if (dflag)
3791590Srgrimes    {
3801590Srgrimes	defines_file_name = MALLOC(len + 7);
3811590Srgrimes	if (defines_file_name == 0)
3821590Srgrimes	    no_space();
3831590Srgrimes	strcpy(defines_file_name, file_prefix);
38422776Ssteve	if (file_prefix == output_file_name)
38522776Ssteve	{
38622776Ssteve#define BISON_DEFINES_SUFFIX  ".h"
38722776Ssteve	    if (len >= 2 && strcmp(defines_file_name + len - 2, ".c") == 0)
38822776Ssteve		strcpy(defines_file_name + len - 2, BISON_DEFINES_SUFFIX);
38922776Ssteve	    else
39022776Ssteve		strcpy(defines_file_name + len, BISON_DEFINES_SUFFIX);
39122776Ssteve	}
39222776Ssteve	else
39322776Ssteve	    strcpy(defines_file_name + len, DEFINES_SUFFIX);
3941590Srgrimes    }
3951590Srgrimes
3961590Srgrimes    if (vflag)
3971590Srgrimes    {
3981590Srgrimes	verbose_file_name = MALLOC(len + 8);
3991590Srgrimes	if (verbose_file_name == 0)
4001590Srgrimes	    no_space();
4011590Srgrimes	strcpy(verbose_file_name, file_prefix);
40222776Ssteve	if (file_prefix == output_file_name)
40322776Ssteve	{
40422776Ssteve	    if (len >= 6 && strcmp(verbose_file_name + len - 6, ".tab.c") == 0)
40522776Ssteve		strcpy(verbose_file_name + len - 6, VERBOSE_SUFFIX);
40622776Ssteve	    else if (len >= 2 && strcmp(verbose_file_name + len - 2, ".c") == 0)
40722776Ssteve		strcpy(verbose_file_name + len - 2, VERBOSE_SUFFIX);
40822776Ssteve	    else
40922776Ssteve		strcpy(verbose_file_name + len, VERBOSE_SUFFIX);
41022776Ssteve	}
41122776Ssteve	else
41222776Ssteve	    strcpy(verbose_file_name + len, VERBOSE_SUFFIX);
4131590Srgrimes    }
4141590Srgrimes}
4151590Srgrimes
4161590Srgrimes
41721622Sstevestatic void
4181590Srgrimesopen_files()
4191590Srgrimes{
42036790Simp    int fd;
42136790Simp
4221590Srgrimes    create_file_names();
4231590Srgrimes
4241590Srgrimes    if (input_file == 0)
4251590Srgrimes    {
4261590Srgrimes	input_file = fopen(input_file_name, "r");
4271590Srgrimes	if (input_file == 0)
4281590Srgrimes	    open_error(input_file_name);
4291590Srgrimes    }
4301590Srgrimes
43136790Simp    fd = mkstemp(action_file_name);
43236790Simp    if (fd < 0 || (action_file = fdopen(fd, "w")) == NULL) {
43336790Simp        if (fd >= 0)
43436790Simp	    close(fd);
4351590Srgrimes	open_error(action_file_name);
43636790Simp    }
43736790Simp    fd = mkstemp(text_file_name);
43836790Simp    if (fd < 0 || (text_file = fdopen(fd, "w")) == NULL) {
43936790Simp        if (fd >= 0)
44036790Simp	    close(fd);
44136790Simp	open_error(text_file_name);
44236790Simp    }
44336790Simp    fd = mkstemp(union_file_name);
44436790Simp    if (fd < 0 || (union_file = fdopen(fd, "w")) == NULL) {
44536790Simp        if (fd >= 0)
44636790Simp	    close(fd);
44736790Simp	open_error(union_file_name);
44836790Simp    }
4491590Srgrimes
4501590Srgrimes    text_file = fopen(text_file_name, "w");
4511590Srgrimes    if (text_file == 0)
4521590Srgrimes	open_error(text_file_name);
4531590Srgrimes
4541590Srgrimes    if (vflag)
4551590Srgrimes    {
4561590Srgrimes	verbose_file = fopen(verbose_file_name, "w");
4571590Srgrimes	if (verbose_file == 0)
4581590Srgrimes	    open_error(verbose_file_name);
4591590Srgrimes    }
4601590Srgrimes
4611590Srgrimes    if (dflag)
4621590Srgrimes    {
4631590Srgrimes	defines_file = fopen(defines_file_name, "w");
4641590Srgrimes	if (defines_file == 0)
4651590Srgrimes	    open_error(defines_file_name);
4661590Srgrimes	union_file = fopen(union_file_name, "w");
4671590Srgrimes	if (union_file ==  0)
4681590Srgrimes	    open_error(union_file_name);
4691590Srgrimes    }
4701590Srgrimes
4711590Srgrimes    output_file = fopen(output_file_name, "w");
4721590Srgrimes    if (output_file == 0)
4731590Srgrimes	open_error(output_file_name);
4741590Srgrimes
4751590Srgrimes    if (rflag)
4761590Srgrimes    {
4771590Srgrimes	code_file = fopen(code_file_name, "w");
4781590Srgrimes	if (code_file == 0)
4791590Srgrimes	    open_error(code_file_name);
4801590Srgrimes    }
4811590Srgrimes    else
4821590Srgrimes	code_file = output_file;
4831590Srgrimes}
4841590Srgrimes
4851590Srgrimes
4861590Srgrimesint
4871590Srgrimesmain(argc, argv)
4881590Srgrimesint argc;
4891590Srgrimeschar *argv[];
4901590Srgrimes{
4911590Srgrimes    set_signals();
4921590Srgrimes    getargs(argc, argv);
4931590Srgrimes    open_files();
4941590Srgrimes    reader();
4951590Srgrimes    lr0();
4961590Srgrimes    lalr();
4971590Srgrimes    make_parser();
4981590Srgrimes    verbose();
4991590Srgrimes    output();
5001590Srgrimes    done(0);
5011590Srgrimes    /*NOTREACHED*/
50221622Ssteve    return (0);
5031590Srgrimes}
504