Mirror of the Vim source from https://github.com/vim/vim
Revisão | 4a4b16c67c62174b3b66848a32f4e5554b9cf6c0 (tree) |
---|---|
Hora | 2007-01-14 23:28:34 |
Autor | vimboss |
Commiter | vimboss |
updated for version 7.0-183
@@ -898,6 +898,7 @@ | ||
898 | 898 | } |
899 | 899 | |
900 | 900 | static lval_T *redir_lval = NULL; |
901 | +static garray_T redir_ga; /* only valid when redir_lval is not NULL */ | |
901 | 902 | static char_u *redir_endp = NULL; |
902 | 903 | static char_u *redir_varname = NULL; |
903 | 904 |
@@ -932,6 +933,9 @@ | ||
932 | 933 | return FAIL; |
933 | 934 | } |
934 | 935 | |
936 | + /* The output is stored in growarray "redir_ga" until redirection ends. */ | |
937 | + ga_init2(&redir_ga, (int)sizeof(char), 500); | |
938 | + | |
935 | 939 | /* Parse the variable name (can be a dict or list entry). */ |
936 | 940 | redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, |
937 | 941 | FNE_CHECK_START); |
@@ -974,42 +978,36 @@ | ||
974 | 978 | } |
975 | 979 | |
976 | 980 | /* |
977 | - * Append "value[len]" to the variable set by var_redir_start(). | |
981 | + * Append "value[value_len]" to the variable set by var_redir_start(). | |
982 | + * The actual appending is postponed until redirection ends, because the value | |
983 | + * appended may in fact be the string we write to, changing it may cause freed | |
984 | + * memory to be used: | |
985 | + * :redir => foo | |
986 | + * :let foo | |
987 | + * :redir END | |
978 | 988 | */ |
979 | 989 | void |
980 | -var_redir_str(value, len) | |
990 | +var_redir_str(value, value_len) | |
981 | 991 | char_u *value; |
982 | - int len; | |
983 | -{ | |
984 | - char_u *val; | |
985 | - typval_T tv; | |
986 | - int save_emsg; | |
987 | - int err; | |
992 | + int value_len; | |
993 | +{ | |
994 | + size_t len; | |
988 | 995 | |
989 | 996 | if (redir_lval == NULL) |
990 | 997 | return; |
991 | 998 | |
992 | - if (len == -1) | |
993 | - /* Append the entire string */ | |
994 | - val = vim_strsave(value); | |
995 | - else | |
996 | - /* Append only the specified number of characters */ | |
997 | - val = vim_strnsave(value, len); | |
998 | - if (val == NULL) | |
999 | - return; | |
1000 | - | |
1001 | - tv.v_type = VAR_STRING; | |
1002 | - tv.vval.v_string = val; | |
1003 | - | |
1004 | - save_emsg = did_emsg; | |
1005 | - did_emsg = FALSE; | |
1006 | - set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); | |
1007 | - err = did_emsg; | |
1008 | - did_emsg |= save_emsg; | |
1009 | - if (err) | |
999 | + if (value_len == -1) | |
1000 | + len = STRLEN(value); /* Append the entire string */ | |
1001 | + else | |
1002 | + len = value_len; /* Append only "value_len" characters */ | |
1003 | + | |
1004 | + if (ga_grow(&redir_ga, (int)len) == OK) | |
1005 | + { | |
1006 | + mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len); | |
1007 | + redir_ga.ga_len += len; | |
1008 | + } | |
1009 | + else | |
1010 | 1010 | var_redir_stop(); |
1011 | - | |
1012 | - vim_free(tv.vval.v_string); | |
1013 | 1011 | } |
1014 | 1012 | |
1015 | 1013 | /* |
@@ -1018,8 +1016,19 @@ | ||
1018 | 1016 | void |
1019 | 1017 | var_redir_stop() |
1020 | 1018 | { |
1019 | + typval_T tv; | |
1020 | + | |
1021 | 1021 | if (redir_lval != NULL) |
1022 | 1022 | { |
1023 | + /* Append the trailing NUL. */ | |
1024 | + ga_append(&redir_ga, NUL); | |
1025 | + | |
1026 | + /* Assign the text to the variable. */ | |
1027 | + tv.v_type = VAR_STRING; | |
1028 | + tv.vval.v_string = redir_ga.ga_data; | |
1029 | + set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); | |
1030 | + vim_free(tv.vval.v_string); | |
1031 | + | |
1023 | 1032 | clear_lval(redir_lval); |
1024 | 1033 | vim_free(redir_lval); |
1025 | 1034 | redir_lval = NULL; |
@@ -667,6 +667,8 @@ | ||
667 | 667 | static int included_patches[] = |
668 | 668 | { /* Add new patch number below this line */ |
669 | 669 | /**/ |
670 | + 183, | |
671 | +/**/ | |
670 | 672 | 182, |
671 | 673 | /**/ |
672 | 674 | 181, |