1*6166fdceSJung-uk Kim /* $Id: main.c,v 1.60 2017/04/30 20:57:56 Julien.Ramseier Exp $ */ 298e903e7SBaptiste Daroussin 398e903e7SBaptiste Daroussin #include <signal.h> 40c8de5b0SBaptiste Daroussin #ifndef _WIN32 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; 3698e903e7SBaptiste Daroussin char gflag; 3798e903e7SBaptiste Daroussin char iflag; 3898e903e7SBaptiste Daroussin char lflag; 3998e903e7SBaptiste Daroussin static char oflag; 4098e903e7SBaptiste Daroussin char rflag; 4198e903e7SBaptiste Daroussin char sflag; 4298e903e7SBaptiste Daroussin char tflag; 4398e903e7SBaptiste Daroussin char vflag; 4498e903e7SBaptiste Daroussin 4598e903e7SBaptiste Daroussin const char *symbol_prefix; 4698e903e7SBaptiste Daroussin const char *myname = "yacc"; 4798e903e7SBaptiste Daroussin 4898e903e7SBaptiste Daroussin int lineno; 4998e903e7SBaptiste Daroussin int outline; 5098e903e7SBaptiste Daroussin 5198e903e7SBaptiste Daroussin static char default_file_prefix[] = "y"; 5298e903e7SBaptiste Daroussin 5398e903e7SBaptiste Daroussin static char *file_prefix = default_file_prefix; 5498e903e7SBaptiste Daroussin 5598e903e7SBaptiste Daroussin char *code_file_name; 563e794565SJung-uk Kim char *input_file_name; 573e794565SJung-uk Kim size_t input_file_name_len = 0; 5898e903e7SBaptiste Daroussin char *defines_file_name; 5998e903e7SBaptiste Daroussin char *externs_file_name; 6098e903e7SBaptiste Daroussin 6198e903e7SBaptiste Daroussin static char *graph_file_name; 6298e903e7SBaptiste Daroussin static char *output_file_name; 6398e903e7SBaptiste Daroussin static char *verbose_file_name; 6498e903e7SBaptiste Daroussin 6598e903e7SBaptiste Daroussin FILE *action_file; /* a temp file, used to save actions associated */ 6698e903e7SBaptiste Daroussin /* with rules until the parser is written */ 6798e903e7SBaptiste Daroussin FILE *code_file; /* y.code.c (used when the -r option is specified) */ 6898e903e7SBaptiste Daroussin FILE *defines_file; /* y.tab.h */ 6998e903e7SBaptiste Daroussin FILE *externs_file; /* y.tab.i */ 7098e903e7SBaptiste Daroussin FILE *input_file; /* the input file */ 7198e903e7SBaptiste Daroussin FILE *output_file; /* y.tab.c */ 7298e903e7SBaptiste Daroussin FILE *text_file; /* a temp file, used to save text until all */ 7398e903e7SBaptiste Daroussin /* symbols have been defined */ 7498e903e7SBaptiste Daroussin FILE *union_file; /* a temp file, used to save the union */ 7598e903e7SBaptiste Daroussin /* definition until all symbol have been */ 7698e903e7SBaptiste Daroussin /* defined */ 7798e903e7SBaptiste Daroussin FILE *verbose_file; /* y.output */ 7898e903e7SBaptiste Daroussin FILE *graph_file; /* y.dot */ 7998e903e7SBaptiste Daroussin 800c8de5b0SBaptiste Daroussin Value_t nitems; 810c8de5b0SBaptiste Daroussin Value_t nrules; 820c8de5b0SBaptiste Daroussin Value_t nsyms; 830c8de5b0SBaptiste Daroussin Value_t ntokens; 840c8de5b0SBaptiste Daroussin Value_t nvars; 8598e903e7SBaptiste Daroussin 8698e903e7SBaptiste Daroussin Value_t start_symbol; 8798e903e7SBaptiste Daroussin char **symbol_name; 8898e903e7SBaptiste Daroussin char **symbol_pname; 8998e903e7SBaptiste Daroussin Value_t *symbol_value; 900c8de5b0SBaptiste Daroussin Value_t *symbol_prec; 9198e903e7SBaptiste Daroussin char *symbol_assoc; 9298e903e7SBaptiste Daroussin 9398e903e7SBaptiste Daroussin int pure_parser; 944b4a8fcaSBaptiste Daroussin int token_table; 952aca18c7SJung-uk Kim int error_verbose; 960c8de5b0SBaptiste Daroussin 970c8de5b0SBaptiste Daroussin #if defined(YYBTYACC) 980c8de5b0SBaptiste Daroussin Value_t *symbol_pval; 990c8de5b0SBaptiste Daroussin char **symbol_destructor; 1000c8de5b0SBaptiste Daroussin char **symbol_type_tag; 1010c8de5b0SBaptiste Daroussin int locations = 0; /* default to no position processing */ 1020c8de5b0SBaptiste Daroussin int backtrack = 0; /* default is no backtracking */ 1032aca18c7SJung-uk Kim char *initial_action = NULL; 1040c8de5b0SBaptiste Daroussin #endif 1050c8de5b0SBaptiste Daroussin 10698e903e7SBaptiste Daroussin int exit_code; 10798e903e7SBaptiste Daroussin 10898e903e7SBaptiste Daroussin Value_t *ritem; 10998e903e7SBaptiste Daroussin Value_t *rlhs; 11098e903e7SBaptiste Daroussin Value_t *rrhs; 11198e903e7SBaptiste Daroussin Value_t *rprec; 11298e903e7SBaptiste Daroussin Assoc_t *rassoc; 11398e903e7SBaptiste Daroussin Value_t **derives; 11498e903e7SBaptiste Daroussin char *nullable; 11598e903e7SBaptiste Daroussin 11698e903e7SBaptiste Daroussin /* 11798e903e7SBaptiste Daroussin * Since fclose() is called via the signal handler, it might die. Don't loop 11898e903e7SBaptiste Daroussin * if there is a problem closing a file. 11998e903e7SBaptiste Daroussin */ 12098e903e7SBaptiste Daroussin #define DO_CLOSE(fp) \ 12198e903e7SBaptiste Daroussin if (fp != 0) { \ 12298e903e7SBaptiste Daroussin FILE *use = fp; \ 12398e903e7SBaptiste Daroussin fp = 0; \ 12498e903e7SBaptiste Daroussin fclose(use); \ 12598e903e7SBaptiste Daroussin } 12698e903e7SBaptiste Daroussin 12798e903e7SBaptiste Daroussin static int got_intr = 0; 12898e903e7SBaptiste Daroussin 12998e903e7SBaptiste Daroussin void 13098e903e7SBaptiste Daroussin done(int k) 13198e903e7SBaptiste Daroussin { 13298e903e7SBaptiste Daroussin DO_CLOSE(input_file); 13398e903e7SBaptiste Daroussin DO_CLOSE(output_file); 1340c8de5b0SBaptiste Daroussin if (iflag) 1350c8de5b0SBaptiste Daroussin DO_CLOSE(externs_file); 1360c8de5b0SBaptiste Daroussin if (rflag) 1370c8de5b0SBaptiste Daroussin DO_CLOSE(code_file); 13898e903e7SBaptiste Daroussin 13998e903e7SBaptiste Daroussin DO_CLOSE(action_file); 14098e903e7SBaptiste Daroussin DO_CLOSE(defines_file); 14198e903e7SBaptiste Daroussin DO_CLOSE(graph_file); 14298e903e7SBaptiste Daroussin DO_CLOSE(text_file); 14398e903e7SBaptiste Daroussin DO_CLOSE(union_file); 14498e903e7SBaptiste Daroussin DO_CLOSE(verbose_file); 14598e903e7SBaptiste Daroussin 14698e903e7SBaptiste Daroussin if (got_intr) 14798e903e7SBaptiste Daroussin _exit(EXIT_FAILURE); 14898e903e7SBaptiste Daroussin 14998e903e7SBaptiste Daroussin #ifdef NO_LEAKS 15098e903e7SBaptiste Daroussin if (rflag) 15198e903e7SBaptiste Daroussin DO_FREE(code_file_name); 15298e903e7SBaptiste Daroussin 15398e903e7SBaptiste Daroussin if (dflag) 15498e903e7SBaptiste Daroussin DO_FREE(defines_file_name); 15598e903e7SBaptiste Daroussin 15698e903e7SBaptiste Daroussin if (iflag) 15798e903e7SBaptiste Daroussin DO_FREE(externs_file_name); 15898e903e7SBaptiste Daroussin 15998e903e7SBaptiste Daroussin if (oflag) 16098e903e7SBaptiste Daroussin DO_FREE(output_file_name); 16198e903e7SBaptiste Daroussin 16298e903e7SBaptiste Daroussin if (vflag) 16398e903e7SBaptiste Daroussin DO_FREE(verbose_file_name); 16498e903e7SBaptiste Daroussin 16598e903e7SBaptiste Daroussin if (gflag) 16698e903e7SBaptiste Daroussin DO_FREE(graph_file_name); 16798e903e7SBaptiste Daroussin 16898e903e7SBaptiste Daroussin lr0_leaks(); 16998e903e7SBaptiste Daroussin lalr_leaks(); 17098e903e7SBaptiste Daroussin mkpar_leaks(); 171497dcf4cSBaptiste Daroussin mstring_leaks(); 17298e903e7SBaptiste Daroussin output_leaks(); 17398e903e7SBaptiste Daroussin reader_leaks(); 17498e903e7SBaptiste Daroussin #endif 17598e903e7SBaptiste Daroussin 17698e903e7SBaptiste Daroussin exit(k); 17798e903e7SBaptiste Daroussin } 17898e903e7SBaptiste Daroussin 17998e903e7SBaptiste Daroussin static void 1803e066022SBaptiste Daroussin onintr(int sig GCC_UNUSED) 18198e903e7SBaptiste Daroussin { 18298e903e7SBaptiste Daroussin got_intr = 1; 18398e903e7SBaptiste Daroussin done(EXIT_FAILURE); 18498e903e7SBaptiste Daroussin } 18598e903e7SBaptiste Daroussin 18698e903e7SBaptiste Daroussin static void 18798e903e7SBaptiste Daroussin set_signals(void) 18898e903e7SBaptiste Daroussin { 18998e903e7SBaptiste Daroussin #ifdef SIGINT 19098e903e7SBaptiste Daroussin if (signal(SIGINT, SIG_IGN) != SIG_IGN) 19198e903e7SBaptiste Daroussin signal(SIGINT, onintr); 19298e903e7SBaptiste Daroussin #endif 19398e903e7SBaptiste Daroussin #ifdef SIGTERM 19498e903e7SBaptiste Daroussin if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 19598e903e7SBaptiste Daroussin signal(SIGTERM, onintr); 19698e903e7SBaptiste Daroussin #endif 19798e903e7SBaptiste Daroussin #ifdef SIGHUP 19898e903e7SBaptiste Daroussin if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 19998e903e7SBaptiste Daroussin signal(SIGHUP, onintr); 20098e903e7SBaptiste Daroussin #endif 20198e903e7SBaptiste Daroussin } 20298e903e7SBaptiste Daroussin 20398e903e7SBaptiste Daroussin static void 20498e903e7SBaptiste Daroussin usage(void) 20598e903e7SBaptiste Daroussin { 20698e903e7SBaptiste Daroussin static const char *msg[] = 20798e903e7SBaptiste Daroussin { 20898e903e7SBaptiste Daroussin "" 20998e903e7SBaptiste Daroussin ,"Options:" 21098e903e7SBaptiste Daroussin ," -b file_prefix set filename prefix (default \"y.\")" 2110c8de5b0SBaptiste Daroussin ," -B create a backtracking parser" 2120c8de5b0SBaptiste Daroussin ," -d write definitions (" DEFINES_SUFFIX ")" 21398e903e7SBaptiste Daroussin ," -i write interface (y.tab.i)" 21498e903e7SBaptiste Daroussin ," -g write a graphical description" 21598e903e7SBaptiste Daroussin ," -l suppress #line directives" 2160c8de5b0SBaptiste Daroussin ," -L enable position processing, e.g., \"%locations\"" 2170c8de5b0SBaptiste Daroussin ," -o output_file (default \"" OUTPUT_SUFFIX "\")" 21898e903e7SBaptiste Daroussin ," -p symbol_prefix set symbol prefix (default \"yy\")" 21998e903e7SBaptiste Daroussin ," -P create a reentrant parser, e.g., \"%pure-parser\"" 22098e903e7SBaptiste Daroussin ," -r produce separate code and table files (y.code.c)" 22198e903e7SBaptiste Daroussin ," -s suppress #define's for quoted names in %token lines" 22298e903e7SBaptiste Daroussin ," -t add debugging support" 22398e903e7SBaptiste Daroussin ," -v write description (y.output)" 22498e903e7SBaptiste Daroussin ," -V show version information and exit" 22598e903e7SBaptiste Daroussin }; 22698e903e7SBaptiste Daroussin unsigned n; 22798e903e7SBaptiste Daroussin 22898e903e7SBaptiste Daroussin fflush(stdout); 22998e903e7SBaptiste Daroussin fprintf(stderr, "Usage: %s [options] filename\n", myname); 23098e903e7SBaptiste Daroussin for (n = 0; n < sizeof(msg) / sizeof(msg[0]); ++n) 23198e903e7SBaptiste Daroussin fprintf(stderr, "%s\n", msg[n]); 23298e903e7SBaptiste Daroussin 23398e903e7SBaptiste Daroussin exit(1); 23498e903e7SBaptiste Daroussin } 23598e903e7SBaptiste Daroussin 23698e903e7SBaptiste Daroussin static void 23798e903e7SBaptiste Daroussin setflag(int ch) 23898e903e7SBaptiste Daroussin { 23998e903e7SBaptiste Daroussin switch (ch) 24098e903e7SBaptiste Daroussin { 2410c8de5b0SBaptiste Daroussin case 'B': 2420c8de5b0SBaptiste Daroussin #if defined(YYBTYACC) 2430c8de5b0SBaptiste Daroussin backtrack = 1; 2440c8de5b0SBaptiste Daroussin #else 2450c8de5b0SBaptiste Daroussin unsupported_flag_warning("-B", "reconfigure with --enable-btyacc"); 2460c8de5b0SBaptiste Daroussin #endif 2470c8de5b0SBaptiste Daroussin break; 2480c8de5b0SBaptiste Daroussin 24998e903e7SBaptiste Daroussin case 'd': 25098e903e7SBaptiste Daroussin dflag = 1; 25198e903e7SBaptiste Daroussin break; 25298e903e7SBaptiste Daroussin 25398e903e7SBaptiste Daroussin case 'g': 25498e903e7SBaptiste Daroussin gflag = 1; 25598e903e7SBaptiste Daroussin break; 25698e903e7SBaptiste Daroussin 25798e903e7SBaptiste Daroussin case 'i': 25898e903e7SBaptiste Daroussin iflag = 1; 25998e903e7SBaptiste Daroussin break; 26098e903e7SBaptiste Daroussin 26198e903e7SBaptiste Daroussin case 'l': 26298e903e7SBaptiste Daroussin lflag = 1; 26398e903e7SBaptiste Daroussin break; 26498e903e7SBaptiste Daroussin 2650c8de5b0SBaptiste Daroussin case 'L': 2660c8de5b0SBaptiste Daroussin #if defined(YYBTYACC) 2670c8de5b0SBaptiste Daroussin locations = 1; 2680c8de5b0SBaptiste Daroussin #else 269*6166fdceSJung-uk Kim unsupported_flag_warning("-L", "reconfigure with --enable-btyacc"); 2700c8de5b0SBaptiste Daroussin #endif 2710c8de5b0SBaptiste Daroussin break; 2720c8de5b0SBaptiste Daroussin 27398e903e7SBaptiste Daroussin case 'P': 27498e903e7SBaptiste Daroussin pure_parser = 1; 27598e903e7SBaptiste Daroussin break; 27698e903e7SBaptiste Daroussin 27798e903e7SBaptiste Daroussin case 'r': 27898e903e7SBaptiste Daroussin rflag = 1; 27998e903e7SBaptiste Daroussin break; 28098e903e7SBaptiste Daroussin 28198e903e7SBaptiste Daroussin case 's': 28298e903e7SBaptiste Daroussin sflag = 1; 28398e903e7SBaptiste Daroussin break; 28498e903e7SBaptiste Daroussin 28598e903e7SBaptiste Daroussin case 't': 28698e903e7SBaptiste Daroussin tflag = 1; 28798e903e7SBaptiste Daroussin break; 28898e903e7SBaptiste Daroussin 28998e903e7SBaptiste Daroussin case 'v': 29098e903e7SBaptiste Daroussin vflag = 1; 29198e903e7SBaptiste Daroussin break; 29298e903e7SBaptiste Daroussin 29398e903e7SBaptiste Daroussin case 'V': 29498e903e7SBaptiste Daroussin printf("%s - %s\n", myname, VERSION); 29598e903e7SBaptiste Daroussin exit(EXIT_SUCCESS); 29698e903e7SBaptiste Daroussin 29798e903e7SBaptiste Daroussin case 'y': 29898e903e7SBaptiste Daroussin /* noop for bison compatibility. byacc is already designed to be posix 29998e903e7SBaptiste Daroussin * yacc compatible. */ 30098e903e7SBaptiste Daroussin break; 30198e903e7SBaptiste Daroussin 30298e903e7SBaptiste Daroussin default: 30398e903e7SBaptiste Daroussin usage(); 30498e903e7SBaptiste Daroussin } 30598e903e7SBaptiste Daroussin } 30698e903e7SBaptiste Daroussin 30798e903e7SBaptiste Daroussin static void 30898e903e7SBaptiste Daroussin getargs(int argc, char *argv[]) 30998e903e7SBaptiste Daroussin { 31098e903e7SBaptiste Daroussin int i; 31198e903e7SBaptiste Daroussin char *s; 31298e903e7SBaptiste Daroussin int ch; 31398e903e7SBaptiste Daroussin 31498e903e7SBaptiste Daroussin if (argc > 0) 31598e903e7SBaptiste Daroussin myname = argv[0]; 31698e903e7SBaptiste Daroussin 31798e903e7SBaptiste Daroussin for (i = 1; i < argc; ++i) 31898e903e7SBaptiste Daroussin { 31998e903e7SBaptiste Daroussin s = argv[i]; 32098e903e7SBaptiste Daroussin if (*s != '-') 32198e903e7SBaptiste Daroussin break; 32298e903e7SBaptiste Daroussin switch (ch = *++s) 32398e903e7SBaptiste Daroussin { 32498e903e7SBaptiste Daroussin case '\0': 32598e903e7SBaptiste Daroussin input_file = stdin; 32698e903e7SBaptiste Daroussin if (i + 1 < argc) 32798e903e7SBaptiste Daroussin usage(); 32898e903e7SBaptiste Daroussin return; 32998e903e7SBaptiste Daroussin 33098e903e7SBaptiste Daroussin case '-': 33198e903e7SBaptiste Daroussin ++i; 33298e903e7SBaptiste Daroussin goto no_more_options; 33398e903e7SBaptiste Daroussin 33498e903e7SBaptiste Daroussin case 'b': 33598e903e7SBaptiste Daroussin if (*++s) 33698e903e7SBaptiste Daroussin file_prefix = s; 33798e903e7SBaptiste Daroussin else if (++i < argc) 33898e903e7SBaptiste Daroussin file_prefix = argv[i]; 33998e903e7SBaptiste Daroussin else 34098e903e7SBaptiste Daroussin usage(); 34198e903e7SBaptiste Daroussin continue; 34298e903e7SBaptiste Daroussin 34398e903e7SBaptiste Daroussin case 'o': 34498e903e7SBaptiste Daroussin if (*++s) 34598e903e7SBaptiste Daroussin output_file_name = s; 34698e903e7SBaptiste Daroussin else if (++i < argc) 34798e903e7SBaptiste Daroussin output_file_name = argv[i]; 34898e903e7SBaptiste Daroussin else 34998e903e7SBaptiste Daroussin usage(); 35098e903e7SBaptiste Daroussin continue; 35198e903e7SBaptiste Daroussin 35298e903e7SBaptiste Daroussin case 'p': 35398e903e7SBaptiste Daroussin if (*++s) 35498e903e7SBaptiste Daroussin symbol_prefix = s; 35598e903e7SBaptiste Daroussin else if (++i < argc) 35698e903e7SBaptiste Daroussin symbol_prefix = argv[i]; 35798e903e7SBaptiste Daroussin else 35898e903e7SBaptiste Daroussin usage(); 35998e903e7SBaptiste Daroussin continue; 36098e903e7SBaptiste Daroussin 36198e903e7SBaptiste Daroussin default: 36298e903e7SBaptiste Daroussin setflag(ch); 36398e903e7SBaptiste Daroussin break; 36498e903e7SBaptiste Daroussin } 36598e903e7SBaptiste Daroussin 36698e903e7SBaptiste Daroussin for (;;) 36798e903e7SBaptiste Daroussin { 36898e903e7SBaptiste Daroussin switch (ch = *++s) 36998e903e7SBaptiste Daroussin { 37098e903e7SBaptiste Daroussin case '\0': 37198e903e7SBaptiste Daroussin goto end_of_option; 37298e903e7SBaptiste Daroussin 37398e903e7SBaptiste Daroussin default: 37498e903e7SBaptiste Daroussin setflag(ch); 37598e903e7SBaptiste Daroussin break; 37698e903e7SBaptiste Daroussin } 37798e903e7SBaptiste Daroussin } 37898e903e7SBaptiste Daroussin end_of_option:; 37998e903e7SBaptiste Daroussin } 38098e903e7SBaptiste Daroussin 38198e903e7SBaptiste Daroussin no_more_options:; 38298e903e7SBaptiste Daroussin if (i + 1 != argc) 38398e903e7SBaptiste Daroussin usage(); 3843e794565SJung-uk Kim input_file_name_len = strlen(argv[i]); 3853e794565SJung-uk Kim input_file_name = TMALLOC(char, input_file_name_len + 1); 3863e794565SJung-uk Kim NO_SPACE(input_file_name); 3873e794565SJung-uk Kim strcpy(input_file_name, argv[i]); 38898e903e7SBaptiste Daroussin } 38998e903e7SBaptiste Daroussin 39098e903e7SBaptiste Daroussin void * 39198e903e7SBaptiste Daroussin allocate(size_t n) 39298e903e7SBaptiste Daroussin { 39398e903e7SBaptiste Daroussin void *p; 39498e903e7SBaptiste Daroussin 39598e903e7SBaptiste Daroussin p = NULL; 39698e903e7SBaptiste Daroussin if (n) 39798e903e7SBaptiste Daroussin { 39898e903e7SBaptiste Daroussin p = CALLOC(1, n); 39998e903e7SBaptiste Daroussin NO_SPACE(p); 40098e903e7SBaptiste Daroussin } 40198e903e7SBaptiste Daroussin return (p); 40298e903e7SBaptiste Daroussin } 40398e903e7SBaptiste Daroussin 40498e903e7SBaptiste Daroussin #define CREATE_FILE_NAME(dest, suffix) \ 4050c8de5b0SBaptiste Daroussin dest = alloc_file_name(len, suffix) 4060c8de5b0SBaptiste Daroussin 4070c8de5b0SBaptiste Daroussin static char * 4080c8de5b0SBaptiste Daroussin alloc_file_name(size_t len, const char *suffix) 4090c8de5b0SBaptiste Daroussin { 4100c8de5b0SBaptiste Daroussin char *result = TMALLOC(char, len + strlen(suffix) + 1); 4110c8de5b0SBaptiste Daroussin if (result == 0) 4120c8de5b0SBaptiste Daroussin no_space(); 4130c8de5b0SBaptiste Daroussin strcpy(result, file_prefix); 4140c8de5b0SBaptiste Daroussin strcpy(result + len, suffix); 4150c8de5b0SBaptiste Daroussin return result; 4160c8de5b0SBaptiste Daroussin } 41798e903e7SBaptiste Daroussin 41820afc491SJung-uk Kim static char * 41920afc491SJung-uk Kim find_suffix(char *name, const char *suffix) 42020afc491SJung-uk Kim { 42120afc491SJung-uk Kim size_t len = strlen(name); 42220afc491SJung-uk Kim size_t slen = strlen(suffix); 42320afc491SJung-uk Kim if (len >= slen) 42420afc491SJung-uk Kim { 42520afc491SJung-uk Kim name += len - slen; 42620afc491SJung-uk Kim if (strcmp(name, suffix) == 0) 42720afc491SJung-uk Kim return name; 42820afc491SJung-uk Kim } 42920afc491SJung-uk Kim return NULL; 43020afc491SJung-uk Kim } 43120afc491SJung-uk Kim 43298e903e7SBaptiste Daroussin static void 43398e903e7SBaptiste Daroussin create_file_names(void) 43498e903e7SBaptiste Daroussin { 43598e903e7SBaptiste Daroussin size_t len; 43698e903e7SBaptiste Daroussin const char *defines_suffix; 43798e903e7SBaptiste Daroussin const char *externs_suffix; 43820afc491SJung-uk Kim char *suffix; 43998e903e7SBaptiste Daroussin 44020afc491SJung-uk Kim suffix = NULL; 44198e903e7SBaptiste Daroussin defines_suffix = DEFINES_SUFFIX; 44298e903e7SBaptiste Daroussin externs_suffix = EXTERNS_SUFFIX; 44398e903e7SBaptiste Daroussin 44498e903e7SBaptiste Daroussin /* compute the file_prefix from the user provided output_file_name */ 44598e903e7SBaptiste Daroussin if (output_file_name != 0) 44698e903e7SBaptiste Daroussin { 44720afc491SJung-uk Kim if (!(suffix = find_suffix(output_file_name, OUTPUT_SUFFIX)) 44820afc491SJung-uk Kim && (suffix = find_suffix(output_file_name, ".c"))) 44998e903e7SBaptiste Daroussin { 45098e903e7SBaptiste Daroussin defines_suffix = ".h"; 45198e903e7SBaptiste Daroussin externs_suffix = ".i"; 45298e903e7SBaptiste Daroussin } 45398e903e7SBaptiste Daroussin } 45498e903e7SBaptiste Daroussin 45520afc491SJung-uk Kim if (suffix != NULL) 45698e903e7SBaptiste Daroussin { 45720afc491SJung-uk Kim len = (size_t) (suffix - output_file_name); 4583e066022SBaptiste Daroussin file_prefix = TMALLOC(char, len + 1); 45998e903e7SBaptiste Daroussin NO_SPACE(file_prefix); 46098e903e7SBaptiste Daroussin strncpy(file_prefix, output_file_name, len)[len] = 0; 46198e903e7SBaptiste Daroussin } 46298e903e7SBaptiste Daroussin else 46398e903e7SBaptiste Daroussin len = strlen(file_prefix); 46498e903e7SBaptiste Daroussin 46598e903e7SBaptiste Daroussin /* if "-o filename" was not given */ 46698e903e7SBaptiste Daroussin if (output_file_name == 0) 46798e903e7SBaptiste Daroussin { 46898e903e7SBaptiste Daroussin oflag = 1; 46998e903e7SBaptiste Daroussin CREATE_FILE_NAME(output_file_name, OUTPUT_SUFFIX); 47098e903e7SBaptiste Daroussin } 47198e903e7SBaptiste Daroussin 47298e903e7SBaptiste Daroussin if (rflag) 47398e903e7SBaptiste Daroussin { 47498e903e7SBaptiste Daroussin CREATE_FILE_NAME(code_file_name, CODE_SUFFIX); 47598e903e7SBaptiste Daroussin } 47698e903e7SBaptiste Daroussin else 47798e903e7SBaptiste Daroussin code_file_name = output_file_name; 47898e903e7SBaptiste Daroussin 47998e903e7SBaptiste Daroussin if (dflag) 48098e903e7SBaptiste Daroussin { 48198e903e7SBaptiste Daroussin CREATE_FILE_NAME(defines_file_name, defines_suffix); 48298e903e7SBaptiste Daroussin } 48398e903e7SBaptiste Daroussin 48498e903e7SBaptiste Daroussin if (iflag) 48598e903e7SBaptiste Daroussin { 48698e903e7SBaptiste Daroussin CREATE_FILE_NAME(externs_file_name, externs_suffix); 48798e903e7SBaptiste Daroussin } 48898e903e7SBaptiste Daroussin 48998e903e7SBaptiste Daroussin if (vflag) 49098e903e7SBaptiste Daroussin { 49198e903e7SBaptiste Daroussin CREATE_FILE_NAME(verbose_file_name, VERBOSE_SUFFIX); 49298e903e7SBaptiste Daroussin } 49398e903e7SBaptiste Daroussin 49498e903e7SBaptiste Daroussin if (gflag) 49598e903e7SBaptiste Daroussin { 49698e903e7SBaptiste Daroussin CREATE_FILE_NAME(graph_file_name, GRAPH_SUFFIX); 49798e903e7SBaptiste Daroussin } 49898e903e7SBaptiste Daroussin 49920afc491SJung-uk Kim if (suffix != NULL) 50098e903e7SBaptiste Daroussin { 50198e903e7SBaptiste Daroussin FREE(file_prefix); 50298e903e7SBaptiste Daroussin } 50398e903e7SBaptiste Daroussin } 50498e903e7SBaptiste Daroussin 50598e903e7SBaptiste Daroussin #if USE_MKSTEMP 50698e903e7SBaptiste Daroussin static void 50798e903e7SBaptiste Daroussin close_tmpfiles(void) 50898e903e7SBaptiste Daroussin { 50998e903e7SBaptiste Daroussin while (my_tmpfiles != 0) 51098e903e7SBaptiste Daroussin { 51198e903e7SBaptiste Daroussin MY_TMPFILES *next = my_tmpfiles->next; 51298e903e7SBaptiste Daroussin 51311fce282SBaptiste Daroussin (void)chmod(my_tmpfiles->name, 0644); 51411fce282SBaptiste Daroussin (void)unlink(my_tmpfiles->name); 51598e903e7SBaptiste Daroussin 51698e903e7SBaptiste Daroussin free(my_tmpfiles->name); 51798e903e7SBaptiste Daroussin free(my_tmpfiles); 51898e903e7SBaptiste Daroussin 51998e903e7SBaptiste Daroussin my_tmpfiles = next; 52098e903e7SBaptiste Daroussin } 52198e903e7SBaptiste Daroussin } 52298e903e7SBaptiste Daroussin 52398e903e7SBaptiste Daroussin #ifndef HAVE_MKSTEMP 52498e903e7SBaptiste Daroussin static int 52598e903e7SBaptiste Daroussin my_mkstemp(char *temp) 52698e903e7SBaptiste Daroussin { 52798e903e7SBaptiste Daroussin int fd; 52898e903e7SBaptiste Daroussin char *dname; 52998e903e7SBaptiste Daroussin char *fname; 53098e903e7SBaptiste Daroussin char *name; 53198e903e7SBaptiste Daroussin 53298e903e7SBaptiste Daroussin /* 53398e903e7SBaptiste Daroussin * Split-up to use tempnam, rather than tmpnam; the latter (like 53498e903e7SBaptiste Daroussin * mkstemp) is unusable on Windows. 53598e903e7SBaptiste Daroussin */ 53698e903e7SBaptiste Daroussin if ((fname = strrchr(temp, '/')) != 0) 53798e903e7SBaptiste Daroussin { 53898e903e7SBaptiste Daroussin dname = strdup(temp); 53998e903e7SBaptiste Daroussin dname[++fname - temp] = '\0'; 54098e903e7SBaptiste Daroussin } 54198e903e7SBaptiste Daroussin else 54298e903e7SBaptiste Daroussin { 54398e903e7SBaptiste Daroussin dname = 0; 54498e903e7SBaptiste Daroussin fname = temp; 54598e903e7SBaptiste Daroussin } 54698e903e7SBaptiste Daroussin if ((name = tempnam(dname, fname)) != 0) 54798e903e7SBaptiste Daroussin { 54898e903e7SBaptiste Daroussin fd = open(name, O_CREAT | O_EXCL | O_RDWR); 54998e903e7SBaptiste Daroussin strcpy(temp, name); 55098e903e7SBaptiste Daroussin } 55198e903e7SBaptiste Daroussin else 55298e903e7SBaptiste Daroussin { 55398e903e7SBaptiste Daroussin fd = -1; 55498e903e7SBaptiste Daroussin } 55598e903e7SBaptiste Daroussin 55698e903e7SBaptiste Daroussin if (dname != 0) 55798e903e7SBaptiste Daroussin free(dname); 55898e903e7SBaptiste Daroussin 55998e903e7SBaptiste Daroussin return fd; 56098e903e7SBaptiste Daroussin } 56198e903e7SBaptiste Daroussin #define mkstemp(s) my_mkstemp(s) 56298e903e7SBaptiste Daroussin #endif 56398e903e7SBaptiste Daroussin 56498e903e7SBaptiste Daroussin #endif 56598e903e7SBaptiste Daroussin 56698e903e7SBaptiste Daroussin /* 56798e903e7SBaptiste Daroussin * tmpfile() should be adequate, except that it may require special privileges 56898e903e7SBaptiste Daroussin * to use, e.g., MinGW and Windows 7 where it tries to use the root directory. 56998e903e7SBaptiste Daroussin */ 57098e903e7SBaptiste Daroussin static FILE * 57198e903e7SBaptiste Daroussin open_tmpfile(const char *label) 57298e903e7SBaptiste Daroussin { 5730f86d14eSJung-uk Kim #define MY_FMT "%s/%.*sXXXXXX" 57498e903e7SBaptiste Daroussin FILE *result; 57598e903e7SBaptiste Daroussin #if USE_MKSTEMP 57698e903e7SBaptiste Daroussin int fd; 57798e903e7SBaptiste Daroussin const char *tmpdir; 57898e903e7SBaptiste Daroussin char *name; 57998e903e7SBaptiste Daroussin const char *mark; 58098e903e7SBaptiste Daroussin 58198e903e7SBaptiste Daroussin if ((tmpdir = getenv("TMPDIR")) == 0 || access(tmpdir, W_OK) != 0) 58298e903e7SBaptiste Daroussin { 58398e903e7SBaptiste Daroussin #ifdef P_tmpdir 58498e903e7SBaptiste Daroussin tmpdir = P_tmpdir; 58598e903e7SBaptiste Daroussin #else 58698e903e7SBaptiste Daroussin tmpdir = "/tmp"; 58798e903e7SBaptiste Daroussin #endif 58898e903e7SBaptiste Daroussin if (access(tmpdir, W_OK) != 0) 58998e903e7SBaptiste Daroussin tmpdir = "."; 59098e903e7SBaptiste Daroussin } 59198e903e7SBaptiste Daroussin 5920f86d14eSJung-uk Kim /* The size of the format is guaranteed to be longer than the result from 5930f86d14eSJung-uk Kim * printing empty strings with it; this calculation accounts for the 5940f86d14eSJung-uk Kim * string-lengths as well. 5950f86d14eSJung-uk Kim */ 5960f86d14eSJung-uk Kim name = malloc(strlen(tmpdir) + sizeof(MY_FMT) + strlen(label)); 59798e903e7SBaptiste Daroussin 59898e903e7SBaptiste Daroussin result = 0; 59998e903e7SBaptiste Daroussin if (name != 0) 60098e903e7SBaptiste Daroussin { 601315e69cbSBaptiste Daroussin mode_t save_umask = umask(0177); 60211fce282SBaptiste Daroussin 60398e903e7SBaptiste Daroussin if ((mark = strrchr(label, '_')) == 0) 60498e903e7SBaptiste Daroussin mark = label + strlen(label); 60598e903e7SBaptiste Daroussin 6060f86d14eSJung-uk Kim sprintf(name, MY_FMT, tmpdir, (int)(mark - label), label); 60798e903e7SBaptiste Daroussin fd = mkstemp(name); 60898e903e7SBaptiste Daroussin if (fd >= 0) 60998e903e7SBaptiste Daroussin { 61098e903e7SBaptiste Daroussin result = fdopen(fd, "w+"); 61198e903e7SBaptiste Daroussin if (result != 0) 61298e903e7SBaptiste Daroussin { 61398e903e7SBaptiste Daroussin MY_TMPFILES *item; 61498e903e7SBaptiste Daroussin 61598e903e7SBaptiste Daroussin if (my_tmpfiles == 0) 61698e903e7SBaptiste Daroussin { 61798e903e7SBaptiste Daroussin atexit(close_tmpfiles); 61898e903e7SBaptiste Daroussin } 61998e903e7SBaptiste Daroussin 62098e903e7SBaptiste Daroussin item = NEW(MY_TMPFILES); 62198e903e7SBaptiste Daroussin NO_SPACE(item); 62298e903e7SBaptiste Daroussin 62398e903e7SBaptiste Daroussin item->name = name; 62498e903e7SBaptiste Daroussin NO_SPACE(item->name); 62598e903e7SBaptiste Daroussin 62698e903e7SBaptiste Daroussin item->next = my_tmpfiles; 62798e903e7SBaptiste Daroussin my_tmpfiles = item; 62898e903e7SBaptiste Daroussin } 62998e903e7SBaptiste Daroussin } 63011fce282SBaptiste Daroussin (void)umask(save_umask); 63198e903e7SBaptiste Daroussin } 63298e903e7SBaptiste Daroussin #else 63398e903e7SBaptiste Daroussin result = tmpfile(); 63498e903e7SBaptiste Daroussin #endif 63598e903e7SBaptiste Daroussin 63698e903e7SBaptiste Daroussin if (result == 0) 63798e903e7SBaptiste Daroussin open_error(label); 63898e903e7SBaptiste Daroussin return result; 6390f86d14eSJung-uk Kim #undef MY_FMT 64098e903e7SBaptiste Daroussin } 64198e903e7SBaptiste Daroussin 64298e903e7SBaptiste Daroussin static void 64398e903e7SBaptiste Daroussin open_files(void) 64498e903e7SBaptiste Daroussin { 64598e903e7SBaptiste Daroussin create_file_names(); 64698e903e7SBaptiste Daroussin 64798e903e7SBaptiste Daroussin if (input_file == 0) 64898e903e7SBaptiste Daroussin { 64998e903e7SBaptiste Daroussin input_file = fopen(input_file_name, "r"); 65098e903e7SBaptiste Daroussin if (input_file == 0) 65198e903e7SBaptiste Daroussin open_error(input_file_name); 65298e903e7SBaptiste Daroussin } 65398e903e7SBaptiste Daroussin 65498e903e7SBaptiste Daroussin action_file = open_tmpfile("action_file"); 65598e903e7SBaptiste Daroussin text_file = open_tmpfile("text_file"); 65698e903e7SBaptiste Daroussin 65798e903e7SBaptiste Daroussin if (vflag) 65898e903e7SBaptiste Daroussin { 65998e903e7SBaptiste Daroussin verbose_file = fopen(verbose_file_name, "w"); 66098e903e7SBaptiste Daroussin if (verbose_file == 0) 66198e903e7SBaptiste Daroussin open_error(verbose_file_name); 66298e903e7SBaptiste Daroussin } 66398e903e7SBaptiste Daroussin 66498e903e7SBaptiste Daroussin if (gflag) 66598e903e7SBaptiste Daroussin { 66698e903e7SBaptiste Daroussin graph_file = fopen(graph_file_name, "w"); 66798e903e7SBaptiste Daroussin if (graph_file == 0) 66898e903e7SBaptiste Daroussin open_error(graph_file_name); 66998e903e7SBaptiste Daroussin fprintf(graph_file, "digraph %s {\n", file_prefix); 67098e903e7SBaptiste Daroussin fprintf(graph_file, "\tedge [fontsize=10];\n"); 67198e903e7SBaptiste Daroussin fprintf(graph_file, "\tnode [shape=box,fontsize=10];\n"); 67298e903e7SBaptiste Daroussin fprintf(graph_file, "\torientation=landscape;\n"); 67398e903e7SBaptiste Daroussin fprintf(graph_file, "\trankdir=LR;\n"); 67498e903e7SBaptiste Daroussin fprintf(graph_file, "\t/*\n"); 67598e903e7SBaptiste Daroussin fprintf(graph_file, "\tmargin=0.2;\n"); 67698e903e7SBaptiste Daroussin fprintf(graph_file, "\tpage=\"8.27,11.69\"; // for A4 printing\n"); 67798e903e7SBaptiste Daroussin fprintf(graph_file, "\tratio=auto;\n"); 67898e903e7SBaptiste Daroussin fprintf(graph_file, "\t*/\n"); 67998e903e7SBaptiste Daroussin } 68098e903e7SBaptiste Daroussin 68198e903e7SBaptiste Daroussin if (dflag) 68298e903e7SBaptiste Daroussin { 68398e903e7SBaptiste Daroussin defines_file = fopen(defines_file_name, "w"); 68498e903e7SBaptiste Daroussin if (defines_file == 0) 68598e903e7SBaptiste Daroussin open_error(defines_file_name); 68698e903e7SBaptiste Daroussin union_file = open_tmpfile("union_file"); 68798e903e7SBaptiste Daroussin } 68898e903e7SBaptiste Daroussin 68998e903e7SBaptiste Daroussin if (iflag) 69098e903e7SBaptiste Daroussin { 69198e903e7SBaptiste Daroussin externs_file = fopen(externs_file_name, "w"); 69298e903e7SBaptiste Daroussin if (externs_file == 0) 69398e903e7SBaptiste Daroussin open_error(externs_file_name); 69498e903e7SBaptiste Daroussin } 69598e903e7SBaptiste Daroussin 69698e903e7SBaptiste Daroussin output_file = fopen(output_file_name, "w"); 69798e903e7SBaptiste Daroussin if (output_file == 0) 69898e903e7SBaptiste Daroussin open_error(output_file_name); 69998e903e7SBaptiste Daroussin 70098e903e7SBaptiste Daroussin if (rflag) 70198e903e7SBaptiste Daroussin { 70298e903e7SBaptiste Daroussin code_file = fopen(code_file_name, "w"); 70398e903e7SBaptiste Daroussin if (code_file == 0) 70498e903e7SBaptiste Daroussin open_error(code_file_name); 70598e903e7SBaptiste Daroussin } 70698e903e7SBaptiste Daroussin else 70798e903e7SBaptiste Daroussin code_file = output_file; 70898e903e7SBaptiste Daroussin } 70998e903e7SBaptiste Daroussin 71098e903e7SBaptiste Daroussin int 71198e903e7SBaptiste Daroussin main(int argc, char *argv[]) 71298e903e7SBaptiste Daroussin { 71398e903e7SBaptiste Daroussin SRexpect = -1; 71498e903e7SBaptiste Daroussin RRexpect = -1; 71598e903e7SBaptiste Daroussin exit_code = EXIT_SUCCESS; 71698e903e7SBaptiste Daroussin 71798e903e7SBaptiste Daroussin set_signals(); 71898e903e7SBaptiste Daroussin getargs(argc, argv); 71998e903e7SBaptiste Daroussin open_files(); 72098e903e7SBaptiste Daroussin reader(); 72198e903e7SBaptiste Daroussin lr0(); 72298e903e7SBaptiste Daroussin lalr(); 72398e903e7SBaptiste Daroussin make_parser(); 72498e903e7SBaptiste Daroussin graph(); 72598e903e7SBaptiste Daroussin finalize_closure(); 72698e903e7SBaptiste Daroussin verbose(); 72798e903e7SBaptiste Daroussin output(); 72898e903e7SBaptiste Daroussin done(exit_code); 72998e903e7SBaptiste Daroussin /*NOTREACHED */ 73098e903e7SBaptiste Daroussin } 731