Imported Upstream version 4.0
[platform/upstream/make.git] / expand.c
index 2315b06..ba04e48 100644 (file)
--- a/expand.c
+++ b/expand.c
@@ -1,7 +1,5 @@
 /* Variable expansion functions 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,7 +14,7 @@ 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>
 
@@ -28,7 +26,7 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* Initially, any errors reported when expanding strings will be reported
    against the file where the error appears.  */
-const struct floc **expanding_var = &reading_file;
+const gmk_floc **expanding_var = &reading_file;
 
 /* The next two describe the variable output buffer.
    This buffer is used to hold the variable-expansion of a line of the
@@ -63,8 +61,8 @@ variable_buffer_output (char *ptr, const char *string, unsigned int length)
     {
       unsigned int offset = ptr - variable_buffer;
       variable_buffer_length = (newlen + 100 > 2 * variable_buffer_length
-                               ? newlen + 100
-                               : 2 * variable_buffer_length);
+                                ? newlen + 100
+                                : 2 * variable_buffer_length);
       variable_buffer = xrealloc (variable_buffer, variable_buffer_length);
       ptr = variable_buffer + offset;
     }
@@ -98,8 +96,8 @@ char *
 recursively_expand_for_file (struct variable *v, struct file *file)
 {
   char *value;
-  const struct floc *this_var;
-  const struct floc **saved_varp;
+  const gmk_floc *this_var;
+  const gmk_floc **saved_varp;
   struct variable_set_list *save = 0;
   int set_reading = 0;
 
@@ -124,7 +122,7 @@ recursively_expand_for_file (struct variable *v, struct file *file)
       if (!v->exp_count)
         /* Expanding V causes infinite recursion.  Lose.  */
         fatal (*expanding_var,
-               _("Recursive variable `%s' references itself (eventually)"),
+               _("Recursive variable '%s' references itself (eventually)"),
                v->name);
       --v->exp_count;
     }
@@ -187,7 +185,7 @@ reference_variable (char *o, const char *name, unsigned int length)
    LENGTH bytes of STRING are actually scanned.  If LENGTH is -1, scan until
    a null byte is found.
 
-   Write the results to LINE, which must point into `variable_buffer'.  If
+   Write the results to LINE, which must point into 'variable_buffer'.  If
    LINE is NULL, start at the beginning of the buffer.
    Return a pointer to LINE, or to the beginning of the buffer if LINE is
    NULL.
@@ -197,12 +195,12 @@ variable_expand_string (char *line, const char *string, long length)
 {
   struct variable *v;
   const char *p, *p1;
-  char *abuf = NULL;
+  char *save;
   char *o;
   unsigned int line_offset;
 
   if (!line)
-    line = initialize_variable_output();
+    line = initialize_variable_output ();
   o = line;
   line_offset = line - variable_buffer;
 
@@ -212,133 +210,126 @@ variable_expand_string (char *line, const char *string, long length)
       return (variable_buffer);
     }
 
-  /* If we want a subset of the string, allocate a temporary buffer for it.
-     Most of the functions we use here don't work with length limits.  */
-  if (length > 0 && string[length] != '\0')
-    {
-      abuf = xmalloc(length+1);
-      memcpy(abuf, string, length);
-      abuf[length] = '\0';
-      string = abuf;
-    }
-  p = string;
+  /* We need a copy of STRING: due to eval, it's possible that it will get
+     freed as we process it (it might be the value of a variable that's reset
+     for example).  Also having a nil-terminated string is handy.  */
+  save = length < 0 ? xstrdup (string) : xstrndup (string, length);
+  p = save;
 
   while (1)
     {
       /* Copy all following uninteresting chars all at once to the
          variable output buffer, and skip them.  Uninteresting chars end
-        at the next $ or the end of the input.  */
+         at the next $ or the end of the input.  */
 
       p1 = strchr (p, '$');
 
       o = variable_buffer_output (o, p, p1 != 0 ? (unsigned int)(p1 - p) : strlen (p) + 1);
 
       if (p1 == 0)
-       break;
+        break;
       p = p1 + 1;
 
       /* Dispatch on the char that follows the $.  */
 
       switch (*p)
-       {
-       case '$':
-         /* $$ seen means output one $ to the variable output buffer.  */
-         o = variable_buffer_output (o, p, 1);
-         break;
-
-       case '(':
-       case '{':
-         /* $(...) or ${...} is the general case of substitution.  */
-         {
-           char openparen = *p;
-           char closeparen = (openparen == '(') ? ')' : '}';
+        {
+        case '$':
+          /* $$ seen means output one $ to the variable output buffer.  */
+          o = variable_buffer_output (o, p, 1);
+          break;
+
+        case '(':
+        case '{':
+          /* $(...) or ${...} is the general case of substitution.  */
+          {
+            char openparen = *p;
+            char closeparen = (openparen == '(') ? ')' : '}';
             const char *begp;
-           const char *beg = p + 1;
-           char *op;
+            const char *beg = p + 1;
+            char *op;
             char *abeg = NULL;
-           const char *end, *colon;
-
-           op = o;
-           begp = p;
-           if (handle_function (&op, &begp))
-             {
-               o = op;
-               p = begp;
-               break;
-             }
-
-           /* Is there a variable reference inside the parens or braces?
-              If so, expand it before expanding the entire reference.  */
-
-           end = strchr (beg, closeparen);
-           if (end == 0)
+            const char *end, *colon;
+
+            op = o;
+            begp = p;
+            if (handle_function (&op, &begp))
+              {
+                o = op;
+                p = begp;
+                break;
+              }
+
+            /* Is there a variable reference inside the parens or braces?
+               If so, expand it before expanding the entire reference.  */
+
+            end = strchr (beg, closeparen);
+            if (end == 0)
               /* Unterminated variable reference.  */
               fatal (*expanding_var, _("unterminated variable reference"));
-           p1 = lindex (beg, end, '$');
-           if (p1 != 0)
-             {
-               /* BEG now points past the opening paren or brace.
-                  Count parens or braces until it is matched.  */
-               int count = 0;
-               for (p = beg; *p != '\0'; ++p)
-                 {
-                   if (*p == openparen)
-                     ++count;
-                   else if (*p == closeparen && --count < 0)
-                     break;
-                 }
-               /* If COUNT is >= 0, there were unmatched opening parens
-                  or braces, so we go to the simple case of a variable name
-                  such as `$($(a)'.  */
-               if (count < 0)
-                 {
-                   abeg = expand_argument (beg, p); /* Expand the name.  */
-                   beg = abeg;
-                   end = strchr (beg, '\0');
-                 }
-             }
-           else
-             /* Advance P to the end of this reference.  After we are
+            p1 = lindex (beg, end, '$');
+            if (p1 != 0)
+              {
+                /* BEG now points past the opening paren or brace.
+                   Count parens or braces until it is matched.  */
+                int count = 0;
+                for (p = beg; *p != '\0'; ++p)
+                  {
+                    if (*p == openparen)
+                      ++count;
+                    else if (*p == closeparen && --count < 0)
+                      break;
+                  }
+                /* If COUNT is >= 0, there were unmatched opening parens
+                   or braces, so we go to the simple case of a variable name
+                   such as '$($(a)'.  */
+                if (count < 0)
+                  {
+                    abeg = expand_argument (beg, p); /* Expand the name.  */
+                    beg = abeg;
+                    end = strchr (beg, '\0');
+                  }
+              }
+            else
+              /* Advance P to the end of this reference.  After we are
                  finished expanding this one, P will be incremented to
                  continue the scan.  */
-             p = end;
-
-           /* This is not a reference to a built-in function and
-              any variable references inside are now expanded.
-              Is the resultant text a substitution reference?  */
-
-           colon = lindex (beg, end, ':');
-           if (colon)
-             {
-               /* This looks like a substitution reference: $(FOO:A=B).  */
-               const char *subst_beg, *subst_end, *replace_beg, *replace_end;
-
-               subst_beg = colon + 1;
-               subst_end = lindex (subst_beg, end, '=');
-               if (subst_end == 0)
-                 /* There is no = in sight.  Punt on the substitution
-                    reference and treat this as a variable name containing
-                    a colon, in the code below.  */
-                 colon = 0;
-               else
-                 {
-                   replace_beg = subst_end + 1;
-                   replace_end = end;
-
-                   /* Extract the variable name before the colon
-                      and look up that variable.  */
-                   v = lookup_variable (beg, colon - beg);
-                   if (v == 0)
-                     warn_undefined (beg, colon - beg);
+              p = end;
+
+            /* This is not a reference to a built-in function and
+               any variable references inside are now expanded.
+               Is the resultant text a substitution reference?  */
+
+            colon = lindex (beg, end, ':');
+            if (colon)
+              {
+                /* This looks like a substitution reference: $(FOO:A=B).  */
+                const char *subst_beg = colon + 1;
+                const char *subst_end = lindex (subst_beg, end, '=');
+                if (subst_end == 0)
+                  /* There is no = in sight.  Punt on the substitution
+                     reference and treat this as a variable name containing
+                     a colon, in the code below.  */
+                  colon = 0;
+                else
+                  {
+                    const char *replace_beg = subst_end + 1;
+                    const char *replace_end = end;
+
+                    /* Extract the variable name before the colon
+                       and look up that variable.  */
+                    v = lookup_variable (beg, colon - beg);
+                    if (v == 0)
+                      warn_undefined (beg, colon - beg);
 
                     /* If the variable is not empty, perform the
                        substitution.  */
-                   if (v != 0 && *v->value != '\0')
-                     {
-                       char *pattern, *replace, *ppercent, *rpercent;
-                       char *value = (v->recursive
+                    if (v != 0 && *v->value != '\0')
+                      {
+                        char *pattern, *replace, *ppercent, *rpercent;
+                        char *value = (v->recursive
                                        ? recursively_expand (v)
-                                      : v->value);
+                                       : v->value);
 
                         /* Copy the pattern and the replacement.  Add in an
                            extra % at the beginning to use in case there
@@ -356,15 +347,15 @@ variable_expand_string (char *line, const char *string, long length)
 
                         /* Look for %.  Set the percent pointers properly
                            based on whether we find one or not.  */
-                       ppercent = find_percent (pattern);
-                       if (ppercent)
+                        ppercent = find_percent (pattern);
+                        if (ppercent)
                           {
                             ++ppercent;
                             rpercent = find_percent (replace);
                             if (rpercent)
                               ++rpercent;
                           }
-                       else
+                        else
                           {
                             ppercent = pattern;
                             rpercent = replace;
@@ -375,64 +366,63 @@ variable_expand_string (char *line, const char *string, long length)
                         o = patsubst_expand_pat (o, value, pattern, replace,
                                                  ppercent, rpercent);
 
-                       if (v->recursive)
-                         free (value);
-                     }
-                 }
-             }
+                        if (v->recursive)
+                          free (value);
+                      }
+                  }
+              }
 
-           if (colon == 0)
-             /* This is an ordinary variable reference.
-                Look up the value of the variable.  */
-               o = reference_variable (o, beg, end - beg);
+            if (colon == 0)
+              /* This is an ordinary variable reference.
+                 Look up the value of the variable.  */
+                o = reference_variable (o, beg, end - beg);
 
-         if (abeg)
-           free (abeg);
-         }
-         break;
+          if (abeg)
+            free (abeg);
+          }
+          break;
 
-       case '\0':
-         break;
+        case '\0':
+          break;
 
-       default:
-         if (isblank ((unsigned char)p[-1]))
-           break;
+        default:
+          if (isblank ((unsigned char)p[-1]))
+            break;
 
-         /* A $ followed by a random char is a variable reference:
-            $a is equivalent to $(a).  */
+          /* A $ followed by a random char is a variable reference:
+             $a is equivalent to $(a).  */
           o = reference_variable (o, p, 1);
 
-         break;
-       }
+          break;
+        }
 
       if (*p == '\0')
-       break;
+        break;
 
       ++p;
     }
 
-  if (abuf)
-    free (abuf);
+  free (save);
 
   variable_buffer_output (o, "", 1);
   return (variable_buffer + line_offset);
 }
 \f
 /* Scan LINE for variable references and expansion-function calls.
-   Build in `variable_buffer' the result of expanding the references and calls.
+   Build in 'variable_buffer' the result of expanding the references and calls.
    Return the address of the resulting string, which is null-terminated
    and is valid only until the next time this function is called.  */
 
 char *
 variable_expand (const char *line)
 {
-  return variable_expand_string(NULL, line, (long)-1);
+  return variable_expand_string (NULL, line, (long)-1);
 }
 \f
 /* Expand an argument for an expansion function.
    The text starting at STR and ending at END is variable-expanded
    into a null-terminated string that is returned as the value.
-   This is done without clobbering `variable_buffer' or the current
+   This is done without clobbering 'variable_buffer' or the current
    variable-expansion that is in progress.  */
 
 char *
@@ -442,7 +432,7 @@ expand_argument (const char *str, const char *end)
   char *r;
 
   if (str == end)
-    return xstrdup("");
+    return xstrdup ("");
 
   if (!end || *end == '\0')
     return allocated_variable_expand (str);
@@ -471,7 +461,7 @@ variable_expand_for_file (const char *line, struct file *file)
 {
   char *result;
   struct variable_set_list *savev;
-  const struct floc *savef;
+  const gmk_floc *savef;
 
   if (file == 0)
     return variable_expand (line);
@@ -499,10 +489,12 @@ variable_expand_for_file (const char *line, struct file *file)
 
 static char *
 variable_append (const char *name, unsigned int length,
-                 const struct variable_set_list *set)
+                 const struct variable_set_list *set, int local)
 {
   const struct variable *v;
   char *buf = 0;
+  /* If this set is local and the next is not a parent, then next is local.  */
+  int nextlocal = local && set->next_is_parent == 0;
 
   /* If there's nothing left to check, return the empty buffer.  */
   if (!set)
@@ -511,14 +503,14 @@ variable_append (const char *name, unsigned int length,
   /* Try to find the variable in this variable set.  */
   v = lookup_variable_in_set (name, length, set->set);
 
-  /* If there isn't one, look to see if there's one in a set above us.  */
-  if (!v)
-    return variable_append (name, length, set->next);
+  /* If there isn't one, or this one is private, try the set above us.  */
+  if (!v || (!local && v->private_var))
+    return variable_append (name, length, set->next, nextlocal);
 
   /* If this variable type is append, first get any upper values.
      If not, initialize the buffer.  */
   if (v->append)
-    buf = variable_append (name, length, set->next);
+    buf = variable_append (name, length, set->next, nextlocal);
   else
     buf = initialize_variable_output ();
 
@@ -548,7 +540,8 @@ allocated_variable_append (const struct variable *v)
 
   variable_buffer = 0;
 
-  val = variable_append (v->name, strlen (v->name), current_variable_set_list);
+  val = variable_append (v->name, strlen (v->name),
+                         current_variable_set_list, 1);
   variable_buffer_output (val, "", 1);
   val = variable_buffer;