X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/6d441fc378923011574bb48a23cfcfd4f2e536a3..2cbd078f5153288a39cbf046231a3870df8170cb:/src/files.c?ds=inline

diff --git a/src/files.c b/src/files.c
index d081f3e0..5a0b2ea4 100644
--- a/src/files.c
+++ b/src/files.c
@@ -1,5 +1,6 @@
-/* Open and close files for bison,
-   Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002
+/* Open and close files for Bison.
+
+   Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
@@ -16,19 +17,22 @@
 
    You should have received a copy of the GNU General Public License
    along with Bison; see the file COPYING.  If not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
 
 #include "system.h"
 
 #include <error.h>
 #include <get-errno.h>
+#include <quote.h>
+#include <xstrndup.h>
 
 #include "complain.h"
 #include "files.h"
 #include "getargs.h"
 #include "gram.h"
+#include "stdio-safer.h"
 
 /* From basename.c.  Almost a lie, as it returns a char *. */
 const char *base_name (char const *name);
@@ -75,7 +79,7 @@ static char *
 concat2 (char const *str1, char const *str2)
 {
   size_t len = strlen (str1) + strlen (str2);
-  char *res = XMALLOC (char, len + 1);
+  char *res = xmalloc (len + 1);
   char *cp;
   cp = stpcpy (res, str1);
   cp = stpcpy (cp, str2);
@@ -92,7 +96,7 @@ xfopen (const char *name, const char *mode)
 {
   FILE *ptr;
 
-  ptr = fopen (name, mode);
+  ptr = fopen_safer (name, mode);
   if (!ptr)
     error (EXIT_FAILURE, get_errno (), _("cannot open file `%s'"), name);
 
@@ -117,9 +121,9 @@ xfclose (FILE *ptr)
 }
 
 
-/*----------------------------------------------------------------.
-| Compute BASE_NAME, SHORT_BASE_NAME and output files extensions. |
-`----------------------------------------------------------------*/
+/*---------------------------------------------------------------------.
+| Compute FULL_BASE_NAME, SHORT_BASE_NAME and output files extensions. |
+`---------------------------------------------------------------------*/
 
 /* Replace all characters FROM by TO in the string IN.
    and returns a new allocated string.  */
@@ -127,9 +131,7 @@ static char *
 tr (const char *in, char from, char to)
 {
   char *temp;
-  char *out;
-
-  out = XMALLOC (char, strlen (in) + 1);
+  char *out = xmalloc (strlen (in) + 1);
 
   for (temp = out; *in; in++, out++)
     if (*in == from)
@@ -140,7 +142,7 @@ tr (const char *in, char from, char to)
   return (temp);
 }
 
-/* Computes extensions from the grammar file extension. */
+/* Compute extensions from the grammar file extension.  */
 static void
 compute_exts_from_gf (const char *ext)
 {
@@ -150,7 +152,7 @@ compute_exts_from_gf (const char *ext)
   header_extension = tr (header_extension, 'Y', 'H');
 }
 
-/* Computes extensions from the given c source file extension. */
+/* Compute extensions from the given c source file extension.  */
 static void
 compute_exts_from_src (const char *ext)
 {
@@ -201,13 +203,17 @@ filename_split (const char *filename,
   *ext = strrchr (*base, '.');
   *tab = NULL;
 
-  /* If there is an exentension, check if there is a `.tab' part right
+  /* If there is an extension, check if there is a `.tab' part right
      before.  */
-  if (*ext
-      && (*ext - *base) > (int) strlen (".tab")
-      && (!strncmp (*ext - strlen (".tab"), ".tab", strlen (".tab"))
-	  || !strncmp (*ext - strlen ("_tab"), "_tab", strlen ("_tab"))))
-    *tab = *ext - strlen (".tab");
+  if (*ext)
+    {
+      size_t baselen = *ext - *base;
+      size_t dottablen = 4;
+      if (dottablen < baselen
+	  && (strncmp (*ext - dottablen, ".tab", dottablen) == 0
+	      || strncmp (*ext - dottablen, "_tab", dottablen) == 0))
+	*tab = *ext - dottablen;
+    }
 }
 
 
@@ -219,10 +225,10 @@ compute_base_names (void)
   const char *base, *tab, *ext;
 
   /* If --output=foo.c was specified (SPEC_OUTFILE == foo.c),
-     BASE_NAME and SHORT_BASE_NAME are `foo'.
+     FULL_BASE_NAME and SHORT_BASE_NAME are `foo'.
 
-     If --output=foo.tab.c was specified, BASE_NAME is `foo.tab' and
-     SHORT_BASE_NAME is `foo'.
+     If --output=foo.tab.c was specified, FULL_BASE_NAME is `foo.tab'
+     and SHORT_BASE_NAME is `foo'.
 
      The precise -o name will be used for FTABLE.  For other output
      files, remove the ".c" or ".tab.c" suffix.  */
@@ -272,25 +278,29 @@ compute_base_names (void)
 		      (strlen (base) - (ext ? strlen (ext) : 0)));
 	}
 
-      full_base_name = XMALLOC (char,
-				strlen (short_base_name)
+      full_base_name = xmalloc (strlen (short_base_name)
 				+ strlen (TAB_EXT) + 1);
       stpcpy (stpcpy (full_base_name, short_base_name), TAB_EXT);
 
-      /* Computes the extensions from the grammar file name.  */
+      /* Compute the extensions from the grammar file name.  */
       filename_split (grammar_file, &base, &tab, &ext);
       if (ext && !yacc_flag)
 	compute_exts_from_gf (ext);
     }
 }
 
-/*-------------------------------------------------------.
-| Close the open files, compute the output files names.  |
-`-------------------------------------------------------*/
+
+/* Compute the output file names.  Warn if we detect conflicting
+   outputs to the same file.  */
 
 void
 compute_output_file_names (void)
 {
+  char const *name[4];
+  int i;
+  int j;
+  int names = 0;
+
   compute_base_names ();
 
   /* If not yet done. */
@@ -299,16 +309,31 @@ compute_output_file_names (void)
   if (!header_extension)
     header_extension = ".h";
 
-  parser_file_name =
+  name[names++] = parser_file_name =
     spec_outfile ? spec_outfile : concat2 (full_base_name, src_extension);
 
-  /* It the defines filename if not given, we create it.  */
-  if (!spec_defines_file)
-    spec_defines_file = concat2 (full_base_name, header_extension);
+  if (defines_flag)
+    {
+      if (! spec_defines_file)
+	spec_defines_file = concat2 (full_base_name, header_extension);
+      name[names++] = spec_defines_file;
+    }
+
+  if (graph_flag)
+    {
+      if (! spec_graph_file)
+	spec_graph_file = concat2 (short_base_name, ".vcg");
+      name[names++] = spec_graph_file;
+    }
 
-  /* It the graph filename if not given, we create it.  */
-  if (!spec_graph_file)
-    spec_graph_file = concat2 (short_base_name, ".vcg");
+  if (report_flag)
+    {
+      spec_verbose_file = concat2 (short_base_name, OUTPUT_EXT);
+      name[names++] = spec_verbose_file;
+    }
 
-  spec_verbose_file = concat2 (short_base_name, OUTPUT_EXT);
+  for (j = 0; j < names; j++)
+    for (i = 0; i < j; i++)
+      if (strcmp (name[i], name[j]) == 0)
+	warn (_("conflicting outputs to file %s"), quote (name[i]));
 }