Changeset 1610 in kBuild
- Timestamp:
- May 8, 2008 3:36:35 AM (17 years ago)
- Location:
- trunk/src/kmk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/expand.c
r1609 r1610 609 609 /* Expands the specified string, appending it to the specified variable value. */ 610 610 void 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 } 611 append_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); 641 618 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 } 696 664 } 697 665 #endif /* CONFIG_WITH_VALUE_LENGTH */ -
trunk/src/kmk/variable.c
r1554 r1610 1591 1591 1592 1592 #ifdef CONFIG_WITH_VALUE_LENGTH 1593 /* Worker function for do_variable_definition_append() and 1594 append_expanded_string_to_variable(). 1595 The APPEND argument indicates whether it's an append or prepend operation. */ 1596 void append_string_to_variable (struct variable *v, const char *value, unsigned int value_len, int append) 1597 { 1598 /* The previous definition of the variable was recursive. 1599 The new value is the unexpanded old and new values. */ 1600 unsigned int new_value_len = value_len + (v->value_length != 0 ? 1 + v->value_length : 0); 1601 int done_1st_prepend_copy = 0; 1602 1603 /* adjust the size. */ 1604 if ((unsigned)v->value_alloc_len <= new_value_len + 1) 1605 { 1606 v->value_alloc_len *= 2; 1607 if (v->value_alloc_len < new_value_len + 1) 1608 v->value_alloc_len = (new_value_len + 1 + value_len + 0x7f) + ~0x7fU; 1609 if (append || !v->value_length) 1610 v->value = xrealloc (v->value, v->value_alloc_len); 1611 else 1612 { 1613 /* avoid the extra memcpy the xrealloc may have to do */ 1614 char *new_buf = xmalloc (v->value_alloc_len); 1615 memcpy (&new_buf[value_len + 1], v->value, v->value_length + 1); 1616 done_1st_prepend_copy = 1; 1617 free (v->value); 1618 v->value = new_buf; 1619 } 1620 } 1621 1622 /* insert the new bits */ 1623 if (v->value_length != 0) 1624 { 1625 if (append) 1626 { 1627 v->value[v->value_length] = ' '; 1628 memcpy (&v->value[v->value_length + 1], value, value_len + 1); 1629 } 1630 else 1631 { 1632 if (!done_1st_prepend_copy) 1633 memmove (&v->value[value_len + 1], v->value, v->value_length + 1); 1634 v->value[value_len] = ' '; 1635 memcpy (v->value, value, value_len); 1636 } 1637 } 1638 else 1639 memcpy (v->value, value, value_len + 1); 1640 v->value_length = new_value_len; 1641 } 1642 1593 1643 static struct variable * 1594 1644 do_variable_definition_append (const struct floc *flocp, struct variable *v, const char *value, … … 1617 1667 This is a heavily exercised code path in kBuild. */ 1618 1668 if (v->recursive) 1619 { 1620 /* The previous definition of the variable was recursive. 1621 The new value is the unexpanded old and new values. */ 1622 unsigned int value_len = strlen (value); 1623 unsigned int new_value_len = value_len + (v->value_length != 0 ? 1 + v->value_length : 0); 1624 int done_1st_prepend_copy = 0; 1625 1626 /* adjust the size. */ 1627 if ((unsigned)v->value_alloc_len <= new_value_len + 1) 1628 { 1629 v->value_alloc_len *= 2; 1630 if (v->value_alloc_len < new_value_len + 1) 1631 v->value_alloc_len = (new_value_len + 1 + value_len + 0x7f) + ~0x7fU; 1632 if (append || !v->value_length) 1633 v->value = xrealloc (v->value, v->value_alloc_len); 1634 else 1635 { 1636 /* avoid the extra memcpy the xrealloc may have to do */ 1637 char *new_buf = xmalloc (v->value_alloc_len); 1638 memcpy (&new_buf[value_len + 1], v->value, v->value_length + 1); 1639 done_1st_prepend_copy = 1; 1640 free (v->value); 1641 v->value = new_buf; 1642 } 1643 } 1644 1645 /* insert the new bits */ 1646 if (v->value_length != 0) 1647 { 1648 if (append) 1649 { 1650 v->value[v->value_length] = ' '; 1651 memcpy (&v->value[v->value_length + 1], value, value_len + 1); 1652 } 1653 else 1654 { 1655 if (!done_1st_prepend_copy) 1656 memmove (&v->value[value_len + 1], v->value, v->value_length + 1); 1657 v->value[value_len] = ' '; 1658 memcpy (v->value, value, value_len); 1659 } 1660 } 1661 else 1662 memcpy (v->value, value, value_len + 1); 1663 v->value_length = new_value_len; 1664 } 1669 append_string_to_variable (v, value, strlen (value), append); 1665 1670 else 1666 { 1667 /* The previous definition of the variable was simple. 1668 The new value comes from the old value, which was expanded 1669 when it was set; and from the expanded new value. */ 1670 append_expanded_string_to_variable(v, value); 1671 } 1671 /* The previous definition of the variable was simple. 1672 The new value comes from the old value, which was expanded 1673 when it was set; and from the expanded new value. */ 1674 append_expanded_string_to_variable (v, value, append); 1672 1675 1673 1676 /* update the variable */ -
trunk/src/kmk/variable.h
r1503 r1610 89 89 #else 90 90 origin ENUM_BITFIELD (3); /* Variable origin. */ 91 #endif 91 #endif 92 92 enum variable_export 93 93 { … … 143 143 void restore_variable_buffer (char *buf, unsigned int len); 144 144 #ifdef CONFIG_WITH_VALUE_LENGTH 145 extern void append_expanded_string_to_variable (struct variable *v, const char *value );145 extern void append_expanded_string_to_variable (struct variable *v, const char *value, int append); 146 146 #endif 147 147 … … 191 191 192 192 #ifdef CONFIG_WITH_VALUE_LENGTH 193 void append_string_to_variable (struct variable *v, const char *value, 194 unsigned int value_len, int append); 193 195 194 196 struct variable *define_variable_in_set (const char *name, unsigned int length,
Note:
See TracChangeset
for help on using the changeset viewer.