1268899Sbapt/* $Id: main.c,v 1.50 2014/04/22 23:34:47 tom Exp $ */ 2234949Sbapt 3234949Sbapt#include <signal.h> 4268899Sbapt#ifndef _WIN32 5234949Sbapt#include <unistd.h> /* for _exit() */ 6268899Sbapt#else 7268899Sbapt#include <stdlib.h> /* for _exit() */ 8268899Sbapt#endif 9234949Sbapt 10234949Sbapt#include "defs.h" 11234949Sbapt 12251143Sbapt#ifdef HAVE_MKSTEMP 13251143Sbapt# define USE_MKSTEMP 1 14251143Sbapt#elif defined(HAVE_FCNTL_H) 15251143Sbapt# define USE_MKSTEMP 1 16251143Sbapt# include <fcntl.h> /* for open(), O_EXCL, etc. */ 17234949Sbapt#else 18234949Sbapt# define USE_MKSTEMP 0 19234949Sbapt#endif 20234949Sbapt 21234949Sbapt#if USE_MKSTEMP 22234949Sbapt#include <sys/types.h> 23234949Sbapt#include <sys/stat.h> 24234949Sbapt 25234949Sbapttypedef struct _my_tmpfiles 26234949Sbapt{ 27234949Sbapt struct _my_tmpfiles *next; 28234949Sbapt char *name; 29234949Sbapt} 30234949SbaptMY_TMPFILES; 31234949Sbapt 32234949Sbaptstatic MY_TMPFILES *my_tmpfiles; 33234949Sbapt#endif /* USE_MKSTEMP */ 34234949Sbapt 35234949Sbaptchar dflag; 36234949Sbaptchar gflag; 37234949Sbaptchar iflag; 38234949Sbaptchar lflag; 39234949Sbaptstatic char oflag; 40234949Sbaptchar rflag; 41234949Sbaptchar sflag; 42234949Sbaptchar tflag; 43234949Sbaptchar vflag; 44234949Sbapt 45234949Sbaptconst char *symbol_prefix; 46234949Sbaptconst char *myname = "yacc"; 47234949Sbapt 48234949Sbaptint lineno; 49234949Sbaptint outline; 50234949Sbapt 51234949Sbaptstatic char empty_string[] = ""; 52234949Sbaptstatic char default_file_prefix[] = "y"; 53234949Sbapt 54234949Sbaptstatic char *file_prefix = default_file_prefix; 55234949Sbapt 56234949Sbaptchar *code_file_name; 57234949Sbaptchar *input_file_name = empty_string; 58234949Sbaptchar *defines_file_name; 59234949Sbaptchar *externs_file_name; 60234949Sbapt 61234949Sbaptstatic char *graph_file_name; 62234949Sbaptstatic char *output_file_name; 63234949Sbaptstatic char *verbose_file_name; 64234949Sbapt 65234949SbaptFILE *action_file; /* a temp file, used to save actions associated */ 66234949Sbapt /* with rules until the parser is written */ 67234949SbaptFILE *code_file; /* y.code.c (used when the -r option is specified) */ 68234949SbaptFILE *defines_file; /* y.tab.h */ 69234949SbaptFILE *externs_file; /* y.tab.i */ 70234949SbaptFILE *input_file; /* the input file */ 71234949SbaptFILE *output_file; /* y.tab.c */ 72234949SbaptFILE *text_file; /* a temp file, used to save text until all */ 73234949Sbapt /* symbols have been defined */ 74234949SbaptFILE *union_file; /* a temp file, used to save the union */ 75234949Sbapt /* definition until all symbol have been */ 76234949Sbapt /* defined */ 77234949SbaptFILE *verbose_file; /* y.output */ 78234949SbaptFILE *graph_file; /* y.dot */ 79234949Sbapt 80268899SbaptValue_t nitems; 81268899SbaptValue_t nrules; 82268899SbaptValue_t nsyms; 83268899SbaptValue_t ntokens; 84268899SbaptValue_t nvars; 85234949Sbapt 86234949SbaptValue_t start_symbol; 87234949Sbaptchar **symbol_name; 88234949Sbaptchar **symbol_pname; 89234949SbaptValue_t *symbol_value; 90268899SbaptValue_t *symbol_prec; 91234949Sbaptchar *symbol_assoc; 92234949Sbapt 93234949Sbaptint pure_parser; 94268899Sbaptint token_table; 95268899Sbapt 96268899Sbapt#if defined(YYBTYACC) 97268899SbaptValue_t *symbol_pval; 98268899Sbaptchar **symbol_destructor; 99268899Sbaptchar **symbol_type_tag; 100268899Sbaptint locations = 0; /* default to no position processing */ 101268899Sbaptint backtrack = 0; /* default is no backtracking */ 102268899Sbapt#endif 103268899Sbapt 104234949Sbaptint exit_code; 105234949Sbapt 106234949SbaptValue_t *ritem; 107234949SbaptValue_t *rlhs; 108234949SbaptValue_t *rrhs; 109234949SbaptValue_t *rprec; 110234949SbaptAssoc_t *rassoc; 111234949SbaptValue_t **derives; 112234949Sbaptchar *nullable; 113234949Sbapt 114234949Sbapt/* 115234949Sbapt * Since fclose() is called via the signal handler, it might die. Don't loop 116234949Sbapt * if there is a problem closing a file. 117234949Sbapt */ 118234949Sbapt#define DO_CLOSE(fp) \ 119234949Sbapt if (fp != 0) { \ 120234949Sbapt FILE *use = fp; \ 121234949Sbapt fp = 0; \ 122234949Sbapt fclose(use); \ 123234949Sbapt } 124234949Sbapt 125234949Sbaptstatic int got_intr = 0; 126234949Sbapt 127234949Sbaptvoid 128234949Sbaptdone(int k) 129234949Sbapt{ 130234949Sbapt DO_CLOSE(input_file); 131234949Sbapt DO_CLOSE(output_file); 132268899Sbapt if (iflag) 133268899Sbapt DO_CLOSE(externs_file); 134268899Sbapt if (rflag) 135268899Sbapt DO_CLOSE(code_file); 136234949Sbapt 137234949Sbapt DO_CLOSE(action_file); 138234949Sbapt DO_CLOSE(defines_file); 139234949Sbapt DO_CLOSE(graph_file); 140234949Sbapt DO_CLOSE(text_file); 141234949Sbapt DO_CLOSE(union_file); 142234949Sbapt DO_CLOSE(verbose_file); 143234949Sbapt 144234949Sbapt if (got_intr) 145234949Sbapt _exit(EXIT_FAILURE); 146234949Sbapt 147234949Sbapt#ifdef NO_LEAKS 148234949Sbapt if (rflag) 149234949Sbapt DO_FREE(code_file_name); 150234949Sbapt 151234949Sbapt if (dflag) 152234949Sbapt DO_FREE(defines_file_name); 153234949Sbapt 154234949Sbapt if (iflag) 155234949Sbapt DO_FREE(externs_file_name); 156234949Sbapt 157234949Sbapt if (oflag) 158234949Sbapt DO_FREE(output_file_name); 159234949Sbapt 160234949Sbapt if (vflag) 161234949Sbapt DO_FREE(verbose_file_name); 162234949Sbapt 163234949Sbapt if (gflag) 164234949Sbapt DO_FREE(graph_file_name); 165234949Sbapt 166234949Sbapt lr0_leaks(); 167234949Sbapt lalr_leaks(); 168234949Sbapt mkpar_leaks(); 169268899Sbapt mstring_leaks(); 170234949Sbapt output_leaks(); 171234949Sbapt reader_leaks(); 172234949Sbapt#endif 173234949Sbapt 174234949Sbapt exit(k); 175234949Sbapt} 176234949Sbapt 177234949Sbaptstatic void 178240517Sbaptonintr(int sig GCC_UNUSED) 179234949Sbapt{ 180234949Sbapt got_intr = 1; 181234949Sbapt done(EXIT_FAILURE); 182234949Sbapt} 183234949Sbapt 184234949Sbaptstatic void 185234949Sbaptset_signals(void) 186234949Sbapt{ 187234949Sbapt#ifdef SIGINT 188234949Sbapt if (signal(SIGINT, SIG_IGN) != SIG_IGN) 189234949Sbapt signal(SIGINT, onintr); 190234949Sbapt#endif 191234949Sbapt#ifdef SIGTERM 192234949Sbapt if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 193234949Sbapt signal(SIGTERM, onintr); 194234949Sbapt#endif 195234949Sbapt#ifdef SIGHUP 196234949Sbapt if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 197234949Sbapt signal(SIGHUP, onintr); 198234949Sbapt#endif 199234949Sbapt} 200234949Sbapt 201234949Sbaptstatic void 202234949Sbaptusage(void) 203234949Sbapt{ 204234949Sbapt static const char *msg[] = 205234949Sbapt { 206234949Sbapt "" 207234949Sbapt ,"Options:" 208234949Sbapt ," -b file_prefix set filename prefix (default \"y.\")" 209268899Sbapt ," -B create a backtracking parser" 210268899Sbapt ," -d write definitions (" DEFINES_SUFFIX ")" 211268899Sbapt ," -D enable value stack memory reclamation" 212234949Sbapt ," -i write interface (y.tab.i)" 213234949Sbapt ," -g write a graphical description" 214234949Sbapt ," -l suppress #line directives" 215268899Sbapt ," -L enable position processing, e.g., \"%locations\"" 216268899Sbapt ," -o output_file (default \"" OUTPUT_SUFFIX "\")" 217234949Sbapt ," -p symbol_prefix set symbol prefix (default \"yy\")" 218234949Sbapt ," -P create a reentrant parser, e.g., \"%pure-parser\"" 219234949Sbapt ," -r produce separate code and table files (y.code.c)" 220234949Sbapt ," -s suppress #define's for quoted names in %token lines" 221234949Sbapt ," -t add debugging support" 222234949Sbapt ," -v write description (y.output)" 223234949Sbapt ," -V show version information and exit" 224234949Sbapt }; 225234949Sbapt unsigned n; 226234949Sbapt 227234949Sbapt fflush(stdout); 228234949Sbapt fprintf(stderr, "Usage: %s [options] filename\n", myname); 229234949Sbapt for (n = 0; n < sizeof(msg) / sizeof(msg[0]); ++n) 230234949Sbapt fprintf(stderr, "%s\n", msg[n]); 231234949Sbapt 232234949Sbapt exit(1); 233234949Sbapt} 234234949Sbapt 235234949Sbaptstatic void 236234949Sbaptsetflag(int ch) 237234949Sbapt{ 238234949Sbapt switch (ch) 239234949Sbapt { 240268899Sbapt case 'B': 241268899Sbapt#if defined(YYBTYACC) 242268899Sbapt backtrack = 1; 243268899Sbapt#else 244268899Sbapt unsupported_flag_warning("-B", "reconfigure with --enable-btyacc"); 245268899Sbapt#endif 246268899Sbapt break; 247268899Sbapt 248234949Sbapt case 'd': 249234949Sbapt dflag = 1; 250234949Sbapt break; 251234949Sbapt 252234949Sbapt case 'g': 253234949Sbapt gflag = 1; 254234949Sbapt break; 255234949Sbapt 256234949Sbapt case 'i': 257234949Sbapt iflag = 1; 258234949Sbapt break; 259234949Sbapt 260234949Sbapt case 'l': 261234949Sbapt lflag = 1; 262234949Sbapt break; 263234949Sbapt 264268899Sbapt case 'L': 265268899Sbapt#if defined(YYBTYACC) 266268899Sbapt locations = 1; 267268899Sbapt#else 268268899Sbapt unsupported_flag_warning("-B", "reconfigure with --enable-btyacc"); 269268899Sbapt#endif 270268899Sbapt break; 271268899Sbapt 272234949Sbapt case 'P': 273234949Sbapt pure_parser = 1; 274234949Sbapt break; 275234949Sbapt 276234949Sbapt case 'r': 277234949Sbapt rflag = 1; 278234949Sbapt break; 279234949Sbapt 280234949Sbapt case 's': 281234949Sbapt sflag = 1; 282234949Sbapt break; 283234949Sbapt 284234949Sbapt case 't': 285234949Sbapt tflag = 1; 286234949Sbapt break; 287234949Sbapt 288234949Sbapt case 'v': 289234949Sbapt vflag = 1; 290234949Sbapt break; 291234949Sbapt 292234949Sbapt case 'V': 293234949Sbapt printf("%s - %s\n", myname, VERSION); 294234949Sbapt exit(EXIT_SUCCESS); 295234949Sbapt 296234949Sbapt case 'y': 297234949Sbapt /* noop for bison compatibility. byacc is already designed to be posix 298234949Sbapt * yacc compatible. */ 299234949Sbapt break; 300234949Sbapt 301234949Sbapt default: 302234949Sbapt usage(); 303234949Sbapt } 304234949Sbapt} 305234949Sbapt 306234949Sbaptstatic void 307234949Sbaptgetargs(int argc, char *argv[]) 308234949Sbapt{ 309234949Sbapt int i; 310234949Sbapt char *s; 311234949Sbapt int ch; 312234949Sbapt 313234949Sbapt if (argc > 0) 314234949Sbapt myname = argv[0]; 315234949Sbapt 316234949Sbapt for (i = 1; i < argc; ++i) 317234949Sbapt { 318234949Sbapt s = argv[i]; 319234949Sbapt if (*s != '-') 320234949Sbapt break; 321234949Sbapt switch (ch = *++s) 322234949Sbapt { 323234949Sbapt case '\0': 324234949Sbapt input_file = stdin; 325234949Sbapt if (i + 1 < argc) 326234949Sbapt usage(); 327234949Sbapt return; 328234949Sbapt 329234949Sbapt case '-': 330234949Sbapt ++i; 331234949Sbapt goto no_more_options; 332234949Sbapt 333234949Sbapt case 'b': 334234949Sbapt if (*++s) 335234949Sbapt file_prefix = s; 336234949Sbapt else if (++i < argc) 337234949Sbapt file_prefix = argv[i]; 338234949Sbapt else 339234949Sbapt usage(); 340234949Sbapt continue; 341234949Sbapt 342234949Sbapt case 'o': 343234949Sbapt if (*++s) 344234949Sbapt output_file_name = s; 345234949Sbapt else if (++i < argc) 346234949Sbapt output_file_name = argv[i]; 347234949Sbapt else 348234949Sbapt usage(); 349234949Sbapt continue; 350234949Sbapt 351234949Sbapt case 'p': 352234949Sbapt if (*++s) 353234949Sbapt symbol_prefix = s; 354234949Sbapt else if (++i < argc) 355234949Sbapt symbol_prefix = argv[i]; 356234949Sbapt else 357234949Sbapt usage(); 358234949Sbapt continue; 359234949Sbapt 360234949Sbapt default: 361234949Sbapt setflag(ch); 362234949Sbapt break; 363234949Sbapt } 364234949Sbapt 365234949Sbapt for (;;) 366234949Sbapt { 367234949Sbapt switch (ch = *++s) 368234949Sbapt { 369234949Sbapt case '\0': 370234949Sbapt goto end_of_option; 371234949Sbapt 372234949Sbapt default: 373234949Sbapt setflag(ch); 374234949Sbapt break; 375234949Sbapt } 376234949Sbapt } 377234949Sbapt end_of_option:; 378234949Sbapt } 379234949Sbapt 380234949Sbapt no_more_options:; 381234949Sbapt if (i + 1 != argc) 382234949Sbapt usage(); 383234949Sbapt input_file_name = argv[i]; 384234949Sbapt} 385234949Sbapt 386234949Sbaptvoid * 387234949Sbaptallocate(size_t n) 388234949Sbapt{ 389234949Sbapt void *p; 390234949Sbapt 391234949Sbapt p = NULL; 392234949Sbapt if (n) 393234949Sbapt { 394234949Sbapt p = CALLOC(1, n); 395234949Sbapt NO_SPACE(p); 396234949Sbapt } 397234949Sbapt return (p); 398234949Sbapt} 399234949Sbapt 400234949Sbapt#define CREATE_FILE_NAME(dest, suffix) \ 401268899Sbapt dest = alloc_file_name(len, suffix) 402234949Sbapt 403268899Sbaptstatic char * 404268899Sbaptalloc_file_name(size_t len, const char *suffix) 405268899Sbapt{ 406268899Sbapt char *result = TMALLOC(char, len + strlen(suffix) + 1); 407268899Sbapt if (result == 0) 408268899Sbapt no_space(); 409268899Sbapt strcpy(result, file_prefix); 410268899Sbapt strcpy(result + len, suffix); 411268899Sbapt return result; 412268899Sbapt} 413268899Sbapt 414234949Sbaptstatic void 415234949Sbaptcreate_file_names(void) 416234949Sbapt{ 417234949Sbapt size_t len; 418234949Sbapt const char *defines_suffix; 419234949Sbapt const char *externs_suffix; 420234949Sbapt char *prefix; 421234949Sbapt 422234949Sbapt prefix = NULL; 423234949Sbapt defines_suffix = DEFINES_SUFFIX; 424234949Sbapt externs_suffix = EXTERNS_SUFFIX; 425234949Sbapt 426234949Sbapt /* compute the file_prefix from the user provided output_file_name */ 427234949Sbapt if (output_file_name != 0) 428234949Sbapt { 429268899Sbapt if (!(prefix = strstr(output_file_name, OUTPUT_SUFFIX)) 430234949Sbapt && (prefix = strstr(output_file_name, ".c"))) 431234949Sbapt { 432234949Sbapt defines_suffix = ".h"; 433234949Sbapt externs_suffix = ".i"; 434234949Sbapt } 435234949Sbapt } 436234949Sbapt 437234949Sbapt if (prefix != NULL) 438234949Sbapt { 439234949Sbapt len = (size_t) (prefix - output_file_name); 440240517Sbapt file_prefix = TMALLOC(char, len + 1); 441234949Sbapt NO_SPACE(file_prefix); 442234949Sbapt strncpy(file_prefix, output_file_name, len)[len] = 0; 443234949Sbapt } 444234949Sbapt else 445234949Sbapt len = strlen(file_prefix); 446234949Sbapt 447234949Sbapt /* if "-o filename" was not given */ 448234949Sbapt if (output_file_name == 0) 449234949Sbapt { 450234949Sbapt oflag = 1; 451234949Sbapt CREATE_FILE_NAME(output_file_name, OUTPUT_SUFFIX); 452234949Sbapt } 453234949Sbapt 454234949Sbapt if (rflag) 455234949Sbapt { 456234949Sbapt CREATE_FILE_NAME(code_file_name, CODE_SUFFIX); 457234949Sbapt } 458234949Sbapt else 459234949Sbapt code_file_name = output_file_name; 460234949Sbapt 461234949Sbapt if (dflag) 462234949Sbapt { 463234949Sbapt CREATE_FILE_NAME(defines_file_name, defines_suffix); 464234949Sbapt } 465234949Sbapt 466234949Sbapt if (iflag) 467234949Sbapt { 468234949Sbapt CREATE_FILE_NAME(externs_file_name, externs_suffix); 469234949Sbapt } 470234949Sbapt 471234949Sbapt if (vflag) 472234949Sbapt { 473234949Sbapt CREATE_FILE_NAME(verbose_file_name, VERBOSE_SUFFIX); 474234949Sbapt } 475234949Sbapt 476234949Sbapt if (gflag) 477234949Sbapt { 478234949Sbapt CREATE_FILE_NAME(graph_file_name, GRAPH_SUFFIX); 479234949Sbapt } 480234949Sbapt 481234949Sbapt if (prefix != NULL) 482234949Sbapt { 483234949Sbapt FREE(file_prefix); 484234949Sbapt } 485234949Sbapt} 486234949Sbapt 487234949Sbapt#if USE_MKSTEMP 488234949Sbaptstatic void 489234949Sbaptclose_tmpfiles(void) 490234949Sbapt{ 491234949Sbapt while (my_tmpfiles != 0) 492234949Sbapt { 493234949Sbapt MY_TMPFILES *next = my_tmpfiles->next; 494234949Sbapt 495234949Sbapt chmod(my_tmpfiles->name, 0644); 496234949Sbapt unlink(my_tmpfiles->name); 497234949Sbapt 498234949Sbapt free(my_tmpfiles->name); 499234949Sbapt free(my_tmpfiles); 500234949Sbapt 501234949Sbapt my_tmpfiles = next; 502234949Sbapt } 503234949Sbapt} 504234949Sbapt 505234949Sbapt#ifndef HAVE_MKSTEMP 506234949Sbaptstatic int 507234949Sbaptmy_mkstemp(char *temp) 508234949Sbapt{ 509234949Sbapt int fd; 510234949Sbapt char *dname; 511234949Sbapt char *fname; 512234949Sbapt char *name; 513234949Sbapt 514234949Sbapt /* 515234949Sbapt * Split-up to use tempnam, rather than tmpnam; the latter (like 516234949Sbapt * mkstemp) is unusable on Windows. 517234949Sbapt */ 518234949Sbapt if ((fname = strrchr(temp, '/')) != 0) 519234949Sbapt { 520234949Sbapt dname = strdup(temp); 521234949Sbapt dname[++fname - temp] = '\0'; 522234949Sbapt } 523234949Sbapt else 524234949Sbapt { 525234949Sbapt dname = 0; 526234949Sbapt fname = temp; 527234949Sbapt } 528234949Sbapt if ((name = tempnam(dname, fname)) != 0) 529234949Sbapt { 530234949Sbapt fd = open(name, O_CREAT | O_EXCL | O_RDWR); 531234949Sbapt strcpy(temp, name); 532234949Sbapt } 533234949Sbapt else 534234949Sbapt { 535234949Sbapt fd = -1; 536234949Sbapt } 537234949Sbapt 538234949Sbapt if (dname != 0) 539234949Sbapt free(dname); 540234949Sbapt 541234949Sbapt return fd; 542234949Sbapt} 543234949Sbapt#define mkstemp(s) my_mkstemp(s) 544234949Sbapt#endif 545234949Sbapt 546234949Sbapt#endif 547234949Sbapt 548234949Sbapt/* 549234949Sbapt * tmpfile() should be adequate, except that it may require special privileges 550234949Sbapt * to use, e.g., MinGW and Windows 7 where it tries to use the root directory. 551234949Sbapt */ 552234949Sbaptstatic FILE * 553234949Sbaptopen_tmpfile(const char *label) 554234949Sbapt{ 555234949Sbapt FILE *result; 556234949Sbapt#if USE_MKSTEMP 557234949Sbapt int fd; 558234949Sbapt const char *tmpdir; 559234949Sbapt char *name; 560234949Sbapt const char *mark; 561234949Sbapt 562234949Sbapt if ((tmpdir = getenv("TMPDIR")) == 0 || access(tmpdir, W_OK) != 0) 563234949Sbapt { 564234949Sbapt#ifdef P_tmpdir 565234949Sbapt tmpdir = P_tmpdir; 566234949Sbapt#else 567234949Sbapt tmpdir = "/tmp"; 568234949Sbapt#endif 569234949Sbapt if (access(tmpdir, W_OK) != 0) 570234949Sbapt tmpdir = "."; 571234949Sbapt } 572234949Sbapt 573234949Sbapt name = malloc(strlen(tmpdir) + 10 + strlen(label)); 574234949Sbapt 575234949Sbapt result = 0; 576234949Sbapt if (name != 0) 577234949Sbapt { 578234949Sbapt if ((mark = strrchr(label, '_')) == 0) 579234949Sbapt mark = label + strlen(label); 580234949Sbapt 581234949Sbapt sprintf(name, "%s/%.*sXXXXXX", tmpdir, (int)(mark - label), label); 582234949Sbapt fd = mkstemp(name); 583234949Sbapt if (fd >= 0) 584234949Sbapt { 585234949Sbapt result = fdopen(fd, "w+"); 586234949Sbapt if (result != 0) 587234949Sbapt { 588234949Sbapt MY_TMPFILES *item; 589234949Sbapt 590234949Sbapt if (my_tmpfiles == 0) 591234949Sbapt { 592234949Sbapt atexit(close_tmpfiles); 593234949Sbapt } 594234949Sbapt 595234949Sbapt item = NEW(MY_TMPFILES); 596234949Sbapt NO_SPACE(item); 597234949Sbapt 598234949Sbapt item->name = name; 599234949Sbapt NO_SPACE(item->name); 600234949Sbapt 601234949Sbapt item->next = my_tmpfiles; 602234949Sbapt my_tmpfiles = item; 603234949Sbapt } 604234949Sbapt } 605234949Sbapt } 606234949Sbapt#else 607234949Sbapt result = tmpfile(); 608234949Sbapt#endif 609234949Sbapt 610234949Sbapt if (result == 0) 611234949Sbapt open_error(label); 612234949Sbapt return result; 613234949Sbapt} 614234949Sbapt 615234949Sbaptstatic void 616234949Sbaptopen_files(void) 617234949Sbapt{ 618234949Sbapt create_file_names(); 619234949Sbapt 620234949Sbapt if (input_file == 0) 621234949Sbapt { 622234949Sbapt input_file = fopen(input_file_name, "r"); 623234949Sbapt if (input_file == 0) 624234949Sbapt open_error(input_file_name); 625234949Sbapt } 626234949Sbapt 627234949Sbapt action_file = open_tmpfile("action_file"); 628234949Sbapt text_file = open_tmpfile("text_file"); 629234949Sbapt 630234949Sbapt if (vflag) 631234949Sbapt { 632234949Sbapt verbose_file = fopen(verbose_file_name, "w"); 633234949Sbapt if (verbose_file == 0) 634234949Sbapt open_error(verbose_file_name); 635234949Sbapt } 636234949Sbapt 637234949Sbapt if (gflag) 638234949Sbapt { 639234949Sbapt graph_file = fopen(graph_file_name, "w"); 640234949Sbapt if (graph_file == 0) 641234949Sbapt open_error(graph_file_name); 642234949Sbapt fprintf(graph_file, "digraph %s {\n", file_prefix); 643234949Sbapt fprintf(graph_file, "\tedge [fontsize=10];\n"); 644234949Sbapt fprintf(graph_file, "\tnode [shape=box,fontsize=10];\n"); 645234949Sbapt fprintf(graph_file, "\torientation=landscape;\n"); 646234949Sbapt fprintf(graph_file, "\trankdir=LR;\n"); 647234949Sbapt fprintf(graph_file, "\t/*\n"); 648234949Sbapt fprintf(graph_file, "\tmargin=0.2;\n"); 649234949Sbapt fprintf(graph_file, "\tpage=\"8.27,11.69\"; // for A4 printing\n"); 650234949Sbapt fprintf(graph_file, "\tratio=auto;\n"); 651234949Sbapt fprintf(graph_file, "\t*/\n"); 652234949Sbapt } 653234949Sbapt 654234949Sbapt if (dflag) 655234949Sbapt { 656234949Sbapt defines_file = fopen(defines_file_name, "w"); 657234949Sbapt if (defines_file == 0) 658234949Sbapt open_error(defines_file_name); 659234949Sbapt union_file = open_tmpfile("union_file"); 660234949Sbapt } 661234949Sbapt 662234949Sbapt if (iflag) 663234949Sbapt { 664234949Sbapt externs_file = fopen(externs_file_name, "w"); 665234949Sbapt if (externs_file == 0) 666234949Sbapt open_error(externs_file_name); 667234949Sbapt } 668234949Sbapt 669234949Sbapt output_file = fopen(output_file_name, "w"); 670234949Sbapt if (output_file == 0) 671234949Sbapt open_error(output_file_name); 672234949Sbapt 673234949Sbapt if (rflag) 674234949Sbapt { 675234949Sbapt code_file = fopen(code_file_name, "w"); 676234949Sbapt if (code_file == 0) 677234949Sbapt open_error(code_file_name); 678234949Sbapt } 679234949Sbapt else 680234949Sbapt code_file = output_file; 681234949Sbapt} 682234949Sbapt 683234949Sbaptint 684234949Sbaptmain(int argc, char *argv[]) 685234949Sbapt{ 686234949Sbapt SRexpect = -1; 687234949Sbapt RRexpect = -1; 688234949Sbapt exit_code = EXIT_SUCCESS; 689234949Sbapt 690234949Sbapt set_signals(); 691234949Sbapt getargs(argc, argv); 692234949Sbapt open_files(); 693234949Sbapt reader(); 694234949Sbapt lr0(); 695234949Sbapt lalr(); 696234949Sbapt make_parser(); 697234949Sbapt graph(); 698234949Sbapt finalize_closure(); 699234949Sbapt verbose(); 700234949Sbapt output(); 701234949Sbapt done(exit_code); 702234949Sbapt /*NOTREACHED */ 703234949Sbapt} 704