bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: target-specific append variable malfunction.


From: Paul D. Smith
Subject: Re: target-specific append variable malfunction.
Date: Thu, 31 Jan 2002 15:32:22 -0500

This is a long-known bug; it will be fixed in the next version.

Try this patch.


--- make-3.79.1/expand.c        Mon Jun 19 16:23:57 2000
+++ make/expand.c       Wed Jan 17 13:28:41 2001
@@ -92,7 +92,7 @@
 
 /* Recursively expand V.  The returned string is malloc'd.  */
 
-static char *allocated_variable_append PARAMS ((struct variable *v));
+static char *allocated_variable_append PARAMS ((const struct variable *v));
 
 char *
 recursively_expand (v)
@@ -469,52 +469,72 @@
   return result;
 }
 
-/* Like allocated_variable_expand, but we first expand this variable in the
-    context of the next variable set, then we append the expanded value.  */
+/* Like allocated_variable_expand, but for += target-specific variables.
+   First recursively construct the variable value from its appended parts in
+   any upper variable sets.  Then expand the resulting value.  */
 
 static char *
-allocated_variable_append (v)
-     struct variable *v;
+variable_append (name, length, set)
+     const char *name;
+     unsigned int length;
+     const struct variable_set_list *set;
 {
-  struct variable_set_list *save;
-  int len = strlen (v->name);
-  char *var = alloca (len + 4);
-  char *value;
+  const struct variable *v;
+  char *buf = 0;
 
-  char *obuf = variable_buffer;
-  unsigned int olen = variable_buffer_length;
+  /* If there's nothing left to check, return the empty buffer.  */
+  if (!set)
+    return initialize_variable_output ();
+
+  /* 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);
 
-  variable_buffer = 0;
+  /* 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);
+  else
+    buf = initialize_variable_output ();
 
-  assert(current_variable_set_list->next != 0);
-  save = current_variable_set_list;
-  current_variable_set_list = current_variable_set_list->next;
+  /* Append this value to the buffer, and return it.
+     If we already have a value, first add a space.  */
+  if (buf > variable_buffer)
+    buf = variable_buffer_output (buf, " ", 1);
 
-  var[0] = '$';
-  var[1] = '(';
-  strcpy (&var[2], v->name);
-  var[len+2] = ')';
-  var[len+3] = '\0';
+  return variable_buffer_output (buf, v->value, strlen (v->value));
+}
 
-  value = variable_expand_for_file (var, 0);
 
-  current_variable_set_list = save;
+static char *
+allocated_variable_append (v)
+     const struct variable *v;
+{
+  char *val, *retval;
 
-  value += strlen (value);
-  value = variable_buffer_output (value, " ", 1);
-  value = variable_expand_string (value, v->value, (long)-1);
-
-  value = variable_buffer;
-
-#if 0
-  /* Waste a little memory and save time.  */
-  value = xrealloc (value, strlen (value))
-#endif
+  /* Construct the appended variable value.  */
+
+  char *obuf = variable_buffer;
+  unsigned int olen = variable_buffer_length;
+
+  variable_buffer = 0;
+
+  val = variable_append (v->name, strlen (v->name), current_variable_set_list);
+  variable_buffer_output (val, "", 1);
+  val = variable_buffer;
 
   variable_buffer = obuf;
   variable_buffer_length = olen;
 
-  return value;
+  /* Now expand it and return that.  */
+
+  retval = allocated_variable_expand (val);
+
+  free (val);
+  return retval;
 }
 
 /* Like variable_expand_for_file, but the returned string is malloc'd.
--- make-3.79.1/variable.c      Fri May 19 12:36:08 2000
+++ make/variable.c     Wed Jan 17 13:53:34 2001
@@ -46,9 +46,6 @@
   = { 0, &global_variable_set };
 struct variable_set_list *current_variable_set_list = &global_setlist;
 
-static struct variable *lookup_variable_in_set PARAMS ((char *name,
-                          unsigned int length, struct variable_set *set));
-
 /* Implement variables.  */
 
 /* Define variable named NAME with value VALUE in SET.  VALUE is copied.
@@ -134,23 +131,17 @@
 /* Lookup a variable whose name is a string starting at NAME
    and with LENGTH chars.  NAME need not be null-terminated.
    Returns address of the `struct variable' containing all info
-   on the variable, or nil if no such variable is defined.
-
-   If we find a variable which is in the process of being expanded,
-   try to find one further up the set_list chain.  If we don't find
-   one that isn't being expanded, return a pointer to whatever we
-   _did_ find.  */
+   on the variable, or nil if no such variable is defined.  */
 
 struct variable *
 lookup_variable (name, length)
-     char *name;
+     const char *name;
      unsigned int length;
 {
-  register struct variable_set_list *setlist;
-  struct variable *firstv = 0;
+  const struct variable_set_list *setlist;
 
-  register unsigned int i;
-  register unsigned int rawhash = 0;
+  unsigned int i;
+  unsigned int rawhash = 0;
 
   for (i = 0; i < length; ++i)
     HASH (rawhash, name[i]);
@@ -158,35 +149,21 @@
   for (setlist = current_variable_set_list;
        setlist != 0; setlist = setlist->next)
     {
-      register struct variable_set *set = setlist->set;
-      register unsigned int hashval = rawhash % set->buckets;
-      register struct variable *v;
+      const struct variable_set *set = setlist->set;
+      unsigned int hashval = rawhash % set->buckets;
+      struct variable *v;
 
-      /* Look through this set list.  */
+      /* Look through this set list; return it if found.  */
       for (v = set->table[hashval]; v != 0; v = v->next)
        if (*v->name == *name
            && strneq (v->name + 1, name + 1, length - 1)
            && v->name[length] == '\0')
-          break;
-
-      /* If we didn't find anything, go to the next set list.  */
-      if (!v)
-        continue;
-
-      /* If it's not being expanded already, we're done.  */
-      if (!v->expanding)
         return v;
-
-      /* It is, so try to find another one.  If this is the first one we've
-         seen, keep a pointer in case we don't find anything else.  */
-      if (!firstv)
-        firstv = v;
     }
 
 #ifdef VMS
   /* since we don't read envp[] on startup, try to get the
      variable via getenv() here.  */
-  if (!firstv)
     {
       char *vname = alloca (length + 1);
       char *value;
@@ -201,9 +178,6 @@
          sptr = value;
          scnt = 0;
 
-          if (listp)
-            *listp = current_variable_set_list;
-
          while ((sptr = strchr (sptr, '$')))
            {
              scnt++;
@@ -242,7 +216,7 @@
     }
 #endif /* VMS */
 
-  return firstv;
+  return 0;
 }
 
 /* Lookup a variable whose name is a string starting at NAME
@@ -250,15 +224,15 @@
    Returns address of the `struct variable' containing all info
    on the variable, or nil if no such variable is defined.  */
 
-static struct variable *
+struct variable *
 lookup_variable_in_set (name, length, set)
-     char *name;
+     const char *name;
      unsigned int length;
-     struct variable_set *set;
+     const struct variable_set *set;
 {
-  register unsigned int i;
-  register unsigned int hash = 0;
-  register struct variable *v;
+  unsigned int i;
+  unsigned int hash = 0;
+  struct variable *v;
 
   for (i = 0; i < length; ++i)
     HASH (hash, name[i]);
@@ -791,7 +765,7 @@
   register char *end;
   enum { f_bogus,
          f_simple, f_recursive, f_append, f_conditional } flavor = f_bogus;
-  char *name, *expanded_name, *value, *alloc_value=NULL;
+  char *name, *expanded_name, *value=0, *alloc_value=NULL;
   struct variable *v;
   int append = 0;
 
@@ -903,19 +877,18 @@
       value = p;
       break;
     case f_append:
-      /* If we have += but we're in a target variable context, defer the
-         append until the context expansion.  */
+      {
+        /* If we have += but we're in a target variable context, we want to
+           append only with other variables in the context of this target.  */
       if (target_var)
         {
           append = 1;
-          flavor = f_recursive;
-          value = p;
-          break;
+            v = lookup_variable_in_set (expanded_name, strlen (expanded_name),
+                                        current_variable_set_list->set);
         }
-
-      /* An appending variable definition "var += value".
-        Extract the old value and append the new one.  */
+        else
       v = lookup_variable (expanded_name, strlen (expanded_name));
+
       if (v == 0)
        {
          /* There was no old value.
@@ -931,7 +904,7 @@
 
          if (v->recursive)
            /* The previous definition of the variable was recursive.
-              The new value comes from the unexpanded old and new values.  */
+                 The new value is the unexpanded old and new values. */
            flavor = f_recursive;
          else
            /* The previous definition of the variable was simple.
@@ -949,6 +922,7 @@
          bcopy (p, &value[oldlen + 1], newlen + 1);
        }
     }
+    }
 
 #ifdef __MSDOS__
   /* Many Unix Makefiles include a line saying "SHELL=/bin/sh", but
@@ -1035,7 +1009,8 @@
 #endif /* __MSDOS__ */
 #ifdef WINDOWS32
   if ((origin == o_file || origin == o_override)
-      && strcmp (expanded_name, "SHELL") == 0) {
+      && strcmp (expanded_name, "SHELL") == 0)
+    {
     extern char* default_shell;
 
     /*
@@ -1049,7 +1024,8 @@
                                 flocp);
        no_default_sh_exe = 0;
     }
-  } else
+    }
+  else
 #endif
 
   v = define_variable_loc (expanded_name, strlen (expanded_name), value,
--- make-3.79.1/variable.h      Thu Feb 24 13:59:14 2000
+++ make/variable.h     Wed Jan 17 13:00:48 2001
@@ -108,7 +108,10 @@
 extern void merge_variable_set_lists PARAMS ((struct variable_set_list 
**setlist0, struct variable_set_list *setlist1));
 extern struct variable *try_variable_definition PARAMS ((const struct floc 
*flocp, char *line, enum variable_origin origin, int target_var));
 
-extern struct variable *lookup_variable PARAMS ((char *name, unsigned int 
length));
+extern struct variable *lookup_variable PARAMS ((const char *name, unsigned 
int length));
+extern struct variable *lookup_variable_in_set PARAMS ((const char *name,
+                                                        unsigned int length,
+                                                        const struct 
variable_set *set));
 
 extern struct variable *define_variable_in_set
     PARAMS ((char *name, unsigned int length, char *value,
-- 
-------------------------------------------------------------------------------
 Paul D. Smith <address@hidden>          Find some GNU make tips at:
 http://www.gnu.org                      http://www.paulandlesley.org/gmake/
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist

reply via email to

[Prev in Thread] Current Thread [Next in Thread]