1*4b4a8fcaSBaptiste Daroussin /* $Id: main.c,v 1.41 2014/01/01 14:23:27 Christos.Zoulas Exp $ */ 298e903e7SBaptiste Daroussin 398e903e7SBaptiste Daroussin #include <signal.h> 498e903e7SBaptiste Daroussin #include <unistd.h> /* for _exit() */ 598e903e7SBaptiste Daroussin 698e903e7SBaptiste Daroussin #include "defs.h" 798e903e7SBaptiste Daroussin 898e903e7SBaptiste Daroussin #ifdef HAVE_MKSTEMP 998e903e7SBaptiste Daroussin # define USE_MKSTEMP 1 1098e903e7SBaptiste Daroussin #elif defined(HAVE_FCNTL_H) 1198e903e7SBaptiste Daroussin # define USE_MKSTEMP 1 1298e903e7SBaptiste Daroussin # include <fcntl.h> /* for open(), O_EXCL, etc. */ 1398e903e7SBaptiste Daroussin #else 1498e903e7SBaptiste Daroussin # define USE_MKSTEMP 0 1598e903e7SBaptiste Daroussin #endif 1698e903e7SBaptiste Daroussin 1798e903e7SBaptiste Daroussin #if USE_MKSTEMP 1898e903e7SBaptiste Daroussin #include <sys/types.h> 1998e903e7SBaptiste Daroussin #include <sys/stat.h> 2098e903e7SBaptiste Daroussin 2198e903e7SBaptiste Daroussin typedef struct _my_tmpfiles 2298e903e7SBaptiste Daroussin { 2398e903e7SBaptiste Daroussin struct _my_tmpfiles *next; 2498e903e7SBaptiste Daroussin char *name; 2598e903e7SBaptiste Daroussin } 2698e903e7SBaptiste Daroussin MY_TMPFILES; 2798e903e7SBaptiste Daroussin 2898e903e7SBaptiste Daroussin static MY_TMPFILES *my_tmpfiles; 2998e903e7SBaptiste Daroussin #endif /* USE_MKSTEMP */ 3098e903e7SBaptiste Daroussin 3198e903e7SBaptiste Daroussin char dflag; 3298e903e7SBaptiste Daroussin char gflag; 3398e903e7SBaptiste Daroussin char iflag; 3498e903e7SBaptiste Daroussin char lflag; 3598e903e7SBaptiste Daroussin static char oflag; 3698e903e7SBaptiste Daroussin char rflag; 3798e903e7SBaptiste Daroussin char sflag; 3898e903e7SBaptiste Daroussin char tflag; 3998e903e7SBaptiste Daroussin char vflag; 4098e903e7SBaptiste Daroussin 4198e903e7SBaptiste Daroussin const char *symbol_prefix; 4298e903e7SBaptiste Daroussin const char *myname = "yacc"; 4398e903e7SBaptiste Daroussin 4498e903e7SBaptiste Daroussin int lineno; 4598e903e7SBaptiste Daroussin int outline; 4698e903e7SBaptiste Daroussin 4798e903e7SBaptiste Daroussin static char empty_string[] = ""; 4898e903e7SBaptiste Daroussin static char default_file_prefix[] = "y"; 4998e903e7SBaptiste Daroussin 5098e903e7SBaptiste Daroussin static char *file_prefix = default_file_prefix; 5198e903e7SBaptiste Daroussin 5298e903e7SBaptiste Daroussin char *code_file_name; 5398e903e7SBaptiste Daroussin char *input_file_name = empty_string; 5498e903e7SBaptiste Daroussin char *defines_file_name; 5598e903e7SBaptiste Daroussin char *externs_file_name; 5698e903e7SBaptiste Daroussin 5798e903e7SBaptiste Daroussin static char *graph_file_name; 5898e903e7SBaptiste Daroussin static char *output_file_name; 5998e903e7SBaptiste Daroussin static char *verbose_file_name; 6098e903e7SBaptiste Daroussin 6198e903e7SBaptiste Daroussin FILE *action_file; /* a temp file, used to save actions associated */ 6298e903e7SBaptiste Daroussin /* with rules until the parser is written */ 6398e903e7SBaptiste Daroussin FILE *code_file; /* y.code.c (used when the -r option is specified) */ 6498e903e7SBaptiste Daroussin FILE *defines_file; /* y.tab.h */ 6598e903e7SBaptiste Daroussin FILE *externs_file; /* y.tab.i */ 6698e903e7SBaptiste Daroussin FILE *input_file; /* the input file */ 6798e903e7SBaptiste Daroussin FILE *output_file; /* y.tab.c */ 6898e903e7SBaptiste Daroussin FILE *text_file; /* a temp file, used to save text until all */ 6998e903e7SBaptiste Daroussin /* symbols have been defined */ 7098e903e7SBaptiste Daroussin FILE *union_file; /* a temp file, used to save the union */ 7198e903e7SBaptiste Daroussin /* definition until all symbol have been */ 7298e903e7SBaptiste Daroussin /* defined */ 7398e903e7SBaptiste Daroussin FILE *verbose_file; /* y.output */ 7498e903e7SBaptiste Daroussin FILE *graph_file; /* y.dot */ 7598e903e7SBaptiste Daroussin 7698e903e7SBaptiste Daroussin int nitems; 7798e903e7SBaptiste Daroussin int nrules; 7898e903e7SBaptiste Daroussin int nsyms; 7998e903e7SBaptiste Daroussin int ntokens; 8098e903e7SBaptiste Daroussin int nvars; 8198e903e7SBaptiste Daroussin 8298e903e7SBaptiste Daroussin Value_t start_symbol; 8398e903e7SBaptiste Daroussin char **symbol_name; 8498e903e7SBaptiste Daroussin char **symbol_pname; 8598e903e7SBaptiste Daroussin Value_t *symbol_value; 8698e903e7SBaptiste Daroussin short *symbol_prec; 8798e903e7SBaptiste Daroussin char *symbol_assoc; 8898e903e7SBaptiste Daroussin 8998e903e7SBaptiste Daroussin int pure_parser; 90*4b4a8fcaSBaptiste Daroussin int token_table; 9198e903e7SBaptiste Daroussin int exit_code; 9298e903e7SBaptiste Daroussin 9398e903e7SBaptiste Daroussin Value_t *ritem; 9498e903e7SBaptiste Daroussin Value_t *rlhs; 9598e903e7SBaptiste Daroussin Value_t *rrhs; 9698e903e7SBaptiste Daroussin Value_t *rprec; 9798e903e7SBaptiste Daroussin Assoc_t *rassoc; 9898e903e7SBaptiste Daroussin Value_t **derives; 9998e903e7SBaptiste Daroussin char *nullable; 10098e903e7SBaptiste Daroussin 10198e903e7SBaptiste Daroussin /* 10298e903e7SBaptiste Daroussin * Since fclose() is called via the signal handler, it might die. Don't loop 10398e903e7SBaptiste Daroussin * if there is a problem closing a file. 10498e903e7SBaptiste Daroussin */ 10598e903e7SBaptiste Daroussin #define DO_CLOSE(fp) \ 10698e903e7SBaptiste Daroussin if (fp != 0) { \ 10798e903e7SBaptiste Daroussin FILE *use = fp; \ 10898e903e7SBaptiste Daroussin fp = 0; \ 10998e903e7SBaptiste Daroussin fclose(use); \ 11098e903e7SBaptiste Daroussin } 11198e903e7SBaptiste Daroussin 11298e903e7SBaptiste Daroussin static int got_intr = 0; 11398e903e7SBaptiste Daroussin 11498e903e7SBaptiste Daroussin void 11598e903e7SBaptiste Daroussin done(int k) 11698e903e7SBaptiste Daroussin { 11798e903e7SBaptiste Daroussin DO_CLOSE(input_file); 11898e903e7SBaptiste Daroussin DO_CLOSE(output_file); 11998e903e7SBaptiste Daroussin 12098e903e7SBaptiste Daroussin DO_CLOSE(action_file); 12198e903e7SBaptiste Daroussin DO_CLOSE(defines_file); 12298e903e7SBaptiste Daroussin DO_CLOSE(graph_file); 12398e903e7SBaptiste Daroussin DO_CLOSE(text_file); 12498e903e7SBaptiste Daroussin DO_CLOSE(union_file); 12598e903e7SBaptiste Daroussin DO_CLOSE(verbose_file); 12698e903e7SBaptiste Daroussin 12798e903e7SBaptiste Daroussin if (got_intr) 12898e903e7SBaptiste Daroussin _exit(EXIT_FAILURE); 12998e903e7SBaptiste Daroussin 13098e903e7SBaptiste Daroussin #ifdef NO_LEAKS 13198e903e7SBaptiste Daroussin if (rflag) 13298e903e7SBaptiste Daroussin DO_FREE(code_file_name); 13398e903e7SBaptiste Daroussin 13498e903e7SBaptiste Daroussin if (dflag) 13598e903e7SBaptiste Daroussin DO_FREE(defines_file_name); 13698e903e7SBaptiste Daroussin 13798e903e7SBaptiste Daroussin if (iflag) 13898e903e7SBaptiste Daroussin DO_FREE(externs_file_name); 13998e903e7SBaptiste Daroussin 14098e903e7SBaptiste Daroussin if (oflag) 14198e903e7SBaptiste Daroussin DO_FREE(output_file_name); 14298e903e7SBaptiste Daroussin 14398e903e7SBaptiste Daroussin if (vflag) 14498e903e7SBaptiste Daroussin DO_FREE(verbose_file_name); 14598e903e7SBaptiste Daroussin 14698e903e7SBaptiste Daroussin if (gflag) 14798e903e7SBaptiste Daroussin DO_FREE(graph_file_name); 14898e903e7SBaptiste Daroussin 14998e903e7SBaptiste Daroussin lr0_leaks(); 15098e903e7SBaptiste Daroussin lalr_leaks(); 15198e903e7SBaptiste Daroussin mkpar_leaks(); 15298e903e7SBaptiste Daroussin output_leaks(); 15398e903e7SBaptiste Daroussin reader_leaks(); 15498e903e7SBaptiste Daroussin #endif 15598e903e7SBaptiste Daroussin 15698e903e7SBaptiste Daroussin if (rflag) 15798e903e7SBaptiste Daroussin DO_CLOSE(code_file); 15898e903e7SBaptiste Daroussin 15998e903e7SBaptiste Daroussin exit(k); 16098e903e7SBaptiste Daroussin } 16198e903e7SBaptiste Daroussin 16298e903e7SBaptiste Daroussin static void 1633e066022SBaptiste Daroussin onintr(int sig GCC_UNUSED) 16498e903e7SBaptiste Daroussin { 16598e903e7SBaptiste Daroussin got_intr = 1; 16698e903e7SBaptiste Daroussin done(EXIT_FAILURE); 16798e903e7SBaptiste Daroussin } 16898e903e7SBaptiste Daroussin 16998e903e7SBaptiste Daroussin static void 17098e903e7SBaptiste Daroussin set_signals(void) 17198e903e7SBaptiste Daroussin { 17298e903e7SBaptiste Daroussin #ifdef SIGINT 17398e903e7SBaptiste Daroussin if (signal(SIGINT, SIG_IGN) != SIG_IGN) 17498e903e7SBaptiste Daroussin signal(SIGINT, onintr); 17598e903e7SBaptiste Daroussin #endif 17698e903e7SBaptiste Daroussin #ifdef SIGTERM 17798e903e7SBaptiste Daroussin if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 17898e903e7SBaptiste Daroussin signal(SIGTERM, onintr); 17998e903e7SBaptiste Daroussin #endif 18098e903e7SBaptiste Daroussin #ifdef SIGHUP 18198e903e7SBaptiste Daroussin if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 18298e903e7SBaptiste Daroussin signal(SIGHUP, onintr); 18398e903e7SBaptiste Daroussin #endif 18498e903e7SBaptiste Daroussin } 18598e903e7SBaptiste Daroussin 18698e903e7SBaptiste Daroussin static void 18798e903e7SBaptiste Daroussin usage(void) 18898e903e7SBaptiste Daroussin { 18998e903e7SBaptiste Daroussin static const char *msg[] = 19098e903e7SBaptiste Daroussin { 19198e903e7SBaptiste Daroussin "" 19298e903e7SBaptiste Daroussin ,"Options:" 19398e903e7SBaptiste Daroussin ," -b file_prefix set filename prefix (default \"y.\")" 19498e903e7SBaptiste Daroussin ," -d write definitions (y.tab.h)" 19598e903e7SBaptiste Daroussin ," -i write interface (y.tab.i)" 19698e903e7SBaptiste Daroussin ," -g write a graphical description" 19798e903e7SBaptiste Daroussin ," -l suppress #line directives" 19898e903e7SBaptiste Daroussin ," -o output_file (default \"y.tab.c\")" 19998e903e7SBaptiste Daroussin ," -p symbol_prefix set symbol prefix (default \"yy\")" 20098e903e7SBaptiste Daroussin ," -P create a reentrant parser, e.g., \"%pure-parser\"" 20198e903e7SBaptiste Daroussin ," -r produce separate code and table files (y.code.c)" 20298e903e7SBaptiste Daroussin ," -s suppress #define's for quoted names in %token lines" 20398e903e7SBaptiste Daroussin ," -t add debugging support" 20498e903e7SBaptiste Daroussin ," -v write description (y.output)" 20598e903e7SBaptiste Daroussin ," -V show version information and exit" 20698e903e7SBaptiste Daroussin }; 20798e903e7SBaptiste Daroussin unsigned n; 20898e903e7SBaptiste Daroussin 20998e903e7SBaptiste Daroussin fflush(stdout); 21098e903e7SBaptiste Daroussin fprintf(stderr, "Usage: %s [options] filename\n", myname); 21198e903e7SBaptiste Daroussin for (n = 0; n < sizeof(msg) / sizeof(msg[0]); ++n) 21298e903e7SBaptiste Daroussin fprintf(stderr, "%s\n", msg[n]); 21398e903e7SBaptiste Daroussin 21498e903e7SBaptiste Daroussin exit(1); 21598e903e7SBaptiste Daroussin } 21698e903e7SBaptiste Daroussin 21798e903e7SBaptiste Daroussin static void 21898e903e7SBaptiste Daroussin setflag(int ch) 21998e903e7SBaptiste Daroussin { 22098e903e7SBaptiste Daroussin switch (ch) 22198e903e7SBaptiste Daroussin { 22298e903e7SBaptiste Daroussin case 'd': 22398e903e7SBaptiste Daroussin dflag = 1; 22498e903e7SBaptiste Daroussin break; 22598e903e7SBaptiste Daroussin 22698e903e7SBaptiste Daroussin case 'g': 22798e903e7SBaptiste Daroussin gflag = 1; 22898e903e7SBaptiste Daroussin break; 22998e903e7SBaptiste Daroussin 23098e903e7SBaptiste Daroussin case 'i': 23198e903e7SBaptiste Daroussin iflag = 1; 23298e903e7SBaptiste Daroussin break; 23398e903e7SBaptiste Daroussin 23498e903e7SBaptiste Daroussin case 'l': 23598e903e7SBaptiste Daroussin lflag = 1; 23698e903e7SBaptiste Daroussin break; 23798e903e7SBaptiste Daroussin 23898e903e7SBaptiste Daroussin case 'P': 23998e903e7SBaptiste Daroussin pure_parser = 1; 24098e903e7SBaptiste Daroussin break; 24198e903e7SBaptiste Daroussin 24298e903e7SBaptiste Daroussin case 'r': 24398e903e7SBaptiste Daroussin rflag = 1; 24498e903e7SBaptiste Daroussin break; 24598e903e7SBaptiste Daroussin 24698e903e7SBaptiste Daroussin case 's': 24798e903e7SBaptiste Daroussin sflag = 1; 24898e903e7SBaptiste Daroussin break; 24998e903e7SBaptiste Daroussin 25098e903e7SBaptiste Daroussin case 't': 25198e903e7SBaptiste Daroussin tflag = 1; 25298e903e7SBaptiste Daroussin break; 25398e903e7SBaptiste Daroussin 25498e903e7SBaptiste Daroussin case 'v': 25598e903e7SBaptiste Daroussin vflag = 1; 25698e903e7SBaptiste Daroussin break; 25798e903e7SBaptiste Daroussin 25898e903e7SBaptiste Daroussin case 'V': 25998e903e7SBaptiste Daroussin printf("%s - %s\n", myname, VERSION); 26098e903e7SBaptiste Daroussin exit(EXIT_SUCCESS); 26198e903e7SBaptiste Daroussin 26298e903e7SBaptiste Daroussin case 'y': 26398e903e7SBaptiste Daroussin /* noop for bison compatibility. byacc is already designed to be posix 26498e903e7SBaptiste Daroussin * yacc compatible. */ 26598e903e7SBaptiste Daroussin break; 26698e903e7SBaptiste Daroussin 26798e903e7SBaptiste Daroussin default: 26898e903e7SBaptiste Daroussin usage(); 26998e903e7SBaptiste Daroussin } 27098e903e7SBaptiste Daroussin } 27198e903e7SBaptiste Daroussin 27298e903e7SBaptiste Daroussin static void 27398e903e7SBaptiste Daroussin getargs(int argc, char *argv[]) 27498e903e7SBaptiste Daroussin { 27598e903e7SBaptiste Daroussin int i; 27698e903e7SBaptiste Daroussin char *s; 27798e903e7SBaptiste Daroussin int ch; 27898e903e7SBaptiste Daroussin 27998e903e7SBaptiste Daroussin if (argc > 0) 28098e903e7SBaptiste Daroussin myname = argv[0]; 28198e903e7SBaptiste Daroussin 28298e903e7SBaptiste Daroussin for (i = 1; i < argc; ++i) 28398e903e7SBaptiste Daroussin { 28498e903e7SBaptiste Daroussin s = argv[i]; 28598e903e7SBaptiste Daroussin if (*s != '-') 28698e903e7SBaptiste Daroussin break; 28798e903e7SBaptiste Daroussin switch (ch = *++s) 28898e903e7SBaptiste Daroussin { 28998e903e7SBaptiste Daroussin case '\0': 29098e903e7SBaptiste Daroussin input_file = stdin; 29198e903e7SBaptiste Daroussin if (i + 1 < argc) 29298e903e7SBaptiste Daroussin usage(); 29398e903e7SBaptiste Daroussin return; 29498e903e7SBaptiste Daroussin 29598e903e7SBaptiste Daroussin case '-': 29698e903e7SBaptiste Daroussin ++i; 29798e903e7SBaptiste Daroussin goto no_more_options; 29898e903e7SBaptiste Daroussin 29998e903e7SBaptiste Daroussin case 'b': 30098e903e7SBaptiste Daroussin if (*++s) 30198e903e7SBaptiste Daroussin file_prefix = s; 30298e903e7SBaptiste Daroussin else if (++i < argc) 30398e903e7SBaptiste Daroussin file_prefix = argv[i]; 30498e903e7SBaptiste Daroussin else 30598e903e7SBaptiste Daroussin usage(); 30698e903e7SBaptiste Daroussin continue; 30798e903e7SBaptiste Daroussin 30898e903e7SBaptiste Daroussin case 'o': 30998e903e7SBaptiste Daroussin if (*++s) 31098e903e7SBaptiste Daroussin output_file_name = s; 31198e903e7SBaptiste Daroussin else if (++i < argc) 31298e903e7SBaptiste Daroussin output_file_name = argv[i]; 31398e903e7SBaptiste Daroussin else 31498e903e7SBaptiste Daroussin usage(); 31598e903e7SBaptiste Daroussin continue; 31698e903e7SBaptiste Daroussin 31798e903e7SBaptiste Daroussin case 'p': 31898e903e7SBaptiste Daroussin if (*++s) 31998e903e7SBaptiste Daroussin symbol_prefix = s; 32098e903e7SBaptiste Daroussin else if (++i < argc) 32198e903e7SBaptiste Daroussin symbol_prefix = argv[i]; 32298e903e7SBaptiste Daroussin else 32398e903e7SBaptiste Daroussin usage(); 32498e903e7SBaptiste Daroussin continue; 32598e903e7SBaptiste Daroussin 32698e903e7SBaptiste Daroussin default: 32798e903e7SBaptiste Daroussin setflag(ch); 32898e903e7SBaptiste Daroussin break; 32998e903e7SBaptiste Daroussin } 33098e903e7SBaptiste Daroussin 33198e903e7SBaptiste Daroussin for (;;) 33298e903e7SBaptiste Daroussin { 33398e903e7SBaptiste Daroussin switch (ch = *++s) 33498e903e7SBaptiste Daroussin { 33598e903e7SBaptiste Daroussin case '\0': 33698e903e7SBaptiste Daroussin goto end_of_option; 33798e903e7SBaptiste Daroussin 33898e903e7SBaptiste Daroussin default: 33998e903e7SBaptiste Daroussin setflag(ch); 34098e903e7SBaptiste Daroussin break; 34198e903e7SBaptiste Daroussin } 34298e903e7SBaptiste Daroussin } 34398e903e7SBaptiste Daroussin end_of_option:; 34498e903e7SBaptiste Daroussin } 34598e903e7SBaptiste Daroussin 34698e903e7SBaptiste Daroussin no_more_options:; 34798e903e7SBaptiste Daroussin if (i + 1 != argc) 34898e903e7SBaptiste Daroussin usage(); 34998e903e7SBaptiste Daroussin input_file_name = argv[i]; 35098e903e7SBaptiste Daroussin } 35198e903e7SBaptiste Daroussin 35298e903e7SBaptiste Daroussin void * 35398e903e7SBaptiste Daroussin allocate(size_t n) 35498e903e7SBaptiste Daroussin { 35598e903e7SBaptiste Daroussin void *p; 35698e903e7SBaptiste Daroussin 35798e903e7SBaptiste Daroussin p = NULL; 35898e903e7SBaptiste Daroussin if (n) 35998e903e7SBaptiste Daroussin { 36098e903e7SBaptiste Daroussin p = CALLOC(1, n); 36198e903e7SBaptiste Daroussin NO_SPACE(p); 36298e903e7SBaptiste Daroussin } 36398e903e7SBaptiste Daroussin return (p); 36498e903e7SBaptiste Daroussin } 36598e903e7SBaptiste Daroussin 36698e903e7SBaptiste Daroussin #define CREATE_FILE_NAME(dest, suffix) \ 3673e066022SBaptiste Daroussin dest = TMALLOC(char, len + strlen(suffix) + 1); \ 36898e903e7SBaptiste Daroussin NO_SPACE(dest); \ 36998e903e7SBaptiste Daroussin strcpy(dest, file_prefix); \ 37098e903e7SBaptiste Daroussin strcpy(dest + len, suffix) 37198e903e7SBaptiste Daroussin 37298e903e7SBaptiste Daroussin static void 37398e903e7SBaptiste Daroussin create_file_names(void) 37498e903e7SBaptiste Daroussin { 37598e903e7SBaptiste Daroussin size_t len; 37698e903e7SBaptiste Daroussin const char *defines_suffix; 37798e903e7SBaptiste Daroussin const char *externs_suffix; 37898e903e7SBaptiste Daroussin char *prefix; 37998e903e7SBaptiste Daroussin 38098e903e7SBaptiste Daroussin prefix = NULL; 38198e903e7SBaptiste Daroussin defines_suffix = DEFINES_SUFFIX; 38298e903e7SBaptiste Daroussin externs_suffix = EXTERNS_SUFFIX; 38398e903e7SBaptiste Daroussin 38498e903e7SBaptiste Daroussin /* compute the file_prefix from the user provided output_file_name */ 38598e903e7SBaptiste Daroussin if (output_file_name != 0) 38698e903e7SBaptiste Daroussin { 38798e903e7SBaptiste Daroussin if (!(prefix = strstr(output_file_name, ".tab.c")) 38898e903e7SBaptiste Daroussin && (prefix = strstr(output_file_name, ".c"))) 38998e903e7SBaptiste Daroussin { 39098e903e7SBaptiste Daroussin defines_suffix = ".h"; 39198e903e7SBaptiste Daroussin externs_suffix = ".i"; 39298e903e7SBaptiste Daroussin } 39398e903e7SBaptiste Daroussin } 39498e903e7SBaptiste Daroussin 39598e903e7SBaptiste Daroussin if (prefix != NULL) 39698e903e7SBaptiste Daroussin { 39798e903e7SBaptiste Daroussin len = (size_t) (prefix - output_file_name); 3983e066022SBaptiste Daroussin file_prefix = TMALLOC(char, len + 1); 39998e903e7SBaptiste Daroussin NO_SPACE(file_prefix); 40098e903e7SBaptiste Daroussin strncpy(file_prefix, output_file_name, len)[len] = 0; 40198e903e7SBaptiste Daroussin } 40298e903e7SBaptiste Daroussin else 40398e903e7SBaptiste Daroussin len = strlen(file_prefix); 40498e903e7SBaptiste Daroussin 40598e903e7SBaptiste Daroussin /* if "-o filename" was not given */ 40698e903e7SBaptiste Daroussin if (output_file_name == 0) 40798e903e7SBaptiste Daroussin { 40898e903e7SBaptiste Daroussin oflag = 1; 40998e903e7SBaptiste Daroussin CREATE_FILE_NAME(output_file_name, OUTPUT_SUFFIX); 41098e903e7SBaptiste Daroussin } 41198e903e7SBaptiste Daroussin 41298e903e7SBaptiste Daroussin if (rflag) 41398e903e7SBaptiste Daroussin { 41498e903e7SBaptiste Daroussin CREATE_FILE_NAME(code_file_name, CODE_SUFFIX); 41598e903e7SBaptiste Daroussin } 41698e903e7SBaptiste Daroussin else 41798e903e7SBaptiste Daroussin code_file_name = output_file_name; 41898e903e7SBaptiste Daroussin 41998e903e7SBaptiste Daroussin if (dflag) 42098e903e7SBaptiste Daroussin { 42198e903e7SBaptiste Daroussin CREATE_FILE_NAME(defines_file_name, defines_suffix); 42298e903e7SBaptiste Daroussin } 42398e903e7SBaptiste Daroussin 42498e903e7SBaptiste Daroussin if (iflag) 42598e903e7SBaptiste Daroussin { 42698e903e7SBaptiste Daroussin CREATE_FILE_NAME(externs_file_name, externs_suffix); 42798e903e7SBaptiste Daroussin } 42898e903e7SBaptiste Daroussin 42998e903e7SBaptiste Daroussin if (vflag) 43098e903e7SBaptiste Daroussin { 43198e903e7SBaptiste Daroussin CREATE_FILE_NAME(verbose_file_name, VERBOSE_SUFFIX); 43298e903e7SBaptiste Daroussin } 43398e903e7SBaptiste Daroussin 43498e903e7SBaptiste Daroussin if (gflag) 43598e903e7SBaptiste Daroussin { 43698e903e7SBaptiste Daroussin CREATE_FILE_NAME(graph_file_name, GRAPH_SUFFIX); 43798e903e7SBaptiste Daroussin } 43898e903e7SBaptiste Daroussin 43998e903e7SBaptiste Daroussin if (prefix != NULL) 44098e903e7SBaptiste Daroussin { 44198e903e7SBaptiste Daroussin FREE(file_prefix); 44298e903e7SBaptiste Daroussin } 44398e903e7SBaptiste Daroussin } 44498e903e7SBaptiste Daroussin 44598e903e7SBaptiste Daroussin #if USE_MKSTEMP 44698e903e7SBaptiste Daroussin static void 44798e903e7SBaptiste Daroussin close_tmpfiles(void) 44898e903e7SBaptiste Daroussin { 44998e903e7SBaptiste Daroussin while (my_tmpfiles != 0) 45098e903e7SBaptiste Daroussin { 45198e903e7SBaptiste Daroussin MY_TMPFILES *next = my_tmpfiles->next; 45298e903e7SBaptiste Daroussin 45398e903e7SBaptiste Daroussin chmod(my_tmpfiles->name, 0644); 45498e903e7SBaptiste Daroussin unlink(my_tmpfiles->name); 45598e903e7SBaptiste Daroussin 45698e903e7SBaptiste Daroussin free(my_tmpfiles->name); 45798e903e7SBaptiste Daroussin free(my_tmpfiles); 45898e903e7SBaptiste Daroussin 45998e903e7SBaptiste Daroussin my_tmpfiles = next; 46098e903e7SBaptiste Daroussin } 46198e903e7SBaptiste Daroussin } 46298e903e7SBaptiste Daroussin 46398e903e7SBaptiste Daroussin #ifndef HAVE_MKSTEMP 46498e903e7SBaptiste Daroussin static int 46598e903e7SBaptiste Daroussin my_mkstemp(char *temp) 46698e903e7SBaptiste Daroussin { 46798e903e7SBaptiste Daroussin int fd; 46898e903e7SBaptiste Daroussin char *dname; 46998e903e7SBaptiste Daroussin char *fname; 47098e903e7SBaptiste Daroussin char *name; 47198e903e7SBaptiste Daroussin 47298e903e7SBaptiste Daroussin /* 47398e903e7SBaptiste Daroussin * Split-up to use tempnam, rather than tmpnam; the latter (like 47498e903e7SBaptiste Daroussin * mkstemp) is unusable on Windows. 47598e903e7SBaptiste Daroussin */ 47698e903e7SBaptiste Daroussin if ((fname = strrchr(temp, '/')) != 0) 47798e903e7SBaptiste Daroussin { 47898e903e7SBaptiste Daroussin dname = strdup(temp); 47998e903e7SBaptiste Daroussin dname[++fname - temp] = '\0'; 48098e903e7SBaptiste Daroussin } 48198e903e7SBaptiste Daroussin else 48298e903e7SBaptiste Daroussin { 48398e903e7SBaptiste Daroussin dname = 0; 48498e903e7SBaptiste Daroussin fname = temp; 48598e903e7SBaptiste Daroussin } 48698e903e7SBaptiste Daroussin if ((name = tempnam(dname, fname)) != 0) 48798e903e7SBaptiste Daroussin { 48898e903e7SBaptiste Daroussin fd = open(name, O_CREAT | O_EXCL | O_RDWR); 48998e903e7SBaptiste Daroussin strcpy(temp, name); 49098e903e7SBaptiste Daroussin } 49198e903e7SBaptiste Daroussin else 49298e903e7SBaptiste Daroussin { 49398e903e7SBaptiste Daroussin fd = -1; 49498e903e7SBaptiste Daroussin } 49598e903e7SBaptiste Daroussin 49698e903e7SBaptiste Daroussin if (dname != 0) 49798e903e7SBaptiste Daroussin free(dname); 49898e903e7SBaptiste Daroussin 49998e903e7SBaptiste Daroussin return fd; 50098e903e7SBaptiste Daroussin } 50198e903e7SBaptiste Daroussin #define mkstemp(s) my_mkstemp(s) 50298e903e7SBaptiste Daroussin #endif 50398e903e7SBaptiste Daroussin 50498e903e7SBaptiste Daroussin #endif 50598e903e7SBaptiste Daroussin 50698e903e7SBaptiste Daroussin /* 50798e903e7SBaptiste Daroussin * tmpfile() should be adequate, except that it may require special privileges 50898e903e7SBaptiste Daroussin * to use, e.g., MinGW and Windows 7 where it tries to use the root directory. 50998e903e7SBaptiste Daroussin */ 51098e903e7SBaptiste Daroussin static FILE * 51198e903e7SBaptiste Daroussin open_tmpfile(const char *label) 51298e903e7SBaptiste Daroussin { 51398e903e7SBaptiste Daroussin FILE *result; 51498e903e7SBaptiste Daroussin #if USE_MKSTEMP 51598e903e7SBaptiste Daroussin int fd; 51698e903e7SBaptiste Daroussin const char *tmpdir; 51798e903e7SBaptiste Daroussin char *name; 51898e903e7SBaptiste Daroussin const char *mark; 51998e903e7SBaptiste Daroussin 52098e903e7SBaptiste Daroussin if ((tmpdir = getenv("TMPDIR")) == 0 || access(tmpdir, W_OK) != 0) 52198e903e7SBaptiste Daroussin { 52298e903e7SBaptiste Daroussin #ifdef P_tmpdir 52398e903e7SBaptiste Daroussin tmpdir = P_tmpdir; 52498e903e7SBaptiste Daroussin #else 52598e903e7SBaptiste Daroussin tmpdir = "/tmp"; 52698e903e7SBaptiste Daroussin #endif 52798e903e7SBaptiste Daroussin if (access(tmpdir, W_OK) != 0) 52898e903e7SBaptiste Daroussin tmpdir = "."; 52998e903e7SBaptiste Daroussin } 53098e903e7SBaptiste Daroussin 53198e903e7SBaptiste Daroussin name = malloc(strlen(tmpdir) + 10 + strlen(label)); 53298e903e7SBaptiste Daroussin 53398e903e7SBaptiste Daroussin result = 0; 53498e903e7SBaptiste Daroussin if (name != 0) 53598e903e7SBaptiste Daroussin { 53698e903e7SBaptiste Daroussin if ((mark = strrchr(label, '_')) == 0) 53798e903e7SBaptiste Daroussin mark = label + strlen(label); 53898e903e7SBaptiste Daroussin 53998e903e7SBaptiste Daroussin sprintf(name, "%s/%.*sXXXXXX", tmpdir, (int)(mark - label), label); 54098e903e7SBaptiste Daroussin fd = mkstemp(name); 54198e903e7SBaptiste Daroussin if (fd >= 0) 54298e903e7SBaptiste Daroussin { 54398e903e7SBaptiste Daroussin result = fdopen(fd, "w+"); 54498e903e7SBaptiste Daroussin if (result != 0) 54598e903e7SBaptiste Daroussin { 54698e903e7SBaptiste Daroussin MY_TMPFILES *item; 54798e903e7SBaptiste Daroussin 54898e903e7SBaptiste Daroussin if (my_tmpfiles == 0) 54998e903e7SBaptiste Daroussin { 55098e903e7SBaptiste Daroussin atexit(close_tmpfiles); 55198e903e7SBaptiste Daroussin } 55298e903e7SBaptiste Daroussin 55398e903e7SBaptiste Daroussin item = NEW(MY_TMPFILES); 55498e903e7SBaptiste Daroussin NO_SPACE(item); 55598e903e7SBaptiste Daroussin 55698e903e7SBaptiste Daroussin item->name = name; 55798e903e7SBaptiste Daroussin NO_SPACE(item->name); 55898e903e7SBaptiste Daroussin 55998e903e7SBaptiste Daroussin item->next = my_tmpfiles; 56098e903e7SBaptiste Daroussin my_tmpfiles = item; 56198e903e7SBaptiste Daroussin } 56298e903e7SBaptiste Daroussin } 56398e903e7SBaptiste Daroussin } 56498e903e7SBaptiste Daroussin #else 56598e903e7SBaptiste Daroussin result = tmpfile(); 56698e903e7SBaptiste Daroussin #endif 56798e903e7SBaptiste Daroussin 56898e903e7SBaptiste Daroussin if (result == 0) 56998e903e7SBaptiste Daroussin open_error(label); 57098e903e7SBaptiste Daroussin return result; 57198e903e7SBaptiste Daroussin } 57298e903e7SBaptiste Daroussin 57398e903e7SBaptiste Daroussin static void 57498e903e7SBaptiste Daroussin open_files(void) 57598e903e7SBaptiste Daroussin { 57698e903e7SBaptiste Daroussin create_file_names(); 57798e903e7SBaptiste Daroussin 57898e903e7SBaptiste Daroussin if (input_file == 0) 57998e903e7SBaptiste Daroussin { 58098e903e7SBaptiste Daroussin input_file = fopen(input_file_name, "r"); 58198e903e7SBaptiste Daroussin if (input_file == 0) 58298e903e7SBaptiste Daroussin open_error(input_file_name); 58398e903e7SBaptiste Daroussin } 58498e903e7SBaptiste Daroussin 58598e903e7SBaptiste Daroussin action_file = open_tmpfile("action_file"); 58698e903e7SBaptiste Daroussin text_file = open_tmpfile("text_file"); 58798e903e7SBaptiste Daroussin 58898e903e7SBaptiste Daroussin if (vflag) 58998e903e7SBaptiste Daroussin { 59098e903e7SBaptiste Daroussin verbose_file = fopen(verbose_file_name, "w"); 59198e903e7SBaptiste Daroussin if (verbose_file == 0) 59298e903e7SBaptiste Daroussin open_error(verbose_file_name); 59398e903e7SBaptiste Daroussin } 59498e903e7SBaptiste Daroussin 59598e903e7SBaptiste Daroussin if (gflag) 59698e903e7SBaptiste Daroussin { 59798e903e7SBaptiste Daroussin graph_file = fopen(graph_file_name, "w"); 59898e903e7SBaptiste Daroussin if (graph_file == 0) 59998e903e7SBaptiste Daroussin open_error(graph_file_name); 60098e903e7SBaptiste Daroussin fprintf(graph_file, "digraph %s {\n", file_prefix); 60198e903e7SBaptiste Daroussin fprintf(graph_file, "\tedge [fontsize=10];\n"); 60298e903e7SBaptiste Daroussin fprintf(graph_file, "\tnode [shape=box,fontsize=10];\n"); 60398e903e7SBaptiste Daroussin fprintf(graph_file, "\torientation=landscape;\n"); 60498e903e7SBaptiste Daroussin fprintf(graph_file, "\trankdir=LR;\n"); 60598e903e7SBaptiste Daroussin fprintf(graph_file, "\t/*\n"); 60698e903e7SBaptiste Daroussin fprintf(graph_file, "\tmargin=0.2;\n"); 60798e903e7SBaptiste Daroussin fprintf(graph_file, "\tpage=\"8.27,11.69\"; // for A4 printing\n"); 60898e903e7SBaptiste Daroussin fprintf(graph_file, "\tratio=auto;\n"); 60998e903e7SBaptiste Daroussin fprintf(graph_file, "\t*/\n"); 61098e903e7SBaptiste Daroussin } 61198e903e7SBaptiste Daroussin 61298e903e7SBaptiste Daroussin if (dflag) 61398e903e7SBaptiste Daroussin { 61498e903e7SBaptiste Daroussin defines_file = fopen(defines_file_name, "w"); 61598e903e7SBaptiste Daroussin if (defines_file == 0) 61698e903e7SBaptiste Daroussin open_error(defines_file_name); 61798e903e7SBaptiste Daroussin union_file = open_tmpfile("union_file"); 61898e903e7SBaptiste Daroussin } 61998e903e7SBaptiste Daroussin 62098e903e7SBaptiste Daroussin if (iflag) 62198e903e7SBaptiste Daroussin { 62298e903e7SBaptiste Daroussin externs_file = fopen(externs_file_name, "w"); 62398e903e7SBaptiste Daroussin if (externs_file == 0) 62498e903e7SBaptiste Daroussin open_error(externs_file_name); 62598e903e7SBaptiste Daroussin } 62698e903e7SBaptiste Daroussin 62798e903e7SBaptiste Daroussin output_file = fopen(output_file_name, "w"); 62898e903e7SBaptiste Daroussin if (output_file == 0) 62998e903e7SBaptiste Daroussin open_error(output_file_name); 63098e903e7SBaptiste Daroussin 63198e903e7SBaptiste Daroussin if (rflag) 63298e903e7SBaptiste Daroussin { 63398e903e7SBaptiste Daroussin code_file = fopen(code_file_name, "w"); 63498e903e7SBaptiste Daroussin if (code_file == 0) 63598e903e7SBaptiste Daroussin open_error(code_file_name); 63698e903e7SBaptiste Daroussin } 63798e903e7SBaptiste Daroussin else 63898e903e7SBaptiste Daroussin code_file = output_file; 63998e903e7SBaptiste Daroussin } 64098e903e7SBaptiste Daroussin 64198e903e7SBaptiste Daroussin int 64298e903e7SBaptiste Daroussin main(int argc, char *argv[]) 64398e903e7SBaptiste Daroussin { 64498e903e7SBaptiste Daroussin SRexpect = -1; 64598e903e7SBaptiste Daroussin RRexpect = -1; 64698e903e7SBaptiste Daroussin exit_code = EXIT_SUCCESS; 64798e903e7SBaptiste Daroussin 64898e903e7SBaptiste Daroussin set_signals(); 64998e903e7SBaptiste Daroussin getargs(argc, argv); 65098e903e7SBaptiste Daroussin open_files(); 65198e903e7SBaptiste Daroussin reader(); 65298e903e7SBaptiste Daroussin lr0(); 65398e903e7SBaptiste Daroussin lalr(); 65498e903e7SBaptiste Daroussin make_parser(); 65598e903e7SBaptiste Daroussin graph(); 65698e903e7SBaptiste Daroussin finalize_closure(); 65798e903e7SBaptiste Daroussin verbose(); 65898e903e7SBaptiste Daroussin output(); 65998e903e7SBaptiste Daroussin done(exit_code); 66098e903e7SBaptiste Daroussin /*NOTREACHED */ 66198e903e7SBaptiste Daroussin } 662