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