1cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Open and close files for Bison. 2cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 305436638acc7c010349a69c3395f1a57c642dc62Ying Wang Copyright (C) 1984, 1986, 1989, 1992, 2000-2012 Free Software 405436638acc7c010349a69c3395f1a57c642dc62Ying Wang Foundation, Inc. 5cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 6cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project This file is part of Bison, the GNU Compiler Compiler. 7cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 805436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is free software: you can redistribute it and/or modify 905436638acc7c010349a69c3395f1a57c642dc62Ying Wang it under the terms of the GNU General Public License as published by 1005436638acc7c010349a69c3395f1a57c642dc62Ying Wang the Free Software Foundation, either version 3 of the License, or 1105436638acc7c010349a69c3395f1a57c642dc62Ying Wang (at your option) any later version. 12cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 1305436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is distributed in the hope that it will be useful, 1405436638acc7c010349a69c3395f1a57c642dc62Ying Wang but WITHOUT ANY WARRANTY; without even the implied warranty of 1505436638acc7c010349a69c3395f1a57c642dc62Ying Wang MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang GNU General Public License for more details. 17cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 18cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project You should have received a copy of the GNU General Public License 1905436638acc7c010349a69c3395f1a57c642dc62Ying Wang along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 21cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <config.h> 22cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include "system.h" 23cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 24cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <error.h> 2505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <dirname.h> 26cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <get-errno.h> 27cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <quote.h> 2805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <quotearg.h> 2905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <stdio-safer.h> 30cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <xstrndup.h> 31cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 32cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include "complain.h" 33cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include "files.h" 34cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include "getargs.h" 35cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include "gram.h" 36cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 37cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Initializing some values below (such SPEC_NAME_PREFIX to `yy') is 38cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project tempting, but don't do that: for the time being our handling of the 39cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project %directive vs --option leaves precedence to the options by deciding 40cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project that if a %directive sets a variable which is really set (i.e., not 41cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project NULL), then the %directive is ignored. As a result, %name-prefix, 42cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project for instance, will not be honored. */ 43cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 44cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectchar const *spec_outfile = NULL; /* for -o. */ 45cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectchar const *spec_file_prefix = NULL; /* for -b. */ 46cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectchar const *spec_name_prefix = NULL; /* for -p. */ 4705436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *spec_verbose_file = NULL; /* for --verbose. */ 4805436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *spec_graph_file = NULL; /* for -g. */ 4905436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *spec_xml_file = NULL; /* for -x. */ 5005436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *spec_defines_file = NULL; /* for --defines. */ 5105436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *parser_file_name; 5205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 5305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* All computed output file names. */ 5405436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic char **file_names = NULL; 5505436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic int file_names_count = 0; 56cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 57cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectuniqstr grammar_file = NULL; 58cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectuniqstr current_file = NULL; 59cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 60cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* If --output=dir/foo.c was specified, 61cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project DIR_PREFIX is `dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are `dir/foo'. 62cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 63cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project If --output=dir/foo.tab.c was specified, DIR_PREFIX is `dir/', 64cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project ALL_BUT_EXT is `dir/foo.tab', and ALL_BUT_TAB_EXT is `dir/foo'. 65cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 66cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project If --output was not specified but --file-prefix=dir/foo was specified, 67cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project ALL_BUT_EXT = `foo.tab' and ALL_BUT_TAB_EXT = `foo'. 68cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 69cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project If neither --output nor --file was specified but the input grammar 70cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project is name dir/foo.y, ALL_BUT_EXT and ALL_BUT_TAB_EXT are `foo'. 71cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 72cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project If neither --output nor --file was specified, DIR_PREFIX is the 73cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project empty string (meaning the current directory); otherwise it is 74cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project `dir/'. */ 75cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 7605436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *all_but_ext; 7705436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic char *all_but_tab_ext; 7805436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *dir_prefix; 79cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 80cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* C source file extension (the parser source). */ 8105436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic char *src_extension = NULL; 82cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Header file extension (if option ``-d'' is specified). */ 8305436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic char *header_extension = NULL; 84cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 85cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/*-----------------------------------------------------------------. 86cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project| Return a newly allocated string composed of the concatenation of | 87cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project| STR1, and STR2. | 88cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project`-----------------------------------------------------------------*/ 89cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 90cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic char * 91cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectconcat2 (char const *str1, char const *str2) 92cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{ 93cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project size_t len = strlen (str1) + strlen (str2); 94cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project char *res = xmalloc (len + 1); 95cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project char *cp; 96cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project cp = stpcpy (res, str1); 97cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project cp = stpcpy (cp, str2); 98cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project return res; 99cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project} 100cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 101cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/*-----------------------------------------------------------------. 102cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project| Try to open file NAME with mode MODE, and print an error message | 103cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project| if fails. | 104cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project`-----------------------------------------------------------------*/ 105cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 106cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source ProjectFILE * 107cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectxfopen (const char *name, const char *mode) 108cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{ 109cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project FILE *ptr; 110cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 111cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project ptr = fopen_safer (name, mode); 112cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (!ptr) 11305436638acc7c010349a69c3395f1a57c642dc62Ying Wang error (EXIT_FAILURE, get_errno (), 11405436638acc7c010349a69c3395f1a57c642dc62Ying Wang _("%s: cannot open"), quotearg_colon (name)); 115cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 116cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project return ptr; 117cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project} 118cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 119cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/*-------------------------------------------------------------. 120cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project| Try to close file PTR, and print an error message if fails. | 121cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project`-------------------------------------------------------------*/ 122cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 123cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectvoid 124cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectxfclose (FILE *ptr) 125cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{ 126cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (ptr == NULL) 127cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project return; 128cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 129cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (ferror (ptr)) 13005436638acc7c010349a69c3395f1a57c642dc62Ying Wang error (EXIT_FAILURE, 0, _("input/output error")); 131cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 132cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (fclose (ptr) != 0) 133cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error (EXIT_FAILURE, get_errno (), _("cannot close file")); 134cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project} 135cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 136cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 137cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/*------------------------------------------------------------------. 138cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project| Compute ALL_BUT_EXT, ALL_BUT_TAB_EXT and output files extensions. | 139cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project`------------------------------------------------------------------*/ 140cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 141cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Compute extensions from the grammar file extension. */ 142cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic void 143cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectcompute_exts_from_gf (const char *ext) 144cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{ 14505436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (strcmp (ext, ".y") == 0) 14605436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 14705436638acc7c010349a69c3395f1a57c642dc62Ying Wang src_extension = xstrdup (language->src_extension); 14805436638acc7c010349a69c3395f1a57c642dc62Ying Wang header_extension = xstrdup (language->header_extension); 14905436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 15005436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 15105436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 15205436638acc7c010349a69c3395f1a57c642dc62Ying Wang src_extension = xstrdup (ext); 15305436638acc7c010349a69c3395f1a57c642dc62Ying Wang header_extension = xstrdup (ext); 15405436638acc7c010349a69c3395f1a57c642dc62Ying Wang tr (src_extension, 'y', 'c'); 15505436638acc7c010349a69c3395f1a57c642dc62Ying Wang tr (src_extension, 'Y', 'C'); 15605436638acc7c010349a69c3395f1a57c642dc62Ying Wang tr (header_extension, 'y', 'h'); 15705436638acc7c010349a69c3395f1a57c642dc62Ying Wang tr (header_extension, 'Y', 'H'); 15805436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 159cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project} 160cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 161cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Compute extensions from the given c source file extension. */ 162cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic void 163cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectcompute_exts_from_src (const char *ext) 164cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{ 165cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* We use this function when the user specifies `-o' or `--output', 166cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project so the extenions must be computed unconditionally from the file name 167cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project given by this option. */ 168cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project src_extension = xstrdup (ext); 16905436638acc7c010349a69c3395f1a57c642dc62Ying Wang header_extension = xstrdup (ext); 17005436638acc7c010349a69c3395f1a57c642dc62Ying Wang tr (header_extension, 'c', 'h'); 17105436638acc7c010349a69c3395f1a57c642dc62Ying Wang tr (header_extension, 'C', 'H'); 172cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project} 173cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 174cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 175cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Decompose FILE_NAME in four parts: *BASE, *TAB, and *EXT, the fourth 176cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project part, (the directory) is ranging from FILE_NAME to the char before 177cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project *BASE, so we don't need an additional parameter. 178cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 179cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project *EXT points to the last period in the basename, or NULL if none. 180cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 181cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project If there is no *EXT, *TAB is NULL. Otherwise, *TAB points to 182cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project `.tab' or `_tab' if present right before *EXT, or is NULL. *TAB 183cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project cannot be equal to *BASE. 184cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 185cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project None are allocated, they are simply pointers to parts of FILE_NAME. 186cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project Examples: 187cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 188cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project '/tmp/foo.tab.c' -> *BASE = 'foo.tab.c', *TAB = '.tab.c', *EXT = 189cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project '.c' 190cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 191cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 'foo.c' -> *BASE = 'foo.c', *TAB = NULL, *EXT = '.c' 192cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 193cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 'tab.c' -> *BASE = 'tab.c', *TAB = NULL, *EXT = '.c' 194cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 195cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project '.tab.c' -> *BASE = '.tab.c', *TAB = NULL, *EXT = '.c' 196cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 197cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 'foo.tab' -> *BASE = 'foo.tab', *TAB = NULL, *EXT = '.tab' 198cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 199cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 'foo_tab' -> *BASE = 'foo_tab', *TAB = NULL, *EXT = NULL 200cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 201cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 'foo' -> *BASE = 'foo', *TAB = NULL, *EXT = NULL. */ 202cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 203cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic void 204cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectfile_name_split (const char *file_name, 205cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project const char **base, const char **tab, const char **ext) 206cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{ 20705436638acc7c010349a69c3395f1a57c642dc62Ying Wang *base = last_component (file_name); 208cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 209cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* Look for the extension, i.e., look for the last dot. */ 21005436638acc7c010349a69c3395f1a57c642dc62Ying Wang *ext = mbsrchr (*base, '.'); 211cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project *tab = NULL; 212cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 213cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* If there is an extension, check if there is a `.tab' part right 214cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project before. */ 215cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (*ext) 216cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 217cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project size_t baselen = *ext - *base; 218cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project size_t dottablen = 4; 219cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (dottablen < baselen 220cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project && (strncmp (*ext - dottablen, ".tab", dottablen) == 0 221cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project || strncmp (*ext - dottablen, "_tab", dottablen) == 0)) 222cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project *tab = *ext - dottablen; 223cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 224cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project} 225cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 226cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 227cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic void 228cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectcompute_file_name_parts (void) 229cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{ 230cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project const char *base, *tab, *ext; 231cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 232cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* Compute ALL_BUT_EXT and ALL_BUT_TAB_EXT from SPEC_OUTFILE 233cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project or GRAMMAR_FILE. 234cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 235cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project The precise -o name will be used for FTABLE. For other output 236cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project files, remove the ".c" or ".tab.c" suffix. */ 237cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (spec_outfile) 238cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 239cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project file_name_split (spec_outfile, &base, &tab, &ext); 240cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project dir_prefix = xstrndup (spec_outfile, base - spec_outfile); 241cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 242cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* ALL_BUT_EXT goes up the EXT, excluding it. */ 243cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project all_but_ext = 244cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project xstrndup (spec_outfile, 245cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project (strlen (spec_outfile) - (ext ? strlen (ext) : 0))); 246cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 247cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* ALL_BUT_TAB_EXT goes up to TAB, excluding it. */ 248cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project all_but_tab_ext = 249cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project xstrndup (spec_outfile, 250cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project (strlen (spec_outfile) 251cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project - (tab ? strlen (tab) : (ext ? strlen (ext) : 0)))); 252cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 253cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (ext) 254cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project compute_exts_from_src (ext); 255cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 256cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project else 257cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 258cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project file_name_split (grammar_file, &base, &tab, &ext); 259cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 260cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (spec_file_prefix) 261cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 262cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* If --file-prefix=foo was specified, ALL_BUT_TAB_EXT = `foo'. */ 26305436638acc7c010349a69c3395f1a57c642dc62Ying Wang dir_prefix = 26405436638acc7c010349a69c3395f1a57c642dc62Ying Wang xstrndup (spec_file_prefix, 26505436638acc7c010349a69c3395f1a57c642dc62Ying Wang last_component (spec_file_prefix) - spec_file_prefix); 266cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project all_but_tab_ext = xstrdup (spec_file_prefix); 267cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 268cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project else if (yacc_flag) 269cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 270cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* If --yacc, then the output is `y.tab.c'. */ 27105436638acc7c010349a69c3395f1a57c642dc62Ying Wang dir_prefix = xstrdup (""); 27205436638acc7c010349a69c3395f1a57c642dc62Ying Wang all_but_tab_ext = xstrdup ("y"); 273cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 274cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project else 275cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 276cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* Otherwise, ALL_BUT_TAB_EXT is computed from the input 277cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project grammar: `foo/bar.yy' => `bar'. */ 27805436638acc7c010349a69c3395f1a57c642dc62Ying Wang dir_prefix = xstrdup (""); 279cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project all_but_tab_ext = 280cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0))); 281cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 282cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 28305436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (language->add_tab) 28405436638acc7c010349a69c3395f1a57c642dc62Ying Wang all_but_ext = concat2 (all_but_tab_ext, TAB_EXT); 28505436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 28605436638acc7c010349a69c3395f1a57c642dc62Ying Wang all_but_ext = xstrdup (all_but_tab_ext); 287cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 288cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* Compute the extensions from the grammar file name. */ 289cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (ext && !yacc_flag) 290cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project compute_exts_from_gf (ext); 291cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 292cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project} 293cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 294cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 295cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Compute the output file names. Warn if we detect conflicting 296cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project outputs to the same file. */ 297cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 298cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectvoid 299cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectcompute_output_file_names (void) 300cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{ 301cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project compute_file_name_parts (); 302cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 303cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* If not yet done. */ 304cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (!src_extension) 30505436638acc7c010349a69c3395f1a57c642dc62Ying Wang src_extension = xstrdup (".c"); 306cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (!header_extension) 30705436638acc7c010349a69c3395f1a57c642dc62Ying Wang header_extension = xstrdup (".h"); 308cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 30905436638acc7c010349a69c3395f1a57c642dc62Ying Wang parser_file_name = 31005436638acc7c010349a69c3395f1a57c642dc62Ying Wang (spec_outfile 31105436638acc7c010349a69c3395f1a57c642dc62Ying Wang ? xstrdup (spec_outfile) 31205436638acc7c010349a69c3395f1a57c642dc62Ying Wang : concat2 (all_but_ext, src_extension)); 313cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 314cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (defines_flag) 315cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 316cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (! spec_defines_file) 317cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project spec_defines_file = concat2 (all_but_ext, header_extension); 318cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 319cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 320cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (graph_flag) 321cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 322cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (! spec_graph_file) 32305436638acc7c010349a69c3395f1a57c642dc62Ying Wang spec_graph_file = concat2 (all_but_tab_ext, ".dot"); 32405436638acc7c010349a69c3395f1a57c642dc62Ying Wang output_file_name_check (&spec_graph_file); 32505436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 32605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 32705436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (xml_flag) 32805436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 32905436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (! spec_xml_file) 33005436638acc7c010349a69c3395f1a57c642dc62Ying Wang spec_xml_file = concat2 (all_but_tab_ext, ".xml"); 33105436638acc7c010349a69c3395f1a57c642dc62Ying Wang output_file_name_check (&spec_xml_file); 332cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 333cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 334cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (report_flag) 335cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 33605436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (!spec_verbose_file) 33705436638acc7c010349a69c3395f1a57c642dc62Ying Wang spec_verbose_file = concat2 (all_but_tab_ext, OUTPUT_EXT); 33805436638acc7c010349a69c3395f1a57c642dc62Ying Wang output_file_name_check (&spec_verbose_file); 33905436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 34005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 34105436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (all_but_tab_ext); 34205436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (src_extension); 34305436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (header_extension); 34405436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 34505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 34605436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid 34705436638acc7c010349a69c3395f1a57c642dc62Ying Wangoutput_file_name_check (char **file_name) 34805436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 34905436638acc7c010349a69c3395f1a57c642dc62Ying Wang bool conflict = false; 35005436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (0 == strcmp (*file_name, grammar_file)) 35105436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 35205436638acc7c010349a69c3395f1a57c642dc62Ying Wang complain (_("refusing to overwrite the input file %s"), 35305436638acc7c010349a69c3395f1a57c642dc62Ying Wang quote (*file_name)); 35405436638acc7c010349a69c3395f1a57c642dc62Ying Wang conflict = true; 35505436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 35605436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 35705436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 35805436638acc7c010349a69c3395f1a57c642dc62Ying Wang int i; 35905436638acc7c010349a69c3395f1a57c642dc62Ying Wang for (i = 0; i < file_names_count; i++) 36005436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (0 == strcmp (file_names[i], *file_name)) 36105436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 36205436638acc7c010349a69c3395f1a57c642dc62Ying Wang warn (_("conflicting outputs to file %s"), 36305436638acc7c010349a69c3395f1a57c642dc62Ying Wang quote (*file_name)); 36405436638acc7c010349a69c3395f1a57c642dc62Ying Wang conflict = true; 36505436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 366cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 36705436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (conflict) 36805436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 36905436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (*file_name); 37005436638acc7c010349a69c3395f1a57c642dc62Ying Wang *file_name = strdup ("/dev/null"); 37105436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 37205436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 37305436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 37405436638acc7c010349a69c3395f1a57c642dc62Ying Wang file_names = xnrealloc (file_names, ++file_names_count, 37505436638acc7c010349a69c3395f1a57c642dc62Ying Wang sizeof *file_names); 37605436638acc7c010349a69c3395f1a57c642dc62Ying Wang file_names[file_names_count-1] = xstrdup (*file_name); 37705436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 37805436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 379cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 38005436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid 38105436638acc7c010349a69c3395f1a57c642dc62Ying Wangoutput_file_names_free (void) 38205436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 38305436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (all_but_ext); 38405436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (spec_verbose_file); 38505436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (spec_graph_file); 38605436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (spec_xml_file); 38705436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (spec_defines_file); 38805436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (parser_file_name); 38905436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (dir_prefix); 39005436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 39105436638acc7c010349a69c3395f1a57c642dc62Ying Wang int i; 39205436638acc7c010349a69c3395f1a57c642dc62Ying Wang for (i = 0; i < file_names_count; i++) 39305436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (file_names[i]); 39405436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 39505436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (file_names); 396cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project} 397