1*b53bb29fSJung-uk Kim /* $Id: main.c,v 1.69 2019/11/25 23:24:36 Tom.Shields Exp $ */ 298e903e7SBaptiste Daroussin 398e903e7SBaptiste Daroussin #include <signal.h> 4*b53bb29fSJung-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; 36*b53bb29fSJung-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 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 15198e903e7SBaptiste Daroussin if (rflag) 15298e903e7SBaptiste Daroussin DO_FREE(code_file_name); 15398e903e7SBaptiste Daroussin 154*b53bb29fSJung-uk Kim if (dflag && !dflag2) 15598e903e7SBaptiste Daroussin DO_FREE(defines_file_name); 15698e903e7SBaptiste Daroussin 15798e903e7SBaptiste Daroussin if (iflag) 15898e903e7SBaptiste Daroussin DO_FREE(externs_file_name); 15998e903e7SBaptiste Daroussin 16098e903e7SBaptiste Daroussin if (oflag) 16198e903e7SBaptiste Daroussin DO_FREE(output_file_name); 16298e903e7SBaptiste Daroussin 16398e903e7SBaptiste Daroussin if (vflag) 16498e903e7SBaptiste Daroussin DO_FREE(verbose_file_name); 16598e903e7SBaptiste Daroussin 16698e903e7SBaptiste Daroussin if (gflag) 16798e903e7SBaptiste Daroussin DO_FREE(graph_file_name); 16898e903e7SBaptiste Daroussin 16998e903e7SBaptiste Daroussin lr0_leaks(); 17098e903e7SBaptiste Daroussin lalr_leaks(); 17198e903e7SBaptiste Daroussin mkpar_leaks(); 172497dcf4cSBaptiste Daroussin mstring_leaks(); 17398e903e7SBaptiste Daroussin output_leaks(); 17498e903e7SBaptiste Daroussin reader_leaks(); 17598e903e7SBaptiste Daroussin #endif 17698e903e7SBaptiste Daroussin 17798e903e7SBaptiste Daroussin exit(k); 17898e903e7SBaptiste Daroussin } 17998e903e7SBaptiste Daroussin 18098e903e7SBaptiste Daroussin static void 1813e066022SBaptiste Daroussin onintr(int sig GCC_UNUSED) 18298e903e7SBaptiste Daroussin { 18398e903e7SBaptiste Daroussin got_intr = 1; 18498e903e7SBaptiste Daroussin done(EXIT_FAILURE); 18598e903e7SBaptiste Daroussin } 18698e903e7SBaptiste Daroussin 18798e903e7SBaptiste Daroussin static void 18898e903e7SBaptiste Daroussin set_signals(void) 18998e903e7SBaptiste Daroussin { 19098e903e7SBaptiste Daroussin #ifdef SIGINT 19198e903e7SBaptiste Daroussin if (signal(SIGINT, SIG_IGN) != SIG_IGN) 19298e903e7SBaptiste Daroussin signal(SIGINT, onintr); 19398e903e7SBaptiste Daroussin #endif 19498e903e7SBaptiste Daroussin #ifdef SIGTERM 19598e903e7SBaptiste Daroussin if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 19698e903e7SBaptiste Daroussin signal(SIGTERM, onintr); 19798e903e7SBaptiste Daroussin #endif 19898e903e7SBaptiste Daroussin #ifdef SIGHUP 19998e903e7SBaptiste Daroussin if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 20098e903e7SBaptiste Daroussin signal(SIGHUP, onintr); 20198e903e7SBaptiste Daroussin #endif 20298e903e7SBaptiste Daroussin } 20398e903e7SBaptiste Daroussin 20498e903e7SBaptiste Daroussin static void 20598e903e7SBaptiste Daroussin usage(void) 20698e903e7SBaptiste Daroussin { 20798e903e7SBaptiste Daroussin static const char *msg[] = 20898e903e7SBaptiste Daroussin { 20998e903e7SBaptiste Daroussin "" 21098e903e7SBaptiste Daroussin ,"Options:" 21198e903e7SBaptiste Daroussin ," -b file_prefix set filename prefix (default \"y.\")" 2120c8de5b0SBaptiste Daroussin ," -B create a backtracking parser" 2130c8de5b0SBaptiste Daroussin ," -d write definitions (" DEFINES_SUFFIX ")" 214*b53bb29fSJung-uk Kim ," -H defines_file write definitions to defines_file" 21598e903e7SBaptiste Daroussin ," -i write interface (y.tab.i)" 21698e903e7SBaptiste Daroussin ," -g write a graphical description" 21798e903e7SBaptiste Daroussin ," -l suppress #line directives" 2180c8de5b0SBaptiste Daroussin ," -L enable position processing, e.g., \"%locations\"" 2190c8de5b0SBaptiste Daroussin ," -o output_file (default \"" OUTPUT_SUFFIX "\")" 22098e903e7SBaptiste Daroussin ," -p symbol_prefix set symbol prefix (default \"yy\")" 22198e903e7SBaptiste Daroussin ," -P create a reentrant parser, e.g., \"%pure-parser\"" 22298e903e7SBaptiste Daroussin ," -r produce separate code and table files (y.code.c)" 22398e903e7SBaptiste Daroussin ," -s suppress #define's for quoted names in %token lines" 22498e903e7SBaptiste Daroussin ," -t add debugging support" 22598e903e7SBaptiste Daroussin ," -v write description (y.output)" 22698e903e7SBaptiste Daroussin ," -V show version information and exit" 22798e903e7SBaptiste Daroussin }; 22898e903e7SBaptiste Daroussin unsigned n; 22998e903e7SBaptiste Daroussin 23098e903e7SBaptiste Daroussin fflush(stdout); 23198e903e7SBaptiste Daroussin fprintf(stderr, "Usage: %s [options] filename\n", myname); 23298e903e7SBaptiste Daroussin for (n = 0; n < sizeof(msg) / sizeof(msg[0]); ++n) 23398e903e7SBaptiste Daroussin fprintf(stderr, "%s\n", msg[n]); 23498e903e7SBaptiste Daroussin 235*b53bb29fSJung-uk Kim exit(EXIT_FAILURE); 23698e903e7SBaptiste Daroussin } 23798e903e7SBaptiste Daroussin 23898e903e7SBaptiste Daroussin static void 23998e903e7SBaptiste Daroussin setflag(int ch) 24098e903e7SBaptiste Daroussin { 24198e903e7SBaptiste Daroussin switch (ch) 24298e903e7SBaptiste Daroussin { 2430c8de5b0SBaptiste Daroussin case 'B': 2440c8de5b0SBaptiste Daroussin #if defined(YYBTYACC) 2450c8de5b0SBaptiste Daroussin backtrack = 1; 2460c8de5b0SBaptiste Daroussin #else 2470c8de5b0SBaptiste Daroussin unsupported_flag_warning("-B", "reconfigure with --enable-btyacc"); 2480c8de5b0SBaptiste Daroussin #endif 2490c8de5b0SBaptiste Daroussin break; 2500c8de5b0SBaptiste Daroussin 25198e903e7SBaptiste Daroussin case 'd': 25298e903e7SBaptiste Daroussin dflag = 1; 253*b53bb29fSJung-uk Kim dflag2 = 0; 25498e903e7SBaptiste Daroussin break; 25598e903e7SBaptiste Daroussin 25698e903e7SBaptiste Daroussin case 'g': 25798e903e7SBaptiste Daroussin gflag = 1; 25898e903e7SBaptiste Daroussin break; 25998e903e7SBaptiste Daroussin 26098e903e7SBaptiste Daroussin case 'i': 26198e903e7SBaptiste Daroussin iflag = 1; 26298e903e7SBaptiste Daroussin break; 26398e903e7SBaptiste Daroussin 26498e903e7SBaptiste Daroussin case 'l': 26598e903e7SBaptiste Daroussin lflag = 1; 26698e903e7SBaptiste Daroussin break; 26798e903e7SBaptiste Daroussin 2680c8de5b0SBaptiste Daroussin case 'L': 2690c8de5b0SBaptiste Daroussin #if defined(YYBTYACC) 2700c8de5b0SBaptiste Daroussin locations = 1; 2710c8de5b0SBaptiste Daroussin #else 2726166fdceSJung-uk Kim unsupported_flag_warning("-L", "reconfigure with --enable-btyacc"); 2730c8de5b0SBaptiste Daroussin #endif 2740c8de5b0SBaptiste Daroussin break; 2750c8de5b0SBaptiste Daroussin 27698e903e7SBaptiste Daroussin case 'P': 27798e903e7SBaptiste Daroussin pure_parser = 1; 27898e903e7SBaptiste Daroussin break; 27998e903e7SBaptiste Daroussin 28098e903e7SBaptiste Daroussin case 'r': 28198e903e7SBaptiste Daroussin rflag = 1; 28298e903e7SBaptiste Daroussin break; 28398e903e7SBaptiste Daroussin 28498e903e7SBaptiste Daroussin case 's': 28598e903e7SBaptiste Daroussin sflag = 1; 28698e903e7SBaptiste Daroussin break; 28798e903e7SBaptiste Daroussin 28898e903e7SBaptiste Daroussin case 't': 28998e903e7SBaptiste Daroussin tflag = 1; 29098e903e7SBaptiste Daroussin break; 29198e903e7SBaptiste Daroussin 29298e903e7SBaptiste Daroussin case 'v': 29398e903e7SBaptiste Daroussin vflag = 1; 29498e903e7SBaptiste Daroussin break; 29598e903e7SBaptiste Daroussin 29698e903e7SBaptiste Daroussin case 'V': 29798e903e7SBaptiste Daroussin printf("%s - %s\n", myname, VERSION); 29898e903e7SBaptiste Daroussin exit(EXIT_SUCCESS); 29998e903e7SBaptiste Daroussin 30098e903e7SBaptiste Daroussin case 'y': 30198e903e7SBaptiste Daroussin /* noop for bison compatibility. byacc is already designed to be posix 30298e903e7SBaptiste Daroussin * yacc compatible. */ 30398e903e7SBaptiste Daroussin break; 30498e903e7SBaptiste Daroussin 30598e903e7SBaptiste Daroussin default: 30698e903e7SBaptiste Daroussin usage(); 30798e903e7SBaptiste Daroussin } 30898e903e7SBaptiste Daroussin } 30998e903e7SBaptiste Daroussin 31098e903e7SBaptiste Daroussin static void 31198e903e7SBaptiste Daroussin getargs(int argc, char *argv[]) 31298e903e7SBaptiste Daroussin { 31398e903e7SBaptiste Daroussin int i; 314*b53bb29fSJung-uk Kim #ifdef HAVE_GETOPT 315*b53bb29fSJung-uk Kim int ch; 316*b53bb29fSJung-uk Kim 317*b53bb29fSJung-uk Kim if (argc > 0) 318*b53bb29fSJung-uk Kim myname = argv[0]; 319*b53bb29fSJung-uk Kim 320*b53bb29fSJung-uk Kim while ((ch = getopt(argc, argv, "Bb:dgH:ilLo:Pp:rstVvy")) != -1) 321*b53bb29fSJung-uk Kim { 322*b53bb29fSJung-uk Kim switch (ch) 323*b53bb29fSJung-uk Kim { 324*b53bb29fSJung-uk Kim case 'b': 325*b53bb29fSJung-uk Kim file_prefix = optarg; 326*b53bb29fSJung-uk Kim break; 327*b53bb29fSJung-uk Kim case 'H': 328*b53bb29fSJung-uk Kim dflag = dflag2 = 1; 329*b53bb29fSJung-uk Kim defines_file_name = optarg; 330*b53bb29fSJung-uk Kim break; 331*b53bb29fSJung-uk Kim case 'o': 332*b53bb29fSJung-uk Kim output_file_name = optarg; 333*b53bb29fSJung-uk Kim break; 334*b53bb29fSJung-uk Kim case 'p': 335*b53bb29fSJung-uk Kim symbol_prefix = optarg; 336*b53bb29fSJung-uk Kim break; 337*b53bb29fSJung-uk Kim default: 338*b53bb29fSJung-uk Kim setflag(ch); 339*b53bb29fSJung-uk Kim break; 340*b53bb29fSJung-uk Kim } 341*b53bb29fSJung-uk Kim } 342*b53bb29fSJung-uk Kim if ((i = optind) < argc) 343*b53bb29fSJung-uk Kim { 344*b53bb29fSJung-uk Kim /* getopt handles "--" specially, while we handle "-" specially */ 345*b53bb29fSJung-uk Kim if (!strcmp(argv[i], "-")) 346*b53bb29fSJung-uk Kim { 347*b53bb29fSJung-uk Kim if ((i + 1) < argc) 348*b53bb29fSJung-uk Kim usage(); 349*b53bb29fSJung-uk Kim input_file = stdin; 350*b53bb29fSJung-uk Kim return; 351*b53bb29fSJung-uk Kim } 352*b53bb29fSJung-uk Kim } 353*b53bb29fSJung-uk Kim #else 35498e903e7SBaptiste Daroussin char *s; 35598e903e7SBaptiste Daroussin int ch; 35698e903e7SBaptiste Daroussin 35798e903e7SBaptiste Daroussin if (argc > 0) 35898e903e7SBaptiste Daroussin myname = argv[0]; 35998e903e7SBaptiste Daroussin 36098e903e7SBaptiste Daroussin for (i = 1; i < argc; ++i) 36198e903e7SBaptiste Daroussin { 36298e903e7SBaptiste Daroussin s = argv[i]; 36398e903e7SBaptiste Daroussin if (*s != '-') 36498e903e7SBaptiste Daroussin break; 36598e903e7SBaptiste Daroussin switch (ch = *++s) 36698e903e7SBaptiste Daroussin { 36798e903e7SBaptiste Daroussin case '\0': 36898e903e7SBaptiste Daroussin input_file = stdin; 36998e903e7SBaptiste Daroussin if (i + 1 < argc) 37098e903e7SBaptiste Daroussin usage(); 37198e903e7SBaptiste Daroussin return; 37298e903e7SBaptiste Daroussin 37398e903e7SBaptiste Daroussin case '-': 37498e903e7SBaptiste Daroussin ++i; 37598e903e7SBaptiste Daroussin goto no_more_options; 37698e903e7SBaptiste Daroussin 37798e903e7SBaptiste Daroussin case 'b': 37898e903e7SBaptiste Daroussin if (*++s) 37998e903e7SBaptiste Daroussin file_prefix = s; 38098e903e7SBaptiste Daroussin else if (++i < argc) 38198e903e7SBaptiste Daroussin file_prefix = argv[i]; 38298e903e7SBaptiste Daroussin else 38398e903e7SBaptiste Daroussin usage(); 38498e903e7SBaptiste Daroussin continue; 38598e903e7SBaptiste Daroussin 386*b53bb29fSJung-uk Kim case 'H': 387*b53bb29fSJung-uk Kim dflag = dflag2 = 1; 388*b53bb29fSJung-uk Kim if (*++s) 389*b53bb29fSJung-uk Kim defines_file_name = s; 390*b53bb29fSJung-uk Kim else if (++i < argc) 391*b53bb29fSJung-uk Kim defines_file_name = argv[i]; 392*b53bb29fSJung-uk Kim else 393*b53bb29fSJung-uk Kim usage(); 394*b53bb29fSJung-uk Kim continue; 395*b53bb29fSJung-uk Kim 39698e903e7SBaptiste Daroussin case 'o': 39798e903e7SBaptiste Daroussin if (*++s) 39898e903e7SBaptiste Daroussin output_file_name = s; 39998e903e7SBaptiste Daroussin else if (++i < argc) 40098e903e7SBaptiste Daroussin output_file_name = argv[i]; 40198e903e7SBaptiste Daroussin else 40298e903e7SBaptiste Daroussin usage(); 40398e903e7SBaptiste Daroussin continue; 40498e903e7SBaptiste Daroussin 40598e903e7SBaptiste Daroussin case 'p': 40698e903e7SBaptiste Daroussin if (*++s) 40798e903e7SBaptiste Daroussin symbol_prefix = s; 40898e903e7SBaptiste Daroussin else if (++i < argc) 40998e903e7SBaptiste Daroussin symbol_prefix = argv[i]; 41098e903e7SBaptiste Daroussin else 41198e903e7SBaptiste Daroussin usage(); 41298e903e7SBaptiste Daroussin continue; 41398e903e7SBaptiste Daroussin 41498e903e7SBaptiste Daroussin default: 41598e903e7SBaptiste Daroussin setflag(ch); 41698e903e7SBaptiste Daroussin break; 41798e903e7SBaptiste Daroussin } 41898e903e7SBaptiste Daroussin 41998e903e7SBaptiste Daroussin for (;;) 42098e903e7SBaptiste Daroussin { 42198e903e7SBaptiste Daroussin switch (ch = *++s) 42298e903e7SBaptiste Daroussin { 42398e903e7SBaptiste Daroussin case '\0': 42498e903e7SBaptiste Daroussin goto end_of_option; 42598e903e7SBaptiste Daroussin 42698e903e7SBaptiste Daroussin default: 42798e903e7SBaptiste Daroussin setflag(ch); 42898e903e7SBaptiste Daroussin break; 42998e903e7SBaptiste Daroussin } 43098e903e7SBaptiste Daroussin } 43198e903e7SBaptiste Daroussin end_of_option:; 43298e903e7SBaptiste Daroussin } 43398e903e7SBaptiste Daroussin 434*b53bb29fSJung-uk Kim no_more_options: 435*b53bb29fSJung-uk Kim 436*b53bb29fSJung-uk Kim #endif /* HAVE_GETOPT */ 43798e903e7SBaptiste Daroussin if (i + 1 != argc) 43898e903e7SBaptiste Daroussin usage(); 4393e794565SJung-uk Kim input_file_name_len = strlen(argv[i]); 4403e794565SJung-uk Kim input_file_name = TMALLOC(char, input_file_name_len + 1); 4413e794565SJung-uk Kim NO_SPACE(input_file_name); 4423e794565SJung-uk Kim strcpy(input_file_name, argv[i]); 44398e903e7SBaptiste Daroussin } 44498e903e7SBaptiste Daroussin 44598e903e7SBaptiste Daroussin void * 44698e903e7SBaptiste Daroussin allocate(size_t n) 44798e903e7SBaptiste Daroussin { 44898e903e7SBaptiste Daroussin void *p; 44998e903e7SBaptiste Daroussin 45098e903e7SBaptiste Daroussin p = NULL; 45198e903e7SBaptiste Daroussin if (n) 45298e903e7SBaptiste Daroussin { 45398e903e7SBaptiste Daroussin p = CALLOC(1, n); 45498e903e7SBaptiste Daroussin NO_SPACE(p); 45598e903e7SBaptiste Daroussin } 45698e903e7SBaptiste Daroussin return (p); 45798e903e7SBaptiste Daroussin } 45898e903e7SBaptiste Daroussin 45998e903e7SBaptiste Daroussin #define CREATE_FILE_NAME(dest, suffix) \ 4600c8de5b0SBaptiste Daroussin dest = alloc_file_name(len, suffix) 4610c8de5b0SBaptiste Daroussin 4620c8de5b0SBaptiste Daroussin static char * 4630c8de5b0SBaptiste Daroussin alloc_file_name(size_t len, const char *suffix) 4640c8de5b0SBaptiste Daroussin { 4650c8de5b0SBaptiste Daroussin char *result = TMALLOC(char, len + strlen(suffix) + 1); 4660c8de5b0SBaptiste Daroussin if (result == 0) 4670c8de5b0SBaptiste Daroussin no_space(); 4680c8de5b0SBaptiste Daroussin strcpy(result, file_prefix); 4690c8de5b0SBaptiste Daroussin strcpy(result + len, suffix); 4700c8de5b0SBaptiste Daroussin return result; 4710c8de5b0SBaptiste Daroussin } 47298e903e7SBaptiste Daroussin 47320afc491SJung-uk Kim static char * 47420afc491SJung-uk Kim find_suffix(char *name, const char *suffix) 47520afc491SJung-uk Kim { 47620afc491SJung-uk Kim size_t len = strlen(name); 47720afc491SJung-uk Kim size_t slen = strlen(suffix); 47820afc491SJung-uk Kim if (len >= slen) 47920afc491SJung-uk Kim { 48020afc491SJung-uk Kim name += len - slen; 48120afc491SJung-uk Kim if (strcmp(name, suffix) == 0) 48220afc491SJung-uk Kim return name; 48320afc491SJung-uk Kim } 48420afc491SJung-uk Kim return NULL; 48520afc491SJung-uk Kim } 48620afc491SJung-uk Kim 48798e903e7SBaptiste Daroussin static void 48898e903e7SBaptiste Daroussin create_file_names(void) 48998e903e7SBaptiste Daroussin { 49098e903e7SBaptiste Daroussin size_t len; 49198e903e7SBaptiste Daroussin const char *defines_suffix; 49298e903e7SBaptiste Daroussin const char *externs_suffix; 49320afc491SJung-uk Kim char *suffix; 49498e903e7SBaptiste Daroussin 49520afc491SJung-uk Kim suffix = NULL; 49698e903e7SBaptiste Daroussin defines_suffix = DEFINES_SUFFIX; 49798e903e7SBaptiste Daroussin externs_suffix = EXTERNS_SUFFIX; 49898e903e7SBaptiste Daroussin 49998e903e7SBaptiste Daroussin /* compute the file_prefix from the user provided output_file_name */ 50098e903e7SBaptiste Daroussin if (output_file_name != 0) 50198e903e7SBaptiste Daroussin { 50220afc491SJung-uk Kim if (!(suffix = find_suffix(output_file_name, OUTPUT_SUFFIX)) 50320afc491SJung-uk Kim && (suffix = find_suffix(output_file_name, ".c"))) 50498e903e7SBaptiste Daroussin { 50598e903e7SBaptiste Daroussin defines_suffix = ".h"; 50698e903e7SBaptiste Daroussin externs_suffix = ".i"; 50798e903e7SBaptiste Daroussin } 50898e903e7SBaptiste Daroussin } 50998e903e7SBaptiste Daroussin 51020afc491SJung-uk Kim if (suffix != NULL) 51198e903e7SBaptiste Daroussin { 51220afc491SJung-uk Kim len = (size_t) (suffix - output_file_name); 5133e066022SBaptiste Daroussin file_prefix = TMALLOC(char, len + 1); 51498e903e7SBaptiste Daroussin NO_SPACE(file_prefix); 51598e903e7SBaptiste Daroussin strncpy(file_prefix, output_file_name, len)[len] = 0; 51698e903e7SBaptiste Daroussin } 51798e903e7SBaptiste Daroussin else 51898e903e7SBaptiste Daroussin len = strlen(file_prefix); 51998e903e7SBaptiste Daroussin 52098e903e7SBaptiste Daroussin /* if "-o filename" was not given */ 52198e903e7SBaptiste Daroussin if (output_file_name == 0) 52298e903e7SBaptiste Daroussin { 52398e903e7SBaptiste Daroussin oflag = 1; 52498e903e7SBaptiste Daroussin CREATE_FILE_NAME(output_file_name, OUTPUT_SUFFIX); 52598e903e7SBaptiste Daroussin } 52698e903e7SBaptiste Daroussin 52798e903e7SBaptiste Daroussin if (rflag) 52898e903e7SBaptiste Daroussin { 52998e903e7SBaptiste Daroussin CREATE_FILE_NAME(code_file_name, CODE_SUFFIX); 53098e903e7SBaptiste Daroussin } 53198e903e7SBaptiste Daroussin else 53298e903e7SBaptiste Daroussin code_file_name = output_file_name; 53398e903e7SBaptiste Daroussin 534*b53bb29fSJung-uk Kim if (dflag && !dflag2) 53598e903e7SBaptiste Daroussin { 53698e903e7SBaptiste Daroussin CREATE_FILE_NAME(defines_file_name, defines_suffix); 53798e903e7SBaptiste Daroussin } 53898e903e7SBaptiste Daroussin 53998e903e7SBaptiste Daroussin if (iflag) 54098e903e7SBaptiste Daroussin { 54198e903e7SBaptiste Daroussin CREATE_FILE_NAME(externs_file_name, externs_suffix); 54298e903e7SBaptiste Daroussin } 54398e903e7SBaptiste Daroussin 54498e903e7SBaptiste Daroussin if (vflag) 54598e903e7SBaptiste Daroussin { 54698e903e7SBaptiste Daroussin CREATE_FILE_NAME(verbose_file_name, VERBOSE_SUFFIX); 54798e903e7SBaptiste Daroussin } 54898e903e7SBaptiste Daroussin 54998e903e7SBaptiste Daroussin if (gflag) 55098e903e7SBaptiste Daroussin { 55198e903e7SBaptiste Daroussin CREATE_FILE_NAME(graph_file_name, GRAPH_SUFFIX); 55298e903e7SBaptiste Daroussin } 55398e903e7SBaptiste Daroussin 55420afc491SJung-uk Kim if (suffix != NULL) 55598e903e7SBaptiste Daroussin { 55698e903e7SBaptiste Daroussin FREE(file_prefix); 55798e903e7SBaptiste Daroussin } 55898e903e7SBaptiste Daroussin } 55998e903e7SBaptiste Daroussin 56098e903e7SBaptiste Daroussin #if USE_MKSTEMP 56198e903e7SBaptiste Daroussin static void 56298e903e7SBaptiste Daroussin close_tmpfiles(void) 56398e903e7SBaptiste Daroussin { 56498e903e7SBaptiste Daroussin while (my_tmpfiles != 0) 56598e903e7SBaptiste Daroussin { 56698e903e7SBaptiste Daroussin MY_TMPFILES *next = my_tmpfiles->next; 56798e903e7SBaptiste Daroussin 56811fce282SBaptiste Daroussin (void)chmod(my_tmpfiles->name, 0644); 56911fce282SBaptiste Daroussin (void)unlink(my_tmpfiles->name); 57098e903e7SBaptiste Daroussin 57198e903e7SBaptiste Daroussin free(my_tmpfiles->name); 57298e903e7SBaptiste Daroussin free(my_tmpfiles); 57398e903e7SBaptiste Daroussin 57498e903e7SBaptiste Daroussin my_tmpfiles = next; 57598e903e7SBaptiste Daroussin } 57698e903e7SBaptiste Daroussin } 57798e903e7SBaptiste Daroussin 57898e903e7SBaptiste Daroussin #ifndef HAVE_MKSTEMP 57998e903e7SBaptiste Daroussin static int 58098e903e7SBaptiste Daroussin my_mkstemp(char *temp) 58198e903e7SBaptiste Daroussin { 58298e903e7SBaptiste Daroussin int fd; 58398e903e7SBaptiste Daroussin char *dname; 58498e903e7SBaptiste Daroussin char *fname; 58598e903e7SBaptiste Daroussin char *name; 58698e903e7SBaptiste Daroussin 58798e903e7SBaptiste Daroussin /* 58898e903e7SBaptiste Daroussin * Split-up to use tempnam, rather than tmpnam; the latter (like 58998e903e7SBaptiste Daroussin * mkstemp) is unusable on Windows. 59098e903e7SBaptiste Daroussin */ 59198e903e7SBaptiste Daroussin if ((fname = strrchr(temp, '/')) != 0) 59298e903e7SBaptiste Daroussin { 59398e903e7SBaptiste Daroussin dname = strdup(temp); 59498e903e7SBaptiste Daroussin dname[++fname - temp] = '\0'; 59598e903e7SBaptiste Daroussin } 59698e903e7SBaptiste Daroussin else 59798e903e7SBaptiste Daroussin { 59898e903e7SBaptiste Daroussin dname = 0; 59998e903e7SBaptiste Daroussin fname = temp; 60098e903e7SBaptiste Daroussin } 60198e903e7SBaptiste Daroussin if ((name = tempnam(dname, fname)) != 0) 60298e903e7SBaptiste Daroussin { 60398e903e7SBaptiste Daroussin fd = open(name, O_CREAT | O_EXCL | O_RDWR); 60498e903e7SBaptiste Daroussin strcpy(temp, name); 60598e903e7SBaptiste Daroussin } 60698e903e7SBaptiste Daroussin else 60798e903e7SBaptiste Daroussin { 60898e903e7SBaptiste Daroussin fd = -1; 60998e903e7SBaptiste Daroussin } 61098e903e7SBaptiste Daroussin 61198e903e7SBaptiste Daroussin if (dname != 0) 61298e903e7SBaptiste Daroussin free(dname); 61398e903e7SBaptiste Daroussin 61498e903e7SBaptiste Daroussin return fd; 61598e903e7SBaptiste Daroussin } 61698e903e7SBaptiste Daroussin #define mkstemp(s) my_mkstemp(s) 61798e903e7SBaptiste Daroussin #endif 61898e903e7SBaptiste Daroussin 61998e903e7SBaptiste Daroussin #endif 62098e903e7SBaptiste Daroussin 62198e903e7SBaptiste Daroussin /* 62298e903e7SBaptiste Daroussin * tmpfile() should be adequate, except that it may require special privileges 62398e903e7SBaptiste Daroussin * to use, e.g., MinGW and Windows 7 where it tries to use the root directory. 62498e903e7SBaptiste Daroussin */ 62598e903e7SBaptiste Daroussin static FILE * 62698e903e7SBaptiste Daroussin open_tmpfile(const char *label) 62798e903e7SBaptiste Daroussin { 6280f86d14eSJung-uk Kim #define MY_FMT "%s/%.*sXXXXXX" 62998e903e7SBaptiste Daroussin FILE *result; 63098e903e7SBaptiste Daroussin #if USE_MKSTEMP 63198e903e7SBaptiste Daroussin int fd; 63298e903e7SBaptiste Daroussin const char *tmpdir; 63398e903e7SBaptiste Daroussin char *name; 63498e903e7SBaptiste Daroussin const char *mark; 63598e903e7SBaptiste Daroussin 636*b53bb29fSJung-uk Kim if (((tmpdir = getenv("TMPDIR")) == 0 || access(tmpdir, W_OK) != 0) || 637*b53bb29fSJung-uk Kim ((tmpdir = getenv("TEMP")) == 0 || access(tmpdir, W_OK) != 0)) 63898e903e7SBaptiste Daroussin { 63998e903e7SBaptiste Daroussin #ifdef P_tmpdir 64098e903e7SBaptiste Daroussin tmpdir = P_tmpdir; 64198e903e7SBaptiste Daroussin #else 64298e903e7SBaptiste Daroussin tmpdir = "/tmp"; 64398e903e7SBaptiste Daroussin #endif 64498e903e7SBaptiste Daroussin if (access(tmpdir, W_OK) != 0) 64598e903e7SBaptiste Daroussin tmpdir = "."; 64698e903e7SBaptiste Daroussin } 64798e903e7SBaptiste Daroussin 6480f86d14eSJung-uk Kim /* The size of the format is guaranteed to be longer than the result from 6490f86d14eSJung-uk Kim * printing empty strings with it; this calculation accounts for the 6500f86d14eSJung-uk Kim * string-lengths as well. 6510f86d14eSJung-uk Kim */ 6520f86d14eSJung-uk Kim name = malloc(strlen(tmpdir) + sizeof(MY_FMT) + strlen(label)); 65398e903e7SBaptiste Daroussin 65498e903e7SBaptiste Daroussin result = 0; 65598e903e7SBaptiste Daroussin if (name != 0) 65698e903e7SBaptiste Daroussin { 657315e69cbSBaptiste Daroussin mode_t save_umask = umask(0177); 65811fce282SBaptiste Daroussin 65998e903e7SBaptiste Daroussin if ((mark = strrchr(label, '_')) == 0) 66098e903e7SBaptiste Daroussin mark = label + strlen(label); 66198e903e7SBaptiste Daroussin 6620f86d14eSJung-uk Kim sprintf(name, MY_FMT, tmpdir, (int)(mark - label), label); 66398e903e7SBaptiste Daroussin fd = mkstemp(name); 664*b53bb29fSJung-uk Kim if (fd >= 0 665*b53bb29fSJung-uk Kim && (result = fdopen(fd, "w+")) != 0) 66698e903e7SBaptiste Daroussin { 66798e903e7SBaptiste Daroussin MY_TMPFILES *item; 66898e903e7SBaptiste Daroussin 66998e903e7SBaptiste Daroussin if (my_tmpfiles == 0) 67098e903e7SBaptiste Daroussin { 67198e903e7SBaptiste Daroussin atexit(close_tmpfiles); 67298e903e7SBaptiste Daroussin } 67398e903e7SBaptiste Daroussin 67498e903e7SBaptiste Daroussin item = NEW(MY_TMPFILES); 67598e903e7SBaptiste Daroussin NO_SPACE(item); 67698e903e7SBaptiste Daroussin 67798e903e7SBaptiste Daroussin item->name = name; 67898e903e7SBaptiste Daroussin NO_SPACE(item->name); 67998e903e7SBaptiste Daroussin 68098e903e7SBaptiste Daroussin item->next = my_tmpfiles; 68198e903e7SBaptiste Daroussin my_tmpfiles = item; 68298e903e7SBaptiste Daroussin } 683*b53bb29fSJung-uk Kim else 684*b53bb29fSJung-uk Kim { 685*b53bb29fSJung-uk Kim FREE(name); 68698e903e7SBaptiste Daroussin } 68711fce282SBaptiste Daroussin (void)umask(save_umask); 68898e903e7SBaptiste Daroussin } 68998e903e7SBaptiste Daroussin #else 69098e903e7SBaptiste Daroussin result = tmpfile(); 69198e903e7SBaptiste Daroussin #endif 69298e903e7SBaptiste Daroussin 69398e903e7SBaptiste Daroussin if (result == 0) 69498e903e7SBaptiste Daroussin open_error(label); 69598e903e7SBaptiste Daroussin return result; 6960f86d14eSJung-uk Kim #undef MY_FMT 69798e903e7SBaptiste Daroussin } 69898e903e7SBaptiste Daroussin 69998e903e7SBaptiste Daroussin static void 70098e903e7SBaptiste Daroussin open_files(void) 70198e903e7SBaptiste Daroussin { 70298e903e7SBaptiste Daroussin create_file_names(); 70398e903e7SBaptiste Daroussin 70498e903e7SBaptiste Daroussin if (input_file == 0) 70598e903e7SBaptiste Daroussin { 70698e903e7SBaptiste Daroussin input_file = fopen(input_file_name, "r"); 70798e903e7SBaptiste Daroussin if (input_file == 0) 70898e903e7SBaptiste Daroussin open_error(input_file_name); 70998e903e7SBaptiste Daroussin } 71098e903e7SBaptiste Daroussin 71198e903e7SBaptiste Daroussin action_file = open_tmpfile("action_file"); 71298e903e7SBaptiste Daroussin text_file = open_tmpfile("text_file"); 71398e903e7SBaptiste Daroussin 71498e903e7SBaptiste Daroussin if (vflag) 71598e903e7SBaptiste Daroussin { 71698e903e7SBaptiste Daroussin verbose_file = fopen(verbose_file_name, "w"); 71798e903e7SBaptiste Daroussin if (verbose_file == 0) 71898e903e7SBaptiste Daroussin open_error(verbose_file_name); 71998e903e7SBaptiste Daroussin } 72098e903e7SBaptiste Daroussin 72198e903e7SBaptiste Daroussin if (gflag) 72298e903e7SBaptiste Daroussin { 72398e903e7SBaptiste Daroussin graph_file = fopen(graph_file_name, "w"); 72498e903e7SBaptiste Daroussin if (graph_file == 0) 72598e903e7SBaptiste Daroussin open_error(graph_file_name); 72698e903e7SBaptiste Daroussin fprintf(graph_file, "digraph %s {\n", file_prefix); 72798e903e7SBaptiste Daroussin fprintf(graph_file, "\tedge [fontsize=10];\n"); 72898e903e7SBaptiste Daroussin fprintf(graph_file, "\tnode [shape=box,fontsize=10];\n"); 72998e903e7SBaptiste Daroussin fprintf(graph_file, "\torientation=landscape;\n"); 73098e903e7SBaptiste Daroussin fprintf(graph_file, "\trankdir=LR;\n"); 73198e903e7SBaptiste Daroussin fprintf(graph_file, "\t/*\n"); 73298e903e7SBaptiste Daroussin fprintf(graph_file, "\tmargin=0.2;\n"); 73398e903e7SBaptiste Daroussin fprintf(graph_file, "\tpage=\"8.27,11.69\"; // for A4 printing\n"); 73498e903e7SBaptiste Daroussin fprintf(graph_file, "\tratio=auto;\n"); 73598e903e7SBaptiste Daroussin fprintf(graph_file, "\t*/\n"); 73698e903e7SBaptiste Daroussin } 73798e903e7SBaptiste Daroussin 738*b53bb29fSJung-uk Kim if (dflag || dflag2) 73998e903e7SBaptiste Daroussin { 74098e903e7SBaptiste Daroussin defines_file = fopen(defines_file_name, "w"); 74198e903e7SBaptiste Daroussin if (defines_file == 0) 74298e903e7SBaptiste Daroussin open_error(defines_file_name); 74398e903e7SBaptiste Daroussin union_file = open_tmpfile("union_file"); 74498e903e7SBaptiste Daroussin } 74598e903e7SBaptiste Daroussin 74698e903e7SBaptiste Daroussin if (iflag) 74798e903e7SBaptiste Daroussin { 74898e903e7SBaptiste Daroussin externs_file = fopen(externs_file_name, "w"); 74998e903e7SBaptiste Daroussin if (externs_file == 0) 75098e903e7SBaptiste Daroussin open_error(externs_file_name); 75198e903e7SBaptiste Daroussin } 75298e903e7SBaptiste Daroussin 75398e903e7SBaptiste Daroussin output_file = fopen(output_file_name, "w"); 75498e903e7SBaptiste Daroussin if (output_file == 0) 75598e903e7SBaptiste Daroussin open_error(output_file_name); 75698e903e7SBaptiste Daroussin 75798e903e7SBaptiste Daroussin if (rflag) 75898e903e7SBaptiste Daroussin { 75998e903e7SBaptiste Daroussin code_file = fopen(code_file_name, "w"); 76098e903e7SBaptiste Daroussin if (code_file == 0) 76198e903e7SBaptiste Daroussin open_error(code_file_name); 76298e903e7SBaptiste Daroussin } 76398e903e7SBaptiste Daroussin else 76498e903e7SBaptiste Daroussin code_file = output_file; 76598e903e7SBaptiste Daroussin } 76698e903e7SBaptiste Daroussin 76798e903e7SBaptiste Daroussin int 76898e903e7SBaptiste Daroussin main(int argc, char *argv[]) 76998e903e7SBaptiste Daroussin { 77098e903e7SBaptiste Daroussin SRexpect = -1; 77198e903e7SBaptiste Daroussin RRexpect = -1; 77298e903e7SBaptiste Daroussin exit_code = EXIT_SUCCESS; 77398e903e7SBaptiste Daroussin 77498e903e7SBaptiste Daroussin set_signals(); 77598e903e7SBaptiste Daroussin getargs(argc, argv); 77698e903e7SBaptiste Daroussin open_files(); 77798e903e7SBaptiste Daroussin reader(); 77898e903e7SBaptiste Daroussin lr0(); 77998e903e7SBaptiste Daroussin lalr(); 78098e903e7SBaptiste Daroussin make_parser(); 78198e903e7SBaptiste Daroussin graph(); 78298e903e7SBaptiste Daroussin finalize_closure(); 78398e903e7SBaptiste Daroussin verbose(); 78498e903e7SBaptiste Daroussin output(); 78598e903e7SBaptiste Daroussin done(exit_code); 78698e903e7SBaptiste Daroussin /*NOTREACHED */ 78798e903e7SBaptiste Daroussin } 788