xref: /freebsd/contrib/byacc/main.c (revision 822ca3276345b4a67ccbc9b54616d8b205fd37f2)
1*822ca327SBaptiste Daroussin /* $Id: main.c,v 1.74 2023/05/11 07:51:36 tom Exp $ */
298e903e7SBaptiste Daroussin 
398e903e7SBaptiste Daroussin #include <signal.h>
4b53bb29fSJung-uk Kim #if !defined(_WIN32) || defined(__MINGW32__)
598e903e7SBaptiste Daroussin #include <unistd.h>		/* for _exit() */
60c8de5b0SBaptiste Daroussin #else
70c8de5b0SBaptiste Daroussin #include <stdlib.h>		/* for _exit() */
80c8de5b0SBaptiste Daroussin #endif
998e903e7SBaptiste Daroussin 
1098e903e7SBaptiste Daroussin #include "defs.h"
1198e903e7SBaptiste Daroussin 
1298e903e7SBaptiste Daroussin #ifdef HAVE_MKSTEMP
1398e903e7SBaptiste Daroussin # define USE_MKSTEMP 1
1498e903e7SBaptiste Daroussin #elif defined(HAVE_FCNTL_H)
1598e903e7SBaptiste Daroussin # define USE_MKSTEMP 1
1698e903e7SBaptiste Daroussin # include <fcntl.h>		/* for open(), O_EXCL, etc. */
1798e903e7SBaptiste Daroussin #else
1898e903e7SBaptiste Daroussin # define USE_MKSTEMP 0
1998e903e7SBaptiste Daroussin #endif
2098e903e7SBaptiste Daroussin 
2198e903e7SBaptiste Daroussin #if USE_MKSTEMP
2298e903e7SBaptiste Daroussin #include <sys/types.h>
2398e903e7SBaptiste Daroussin #include <sys/stat.h>
2498e903e7SBaptiste Daroussin 
2598e903e7SBaptiste Daroussin typedef struct _my_tmpfiles
2698e903e7SBaptiste Daroussin {
2798e903e7SBaptiste Daroussin     struct _my_tmpfiles *next;
2898e903e7SBaptiste Daroussin     char *name;
2998e903e7SBaptiste Daroussin }
3098e903e7SBaptiste Daroussin MY_TMPFILES;
3198e903e7SBaptiste Daroussin 
3298e903e7SBaptiste Daroussin static MY_TMPFILES *my_tmpfiles;
3398e903e7SBaptiste Daroussin #endif /* USE_MKSTEMP */
3498e903e7SBaptiste Daroussin 
3598e903e7SBaptiste Daroussin char dflag;
36b53bb29fSJung-uk Kim char dflag2;
3798e903e7SBaptiste Daroussin char gflag;
3898e903e7SBaptiste Daroussin char iflag;
3998e903e7SBaptiste Daroussin char lflag;
4098e903e7SBaptiste Daroussin static char oflag;
4198e903e7SBaptiste Daroussin char rflag;
4298e903e7SBaptiste Daroussin char sflag;
4398e903e7SBaptiste Daroussin char tflag;
4498e903e7SBaptiste Daroussin char vflag;
4598e903e7SBaptiste Daroussin 
4698e903e7SBaptiste Daroussin const char *symbol_prefix;
4798e903e7SBaptiste Daroussin const char *myname = "yacc";
4898e903e7SBaptiste Daroussin 
4998e903e7SBaptiste Daroussin int lineno;
5098e903e7SBaptiste Daroussin int outline;
5198e903e7SBaptiste Daroussin 
5298e903e7SBaptiste Daroussin static char default_file_prefix[] = "y";
5398e903e7SBaptiste Daroussin 
5498e903e7SBaptiste Daroussin static char *file_prefix = default_file_prefix;
5598e903e7SBaptiste Daroussin 
5698e903e7SBaptiste Daroussin char *code_file_name;
573e794565SJung-uk Kim char *input_file_name;
583e794565SJung-uk Kim size_t input_file_name_len = 0;
5998e903e7SBaptiste Daroussin char *defines_file_name;
6098e903e7SBaptiste Daroussin char *externs_file_name;
6198e903e7SBaptiste Daroussin 
6298e903e7SBaptiste Daroussin static char *graph_file_name;
6398e903e7SBaptiste Daroussin static char *output_file_name;
6498e903e7SBaptiste Daroussin static char *verbose_file_name;
6598e903e7SBaptiste Daroussin 
6698e903e7SBaptiste Daroussin FILE *action_file;	/*  a temp file, used to save actions associated    */
6798e903e7SBaptiste Daroussin 			/*  with rules until the parser is written          */
6898e903e7SBaptiste Daroussin FILE *code_file;	/*  y.code.c (used when the -r option is specified) */
6998e903e7SBaptiste Daroussin FILE *defines_file;	/*  y.tab.h                                         */
7098e903e7SBaptiste Daroussin FILE *externs_file;	/*  y.tab.i                                         */
7198e903e7SBaptiste Daroussin FILE *input_file;	/*  the input file                                  */
7298e903e7SBaptiste Daroussin FILE *output_file;	/*  y.tab.c                                         */
7398e903e7SBaptiste Daroussin FILE *text_file;	/*  a temp file, used to save text until all        */
7498e903e7SBaptiste Daroussin 			/*  symbols have been defined                       */
7598e903e7SBaptiste Daroussin FILE *union_file;	/*  a temp file, used to save the union             */
7698e903e7SBaptiste Daroussin 			/*  definition until all symbol have been           */
7798e903e7SBaptiste Daroussin 			/*  defined                                         */
7898e903e7SBaptiste Daroussin FILE *verbose_file;	/*  y.output                                        */
7998e903e7SBaptiste Daroussin FILE *graph_file;	/*  y.dot                                           */
8098e903e7SBaptiste Daroussin 
810c8de5b0SBaptiste Daroussin Value_t nitems;
820c8de5b0SBaptiste Daroussin Value_t nrules;
830c8de5b0SBaptiste Daroussin Value_t nsyms;
840c8de5b0SBaptiste Daroussin Value_t ntokens;
850c8de5b0SBaptiste Daroussin Value_t nvars;
8698e903e7SBaptiste Daroussin 
8798e903e7SBaptiste Daroussin Value_t start_symbol;
8898e903e7SBaptiste Daroussin char **symbol_name;
8998e903e7SBaptiste Daroussin char **symbol_pname;
9098e903e7SBaptiste Daroussin Value_t *symbol_value;
910c8de5b0SBaptiste Daroussin Value_t *symbol_prec;
9298e903e7SBaptiste Daroussin char *symbol_assoc;
9398e903e7SBaptiste Daroussin 
9498e903e7SBaptiste Daroussin int pure_parser;
954b4a8fcaSBaptiste Daroussin int token_table;
962aca18c7SJung-uk Kim int error_verbose;
970c8de5b0SBaptiste Daroussin 
980c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
990c8de5b0SBaptiste Daroussin Value_t *symbol_pval;
1000c8de5b0SBaptiste Daroussin char **symbol_destructor;
1010c8de5b0SBaptiste Daroussin char **symbol_type_tag;
1020c8de5b0SBaptiste Daroussin int locations = 0;	/* default to no position processing */
1030c8de5b0SBaptiste Daroussin int backtrack = 0;	/* default is no backtracking */
1042aca18c7SJung-uk Kim char *initial_action = NULL;
1050c8de5b0SBaptiste Daroussin #endif
1060c8de5b0SBaptiste Daroussin 
10798e903e7SBaptiste Daroussin int exit_code;
10898e903e7SBaptiste Daroussin 
10998e903e7SBaptiste Daroussin Value_t *ritem;
11098e903e7SBaptiste Daroussin Value_t *rlhs;
11198e903e7SBaptiste Daroussin Value_t *rrhs;
11298e903e7SBaptiste Daroussin Value_t *rprec;
11398e903e7SBaptiste Daroussin Assoc_t *rassoc;
11498e903e7SBaptiste Daroussin Value_t **derives;
11598e903e7SBaptiste Daroussin char *nullable;
11698e903e7SBaptiste Daroussin 
11798e903e7SBaptiste Daroussin /*
11898e903e7SBaptiste Daroussin  * Since fclose() is called via the signal handler, it might die.  Don't loop
11998e903e7SBaptiste Daroussin  * if there is a problem closing a file.
12098e903e7SBaptiste Daroussin  */
12198e903e7SBaptiste Daroussin #define DO_CLOSE(fp) \
12298e903e7SBaptiste Daroussin 	if (fp != 0) { \
12398e903e7SBaptiste Daroussin 	    FILE *use = fp; \
12498e903e7SBaptiste Daroussin 	    fp = 0; \
12598e903e7SBaptiste Daroussin 	    fclose(use); \
12698e903e7SBaptiste Daroussin 	}
12798e903e7SBaptiste Daroussin 
12898e903e7SBaptiste Daroussin static int got_intr = 0;
12998e903e7SBaptiste Daroussin 
13098e903e7SBaptiste Daroussin void
done(int k)13198e903e7SBaptiste Daroussin done(int k)
13298e903e7SBaptiste Daroussin {
13398e903e7SBaptiste Daroussin     DO_CLOSE(input_file);
13498e903e7SBaptiste Daroussin     DO_CLOSE(output_file);
1350c8de5b0SBaptiste Daroussin     if (iflag)
1360c8de5b0SBaptiste Daroussin 	DO_CLOSE(externs_file);
1370c8de5b0SBaptiste Daroussin     if (rflag)
1380c8de5b0SBaptiste Daroussin 	DO_CLOSE(code_file);
13998e903e7SBaptiste Daroussin 
14098e903e7SBaptiste Daroussin     DO_CLOSE(action_file);
14198e903e7SBaptiste Daroussin     DO_CLOSE(defines_file);
14298e903e7SBaptiste Daroussin     DO_CLOSE(graph_file);
14398e903e7SBaptiste Daroussin     DO_CLOSE(text_file);
14498e903e7SBaptiste Daroussin     DO_CLOSE(union_file);
14598e903e7SBaptiste Daroussin     DO_CLOSE(verbose_file);
14698e903e7SBaptiste Daroussin 
14798e903e7SBaptiste Daroussin     if (got_intr)
14898e903e7SBaptiste Daroussin 	_exit(EXIT_FAILURE);
14998e903e7SBaptiste Daroussin 
15098e903e7SBaptiste Daroussin #ifdef NO_LEAKS
1518e022d3cSDag-Erling Smørgrav     DO_FREE(input_file_name);
1528e022d3cSDag-Erling Smørgrav 
15398e903e7SBaptiste Daroussin     if (rflag)
15498e903e7SBaptiste Daroussin 	DO_FREE(code_file_name);
15598e903e7SBaptiste Daroussin 
156b53bb29fSJung-uk Kim     if (dflag && !dflag2)
15798e903e7SBaptiste Daroussin 	DO_FREE(defines_file_name);
15898e903e7SBaptiste Daroussin 
15998e903e7SBaptiste Daroussin     if (iflag)
16098e903e7SBaptiste Daroussin 	DO_FREE(externs_file_name);
16198e903e7SBaptiste Daroussin 
16298e903e7SBaptiste Daroussin     if (oflag)
16398e903e7SBaptiste Daroussin 	DO_FREE(output_file_name);
16498e903e7SBaptiste Daroussin 
16598e903e7SBaptiste Daroussin     if (vflag)
16698e903e7SBaptiste Daroussin 	DO_FREE(verbose_file_name);
16798e903e7SBaptiste Daroussin 
16898e903e7SBaptiste Daroussin     if (gflag)
16998e903e7SBaptiste Daroussin 	DO_FREE(graph_file_name);
17098e903e7SBaptiste Daroussin 
17198e903e7SBaptiste Daroussin     lr0_leaks();
17298e903e7SBaptiste Daroussin     lalr_leaks();
17398e903e7SBaptiste Daroussin     mkpar_leaks();
174497dcf4cSBaptiste Daroussin     mstring_leaks();
17598e903e7SBaptiste Daroussin     output_leaks();
17698e903e7SBaptiste Daroussin     reader_leaks();
17798e903e7SBaptiste Daroussin #endif
17898e903e7SBaptiste Daroussin 
17998e903e7SBaptiste Daroussin     exit(k);
18098e903e7SBaptiste Daroussin }
18198e903e7SBaptiste Daroussin 
18298e903e7SBaptiste Daroussin static void
onintr(int sig GCC_UNUSED)1833e066022SBaptiste Daroussin onintr(int sig GCC_UNUSED)
18498e903e7SBaptiste Daroussin {
18598e903e7SBaptiste Daroussin     got_intr = 1;
18698e903e7SBaptiste Daroussin     done(EXIT_FAILURE);
18798e903e7SBaptiste Daroussin }
18898e903e7SBaptiste Daroussin 
18998e903e7SBaptiste Daroussin static void
set_signals(void)19098e903e7SBaptiste Daroussin set_signals(void)
19198e903e7SBaptiste Daroussin {
19298e903e7SBaptiste Daroussin #ifdef SIGINT
19398e903e7SBaptiste Daroussin     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
19498e903e7SBaptiste Daroussin 	signal(SIGINT, onintr);
19598e903e7SBaptiste Daroussin #endif
19698e903e7SBaptiste Daroussin #ifdef SIGTERM
19798e903e7SBaptiste Daroussin     if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
19898e903e7SBaptiste Daroussin 	signal(SIGTERM, onintr);
19998e903e7SBaptiste Daroussin #endif
20098e903e7SBaptiste Daroussin #ifdef SIGHUP
20198e903e7SBaptiste Daroussin     if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
20298e903e7SBaptiste Daroussin 	signal(SIGHUP, onintr);
20398e903e7SBaptiste Daroussin #endif
20498e903e7SBaptiste Daroussin }
20598e903e7SBaptiste Daroussin 
2068e022d3cSDag-Erling Smørgrav #define SIZEOF(v) (sizeof(v) / sizeof((v)[0]))
2078e022d3cSDag-Erling Smørgrav 
2088e022d3cSDag-Erling Smørgrav /*
2098e022d3cSDag-Erling Smørgrav  * Long options are provided only as a compatibility aid for scripters.
2108e022d3cSDag-Erling Smørgrav  */
2118e022d3cSDag-Erling Smørgrav /* *INDENT-OFF* */
2128e022d3cSDag-Erling Smørgrav static const struct {
2138e022d3cSDag-Erling Smørgrav     const char long_opt[16];
2148e022d3cSDag-Erling Smørgrav     const char yacc_arg;
2158e022d3cSDag-Erling Smørgrav     const char yacc_opt;
2168e022d3cSDag-Erling Smørgrav } long_opts[] = {
2178e022d3cSDag-Erling Smørgrav     { "defines",     1, 'H' },
2188e022d3cSDag-Erling Smørgrav     { "file-prefix", 1, 'b' },
2198e022d3cSDag-Erling Smørgrav     { "graph",       0, 'g' },
2208e022d3cSDag-Erling Smørgrav     { "help",        0, 'h' },
2218e022d3cSDag-Erling Smørgrav     { "name-prefix", 1, 'p' },
2228e022d3cSDag-Erling Smørgrav     { "no-lines",    0, 'l' },
2238e022d3cSDag-Erling Smørgrav     { "output",      1, 'o' },
2248e022d3cSDag-Erling Smørgrav     { "version",     0, 'V' }
2258e022d3cSDag-Erling Smørgrav };
2268e022d3cSDag-Erling Smørgrav /* *INDENT-ON* */
2278e022d3cSDag-Erling Smørgrav 
2288e022d3cSDag-Erling Smørgrav /*
2298e022d3cSDag-Erling Smørgrav  * Usage-message is designed for 80 columns, with some unknowns.  Account for
2308e022d3cSDag-Erling Smørgrav  * those in the maximum width so that the usage message uses no relocatable
2318e022d3cSDag-Erling Smørgrav  * pointers.
2328e022d3cSDag-Erling Smørgrav  */
2338e022d3cSDag-Erling Smørgrav #define USAGE_COLS (80 + sizeof(DEFINES_SUFFIX) + sizeof(OUTPUT_SUFFIX))
2348e022d3cSDag-Erling Smørgrav 
23598e903e7SBaptiste Daroussin static void
usage(void)23698e903e7SBaptiste Daroussin usage(void)
23798e903e7SBaptiste Daroussin {
2388e022d3cSDag-Erling Smørgrav     /* *INDENT-OFF* */
2398e022d3cSDag-Erling Smørgrav     static const char msg[][USAGE_COLS] =
24098e903e7SBaptiste Daroussin     {
2418e022d3cSDag-Erling Smørgrav 	{ "  -b file_prefix        set filename prefix (default \"y.\")" },
2428e022d3cSDag-Erling Smørgrav 	{ "  -B                    create a backtracking parser" },
2438e022d3cSDag-Erling Smørgrav 	{ "  -d                    write definitions (" DEFINES_SUFFIX ")" },
2448e022d3cSDag-Erling Smørgrav 	{ "  -h                    print this help-message" },
2458e022d3cSDag-Erling Smørgrav 	{ "  -H defines_file       write definitions to defines_file" },
2468e022d3cSDag-Erling Smørgrav 	{ "  -i                    write interface (y.tab.i)" },
2478e022d3cSDag-Erling Smørgrav 	{ "  -g                    write a graphical description" },
2488e022d3cSDag-Erling Smørgrav 	{ "  -l                    suppress #line directives" },
2498e022d3cSDag-Erling Smørgrav 	{ "  -L                    enable position processing, e.g., \"%locations\"" },
2508e022d3cSDag-Erling Smørgrav 	{ "  -o output_file        (default \"" OUTPUT_SUFFIX "\")" },
2518e022d3cSDag-Erling Smørgrav 	{ "  -p symbol_prefix      set symbol prefix (default \"yy\")" },
2528e022d3cSDag-Erling Smørgrav 	{ "  -P                    create a reentrant parser, e.g., \"%pure-parser\"" },
2538e022d3cSDag-Erling Smørgrav 	{ "  -r                    produce separate code and table files (y.code.c)" },
2548e022d3cSDag-Erling Smørgrav 	{ "  -s                    suppress #define's for quoted names in %token lines" },
2558e022d3cSDag-Erling Smørgrav 	{ "  -t                    add debugging support" },
2568e022d3cSDag-Erling Smørgrav 	{ "  -v                    write description (y.output)" },
2578e022d3cSDag-Erling Smørgrav 	{ "  -V                    show version information and exit" },
25898e903e7SBaptiste Daroussin     };
2598e022d3cSDag-Erling Smørgrav     /* *INDENT-ON* */
26098e903e7SBaptiste Daroussin     unsigned n;
26198e903e7SBaptiste Daroussin 
26298e903e7SBaptiste Daroussin     fflush(stdout);
26398e903e7SBaptiste Daroussin     fprintf(stderr, "Usage: %s [options] filename\n", myname);
2648e022d3cSDag-Erling Smørgrav 
2658e022d3cSDag-Erling Smørgrav     fprintf(stderr, "\nOptions:\n");
2668e022d3cSDag-Erling Smørgrav     for (n = 0; n < SIZEOF(msg); ++n)
2678e022d3cSDag-Erling Smørgrav     {
26898e903e7SBaptiste Daroussin 	fprintf(stderr, "%s\n", msg[n]);
2698e022d3cSDag-Erling Smørgrav     }
2708e022d3cSDag-Erling Smørgrav 
2718e022d3cSDag-Erling Smørgrav     fprintf(stderr, "\nLong options:\n");
2728e022d3cSDag-Erling Smørgrav     for (n = 0; n < SIZEOF(long_opts); ++n)
2738e022d3cSDag-Erling Smørgrav     {
2748e022d3cSDag-Erling Smørgrav 	fprintf(stderr, "  --%-20s-%c\n",
2758e022d3cSDag-Erling Smørgrav 		long_opts[n].long_opt,
2768e022d3cSDag-Erling Smørgrav 		long_opts[n].yacc_opt);
2778e022d3cSDag-Erling Smørgrav     }
27898e903e7SBaptiste Daroussin 
279b53bb29fSJung-uk Kim     exit(EXIT_FAILURE);
28098e903e7SBaptiste Daroussin }
28198e903e7SBaptiste Daroussin 
28298e903e7SBaptiste Daroussin static void
invalid_option(const char * option)2838e022d3cSDag-Erling Smørgrav invalid_option(const char *option)
2848e022d3cSDag-Erling Smørgrav {
2858e022d3cSDag-Erling Smørgrav     fprintf(stderr, "invalid option: %s\n", option);
2868e022d3cSDag-Erling Smørgrav     usage();
2878e022d3cSDag-Erling Smørgrav }
2888e022d3cSDag-Erling Smørgrav 
2898e022d3cSDag-Erling Smørgrav static void
setflag(int ch)29098e903e7SBaptiste Daroussin setflag(int ch)
29198e903e7SBaptiste Daroussin {
29298e903e7SBaptiste Daroussin     switch (ch)
29398e903e7SBaptiste Daroussin     {
2940c8de5b0SBaptiste Daroussin     case 'B':
2950c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
2960c8de5b0SBaptiste Daroussin 	backtrack = 1;
2970c8de5b0SBaptiste Daroussin #else
2980c8de5b0SBaptiste Daroussin 	unsupported_flag_warning("-B", "reconfigure with --enable-btyacc");
2990c8de5b0SBaptiste Daroussin #endif
3000c8de5b0SBaptiste Daroussin 	break;
3010c8de5b0SBaptiste Daroussin 
30298e903e7SBaptiste Daroussin     case 'd':
30398e903e7SBaptiste Daroussin 	dflag = 1;
304b53bb29fSJung-uk Kim 	dflag2 = 0;
30598e903e7SBaptiste Daroussin 	break;
30698e903e7SBaptiste Daroussin 
30798e903e7SBaptiste Daroussin     case 'g':
30898e903e7SBaptiste Daroussin 	gflag = 1;
30998e903e7SBaptiste Daroussin 	break;
31098e903e7SBaptiste Daroussin 
31198e903e7SBaptiste Daroussin     case 'i':
31298e903e7SBaptiste Daroussin 	iflag = 1;
31398e903e7SBaptiste Daroussin 	break;
31498e903e7SBaptiste Daroussin 
31598e903e7SBaptiste Daroussin     case 'l':
31698e903e7SBaptiste Daroussin 	lflag = 1;
31798e903e7SBaptiste Daroussin 	break;
31898e903e7SBaptiste Daroussin 
3190c8de5b0SBaptiste Daroussin     case 'L':
3200c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
3210c8de5b0SBaptiste Daroussin 	locations = 1;
3220c8de5b0SBaptiste Daroussin #else
3236166fdceSJung-uk Kim 	unsupported_flag_warning("-L", "reconfigure with --enable-btyacc");
3240c8de5b0SBaptiste Daroussin #endif
3250c8de5b0SBaptiste Daroussin 	break;
3260c8de5b0SBaptiste Daroussin 
32798e903e7SBaptiste Daroussin     case 'P':
32898e903e7SBaptiste Daroussin 	pure_parser = 1;
32998e903e7SBaptiste Daroussin 	break;
33098e903e7SBaptiste Daroussin 
33198e903e7SBaptiste Daroussin     case 'r':
33298e903e7SBaptiste Daroussin 	rflag = 1;
33398e903e7SBaptiste Daroussin 	break;
33498e903e7SBaptiste Daroussin 
33598e903e7SBaptiste Daroussin     case 's':
33698e903e7SBaptiste Daroussin 	sflag = 1;
33798e903e7SBaptiste Daroussin 	break;
33898e903e7SBaptiste Daroussin 
33998e903e7SBaptiste Daroussin     case 't':
34098e903e7SBaptiste Daroussin 	tflag = 1;
34198e903e7SBaptiste Daroussin 	break;
34298e903e7SBaptiste Daroussin 
34398e903e7SBaptiste Daroussin     case 'v':
34498e903e7SBaptiste Daroussin 	vflag = 1;
34598e903e7SBaptiste Daroussin 	break;
34698e903e7SBaptiste Daroussin 
34798e903e7SBaptiste Daroussin     case 'V':
34898e903e7SBaptiste Daroussin 	printf("%s - %s\n", myname, VERSION);
34998e903e7SBaptiste Daroussin 	exit(EXIT_SUCCESS);
35098e903e7SBaptiste Daroussin 
35198e903e7SBaptiste Daroussin     case 'y':
35298e903e7SBaptiste Daroussin 	/* noop for bison compatibility. byacc is already designed to be posix
35398e903e7SBaptiste Daroussin 	 * yacc compatible. */
35498e903e7SBaptiste Daroussin 	break;
35598e903e7SBaptiste Daroussin 
35698e903e7SBaptiste Daroussin     default:
35798e903e7SBaptiste Daroussin 	usage();
35898e903e7SBaptiste Daroussin     }
35998e903e7SBaptiste Daroussin }
36098e903e7SBaptiste Daroussin 
36198e903e7SBaptiste Daroussin static void
getargs(int argc,char * argv[])36298e903e7SBaptiste Daroussin getargs(int argc, char *argv[])
36398e903e7SBaptiste Daroussin {
36498e903e7SBaptiste Daroussin     int i;
365b53bb29fSJung-uk Kim #ifdef HAVE_GETOPT
366b53bb29fSJung-uk Kim     int ch;
3678e022d3cSDag-Erling Smørgrav #endif
368b53bb29fSJung-uk Kim 
3698e022d3cSDag-Erling Smørgrav     /*
3708e022d3cSDag-Erling Smørgrav      * Map bison's long-options into yacc short options.
3718e022d3cSDag-Erling Smørgrav      */
3728e022d3cSDag-Erling Smørgrav     for (i = 1; i < argc; ++i)
3738e022d3cSDag-Erling Smørgrav     {
3748e022d3cSDag-Erling Smørgrav 	char *a = argv[i];
3758e022d3cSDag-Erling Smørgrav 
3768e022d3cSDag-Erling Smørgrav 	if (!strncmp(a, "--", 2))
3778e022d3cSDag-Erling Smørgrav 	{
3788e022d3cSDag-Erling Smørgrav 	    char *eqls;
3798e022d3cSDag-Erling Smørgrav 	    size_t lc;
3808e022d3cSDag-Erling Smørgrav 	    size_t len;
3818e022d3cSDag-Erling Smørgrav 
3828e022d3cSDag-Erling Smørgrav 	    if ((len = strlen(a)) == 2)
3838e022d3cSDag-Erling Smørgrav 		break;
3848e022d3cSDag-Erling Smørgrav 
3858e022d3cSDag-Erling Smørgrav 	    if ((eqls = strchr(a, '=')) != NULL)
3868e022d3cSDag-Erling Smørgrav 	    {
3878e022d3cSDag-Erling Smørgrav 		len = (size_t)(eqls - a);
3888e022d3cSDag-Erling Smørgrav 		if (len == 0 || eqls[1] == '\0')
3898e022d3cSDag-Erling Smørgrav 		    invalid_option(a);
3908e022d3cSDag-Erling Smørgrav 	    }
3918e022d3cSDag-Erling Smørgrav 
3928e022d3cSDag-Erling Smørgrav 	    for (lc = 0; lc < SIZEOF(long_opts); ++lc)
3938e022d3cSDag-Erling Smørgrav 	    {
3948e022d3cSDag-Erling Smørgrav 		if (!strncmp(long_opts[lc].long_opt, a + 2, len - 2))
3958e022d3cSDag-Erling Smørgrav 		{
3968e022d3cSDag-Erling Smørgrav 		    if (eqls != NULL && !long_opts[lc].yacc_arg)
3978e022d3cSDag-Erling Smørgrav 			invalid_option(a);
3988e022d3cSDag-Erling Smørgrav 		    *a++ = '-';
3998e022d3cSDag-Erling Smørgrav 		    *a++ = long_opts[lc].yacc_opt;
4008e022d3cSDag-Erling Smørgrav 		    *a = '\0';
4018e022d3cSDag-Erling Smørgrav 		    if (eqls)
4028e022d3cSDag-Erling Smørgrav 		    {
4038e022d3cSDag-Erling Smørgrav 			while ((*a++ = *++eqls) != '\0') /* empty */ ;
4048e022d3cSDag-Erling Smørgrav 		    }
4058e022d3cSDag-Erling Smørgrav 		    break;
4068e022d3cSDag-Erling Smørgrav 		}
4078e022d3cSDag-Erling Smørgrav 	    }
4088e022d3cSDag-Erling Smørgrav 	    if (!strncmp(a, "--", 2))
4098e022d3cSDag-Erling Smørgrav 		invalid_option(a);
4108e022d3cSDag-Erling Smørgrav 	}
4118e022d3cSDag-Erling Smørgrav     }
4128e022d3cSDag-Erling Smørgrav 
4138e022d3cSDag-Erling Smørgrav #ifdef HAVE_GETOPT
414b53bb29fSJung-uk Kim     if (argc > 0)
415b53bb29fSJung-uk Kim 	myname = argv[0];
416b53bb29fSJung-uk Kim 
4178e022d3cSDag-Erling Smørgrav     while ((ch = getopt(argc, argv, "Bb:dghH:ilLo:Pp:rstVvy")) != -1)
418b53bb29fSJung-uk Kim     {
419b53bb29fSJung-uk Kim 	switch (ch)
420b53bb29fSJung-uk Kim 	{
421b53bb29fSJung-uk Kim 	case 'b':
422b53bb29fSJung-uk Kim 	    file_prefix = optarg;
423b53bb29fSJung-uk Kim 	    break;
4248e022d3cSDag-Erling Smørgrav 	case 'h':
4258e022d3cSDag-Erling Smørgrav 	    usage();
4268e022d3cSDag-Erling Smørgrav 	    break;
427b53bb29fSJung-uk Kim 	case 'H':
428b53bb29fSJung-uk Kim 	    dflag = dflag2 = 1;
429b53bb29fSJung-uk Kim 	    defines_file_name = optarg;
430b53bb29fSJung-uk Kim 	    break;
431b53bb29fSJung-uk Kim 	case 'o':
432b53bb29fSJung-uk Kim 	    output_file_name = optarg;
433b53bb29fSJung-uk Kim 	    break;
434b53bb29fSJung-uk Kim 	case 'p':
435b53bb29fSJung-uk Kim 	    symbol_prefix = optarg;
436b53bb29fSJung-uk Kim 	    break;
437b53bb29fSJung-uk Kim 	default:
438b53bb29fSJung-uk Kim 	    setflag(ch);
439b53bb29fSJung-uk Kim 	    break;
440b53bb29fSJung-uk Kim 	}
441b53bb29fSJung-uk Kim     }
442b53bb29fSJung-uk Kim     if ((i = optind) < argc)
443b53bb29fSJung-uk Kim     {
444b53bb29fSJung-uk Kim 	/* getopt handles "--" specially, while we handle "-" specially */
445b53bb29fSJung-uk Kim 	if (!strcmp(argv[i], "-"))
446b53bb29fSJung-uk Kim 	{
447b53bb29fSJung-uk Kim 	    if ((i + 1) < argc)
448b53bb29fSJung-uk Kim 		usage();
449b53bb29fSJung-uk Kim 	    input_file = stdin;
450b53bb29fSJung-uk Kim 	    return;
451b53bb29fSJung-uk Kim 	}
452b53bb29fSJung-uk Kim     }
453b53bb29fSJung-uk Kim #else
45498e903e7SBaptiste Daroussin     char *s;
45598e903e7SBaptiste Daroussin     int ch;
45698e903e7SBaptiste Daroussin 
45798e903e7SBaptiste Daroussin     if (argc > 0)
45898e903e7SBaptiste Daroussin 	myname = argv[0];
45998e903e7SBaptiste Daroussin 
46098e903e7SBaptiste Daroussin     for (i = 1; i < argc; ++i)
46198e903e7SBaptiste Daroussin     {
46298e903e7SBaptiste Daroussin 	s = argv[i];
46398e903e7SBaptiste Daroussin 	if (*s != '-')
46498e903e7SBaptiste Daroussin 	    break;
46598e903e7SBaptiste Daroussin 	switch (ch = *++s)
46698e903e7SBaptiste Daroussin 	{
46798e903e7SBaptiste Daroussin 	case '\0':
46898e903e7SBaptiste Daroussin 	    input_file = stdin;
46998e903e7SBaptiste Daroussin 	    if (i + 1 < argc)
47098e903e7SBaptiste Daroussin 		usage();
47198e903e7SBaptiste Daroussin 	    return;
47298e903e7SBaptiste Daroussin 
47398e903e7SBaptiste Daroussin 	case '-':
47498e903e7SBaptiste Daroussin 	    ++i;
47598e903e7SBaptiste Daroussin 	    goto no_more_options;
47698e903e7SBaptiste Daroussin 
47798e903e7SBaptiste Daroussin 	case 'b':
47898e903e7SBaptiste Daroussin 	    if (*++s)
47998e903e7SBaptiste Daroussin 		file_prefix = s;
48098e903e7SBaptiste Daroussin 	    else if (++i < argc)
48198e903e7SBaptiste Daroussin 		file_prefix = argv[i];
48298e903e7SBaptiste Daroussin 	    else
48398e903e7SBaptiste Daroussin 		usage();
48498e903e7SBaptiste Daroussin 	    continue;
48598e903e7SBaptiste Daroussin 
486b53bb29fSJung-uk Kim 	case 'H':
487b53bb29fSJung-uk Kim 	    dflag = dflag2 = 1;
488b53bb29fSJung-uk Kim 	    if (*++s)
489b53bb29fSJung-uk Kim 		defines_file_name = s;
490b53bb29fSJung-uk Kim 	    else if (++i < argc)
491b53bb29fSJung-uk Kim 		defines_file_name = argv[i];
492b53bb29fSJung-uk Kim 	    else
493b53bb29fSJung-uk Kim 		usage();
494b53bb29fSJung-uk Kim 	    continue;
495b53bb29fSJung-uk Kim 
49698e903e7SBaptiste Daroussin 	case 'o':
49798e903e7SBaptiste Daroussin 	    if (*++s)
49898e903e7SBaptiste Daroussin 		output_file_name = s;
49998e903e7SBaptiste Daroussin 	    else if (++i < argc)
50098e903e7SBaptiste Daroussin 		output_file_name = argv[i];
50198e903e7SBaptiste Daroussin 	    else
50298e903e7SBaptiste Daroussin 		usage();
50398e903e7SBaptiste Daroussin 	    continue;
50498e903e7SBaptiste Daroussin 
50598e903e7SBaptiste Daroussin 	case 'p':
50698e903e7SBaptiste Daroussin 	    if (*++s)
50798e903e7SBaptiste Daroussin 		symbol_prefix = s;
50898e903e7SBaptiste Daroussin 	    else if (++i < argc)
50998e903e7SBaptiste Daroussin 		symbol_prefix = argv[i];
51098e903e7SBaptiste Daroussin 	    else
51198e903e7SBaptiste Daroussin 		usage();
51298e903e7SBaptiste Daroussin 	    continue;
51398e903e7SBaptiste Daroussin 
51498e903e7SBaptiste Daroussin 	default:
51598e903e7SBaptiste Daroussin 	    setflag(ch);
51698e903e7SBaptiste Daroussin 	    break;
51798e903e7SBaptiste Daroussin 	}
51898e903e7SBaptiste Daroussin 
51998e903e7SBaptiste Daroussin 	for (;;)
52098e903e7SBaptiste Daroussin 	{
52198e903e7SBaptiste Daroussin 	    switch (ch = *++s)
52298e903e7SBaptiste Daroussin 	    {
52398e903e7SBaptiste Daroussin 	    case '\0':
52498e903e7SBaptiste Daroussin 		goto end_of_option;
52598e903e7SBaptiste Daroussin 
52698e903e7SBaptiste Daroussin 	    default:
52798e903e7SBaptiste Daroussin 		setflag(ch);
52898e903e7SBaptiste Daroussin 		break;
52998e903e7SBaptiste Daroussin 	    }
53098e903e7SBaptiste Daroussin 	}
53198e903e7SBaptiste Daroussin       end_of_option:;
53298e903e7SBaptiste Daroussin     }
53398e903e7SBaptiste Daroussin 
534b53bb29fSJung-uk Kim   no_more_options:
535b53bb29fSJung-uk Kim 
536b53bb29fSJung-uk Kim #endif /* HAVE_GETOPT */
53798e903e7SBaptiste Daroussin     if (i + 1 != argc)
53898e903e7SBaptiste Daroussin 	usage();
5393e794565SJung-uk Kim     input_file_name_len = strlen(argv[i]);
5403e794565SJung-uk Kim     input_file_name = TMALLOC(char, input_file_name_len + 1);
5413e794565SJung-uk Kim     NO_SPACE(input_file_name);
5423e794565SJung-uk Kim     strcpy(input_file_name, argv[i]);
54398e903e7SBaptiste Daroussin }
54498e903e7SBaptiste Daroussin 
54598e903e7SBaptiste Daroussin void *
allocate(size_t n)54698e903e7SBaptiste Daroussin allocate(size_t n)
54798e903e7SBaptiste Daroussin {
54898e903e7SBaptiste Daroussin     void *p;
54998e903e7SBaptiste Daroussin 
55098e903e7SBaptiste Daroussin     p = NULL;
55198e903e7SBaptiste Daroussin     if (n)
55298e903e7SBaptiste Daroussin     {
55398e903e7SBaptiste Daroussin 	p = CALLOC(1, n);
55498e903e7SBaptiste Daroussin 	NO_SPACE(p);
55598e903e7SBaptiste Daroussin     }
55698e903e7SBaptiste Daroussin     return (p);
55798e903e7SBaptiste Daroussin }
55898e903e7SBaptiste Daroussin 
55998e903e7SBaptiste Daroussin #define CREATE_FILE_NAME(dest, suffix) \
5600c8de5b0SBaptiste Daroussin 	dest = alloc_file_name(len, suffix)
5610c8de5b0SBaptiste Daroussin 
5620c8de5b0SBaptiste Daroussin static char *
alloc_file_name(size_t len,const char * suffix)5630c8de5b0SBaptiste Daroussin alloc_file_name(size_t len, const char *suffix)
5640c8de5b0SBaptiste Daroussin {
5650c8de5b0SBaptiste Daroussin     char *result = TMALLOC(char, len + strlen(suffix) + 1);
566*822ca327SBaptiste Daroussin     if (result == NULL)
567*822ca327SBaptiste Daroussin 	on_error();
5680c8de5b0SBaptiste Daroussin     strcpy(result, file_prefix);
5690c8de5b0SBaptiste Daroussin     strcpy(result + len, suffix);
5700c8de5b0SBaptiste Daroussin     return result;
5710c8de5b0SBaptiste Daroussin }
57298e903e7SBaptiste Daroussin 
57320afc491SJung-uk Kim static char *
find_suffix(char * name,const char * suffix)57420afc491SJung-uk Kim find_suffix(char *name, const char *suffix)
57520afc491SJung-uk Kim {
57620afc491SJung-uk Kim     size_t len = strlen(name);
57720afc491SJung-uk Kim     size_t slen = strlen(suffix);
57820afc491SJung-uk Kim     if (len >= slen)
57920afc491SJung-uk Kim     {
58020afc491SJung-uk Kim 	name += len - slen;
58120afc491SJung-uk Kim 	if (strcmp(name, suffix) == 0)
58220afc491SJung-uk Kim 	    return name;
58320afc491SJung-uk Kim     }
58420afc491SJung-uk Kim     return NULL;
58520afc491SJung-uk Kim }
58620afc491SJung-uk Kim 
58798e903e7SBaptiste Daroussin static void
create_file_names(void)58898e903e7SBaptiste Daroussin create_file_names(void)
58998e903e7SBaptiste Daroussin {
59098e903e7SBaptiste Daroussin     size_t len;
59198e903e7SBaptiste Daroussin     const char *defines_suffix;
59298e903e7SBaptiste Daroussin     const char *externs_suffix;
59320afc491SJung-uk Kim     char *suffix;
59498e903e7SBaptiste Daroussin 
59520afc491SJung-uk Kim     suffix = NULL;
59698e903e7SBaptiste Daroussin     defines_suffix = DEFINES_SUFFIX;
59798e903e7SBaptiste Daroussin     externs_suffix = EXTERNS_SUFFIX;
59898e903e7SBaptiste Daroussin 
59998e903e7SBaptiste Daroussin     /* compute the file_prefix from the user provided output_file_name */
60098e903e7SBaptiste Daroussin     if (output_file_name != 0)
60198e903e7SBaptiste Daroussin     {
60220afc491SJung-uk Kim 	if (!(suffix = find_suffix(output_file_name, OUTPUT_SUFFIX))
60320afc491SJung-uk Kim 	    && (suffix = find_suffix(output_file_name, ".c")))
60498e903e7SBaptiste Daroussin 	{
60598e903e7SBaptiste Daroussin 	    defines_suffix = ".h";
60698e903e7SBaptiste Daroussin 	    externs_suffix = ".i";
60798e903e7SBaptiste Daroussin 	}
60898e903e7SBaptiste Daroussin     }
60998e903e7SBaptiste Daroussin 
61020afc491SJung-uk Kim     if (suffix != NULL)
61198e903e7SBaptiste Daroussin     {
61220afc491SJung-uk Kim 	len = (size_t)(suffix - output_file_name);
6133e066022SBaptiste Daroussin 	file_prefix = TMALLOC(char, len + 1);
61498e903e7SBaptiste Daroussin 	NO_SPACE(file_prefix);
61598e903e7SBaptiste Daroussin 	strncpy(file_prefix, output_file_name, len)[len] = 0;
61698e903e7SBaptiste Daroussin     }
61798e903e7SBaptiste Daroussin     else
61898e903e7SBaptiste Daroussin 	len = strlen(file_prefix);
61998e903e7SBaptiste Daroussin 
62098e903e7SBaptiste Daroussin     /* if "-o filename" was not given */
62198e903e7SBaptiste Daroussin     if (output_file_name == 0)
62298e903e7SBaptiste Daroussin     {
62398e903e7SBaptiste Daroussin 	oflag = 1;
62498e903e7SBaptiste Daroussin 	CREATE_FILE_NAME(output_file_name, OUTPUT_SUFFIX);
62598e903e7SBaptiste Daroussin     }
62698e903e7SBaptiste Daroussin 
62798e903e7SBaptiste Daroussin     if (rflag)
62898e903e7SBaptiste Daroussin     {
62998e903e7SBaptiste Daroussin 	CREATE_FILE_NAME(code_file_name, CODE_SUFFIX);
63098e903e7SBaptiste Daroussin     }
63198e903e7SBaptiste Daroussin     else
63298e903e7SBaptiste Daroussin 	code_file_name = output_file_name;
63398e903e7SBaptiste Daroussin 
634b53bb29fSJung-uk Kim     if (dflag && !dflag2)
63598e903e7SBaptiste Daroussin     {
63698e903e7SBaptiste Daroussin 	CREATE_FILE_NAME(defines_file_name, defines_suffix);
63798e903e7SBaptiste Daroussin     }
63898e903e7SBaptiste Daroussin 
63998e903e7SBaptiste Daroussin     if (iflag)
64098e903e7SBaptiste Daroussin     {
64198e903e7SBaptiste Daroussin 	CREATE_FILE_NAME(externs_file_name, externs_suffix);
64298e903e7SBaptiste Daroussin     }
64398e903e7SBaptiste Daroussin 
64498e903e7SBaptiste Daroussin     if (vflag)
64598e903e7SBaptiste Daroussin     {
64698e903e7SBaptiste Daroussin 	CREATE_FILE_NAME(verbose_file_name, VERBOSE_SUFFIX);
64798e903e7SBaptiste Daroussin     }
64898e903e7SBaptiste Daroussin 
64998e903e7SBaptiste Daroussin     if (gflag)
65098e903e7SBaptiste Daroussin     {
65198e903e7SBaptiste Daroussin 	CREATE_FILE_NAME(graph_file_name, GRAPH_SUFFIX);
65298e903e7SBaptiste Daroussin     }
65398e903e7SBaptiste Daroussin 
65420afc491SJung-uk Kim     if (suffix != NULL)
65598e903e7SBaptiste Daroussin     {
65698e903e7SBaptiste Daroussin 	FREE(file_prefix);
65798e903e7SBaptiste Daroussin     }
65898e903e7SBaptiste Daroussin }
65998e903e7SBaptiste Daroussin 
66098e903e7SBaptiste Daroussin #if USE_MKSTEMP
66198e903e7SBaptiste Daroussin static void
close_tmpfiles(void)66298e903e7SBaptiste Daroussin close_tmpfiles(void)
66398e903e7SBaptiste Daroussin {
66498e903e7SBaptiste Daroussin     while (my_tmpfiles != 0)
66598e903e7SBaptiste Daroussin     {
66698e903e7SBaptiste Daroussin 	MY_TMPFILES *next = my_tmpfiles->next;
66798e903e7SBaptiste Daroussin 
66811fce282SBaptiste Daroussin 	(void)chmod(my_tmpfiles->name, 0644);
66911fce282SBaptiste Daroussin 	(void)unlink(my_tmpfiles->name);
67098e903e7SBaptiste Daroussin 
67198e903e7SBaptiste Daroussin 	free(my_tmpfiles->name);
67298e903e7SBaptiste Daroussin 	free(my_tmpfiles);
67398e903e7SBaptiste Daroussin 
67498e903e7SBaptiste Daroussin 	my_tmpfiles = next;
67598e903e7SBaptiste Daroussin     }
67698e903e7SBaptiste Daroussin }
67798e903e7SBaptiste Daroussin 
67898e903e7SBaptiste Daroussin #ifndef HAVE_MKSTEMP
67998e903e7SBaptiste Daroussin static int
my_mkstemp(char * temp)68098e903e7SBaptiste Daroussin my_mkstemp(char *temp)
68198e903e7SBaptiste Daroussin {
68298e903e7SBaptiste Daroussin     int fd;
68398e903e7SBaptiste Daroussin     char *dname;
68498e903e7SBaptiste Daroussin     char *fname;
68598e903e7SBaptiste Daroussin     char *name;
68698e903e7SBaptiste Daroussin 
68798e903e7SBaptiste Daroussin     /*
68898e903e7SBaptiste Daroussin      * Split-up to use tempnam, rather than tmpnam; the latter (like
68998e903e7SBaptiste Daroussin      * mkstemp) is unusable on Windows.
69098e903e7SBaptiste Daroussin      */
69198e903e7SBaptiste Daroussin     if ((fname = strrchr(temp, '/')) != 0)
69298e903e7SBaptiste Daroussin     {
69398e903e7SBaptiste Daroussin 	dname = strdup(temp);
69498e903e7SBaptiste Daroussin 	dname[++fname - temp] = '\0';
69598e903e7SBaptiste Daroussin     }
69698e903e7SBaptiste Daroussin     else
69798e903e7SBaptiste Daroussin     {
69898e903e7SBaptiste Daroussin 	dname = 0;
69998e903e7SBaptiste Daroussin 	fname = temp;
70098e903e7SBaptiste Daroussin     }
70198e903e7SBaptiste Daroussin     if ((name = tempnam(dname, fname)) != 0)
70298e903e7SBaptiste Daroussin     {
70398e903e7SBaptiste Daroussin 	fd = open(name, O_CREAT | O_EXCL | O_RDWR);
70498e903e7SBaptiste Daroussin 	strcpy(temp, name);
70598e903e7SBaptiste Daroussin     }
70698e903e7SBaptiste Daroussin     else
70798e903e7SBaptiste Daroussin     {
70898e903e7SBaptiste Daroussin 	fd = -1;
70998e903e7SBaptiste Daroussin     }
71098e903e7SBaptiste Daroussin 
71198e903e7SBaptiste Daroussin     if (dname != 0)
71298e903e7SBaptiste Daroussin 	free(dname);
71398e903e7SBaptiste Daroussin 
71498e903e7SBaptiste Daroussin     return fd;
71598e903e7SBaptiste Daroussin }
71698e903e7SBaptiste Daroussin #define mkstemp(s) my_mkstemp(s)
71798e903e7SBaptiste Daroussin #endif
71898e903e7SBaptiste Daroussin 
71998e903e7SBaptiste Daroussin #endif
72098e903e7SBaptiste Daroussin 
72198e903e7SBaptiste Daroussin /*
72298e903e7SBaptiste Daroussin  * tmpfile() should be adequate, except that it may require special privileges
72398e903e7SBaptiste Daroussin  * to use, e.g., MinGW and Windows 7 where it tries to use the root directory.
72498e903e7SBaptiste Daroussin  */
72598e903e7SBaptiste Daroussin static FILE *
open_tmpfile(const char * label)72698e903e7SBaptiste Daroussin open_tmpfile(const char *label)
72798e903e7SBaptiste Daroussin {
7280f86d14eSJung-uk Kim #define MY_FMT "%s/%.*sXXXXXX"
72998e903e7SBaptiste Daroussin     FILE *result;
73098e903e7SBaptiste Daroussin #if USE_MKSTEMP
73198e903e7SBaptiste Daroussin     const char *tmpdir;
73298e903e7SBaptiste Daroussin     char *name;
73398e903e7SBaptiste Daroussin 
734b53bb29fSJung-uk Kim     if (((tmpdir = getenv("TMPDIR")) == 0 || access(tmpdir, W_OK) != 0) ||
735b53bb29fSJung-uk Kim 	((tmpdir = getenv("TEMP")) == 0 || access(tmpdir, W_OK) != 0))
73698e903e7SBaptiste Daroussin     {
73798e903e7SBaptiste Daroussin #ifdef P_tmpdir
73898e903e7SBaptiste Daroussin 	tmpdir = P_tmpdir;
73998e903e7SBaptiste Daroussin #else
74098e903e7SBaptiste Daroussin 	tmpdir = "/tmp";
74198e903e7SBaptiste Daroussin #endif
74298e903e7SBaptiste Daroussin 	if (access(tmpdir, W_OK) != 0)
74398e903e7SBaptiste Daroussin 	    tmpdir = ".";
74498e903e7SBaptiste Daroussin     }
74598e903e7SBaptiste Daroussin 
7460f86d14eSJung-uk Kim     /* The size of the format is guaranteed to be longer than the result from
7470f86d14eSJung-uk Kim      * printing empty strings with it; this calculation accounts for the
7480f86d14eSJung-uk Kim      * string-lengths as well.
7490f86d14eSJung-uk Kim      */
7500f86d14eSJung-uk Kim     name = malloc(strlen(tmpdir) + sizeof(MY_FMT) + strlen(label));
75198e903e7SBaptiste Daroussin 
75298e903e7SBaptiste Daroussin     result = 0;
75398e903e7SBaptiste Daroussin     if (name != 0)
75498e903e7SBaptiste Daroussin     {
7558e022d3cSDag-Erling Smørgrav 	int fd;
7568e022d3cSDag-Erling Smørgrav 	const char *mark;
7578e022d3cSDag-Erling Smørgrav 
758315e69cbSBaptiste Daroussin 	mode_t save_umask = umask(0177);
75911fce282SBaptiste Daroussin 
76098e903e7SBaptiste Daroussin 	if ((mark = strrchr(label, '_')) == 0)
76198e903e7SBaptiste Daroussin 	    mark = label + strlen(label);
76298e903e7SBaptiste Daroussin 
7630f86d14eSJung-uk Kim 	sprintf(name, MY_FMT, tmpdir, (int)(mark - label), label);
76498e903e7SBaptiste Daroussin 	fd = mkstemp(name);
765b53bb29fSJung-uk Kim 	if (fd >= 0
766b53bb29fSJung-uk Kim 	    && (result = fdopen(fd, "w+")) != 0)
76798e903e7SBaptiste Daroussin 	{
76898e903e7SBaptiste Daroussin 	    MY_TMPFILES *item;
76998e903e7SBaptiste Daroussin 
77098e903e7SBaptiste Daroussin 	    if (my_tmpfiles == 0)
77198e903e7SBaptiste Daroussin 	    {
77298e903e7SBaptiste Daroussin 		atexit(close_tmpfiles);
77398e903e7SBaptiste Daroussin 	    }
77498e903e7SBaptiste Daroussin 
77598e903e7SBaptiste Daroussin 	    item = NEW(MY_TMPFILES);
77698e903e7SBaptiste Daroussin 	    NO_SPACE(item);
77798e903e7SBaptiste Daroussin 
77898e903e7SBaptiste Daroussin 	    item->name = name;
77998e903e7SBaptiste Daroussin 	    NO_SPACE(item->name);
78098e903e7SBaptiste Daroussin 
78198e903e7SBaptiste Daroussin 	    item->next = my_tmpfiles;
78298e903e7SBaptiste Daroussin 	    my_tmpfiles = item;
78398e903e7SBaptiste Daroussin 	}
784b53bb29fSJung-uk Kim 	else
785b53bb29fSJung-uk Kim 	{
786b53bb29fSJung-uk Kim 	    FREE(name);
78798e903e7SBaptiste Daroussin 	}
78811fce282SBaptiste Daroussin 	(void)umask(save_umask);
78998e903e7SBaptiste Daroussin     }
79098e903e7SBaptiste Daroussin #else
79198e903e7SBaptiste Daroussin     result = tmpfile();
79298e903e7SBaptiste Daroussin #endif
79398e903e7SBaptiste Daroussin 
79498e903e7SBaptiste Daroussin     if (result == 0)
79598e903e7SBaptiste Daroussin 	open_error(label);
79698e903e7SBaptiste Daroussin     return result;
7970f86d14eSJung-uk Kim #undef MY_FMT
79898e903e7SBaptiste Daroussin }
79998e903e7SBaptiste Daroussin 
80098e903e7SBaptiste Daroussin static void
open_files(void)80198e903e7SBaptiste Daroussin open_files(void)
80298e903e7SBaptiste Daroussin {
80398e903e7SBaptiste Daroussin     create_file_names();
80498e903e7SBaptiste Daroussin 
80598e903e7SBaptiste Daroussin     if (input_file == 0)
80698e903e7SBaptiste Daroussin     {
80798e903e7SBaptiste Daroussin 	input_file = fopen(input_file_name, "r");
80898e903e7SBaptiste Daroussin 	if (input_file == 0)
80998e903e7SBaptiste Daroussin 	    open_error(input_file_name);
81098e903e7SBaptiste Daroussin     }
81198e903e7SBaptiste Daroussin 
81298e903e7SBaptiste Daroussin     action_file = open_tmpfile("action_file");
81398e903e7SBaptiste Daroussin     text_file = open_tmpfile("text_file");
81498e903e7SBaptiste Daroussin 
81598e903e7SBaptiste Daroussin     if (vflag)
81698e903e7SBaptiste Daroussin     {
81798e903e7SBaptiste Daroussin 	verbose_file = fopen(verbose_file_name, "w");
81898e903e7SBaptiste Daroussin 	if (verbose_file == 0)
81998e903e7SBaptiste Daroussin 	    open_error(verbose_file_name);
82098e903e7SBaptiste Daroussin     }
82198e903e7SBaptiste Daroussin 
82298e903e7SBaptiste Daroussin     if (gflag)
82398e903e7SBaptiste Daroussin     {
82498e903e7SBaptiste Daroussin 	graph_file = fopen(graph_file_name, "w");
82598e903e7SBaptiste Daroussin 	if (graph_file == 0)
82698e903e7SBaptiste Daroussin 	    open_error(graph_file_name);
82798e903e7SBaptiste Daroussin 	fprintf(graph_file, "digraph %s {\n", file_prefix);
82898e903e7SBaptiste Daroussin 	fprintf(graph_file, "\tedge [fontsize=10];\n");
82998e903e7SBaptiste Daroussin 	fprintf(graph_file, "\tnode [shape=box,fontsize=10];\n");
83098e903e7SBaptiste Daroussin 	fprintf(graph_file, "\torientation=landscape;\n");
83198e903e7SBaptiste Daroussin 	fprintf(graph_file, "\trankdir=LR;\n");
83298e903e7SBaptiste Daroussin 	fprintf(graph_file, "\t/*\n");
83398e903e7SBaptiste Daroussin 	fprintf(graph_file, "\tmargin=0.2;\n");
83498e903e7SBaptiste Daroussin 	fprintf(graph_file, "\tpage=\"8.27,11.69\"; // for A4 printing\n");
83598e903e7SBaptiste Daroussin 	fprintf(graph_file, "\tratio=auto;\n");
83698e903e7SBaptiste Daroussin 	fprintf(graph_file, "\t*/\n");
83798e903e7SBaptiste Daroussin     }
83898e903e7SBaptiste Daroussin 
839b53bb29fSJung-uk Kim     if (dflag || dflag2)
84098e903e7SBaptiste Daroussin     {
84198e903e7SBaptiste Daroussin 	defines_file = fopen(defines_file_name, "w");
84298e903e7SBaptiste Daroussin 	if (defines_file == 0)
84398e903e7SBaptiste Daroussin 	    open_error(defines_file_name);
84498e903e7SBaptiste Daroussin 	union_file = open_tmpfile("union_file");
84598e903e7SBaptiste Daroussin     }
84698e903e7SBaptiste Daroussin 
84798e903e7SBaptiste Daroussin     if (iflag)
84898e903e7SBaptiste Daroussin     {
84998e903e7SBaptiste Daroussin 	externs_file = fopen(externs_file_name, "w");
85098e903e7SBaptiste Daroussin 	if (externs_file == 0)
85198e903e7SBaptiste Daroussin 	    open_error(externs_file_name);
85298e903e7SBaptiste Daroussin     }
85398e903e7SBaptiste Daroussin 
85498e903e7SBaptiste Daroussin     output_file = fopen(output_file_name, "w");
85598e903e7SBaptiste Daroussin     if (output_file == 0)
85698e903e7SBaptiste Daroussin 	open_error(output_file_name);
85798e903e7SBaptiste Daroussin 
85898e903e7SBaptiste Daroussin     if (rflag)
85998e903e7SBaptiste Daroussin     {
86098e903e7SBaptiste Daroussin 	code_file = fopen(code_file_name, "w");
86198e903e7SBaptiste Daroussin 	if (code_file == 0)
86298e903e7SBaptiste Daroussin 	    open_error(code_file_name);
86398e903e7SBaptiste Daroussin     }
86498e903e7SBaptiste Daroussin     else
86598e903e7SBaptiste Daroussin 	code_file = output_file;
86698e903e7SBaptiste Daroussin }
86798e903e7SBaptiste Daroussin 
86898e903e7SBaptiste Daroussin int
main(int argc,char * argv[])86998e903e7SBaptiste Daroussin main(int argc, char *argv[])
87098e903e7SBaptiste Daroussin {
87198e903e7SBaptiste Daroussin     SRexpect = -1;
87298e903e7SBaptiste Daroussin     RRexpect = -1;
87398e903e7SBaptiste Daroussin     exit_code = EXIT_SUCCESS;
87498e903e7SBaptiste Daroussin 
87598e903e7SBaptiste Daroussin     set_signals();
87698e903e7SBaptiste Daroussin     getargs(argc, argv);
87798e903e7SBaptiste Daroussin     open_files();
87898e903e7SBaptiste Daroussin     reader();
87998e903e7SBaptiste Daroussin     lr0();
88098e903e7SBaptiste Daroussin     lalr();
88198e903e7SBaptiste Daroussin     make_parser();
88298e903e7SBaptiste Daroussin     graph();
88398e903e7SBaptiste Daroussin     finalize_closure();
88498e903e7SBaptiste Daroussin     verbose();
88598e903e7SBaptiste Daroussin     output();
88698e903e7SBaptiste Daroussin     done(exit_code);
88798e903e7SBaptiste Daroussin     /*NOTREACHED */
88898e903e7SBaptiste Daroussin }
889