Ignore:
Timestamp:
May 8, 2008, 5:36:35 AM (17 years ago)
Author:
bird
Message:

Fixed prepend w/ expansion (would append instead of prepend). Optimized append_expanded_string_to_variable().

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/expand.c

    r1609 r1610  
    609609/* Expands the specified string, appending it to the specified variable value. */
    610610void
    611 append_expanded_string_to_variable (struct variable *v, const char *value)
    612 {
    613 #if 0 /* This isn't safe because the v->value will become invalid if the
    614          variable buffer is reallocated to a new address. Sad but true. */
    615   static char const empty_string[] = "";
    616   unsigned int original_value_length = v->value_length;
    617   char *p;
    618 
    619   /* Switch the variable buffer to the variable value buffer. */
    620   char *saved_buffer = variable_buffer;
    621   unsigned int saved_buffer_length = variable_buffer_length;
    622   variable_buffer = v->value;
    623   variable_buffer_length = v->value_alloc_len;
    624 
    625   /* Mark the variable as being expanding. */
    626   if (v->value_alloc_len == -42)
    627     fatal (*expanding_var, _("var=%s"), v->name);
    628   assert (v->value_alloc_len >= 0);
    629   v->value_alloc_len = -42;
    630 
    631   /* Skip the current value and start appending a '\0' / space before
    632      expanding the string so recursive references are handled correctly.
    633      Alternatively, if it's an empty value, replace the value with a fixed
    634      empty string. */
    635   p = v->value + original_value_length;
    636   if (original_value_length)
    637     {
    638       p = variable_buffer_output (p, " ", 1);
    639       p[-1] = '\0';
    640     }
     611append_expanded_string_to_variable (struct variable *v, const char *value, int append)
     612{
     613  unsigned int value_len = strlen (value);
     614  char *p = (char *) memchr (value, '$', value_len);
     615  if (!p)
     616    /* fast path */
     617    append_string_to_variable (v,value, value_len, append);
    641618  else
    642     v->value = (char *)&empty_string[0];
    643   p = variable_expand_string (p, value, (long)-1);
    644 
    645   /* Replace the '\0' with the space separator. */
    646   if (original_value_length)
    647     {
    648       assert (variable_buffer[original_value_length] == '\0');
    649       variable_buffer[original_value_length] = ' ';
    650     }
    651   else
    652     {
    653       assert (v->value == (char *)&empty_string[0]);
    654       assert (empty_string[0] == '\0');
    655     }
    656 
    657   /* Update the variable. (mind the variable_expand_string() return) */
    658   p = strchr (p, '\0');
    659   v->value = variable_buffer;
    660   v->value_length = p - v->value;
    661   v->value_alloc_len = variable_buffer_length;
    662 
    663   /* Restore the variable buffer. */
    664   variable_buffer = saved_buffer;
    665   variable_buffer_length = saved_buffer_length;
    666 #else
    667   char *p;
    668 
    669   /* Install a fresh variable buffer. */
    670   char *saved_buffer;
    671   unsigned int saved_buffer_length;
    672   install_variable_buffer (&saved_buffer, &saved_buffer_length);
    673 
    674   /* Copy the current value into it and append a space. */
    675   p = variable_buffer;
    676   if (v->value_length)
    677     {
    678       p = variable_buffer_output (p, v->value, v->value_length);
    679       p = variable_buffer_output (p, " ", 1);
    680     }
    681 
    682   /* Append the assignment value. */
    683   p = variable_expand_string (p, value, (long)-1);
    684   p = strchr (p, '\0');
    685 
    686   /* Replace the variable with the variable buffer. */
    687   free (v->value);
    688   v->value = variable_buffer;
    689   v->value_length = p - v->value;
    690   v->value_alloc_len = variable_buffer_length;
    691 
    692   /* Restore the variable buffer, but without freeing the current. */
    693   variable_buffer = NULL;
    694   restore_variable_buffer (saved_buffer, saved_buffer_length);
    695 #endif
     619    {
     620      unsigned int off_dollar = p - (char *)value;
     621
     622      /* Install a fresh variable buffer. */
     623      char *saved_buffer;
     624      unsigned int saved_buffer_length;
     625      install_variable_buffer (&saved_buffer, &saved_buffer_length);
     626
     627      p = variable_buffer;
     628      if (append || !v->value_length)
     629        {
     630          /* Copy the current value into it and append a space. */
     631          if (v->value_length)
     632            {
     633              p = variable_buffer_output (p, v->value, v->value_length);
     634              p = variable_buffer_output (p, " ", 1);
     635            }
     636
     637          /* Append the assignment value. */
     638          p = variable_buffer_output (p, value, off_dollar);
     639          p = variable_expand_string (p, value + off_dollar, value_len - off_dollar);
     640          p = strchr (p, '\0');
     641        }
     642      else
     643        {
     644          /* Expand the assignemnt value. */
     645          p = variable_buffer_output (p, value, off_dollar);
     646          p = variable_expand_string (p, value + off_dollar, value_len - off_dollar);
     647          p = strchr (p, '\0');
     648
     649          /* Append a space followed by the old value. */
     650          p = variable_buffer_output (p, " ", 1);
     651          p = variable_buffer_output (p, v->value, v->value_length + 1) - 1;
     652        }
     653
     654      /* Replace the variable with the variable buffer. */
     655      free (v->value);
     656      v->value = variable_buffer;
     657      v->value_length = p - v->value;
     658      v->value_alloc_len = variable_buffer_length;
     659
     660      /* Restore the variable buffer, but without freeing the current. */
     661      variable_buffer = NULL;
     662      restore_variable_buffer (saved_buffer, saved_buffer_length);
     663    }
    696664}
    697665#endif /* CONFIG_WITH_VALUE_LENGTH */
Note: See TracChangeset for help on using the changeset viewer.