Changeset 1610 for trunk/src/kmk/expand.c
- Timestamp:
- May 8, 2008, 5:36:35 AM (17 years ago)
- File:
-
- 1 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 */
Note:
See TracChangeset
for help on using the changeset viewer.