main.c revision 272769
1272769Sbapt/* $Id: main.c,v 1.54 2014/10/06 22:40:07 tom Exp $ */ 2234949Sbapt 3234949Sbapt#include <signal.h> 4264803Sbapt#ifndef _WIN32 5234949Sbapt#include <unistd.h> /* for _exit() */ 6264803Sbapt#else 7264803Sbapt#include <stdlib.h> /* for _exit() */ 8264803Sbapt#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 80264803SbaptValue_t nitems; 81264803SbaptValue_t nrules; 82264803SbaptValue_t nsyms; 83264803SbaptValue_t ntokens; 84264803SbaptValue_t nvars; 85234949Sbapt 86234949SbaptValue_t start_symbol; 87234949Sbaptchar **symbol_name; 88234949Sbaptchar **symbol_pname; 89234949SbaptValue_t *symbol_value; 90264803SbaptValue_t *symbol_prec; 91234949Sbaptchar *symbol_assoc; 92234949Sbapt 93234949Sbaptint pure_parser; 94260445Sbaptint token_table; 95264803Sbapt 96264803Sbapt#if defined(YYBTYACC) 97264803SbaptValue_t *symbol_pval; 98264803Sbaptchar **symbol_destructor; 99264803Sbaptchar **symbol_type_tag; 100264803Sbaptint locations = 0; /* default to no position processing */ 101264803Sbaptint backtrack = 0; /* default is no backtracking */ 102264803Sbapt#endif 103264803Sbapt 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); 132264803Sbapt if (iflag) 133264803Sbapt DO_CLOSE(externs_file); 134264803Sbapt if (rflag) 135264803Sbapt 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(); 169266639Sbapt 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.\")" 209264803Sbapt ," -B create a backtracking parser" 210264803Sbapt ," -d write definitions (" DEFINES_SUFFIX ")" 211234949Sbapt ," -i write interface (y.tab.i)" 212234949Sbapt ," -g write a graphical description" 213234949Sbapt ," -l suppress #line directives" 214264803Sbapt ," -L enable position processing, e.g., \"%locations\"" 215264803Sbapt ," -o output_file (default \"" OUTPUT_SUFFIX "\")" 216234949Sbapt ," -p symbol_prefix set symbol prefix (default \"yy\")" 217234949Sbapt ," -P create a reentrant parser, e.g., \"%pure-parser\"" 218234949Sbapt ," -r produce separate code and table files (y.code.c)" 219234949Sbapt ," -s suppress #define's for quoted names in %token lines" 220234949Sbapt ," -t add debugging support" 221234949Sbapt ," -v write description (y.output)" 222234949Sbapt ," -V show version information and exit" 223234949Sbapt }; 224234949Sbapt unsigned n; 225234949Sbapt 226234949Sbapt fflush(stdout); 227234949Sbapt fprintf(stderr, "Usage: %s [options] filename\n", myname); 228234949Sbapt for (n = 0; n < sizeof(msg) / sizeof(msg[0]); ++n) 229234949Sbapt fprintf(stderr, "%s\n", msg[n]); 230234949Sbapt 231234949Sbapt exit(1); 232234949Sbapt} 233234949Sbapt 234234949Sbaptstatic void 235234949Sbaptsetflag(int ch) 236234949Sbapt{ 237234949Sbapt switch (ch) 238234949Sbapt { 239264803Sbapt case 'B': 240264803Sbapt#if defined(YYBTYACC) 241264803Sbapt backtrack = 1; 242264803Sbapt#else 243264803Sbapt unsupported_flag_warning("-B", "reconfigure with --enable-btyacc"); 244264803Sbapt#endif 245264803Sbapt break; 246264803Sbapt 247234949Sbapt case 'd': 248234949Sbapt dflag = 1; 249234949Sbapt break; 250234949Sbapt 251234949Sbapt case 'g': 252234949Sbapt gflag = 1; 253234949Sbapt break; 254234949Sbapt 255234949Sbapt case 'i': 256234949Sbapt iflag = 1; 257234949Sbapt break; 258234949Sbapt 259234949Sbapt case 'l': 260234949Sbapt lflag = 1; 261234949Sbapt break; 262234949Sbapt 263264803Sbapt case 'L': 264264803Sbapt#if defined(YYBTYACC) 265264803Sbapt locations = 1; 266264803Sbapt#else 267264803Sbapt unsupported_flag_warning("-B", "reconfigure with --enable-btyacc"); 268264803Sbapt#endif 269264803Sbapt break; 270264803Sbapt 271234949Sbapt case 'P': 272234949Sbapt pure_parser = 1; 273234949Sbapt break; 274234949Sbapt 275234949Sbapt case 'r': 276234949Sbapt rflag = 1; 277234949Sbapt break; 278234949Sbapt 279234949Sbapt case 's': 280234949Sbapt sflag = 1; 281234949Sbapt break; 282234949Sbapt 283234949Sbapt case 't': 284234949Sbapt tflag = 1; 285234949Sbapt break; 286234949Sbapt 287234949Sbapt case 'v': 288234949Sbapt vflag = 1; 289234949Sbapt break; 290234949Sbapt 291234949Sbapt case 'V': 292234949Sbapt printf("%s - %s\n", myname, VERSION); 293234949Sbapt exit(EXIT_SUCCESS); 294234949Sbapt 295234949Sbapt case 'y': 296234949Sbapt /* noop for bison compatibility. byacc is already designed to be posix 297234949Sbapt * yacc compatible. */ 298234949Sbapt break; 299234949Sbapt 300234949Sbapt default: 301234949Sbapt usage(); 302234949Sbapt } 303234949Sbapt} 304234949Sbapt 305234949Sbaptstatic void 306234949Sbaptgetargs(int argc, char *argv[]) 307234949Sbapt{ 308234949Sbapt int i; 309234949Sbapt char *s; 310234949Sbapt int ch; 311234949Sbapt 312234949Sbapt if (argc > 0) 313234949Sbapt myname = argv[0]; 314234949Sbapt 315234949Sbapt for (i = 1; i < argc; ++i) 316234949Sbapt { 317234949Sbapt s = argv[i]; 318234949Sbapt if (*s != '-') 319234949Sbapt break; 320234949Sbapt switch (ch = *++s) 321234949Sbapt { 322234949Sbapt case '\0': 323234949Sbapt input_file = stdin; 324234949Sbapt if (i + 1 < argc) 325234949Sbapt usage(); 326234949Sbapt return; 327234949Sbapt 328234949Sbapt case '-': 329234949Sbapt ++i; 330234949Sbapt goto no_more_options; 331234949Sbapt 332234949Sbapt case 'b': 333234949Sbapt if (*++s) 334234949Sbapt file_prefix = s; 335234949Sbapt else if (++i < argc) 336234949Sbapt file_prefix = argv[i]; 337234949Sbapt else 338234949Sbapt usage(); 339234949Sbapt continue; 340234949Sbapt 341234949Sbapt case 'o': 342234949Sbapt if (*++s) 343234949Sbapt output_file_name = s; 344234949Sbapt else if (++i < argc) 345234949Sbapt output_file_name = argv[i]; 346234949Sbapt else 347234949Sbapt usage(); 348234949Sbapt continue; 349234949Sbapt 350234949Sbapt case 'p': 351234949Sbapt if (*++s) 352234949Sbapt symbol_prefix = s; 353234949Sbapt else if (++i < argc) 354234949Sbapt symbol_prefix = argv[i]; 355234949Sbapt else 356234949Sbapt usage(); 357234949Sbapt continue; 358234949Sbapt 359234949Sbapt default: 360234949Sbapt setflag(ch); 361234949Sbapt break; 362234949Sbapt } 363234949Sbapt 364234949Sbapt for (;;) 365234949Sbapt { 366234949Sbapt switch (ch = *++s) 367234949Sbapt { 368234949Sbapt case '\0': 369234949Sbapt goto end_of_option; 370234949Sbapt 371234949Sbapt default: 372234949Sbapt setflag(ch); 373234949Sbapt break; 374234949Sbapt } 375234949Sbapt } 376234949Sbapt end_of_option:; 377234949Sbapt } 378234949Sbapt 379234949Sbapt no_more_options:; 380234949Sbapt if (i + 1 != argc) 381234949Sbapt usage(); 382234949Sbapt input_file_name = argv[i]; 383234949Sbapt} 384234949Sbapt 385234949Sbaptvoid * 386234949Sbaptallocate(size_t n) 387234949Sbapt{ 388234949Sbapt void *p; 389234949Sbapt 390234949Sbapt p = NULL; 391234949Sbapt if (n) 392234949Sbapt { 393234949Sbapt p = CALLOC(1, n); 394234949Sbapt NO_SPACE(p); 395234949Sbapt } 396234949Sbapt return (p); 397234949Sbapt} 398234949Sbapt 399234949Sbapt#define CREATE_FILE_NAME(dest, suffix) \ 400264803Sbapt dest = alloc_file_name(len, suffix) 401234949Sbapt 402264803Sbaptstatic char * 403264803Sbaptalloc_file_name(size_t len, const char *suffix) 404264803Sbapt{ 405264803Sbapt char *result = TMALLOC(char, len + strlen(suffix) + 1); 406264803Sbapt if (result == 0) 407264803Sbapt no_space(); 408264803Sbapt strcpy(result, file_prefix); 409264803Sbapt strcpy(result + len, suffix); 410264803Sbapt return result; 411264803Sbapt} 412264803Sbapt 413234949Sbaptstatic void 414234949Sbaptcreate_file_names(void) 415234949Sbapt{ 416234949Sbapt size_t len; 417234949Sbapt const char *defines_suffix; 418234949Sbapt const char *externs_suffix; 419234949Sbapt char *prefix; 420234949Sbapt 421234949Sbapt prefix = NULL; 422234949Sbapt defines_suffix = DEFINES_SUFFIX; 423234949Sbapt externs_suffix = EXTERNS_SUFFIX; 424234949Sbapt 425234949Sbapt /* compute the file_prefix from the user provided output_file_name */ 426234949Sbapt if (output_file_name != 0) 427234949Sbapt { 428264803Sbapt if (!(prefix = strstr(output_file_name, OUTPUT_SUFFIX)) 429234949Sbapt && (prefix = strstr(output_file_name, ".c"))) 430234949Sbapt { 431234949Sbapt defines_suffix = ".h"; 432234949Sbapt externs_suffix = ".i"; 433234949Sbapt } 434234949Sbapt } 435234949Sbapt 436234949Sbapt if (prefix != NULL) 437234949Sbapt { 438234949Sbapt len = (size_t) (prefix - output_file_name); 439240517Sbapt file_prefix = TMALLOC(char, len + 1); 440234949Sbapt NO_SPACE(file_prefix); 441234949Sbapt strncpy(file_prefix, output_file_name, len)[len] = 0; 442234949Sbapt } 443234949Sbapt else 444234949Sbapt len = strlen(file_prefix); 445234949Sbapt 446234949Sbapt /* if "-o filename" was not given */ 447234949Sbapt if (output_file_name == 0) 448234949Sbapt { 449234949Sbapt oflag = 1; 450234949Sbapt CREATE_FILE_NAME(output_file_name, OUTPUT_SUFFIX); 451234949Sbapt } 452234949Sbapt 453234949Sbapt if (rflag) 454234949Sbapt { 455234949Sbapt CREATE_FILE_NAME(code_file_name, CODE_SUFFIX); 456234949Sbapt } 457234949Sbapt else 458234949Sbapt code_file_name = output_file_name; 459234949Sbapt 460234949Sbapt if (dflag) 461234949Sbapt { 462234949Sbapt CREATE_FILE_NAME(defines_file_name, defines_suffix); 463234949Sbapt } 464234949Sbapt 465234949Sbapt if (iflag) 466234949Sbapt { 467234949Sbapt CREATE_FILE_NAME(externs_file_name, externs_suffix); 468234949Sbapt } 469234949Sbapt 470234949Sbapt if (vflag) 471234949Sbapt { 472234949Sbapt CREATE_FILE_NAME(verbose_file_name, VERBOSE_SUFFIX); 473234949Sbapt } 474234949Sbapt 475234949Sbapt if (gflag) 476234949Sbapt { 477234949Sbapt CREATE_FILE_NAME(graph_file_name, GRAPH_SUFFIX); 478234949Sbapt } 479234949Sbapt 480234949Sbapt if (prefix != NULL) 481234949Sbapt { 482234949Sbapt FREE(file_prefix); 483234949Sbapt } 484234949Sbapt} 485234949Sbapt 486234949Sbapt#if USE_MKSTEMP 487234949Sbaptstatic void 488234949Sbaptclose_tmpfiles(void) 489234949Sbapt{ 490234949Sbapt while (my_tmpfiles != 0) 491234949Sbapt { 492234949Sbapt MY_TMPFILES *next = my_tmpfiles->next; 493234949Sbapt 494272655Sbapt (void)chmod(my_tmpfiles->name, 0644); 495272655Sbapt (void)unlink(my_tmpfiles->name); 496234949Sbapt 497234949Sbapt free(my_tmpfiles->name); 498234949Sbapt free(my_tmpfiles); 499234949Sbapt 500234949Sbapt my_tmpfiles = next; 501234949Sbapt } 502234949Sbapt} 503234949Sbapt 504234949Sbapt#ifndef HAVE_MKSTEMP 505234949Sbaptstatic int 506234949Sbaptmy_mkstemp(char *temp) 507234949Sbapt{ 508234949Sbapt int fd; 509234949Sbapt char *dname; 510234949Sbapt char *fname; 511234949Sbapt char *name; 512234949Sbapt 513234949Sbapt /* 514234949Sbapt * Split-up to use tempnam, rather than tmpnam; the latter (like 515234949Sbapt * mkstemp) is unusable on Windows. 516234949Sbapt */ 517234949Sbapt if ((fname = strrchr(temp, '/')) != 0) 518234949Sbapt { 519234949Sbapt dname = strdup(temp); 520234949Sbapt dname[++fname - temp] = '\0'; 521234949Sbapt } 522234949Sbapt else 523234949Sbapt { 524234949Sbapt dname = 0; 525234949Sbapt fname = temp; 526234949Sbapt } 527234949Sbapt if ((name = tempnam(dname, fname)) != 0) 528234949Sbapt { 529234949Sbapt fd = open(name, O_CREAT | O_EXCL | O_RDWR); 530234949Sbapt strcpy(temp, name); 531234949Sbapt } 532234949Sbapt else 533234949Sbapt { 534234949Sbapt fd = -1; 535234949Sbapt } 536234949Sbapt 537234949Sbapt if (dname != 0) 538234949Sbapt free(dname); 539234949Sbapt 540234949Sbapt return fd; 541234949Sbapt} 542234949Sbapt#define mkstemp(s) my_mkstemp(s) 543234949Sbapt#endif 544234949Sbapt 545234949Sbapt#endif 546234949Sbapt 547234949Sbapt/* 548234949Sbapt * tmpfile() should be adequate, except that it may require special privileges 549234949Sbapt * to use, e.g., MinGW and Windows 7 where it tries to use the root directory. 550234949Sbapt */ 551234949Sbaptstatic FILE * 552234949Sbaptopen_tmpfile(const char *label) 553234949Sbapt{ 554234949Sbapt FILE *result; 555234949Sbapt#if USE_MKSTEMP 556234949Sbapt int fd; 557234949Sbapt const char *tmpdir; 558234949Sbapt char *name; 559234949Sbapt const char *mark; 560234949Sbapt 561234949Sbapt if ((tmpdir = getenv("TMPDIR")) == 0 || access(tmpdir, W_OK) != 0) 562234949Sbapt { 563234949Sbapt#ifdef P_tmpdir 564234949Sbapt tmpdir = P_tmpdir; 565234949Sbapt#else 566234949Sbapt tmpdir = "/tmp"; 567234949Sbapt#endif 568234949Sbapt if (access(tmpdir, W_OK) != 0) 569234949Sbapt tmpdir = "."; 570234949Sbapt } 571234949Sbapt 572234949Sbapt name = malloc(strlen(tmpdir) + 10 + strlen(label)); 573234949Sbapt 574234949Sbapt result = 0; 575234949Sbapt if (name != 0) 576234949Sbapt { 577272769Sbapt mode_t save_umask = umask(0177); 578272655Sbapt 579234949Sbapt if ((mark = strrchr(label, '_')) == 0) 580234949Sbapt mark = label + strlen(label); 581234949Sbapt 582234949Sbapt sprintf(name, "%s/%.*sXXXXXX", tmpdir, (int)(mark - label), label); 583234949Sbapt fd = mkstemp(name); 584234949Sbapt if (fd >= 0) 585234949Sbapt { 586234949Sbapt result = fdopen(fd, "w+"); 587234949Sbapt if (result != 0) 588234949Sbapt { 589234949Sbapt MY_TMPFILES *item; 590234949Sbapt 591234949Sbapt if (my_tmpfiles == 0) 592234949Sbapt { 593234949Sbapt atexit(close_tmpfiles); 594234949Sbapt } 595234949Sbapt 596234949Sbapt item = NEW(MY_TMPFILES); 597234949Sbapt NO_SPACE(item); 598234949Sbapt 599234949Sbapt item->name = name; 600234949Sbapt NO_SPACE(item->name); 601234949Sbapt 602234949Sbapt item->next = my_tmpfiles; 603234949Sbapt my_tmpfiles = item; 604234949Sbapt } 605234949Sbapt } 606272655Sbapt (void)umask(save_umask); 607234949Sbapt } 608234949Sbapt#else 609234949Sbapt result = tmpfile(); 610234949Sbapt#endif 611234949Sbapt 612234949Sbapt if (result == 0) 613234949Sbapt open_error(label); 614234949Sbapt return result; 615234949Sbapt} 616234949Sbapt 617234949Sbaptstatic void 618234949Sbaptopen_files(void) 619234949Sbapt{ 620234949Sbapt create_file_names(); 621234949Sbapt 622234949Sbapt if (input_file == 0) 623234949Sbapt { 624234949Sbapt input_file = fopen(input_file_name, "r"); 625234949Sbapt if (input_file == 0) 626234949Sbapt open_error(input_file_name); 627234949Sbapt } 628234949Sbapt 629234949Sbapt action_file = open_tmpfile("action_file"); 630234949Sbapt text_file = open_tmpfile("text_file"); 631234949Sbapt 632234949Sbapt if (vflag) 633234949Sbapt { 634234949Sbapt verbose_file = fopen(verbose_file_name, "w"); 635234949Sbapt if (verbose_file == 0) 636234949Sbapt open_error(verbose_file_name); 637234949Sbapt } 638234949Sbapt 639234949Sbapt if (gflag) 640234949Sbapt { 641234949Sbapt graph_file = fopen(graph_file_name, "w"); 642234949Sbapt if (graph_file == 0) 643234949Sbapt open_error(graph_file_name); 644234949Sbapt fprintf(graph_file, "digraph %s {\n", file_prefix); 645234949Sbapt fprintf(graph_file, "\tedge [fontsize=10];\n"); 646234949Sbapt fprintf(graph_file, "\tnode [shape=box,fontsize=10];\n"); 647234949Sbapt fprintf(graph_file, "\torientation=landscape;\n"); 648234949Sbapt fprintf(graph_file, "\trankdir=LR;\n"); 649234949Sbapt fprintf(graph_file, "\t/*\n"); 650234949Sbapt fprintf(graph_file, "\tmargin=0.2;\n"); 651234949Sbapt fprintf(graph_file, "\tpage=\"8.27,11.69\"; // for A4 printing\n"); 652234949Sbapt fprintf(graph_file, "\tratio=auto;\n"); 653234949Sbapt fprintf(graph_file, "\t*/\n"); 654234949Sbapt } 655234949Sbapt 656234949Sbapt if (dflag) 657234949Sbapt { 658234949Sbapt defines_file = fopen(defines_file_name, "w"); 659234949Sbapt if (defines_file == 0) 660234949Sbapt open_error(defines_file_name); 661234949Sbapt union_file = open_tmpfile("union_file"); 662234949Sbapt } 663234949Sbapt 664234949Sbapt if (iflag) 665234949Sbapt { 666234949Sbapt externs_file = fopen(externs_file_name, "w"); 667234949Sbapt if (externs_file == 0) 668234949Sbapt open_error(externs_file_name); 669234949Sbapt } 670234949Sbapt 671234949Sbapt output_file = fopen(output_file_name, "w"); 672234949Sbapt if (output_file == 0) 673234949Sbapt open_error(output_file_name); 674234949Sbapt 675234949Sbapt if (rflag) 676234949Sbapt { 677234949Sbapt code_file = fopen(code_file_name, "w"); 678234949Sbapt if (code_file == 0) 679234949Sbapt open_error(code_file_name); 680234949Sbapt } 681234949Sbapt else 682234949Sbapt code_file = output_file; 683234949Sbapt} 684234949Sbapt 685234949Sbaptint 686234949Sbaptmain(int argc, char *argv[]) 687234949Sbapt{ 688234949Sbapt SRexpect = -1; 689234949Sbapt RRexpect = -1; 690234949Sbapt exit_code = EXIT_SUCCESS; 691234949Sbapt 692234949Sbapt set_signals(); 693234949Sbapt getargs(argc, argv); 694234949Sbapt open_files(); 695234949Sbapt reader(); 696234949Sbapt lr0(); 697234949Sbapt lalr(); 698234949Sbapt make_parser(); 699234949Sbapt graph(); 700234949Sbapt finalize_closure(); 701234949Sbapt verbose(); 702234949Sbapt output(); 703234949Sbapt done(exit_code); 704234949Sbapt /*NOTREACHED */ 705234949Sbapt} 706