Automatic date update in version.in
[deliverable/binutils-gdb.git] / gas / depend.c
index fcb150040473a0cbb39ad12a92df45f8b6424736..f569484c42e9285b739226da93e815e53cd29913 100644 (file)
@@ -1,11 +1,11 @@
 /* depend.c - Handle dependency tracking.
-   Copyright (C) 1997 Free Software Foundation, Inc.
+   Copyright (C) 1997-2020 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
    GAS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
+   the Free Software Foundation; either version 3, or (at your option)
    any later version.
 
    GAS is distributed in the hope that it will be useful,
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to the Free
-   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
 #include "as.h"
+#include "filenames.h"
 
 /* The file to write to, or NULL if no dependencies being kept.  */
-static char *dep_file = NULL;
+static char * dep_file = NULL;
 
 struct dependency
 {
-  char *file;
-  struct dependency *next;
+  char * file;
+  struct dependency * next;
 };
 
 /* All the files we depend on.  */
-static struct dependency *dep_chain = NULL;
+static struct dependency * dep_chain = NULL;
 
 /* Current column in output file.  */
 static int column = 0;
 
-static void wrap_output PARAMS ((FILE *, char *, int));
+static int quote_string_for_make (FILE *, const char *);
+static void wrap_output (FILE *, const char *, int);
 
 /* Number of columns allowable.  */
 #define MAX_COLUMNS 72
-
 \f
-
 /* Start saving dependencies, to be written to FILENAME.  If this is
    never called, then dependency tracking is simply skipped.  */
 
 void
-start_dependencies (filename)
-     char *filename;
+start_dependencies (char *filename)
 {
   dep_file = filename;
 }
@@ -55,8 +54,7 @@ start_dependencies (filename)
 /* Noticed a new filename, so try to register it.  */
 
 void
-register_dependency (filename)
-     char *filename;
+register_dependency (const char *filename)
 {
   struct dependency *dep;
 
@@ -65,31 +63,97 @@ register_dependency (filename)
 
   for (dep = dep_chain; dep != NULL; dep = dep->next)
     {
-      if (! strcmp (filename, dep->file))
+      if (!filename_cmp (filename, dep->file))
        return;
     }
 
-  dep = (struct dependency *) xmalloc (sizeof (struct dependency));
+  dep = XNEW (struct dependency);
   dep->file = xstrdup (filename);
   dep->next = dep_chain;
   dep_chain = dep;
 }
 
+/* Quote a file name the way `make' wants it, and print it to FILE.
+   If FILE is NULL, do no printing, but return the length of the
+   quoted string.
+
+   This code is taken from gcc with only minor changes.  */
+
+static int
+quote_string_for_make (FILE *file, const char *src)
+{
+  const char *p = src;
+  int i = 0;
+
+  for (;;)
+    {
+      char c = *p++;
+
+      switch (c)
+       {
+       case '\0':
+       case ' ':
+       case '\t':
+         {
+           /* GNU make uses a weird quoting scheme for white space.
+              A space or tab preceded by 2N+1 backslashes represents
+              N backslashes followed by space; a space or tab
+              preceded by 2N backslashes represents N backslashes at
+              the end of a file name; and backslashes in other
+              contexts should not be doubled.  */
+           const char *q;
+
+           for (q = p - 1; src < q && q[-1] == '\\'; q--)
+             {
+               if (file)
+                 putc ('\\', file);
+               i++;
+             }
+         }
+         if (!c)
+           return i;
+         if (file)
+           putc ('\\', file);
+         i++;
+         goto ordinary_char;
+
+       case '$':
+         if (file)
+           putc (c, file);
+         i++;
+         /* Fall through.  */
+         /* This can mishandle things like "$(" but there's no easy fix.  */
+       default:
+       ordinary_char:
+         /* This can mishandle characters in the string "\0\n%*?[\\~";
+            exactly which chars are mishandled depends on the `make' version.
+            We know of no portable solution for this;
+            even GNU make 3.76.1 doesn't solve the problem entirely.
+            (Also, '\0' is mishandled due to our calling conventions.)  */
+         if (file)
+           putc (c, file);
+         i++;
+         break;
+       }
+    }
+}
+
 /* Append some output to the file, keeping track of columns and doing
    wrapping as necessary.  */
 
 static void
-wrap_output (f, string, spacer)
-     FILE *f;
-     char *string;
-     int spacer;
+wrap_output (FILE *f, const char *string, int spacer)
 {
-  int len = strlen (string);
+  int len = quote_string_for_make (NULL, string);
 
   if (len == 0)
     return;
 
-  if (column && MAX_COLUMNS - 1 /*spacer*/ - 2 /*` \'*/ < column + len)
+  if (column
+      && (MAX_COLUMNS
+         - 1 /* spacer */
+         - 2 /* ` \'   */
+         < column + len))
     {
       fprintf (f, " \\\n ");
       column = 0;
@@ -103,7 +167,7 @@ wrap_output (f, string, spacer)
       ++column;
     }
 
-  fputs (string, f);
+  quote_string_for_make (f, string);
   column += len;
 
   if (spacer == ':')
@@ -116,7 +180,7 @@ wrap_output (f, string, spacer)
 /* Print dependency file.  */
 
 void
-print_dependencies ()
+print_dependencies (void)
 {
   FILE *f;
   struct dependency *dep;
@@ -124,10 +188,10 @@ print_dependencies ()
   if (dep_file == NULL)
     return;
 
-  f = fopen (dep_file, "w");
+  f = fopen (dep_file, FOPEN_WT);
   if (f == NULL)
     {
-      as_warn ("Can't open `%s' for writing", dep_file);
+      as_warn (_("can't open `%s' for writing"), dep_file);
       return;
     }
 
@@ -139,5 +203,5 @@ print_dependencies ()
   putc ('\n', f);
 
   if (fclose (f))
-    as_warn ("Can't close %s", dep_file);
+    as_warn (_("can't close `%s'"), dep_file);
 }
This page took 0.03239 seconds and 4 git commands to generate.