Imported Upstream version 4.0
[platform/upstream/make.git] / file.c
diff --git a/file.c b/file.c
index 0a4edb2..b209d88 100644 (file)
--- a/file.c
+++ b/file.c
@@ -1,7 +1,5 @@
 /* Target file management for GNU Make.
-Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-2010 Free Software Foundation, Inc.
+Copyright (C) 1988-2013 Free Software Foundation, Inc.
 This file is part of GNU Make.
 
 GNU Make is free software; you can redistribute it and/or modify it under the
@@ -16,12 +14,12 @@ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 You should have received a copy of the GNU General Public License along with
 this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#include "make.h"
+#include "makeint.h"
 
 #include <assert.h>
 
-#include "dep.h"
 #include "filedef.h"
+#include "dep.h"
 #include "job.h"
 #include "commands.h"
 #include "variable.h"
@@ -56,11 +54,11 @@ static int
 file_hash_cmp (const void *x, const void *y)
 {
   return_ISTRING_COMPARE (((struct file const *) x)->hname,
-                         ((struct file const *) y)->hname);
+                          ((struct file const *) y)->hname);
 }
 
-#ifndef        FILE_BUCKETS
-#define FILE_BUCKETS   1007
+#ifndef FILE_BUCKETS
+#define FILE_BUCKETS    1007
 #endif
 static struct hash_table files;
 
@@ -105,20 +103,20 @@ lookup_file (const char *name)
 #endif
   while (name[0] == '.'
 #ifdef HAVE_DOS_PATHS
-        && (name[1] == '/' || name[1] == '\\')
+         && (name[1] == '/' || name[1] == '\\')
 #else
-        && name[1] == '/'
+         && name[1] == '/'
 #endif
-        && name[2] != '\0')
+         && name[2] != '\0')
     {
       name += 2;
       while (*name == '/'
 #ifdef HAVE_DOS_PATHS
-            || *name == '\\'
+             || *name == '\\'
 #endif
-            )
-       /* Skip following slashes: ".//foo" is "foo", not "/foo".  */
-       ++name;
+             )
+        /* Skip following slashes: ".//foo" is "foo", not "/foo".  */
+        ++name;
     }
 
   if (*name == '\0')
@@ -155,7 +153,7 @@ enter_file (const char *name)
   struct file file_key;
 
   assert (*name != '\0');
-  assert (strcache_iscached (name));
+  assert (! verify_flag || strcache_iscached (name));
 
 #if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
   if (*name != '.')
@@ -179,11 +177,14 @@ enter_file (const char *name)
   file_slot = (struct file **) hash_find_slot (&files, &file_key);
   f = *file_slot;
   if (! HASH_VACANT (f) && !f->double_colon)
-    return f;
+    {
+      f->builtin = 0;
+      return f;
+    }
 
   new = xcalloc (sizeof (struct file));
   new->name = new->hname = name;
-  new->update_status = -1;
+  new->update_status = us_none;
 
   if (HASH_VACANT (f))
     {
@@ -202,7 +203,7 @@ enter_file (const char *name)
 }
 \f
 /* Rehash FILE to NAME.  This is not as simple as resetting
-   the `hname' member, since it must be put in a new hash bucket,
+   the 'hname' member, since it must be put in a new hash bucket,
    and possibly merged with an existing file called NAME.  */
 
 void
@@ -215,6 +216,7 @@ rehash_file (struct file *from_file, const char *to_hname)
   struct file *f;
 
   /* If it's already that name, we're done.  */
+  from_file->builtin = 0;
   file_key.hname = to_hname;
   if (! file_hash_cmp (from_file, &file_key))
     return;
@@ -264,18 +266,18 @@ rehash_file (struct file *from_file, const char *to_hname)
              but give a message to let the user know what's going on.  */
           if (to_file->cmds->fileinfo.filenm != 0)
             error (&from_file->cmds->fileinfo,
-                   _("Recipe was specified for file `%s' at %s:%lu,"),
+                   _("Recipe was specified for file '%s' at %s:%lu,"),
                    from_file->name, to_file->cmds->fileinfo.filenm,
                    to_file->cmds->fileinfo.lineno);
           else
             error (&from_file->cmds->fileinfo,
-                   _("Recipe for file `%s' was found by implicit rule search,"),
+                   _("Recipe for file '%s' was found by implicit rule search,"),
                    from_file->name);
           error (&from_file->cmds->fileinfo,
-                 _("but `%s' is now considered the same file as `%s'."),
+                 _("but '%s' is now considered the same file as '%s'."),
                  from_file->name, to_hname);
           error (&from_file->cmds->fileinfo,
-                 _("Recipe for `%s' will be ignored in favor of the one for `%s'."),
+                 _("Recipe for '%s' will be ignored in favor of the one for '%s'."),
                  to_hname, from_file->name);
         }
     }
@@ -295,12 +297,12 @@ rehash_file (struct file *from_file, const char *to_hname)
   merge_variable_set_lists (&to_file->variables, from_file->variables);
 
   if (to_file->double_colon && from_file->is_target && !from_file->double_colon)
-    fatal (NILF, _("can't rename single-colon `%s' to double-colon `%s'"),
+    fatal (NILF, _("can't rename single-colon '%s' to double-colon '%s'"),
            from_file->name, to_hname);
   if (!to_file->double_colon  && from_file->double_colon)
     {
       if (to_file->is_target)
-        fatal (NILF, _("can't rename double-colon `%s' to single-colon `%s'"),
+        fatal (NILF, _("can't rename double-colon '%s' to single-colon '%s'"),
                from_file->name, to_hname);
       else
         to_file->double_colon = from_file->double_colon;
@@ -320,14 +322,16 @@ rehash_file (struct file *from_file, const char *to_hname)
   MERGE (is_target);
   MERGE (cmd_target);
   MERGE (phony);
+  MERGE (loaded);
   MERGE (ignore_vpath);
 #undef MERGE
 
+  to_file->builtin = 0;
   from_file->renamed = to_file;
 }
 
 /* Rename FILE to NAME.  This is not as simple as resetting
-   the `name' member, since it must be put in a new hash bucket,
+   the 'name' member, since it must be put in a new hash bucket,
    and possibly merged with an existing file called NAME.  */
 
 void
@@ -365,52 +369,52 @@ remove_intermediates (int sig)
   for ( ; file_slot < file_end; file_slot++)
     if (! HASH_VACANT (*file_slot))
       {
-       struct file *f = *file_slot;
+        struct file *f = *file_slot;
         /* Is this file eligible for automatic deletion?
            Yes, IFF: it's marked intermediate, it's not secondary, it wasn't
            given on the command line, and it's either a -include makefile or
            it's not precious.  */
-       if (f->intermediate && (f->dontcare || !f->precious)
-           && !f->secondary && !f->cmd_target)
-         {
-           int status;
-           if (f->update_status == -1)
-             /* If nothing would have created this file yet,
-                don't print an "rm" command for it.  */
-             continue;
-           if (just_print_flag)
-             status = 0;
-           else
-             {
-               status = unlink (f->name);
-               if (status < 0 && errno == ENOENT)
-                 continue;
-             }
-           if (!f->dontcare)
-             {
-               if (sig)
-                 error (NILF, _("*** Deleting intermediate file `%s'"), f->name);
-               else
-                 {
-                   if (! doneany)
-                     DB (DB_BASIC, (_("Removing intermediate files...\n")));
-                   if (!silent_flag)
-                     {
-                       if (! doneany)
-                         {
-                           fputs ("rm ", stdout);
-                           doneany = 1;
-                         }
-                       else
-                         putchar (' ');
-                       fputs (f->name, stdout);
-                       fflush (stdout);
-                     }
-                 }
-               if (status < 0)
-                 perror_with_name ("unlink: ", f->name);
-             }
-         }
+        if (f->intermediate && (f->dontcare || !f->precious)
+            && !f->secondary && !f->cmd_target)
+          {
+            int status;
+            if (f->update_status == us_none)
+              /* If nothing would have created this file yet,
+                 don't print an "rm" command for it.  */
+              continue;
+            if (just_print_flag)
+              status = 0;
+            else
+              {
+                status = unlink (f->name);
+                if (status < 0 && errno == ENOENT)
+                  continue;
+              }
+            if (!f->dontcare)
+              {
+                if (sig)
+                  error (NILF, _("*** Deleting intermediate file '%s'"), f->name);
+                else
+                  {
+                    if (! doneany)
+                      DB (DB_BASIC, (_("Removing intermediate files...\n")));
+                    if (!silent_flag)
+                      {
+                        if (! doneany)
+                          {
+                            fputs ("rm ", stdout);
+                            doneany = 1;
+                          }
+                        else
+                          putchar (' ');
+                        fputs (f->name, stdout);
+                        fflush (stdout);
+                      }
+                  }
+                if (status < 0)
+                  perror_with_name ("unlink: ", f->name);
+              }
+          }
       }
 
   if (doneany && !sig)
@@ -426,7 +430,8 @@ remove_intermediates (int sig)
 struct dep *
 split_prereqs (char *p)
 {
-  struct dep *new = PARSE_FILE_SEQ (&p, struct dep, '|', NULL, 0);
+  struct dep *new = PARSE_FILE_SEQ (&p, struct dep, MAP_PIPE, NULL,
+                                    PARSEFS_NONE);
 
   if (*p)
     {
@@ -435,7 +440,7 @@ split_prereqs (char *p)
       struct dep *ood;
 
       ++p;
-      ood = PARSE_FILE_SEQ (&p, struct dep, '\0', NULL, 0);
+      ood = PARSE_SIMPLE_SEQ (&p, struct dep);
 
       if (! new)
         new = ood;
@@ -575,12 +580,11 @@ expand_deps (struct file *f)
          "$*" so they'll expand properly.  */
       if (d->staticpattern)
         {
-          char *o;
-          d->name = o = variable_expand ("");
+          char *o = variable_expand ("");
           o = subst_expand (o, name, "%", "$*", 1, 2, 0);
           *o = '\0';
           free (name);
-          d->name = name = xstrdup (d->name);
+          d->name = name = xstrdup (variable_buffer);
           d->staticpattern = 0;
         }
 
@@ -637,8 +641,8 @@ reset_updating (const void *item)
   f->updating = 0;
 }
 
-/* For each dependency of each file, make the `struct dep' point
-   at the appropriate `struct file' (which may have to be created).
+/* For each dependency of each file, make the 'struct dep' point
+   at the appropriate 'struct file' (which may have to be created).
 
    Also mark the files depended on by .PRECIOUS, .PHONY, .SILENT,
    and various other special targets.  */
@@ -693,23 +697,23 @@ snap_deps (void)
   for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev)
     for (d = f->deps; d != 0; d = d->next)
       for (f2 = d->file; f2 != 0; f2 = f2->prev)
-       f2->precious = 1;
+        f2->precious = 1;
 
   for (f = lookup_file (".LOW_RESOLUTION_TIME"); f != 0; f = f->prev)
     for (d = f->deps; d != 0; d = d->next)
       for (f2 = d->file; f2 != 0; f2 = f2->prev)
-       f2->low_resolution_time = 1;
+        f2->low_resolution_time = 1;
 
   for (f = lookup_file (".PHONY"); f != 0; f = f->prev)
     for (d = f->deps; d != 0; d = d->next)
       for (f2 = d->file; f2 != 0; f2 = f2->prev)
-       {
-         /* Mark this file as phony nonexistent target.  */
-         f2->phony = 1;
+        {
+          /* Mark this file as phony nonexistent target.  */
+          f2->phony = 1;
           f2->is_target = 1;
-         f2->last_mtime = NONEXISTENT_MTIME;
-         f2->mtime_before_update = NONEXISTENT_MTIME;
-       }
+          f2->last_mtime = NONEXISTENT_MTIME;
+          f2->mtime_before_update = NONEXISTENT_MTIME;
+        }
 
   for (f = lookup_file (".INTERMEDIATE"); f != 0; f = f->prev)
     /* Mark .INTERMEDIATE deps as intermediate files.  */
@@ -741,22 +745,22 @@ snap_deps (void)
   if (f != 0 && f->is_target)
     {
       if (f->deps == 0)
-       ignore_errors_flag = 1;
+        ignore_errors_flag = 1;
       else
-       for (d = f->deps; d != 0; d = d->next)
-         for (f2 = d->file; f2 != 0; f2 = f2->prev)
-           f2->command_flags |= COMMANDS_NOERROR;
+        for (d = f->deps; d != 0; d = d->next)
+          for (f2 = d->file; f2 != 0; f2 = f2->prev)
+            f2->command_flags |= COMMANDS_NOERROR;
     }
 
   f = lookup_file (".SILENT");
   if (f != 0 && f->is_target)
     {
       if (f->deps == 0)
-       silent_flag = 1;
+        silent_flag = 1;
       else
-       for (d = f->deps; d != 0; d = d->next)
-         for (f2 = d->file; f2 != 0; f2 = f2->prev)
-           f2->command_flags |= COMMANDS_SILENT;
+        for (d = f->deps; d != 0; d = d->next)
+          for (f2 = d->file; f2 != 0; f2 = f2->prev)
+            f2->command_flags |= COMMANDS_SILENT;
     }
 
   f = lookup_file (".NOTPARALLEL");
@@ -772,7 +776,7 @@ snap_deps (void)
 #endif
 }
 \f
-/* Set the `command_state' member of FILE and all its `also_make's.  */
+/* Set the 'command_state' member of FILE and all its 'also_make's.  */
 
 void
 set_command_state (struct file *file, enum cmd_state state)
@@ -788,20 +792,21 @@ set_command_state (struct file *file, enum cmd_state state)
 /* Convert an external file timestamp to internal form.  */
 
 FILE_TIMESTAMP
-file_timestamp_cons (const char *fname, time_t s, int ns)
+file_timestamp_cons (const char *fname, time_t stamp, long int ns)
 {
   int offset = ORDINARY_MTIME_MIN + (FILE_TIMESTAMP_HI_RES ? ns : 0);
+  FILE_TIMESTAMP s = stamp;
   FILE_TIMESTAMP product = (FILE_TIMESTAMP) s << FILE_TIMESTAMP_LO_BITS;
   FILE_TIMESTAMP ts = product + offset;
 
   if (! (s <= FILE_TIMESTAMP_S (ORDINARY_MTIME_MAX)
-        && product <= ts && ts <= ORDINARY_MTIME_MAX))
+         && product <= ts && ts <= ORDINARY_MTIME_MAX))
     {
       char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
       ts = s <= OLD_MTIME ? ORDINARY_MTIME_MIN : ORDINARY_MTIME_MAX;
       file_timestamp_sprintf (buf, ts);
       error (NILF, _("%s: Timestamp out of range; substituting %s"),
-            fname ? fname : _("Current time"), buf);
+             fname ? fname : _("Current time"), buf);
     }
 
   return ts;
@@ -825,10 +830,10 @@ file_timestamp_now (int *resolution)
     struct timespec timespec;
     if (clock_gettime (CLOCK_REALTIME, &timespec) == 0)
       {
-       r = 1;
-       s = timespec.tv_sec;
-       ns = timespec.tv_nsec;
-       goto got_time;
+        r = 1;
+        s = timespec.tv_sec;
+        ns = timespec.tv_nsec;
+        goto got_time;
       }
   }
 # endif
@@ -837,10 +842,10 @@ file_timestamp_now (int *resolution)
     struct timeval timeval;
     if (gettimeofday (&timeval, 0) == 0)
       {
-       r = 1000;
-       s = timeval.tv_sec;
-       ns = timeval.tv_usec * 1000;
-       goto got_time;
+        r = 1000;
+        s = timeval.tv_sec;
+        ns = timeval.tv_usec * 1000;
+        goto got_time;
       }
   }
 # endif
@@ -867,8 +872,8 @@ file_timestamp_sprintf (char *p, FILE_TIMESTAMP ts)
 
   if (tm)
     sprintf (p, "%04d-%02d-%02d %02d:%02d:%02d",
-            tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
-            tm->tm_hour, tm->tm_min, tm->tm_sec);
+             tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+             tm->tm_hour, tm->tm_min, tm->tm_sec);
   else if (t < 0)
     sprintf (p, "%ld", (long) t);
   else
@@ -919,7 +924,27 @@ print_file (const void *item)
 {
   const struct file *f = item;
 
+  /* If we're not using builtin targets, don't show them.
+
+     Ideally we'd be able to delete them altogether but currently there's no
+     facility to ever delete a file once it's been added.  */
+  if (no_builtin_rules_flag && f->builtin)
+    return;
+
   putchar ('\n');
+
+  if (f->cmds && f->cmds->recipe_prefix != cmd_prefix)
+    {
+      fputs (".RECIPEPREFIX = ", stdout);
+      cmd_prefix = f->cmds->recipe_prefix;
+      if (cmd_prefix != RECIPEPREFIX_DEFAULT)
+        putchar (cmd_prefix);
+      putchar ('\n');
+    }
+
+  if (f->variables != 0)
+    print_target_variables (f);
+
   if (!f->is_target)
     puts (_("# Not a target:"));
   printf ("%s:%s", f->name, f->double_colon ? ":" : "");
@@ -933,11 +958,13 @@ print_file (const void *item)
     puts (_("#  Command line target."));
   if (f->dontcare)
     puts (_("#  A default, MAKEFILES, or -include/sinclude makefile."));
+  if (f->builtin)
+    puts (_("#  Builtin rule"));
   puts (f->tried_implicit
         ? _("#  Implicit rule search has been done.")
         : _("#  Implicit rule search has not been done."));
   if (f->stem != 0)
-    printf (_("#  Implicit/static pattern stem: `%s'\n"), f->stem);
+    printf (_("#  Implicit/static pattern stem: '%s'\n"), f->stem);
   if (f->intermediate)
     puts (_("#  File is an intermediate prerequisite."));
   if (f->also_make != 0)
@@ -945,7 +972,7 @@ print_file (const void *item)
       const struct dep *d;
       fputs (_("#  Also makes:"), stdout);
       for (d = f->also_make; d != 0; d = d->next)
-       printf (" %s", dep_name (d));
+        printf (" %s", dep_name (d));
       putchar ('\n');
     }
   if (f->last_mtime == UNKNOWN_MTIME)
@@ -973,28 +1000,23 @@ print_file (const void *item)
     case cs_not_started:
     case cs_finished:
       switch (f->update_status)
-       {
-       case -1:
-         break;
-       case 0:
-         puts (_("#  Successfully updated."));
-         break;
-       case 1:
-         assert (question_flag);
-         puts (_("#  Needs to be updated (-q is set)."));
-         break;
-       case 2:
-         puts (_("#  Failed to be updated."));
-         break;
-       default:
-         puts (_("#  Invalid value in `update_status' member!"));
-         fflush (stdout);
-         fflush (stderr);
-         abort ();
-       }
+        {
+        case us_none:
+          break;
+        case us_success:
+          puts (_("#  Successfully updated."));
+          break;
+        case us_question:
+          assert (question_flag);
+          puts (_("#  Needs to be updated (-q is set)."));
+          break;
+        case us_failed:
+          puts (_("#  Failed to be updated."));
+          break;
+        }
       break;
     default:
-      puts (_("#  Invalid value in `command_state' member!"));
+      puts (_("#  Invalid value in 'command_state' member!"));
       fflush (stdout);
       fflush (stderr);
       abort ();
@@ -1026,7 +1048,7 @@ print_file_data_base (void)
 #define VERIFY_CACHED(_p,_n) \
     do{\
         if (_p->_n && _p->_n[0] && !strcache_iscached (_p->_n)) \
-          error (NULL, "%s: Field '%s' not cached: %s\n", _p->name, # _n, _p->_n); \
+          error (NULL, _("%s: Field '%s' not cached: %s"), _p->name, # _n, _p->_n); \
     }while(0)
 
 static void