Mercurial > vim
comparison src/eval.c @ 9157:e316b83892c1 v7.4.1862
commit https://github.com/vim/vim/commit/18dfb4404a618c52ee7138630a2381aed4d66eaf
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue May 31 22:31:23 2016 +0200
patch 7.4.1862
Problem: string() with repeated argument does not give a result usable by
eval().
Solution: Refactor echo_striong and tv2string(), moving the common part to
echo_string_core(). (Ken Takata)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 31 May 2016 22:45:06 +0200 |
parents | c2fe86f2bda1 |
children | 731ee601de16 |
comparison
equal
deleted
inserted
replaced
9156:724c5ba6e649 | 9157:e316b83892c1 |
---|---|
443 static long list_find_nr(list_T *l, long idx, int *errorp); | 443 static long list_find_nr(list_T *l, long idx, int *errorp); |
444 static long list_idx_of_item(list_T *l, listitem_T *item); | 444 static long list_idx_of_item(list_T *l, listitem_T *item); |
445 static int list_extend(list_T *l1, list_T *l2, listitem_T *bef); | 445 static int list_extend(list_T *l1, list_T *l2, listitem_T *bef); |
446 static int list_concat(list_T *l1, list_T *l2, typval_T *tv); | 446 static int list_concat(list_T *l1, list_T *l2, typval_T *tv); |
447 static list_T *list_copy(list_T *orig, int deep, int copyID); | 447 static list_T *list_copy(list_T *orig, int deep, int copyID); |
448 static char_u *list2string(typval_T *tv, int copyID); | 448 static char_u *list2string(typval_T *tv, int copyID, int restore_copyID); |
449 static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int echo_style, int copyID, garray_T *join_gap); | 449 static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID, garray_T *join_gap); |
450 static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo, int copyID); | 450 static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID); |
451 static int free_unref_items(int copyID); | 451 static int free_unref_items(int copyID); |
452 static dictitem_T *dictitem_copy(dictitem_T *org); | 452 static dictitem_T *dictitem_copy(dictitem_T *org); |
453 static void dictitem_remove(dict_T *dict, dictitem_T *item); | 453 static void dictitem_remove(dict_T *dict, dictitem_T *item); |
454 static dict_T *dict_copy(dict_T *orig, int deep, int copyID); | 454 static dict_T *dict_copy(dict_T *orig, int deep, int copyID); |
455 static long dict_len(dict_T *d); | 455 static long dict_len(dict_T *d); |
456 static char_u *dict2string(typval_T *tv, int copyID); | 456 static char_u *dict2string(typval_T *tv, int copyID, int restore_copyID); |
457 static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate); | 457 static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate); |
458 static char_u *echo_string_core(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID, int echo_style, int restore_copyID, int dict_val); | |
458 static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); | 459 static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); |
459 static char_u *string_quote(char_u *str, int function); | 460 static char_u *string_quote(char_u *str, int function); |
460 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); | 461 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); |
461 static int find_internal_func(char_u *name); | 462 static int find_internal_func(char_u *name); |
462 static char_u *deref_func_name(char_u *name, int *lenp, partial_T **partial, int no_autoload); | 463 static char_u *deref_func_name(char_u *name, int *lenp, partial_T **partial, int no_autoload); |
1460 if (convert && tv.v_type == VAR_LIST) | 1461 if (convert && tv.v_type == VAR_LIST) |
1461 { | 1462 { |
1462 ga_init2(&ga, (int)sizeof(char), 80); | 1463 ga_init2(&ga, (int)sizeof(char), 80); |
1463 if (tv.vval.v_list != NULL) | 1464 if (tv.vval.v_list != NULL) |
1464 { | 1465 { |
1465 list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0); | 1466 list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, FALSE, 0); |
1466 if (tv.vval.v_list->lv_len > 0) | 1467 if (tv.vval.v_list->lv_len > 0) |
1467 ga_append(&ga, NL); | 1468 ga_append(&ga, NL); |
1468 } | 1469 } |
1469 ga_append(&ga, NUL); | 1470 ga_append(&ga, NUL); |
1470 retval = (char_u *)ga.ga_data; | 1471 retval = (char_u *)ga.ga_data; |
6764 /* | 6765 /* |
6765 * Return an allocated string with the string representation of a list. | 6766 * Return an allocated string with the string representation of a list. |
6766 * May return NULL. | 6767 * May return NULL. |
6767 */ | 6768 */ |
6768 static char_u * | 6769 static char_u * |
6769 list2string(typval_T *tv, int copyID) | 6770 list2string(typval_T *tv, int copyID, int restore_copyID) |
6770 { | 6771 { |
6771 garray_T ga; | 6772 garray_T ga; |
6772 | 6773 |
6773 if (tv->vval.v_list == NULL) | 6774 if (tv->vval.v_list == NULL) |
6774 return NULL; | 6775 return NULL; |
6775 ga_init2(&ga, (int)sizeof(char), 80); | 6776 ga_init2(&ga, (int)sizeof(char), 80); |
6776 ga_append(&ga, '['); | 6777 ga_append(&ga, '['); |
6777 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL) | 6778 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", |
6779 FALSE, restore_copyID, copyID) == FAIL) | |
6778 { | 6780 { |
6779 vim_free(ga.ga_data); | 6781 vim_free(ga.ga_data); |
6780 return NULL; | 6782 return NULL; |
6781 } | 6783 } |
6782 ga_append(&ga, ']'); | 6784 ga_append(&ga, ']'); |
6793 list_join_inner( | 6795 list_join_inner( |
6794 garray_T *gap, /* to store the result in */ | 6796 garray_T *gap, /* to store the result in */ |
6795 list_T *l, | 6797 list_T *l, |
6796 char_u *sep, | 6798 char_u *sep, |
6797 int echo_style, | 6799 int echo_style, |
6800 int restore_copyID, | |
6798 int copyID, | 6801 int copyID, |
6799 garray_T *join_gap) /* to keep each list item string */ | 6802 garray_T *join_gap) /* to keep each list item string */ |
6800 { | 6803 { |
6801 int i; | 6804 int i; |
6802 join_T *p; | 6805 join_T *p; |
6809 char_u *s; | 6812 char_u *s; |
6810 | 6813 |
6811 /* Stringify each item in the list. */ | 6814 /* Stringify each item in the list. */ |
6812 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) | 6815 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) |
6813 { | 6816 { |
6814 if (echo_style) | 6817 s = echo_string_core(&item->li_tv, &tofree, numbuf, copyID, |
6815 s = echo_string(&item->li_tv, &tofree, numbuf, copyID); | 6818 echo_style, restore_copyID, FALSE); |
6816 else | |
6817 s = tv2string(&item->li_tv, &tofree, numbuf, copyID); | |
6818 if (s == NULL) | 6819 if (s == NULL) |
6819 return FAIL; | 6820 return FAIL; |
6820 | 6821 |
6821 len = (int)STRLEN(s); | 6822 len = (int)STRLEN(s); |
6822 sumlen += len; | 6823 sumlen += len; |
6871 list_join( | 6872 list_join( |
6872 garray_T *gap, | 6873 garray_T *gap, |
6873 list_T *l, | 6874 list_T *l, |
6874 char_u *sep, | 6875 char_u *sep, |
6875 int echo_style, | 6876 int echo_style, |
6877 int restore_copyID, | |
6876 int copyID) | 6878 int copyID) |
6877 { | 6879 { |
6878 garray_T join_ga; | 6880 garray_T join_ga; |
6879 int retval; | 6881 int retval; |
6880 join_T *p; | 6882 join_T *p; |
6881 int i; | 6883 int i; |
6882 | 6884 |
6883 if (l->lv_len < 1) | 6885 if (l->lv_len < 1) |
6884 return OK; /* nothing to do */ | 6886 return OK; /* nothing to do */ |
6885 ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len); | 6887 ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len); |
6886 retval = list_join_inner(gap, l, sep, echo_style, copyID, &join_ga); | 6888 retval = list_join_inner(gap, l, sep, echo_style, restore_copyID, |
6889 copyID, &join_ga); | |
6887 | 6890 |
6888 /* Dispose each item in join_ga. */ | 6891 /* Dispose each item in join_ga. */ |
6889 if (join_ga.ga_data != NULL) | 6892 if (join_ga.ga_data != NULL) |
6890 { | 6893 { |
6891 p = (join_T *)join_ga.ga_data; | 6894 p = (join_T *)join_ga.ga_data; |
7831 /* | 7834 /* |
7832 * Return an allocated string with the string representation of a Dictionary. | 7835 * Return an allocated string with the string representation of a Dictionary. |
7833 * May return NULL. | 7836 * May return NULL. |
7834 */ | 7837 */ |
7835 static char_u * | 7838 static char_u * |
7836 dict2string(typval_T *tv, int copyID) | 7839 dict2string(typval_T *tv, int copyID, int restore_copyID) |
7837 { | 7840 { |
7838 garray_T ga; | 7841 garray_T ga; |
7839 int first = TRUE; | 7842 int first = TRUE; |
7840 char_u *tofree; | 7843 char_u *tofree; |
7841 char_u numbuf[NUMBUFLEN]; | 7844 char_u numbuf[NUMBUFLEN]; |
7866 { | 7869 { |
7867 ga_concat(&ga, tofree); | 7870 ga_concat(&ga, tofree); |
7868 vim_free(tofree); | 7871 vim_free(tofree); |
7869 } | 7872 } |
7870 ga_concat(&ga, (char_u *)": "); | 7873 ga_concat(&ga, (char_u *)": "); |
7871 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID); | 7874 s = echo_string_core(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID, |
7875 FALSE, restore_copyID, TRUE); | |
7872 if (s != NULL) | 7876 if (s != NULL) |
7873 ga_concat(&ga, s); | 7877 ga_concat(&ga, s); |
7874 vim_free(tofree); | 7878 vim_free(tofree); |
7875 if (s == NULL || did_echo_string_emsg) | 7879 if (s == NULL || did_echo_string_emsg) |
7876 break; | 7880 break; |
8024 | 8028 |
8025 /* | 8029 /* |
8026 * Return a string with the string representation of a variable. | 8030 * Return a string with the string representation of a variable. |
8027 * If the memory is allocated "tofree" is set to it, otherwise NULL. | 8031 * If the memory is allocated "tofree" is set to it, otherwise NULL. |
8028 * "numbuf" is used for a number. | 8032 * "numbuf" is used for a number. |
8029 * Does not put quotes around strings, as ":echo" displays values. | |
8030 * When "copyID" is not NULL replace recursive lists and dicts with "...". | 8033 * When "copyID" is not NULL replace recursive lists and dicts with "...". |
8034 * When both "echo_style" and "dict_val" are FALSE, put quotes around stings as | |
8035 * "string()", otherwise does not put quotes around strings, as ":echo" | |
8036 * displays values. | |
8037 * When "restore_copyID" is FALSE, repeated items in dictionaries and lists | |
8038 * are replaced with "...". | |
8031 * May return NULL. | 8039 * May return NULL. |
8032 */ | 8040 */ |
8033 static char_u * | 8041 static char_u * |
8034 echo_string( | 8042 echo_string_core( |
8035 typval_T *tv, | 8043 typval_T *tv, |
8036 char_u **tofree, | 8044 char_u **tofree, |
8037 char_u *numbuf, | 8045 char_u *numbuf, |
8038 int copyID) | 8046 int copyID, |
8047 int echo_style, | |
8048 int restore_copyID, | |
8049 int dict_val) | |
8039 { | 8050 { |
8040 static int recurse = 0; | 8051 static int recurse = 0; |
8041 char_u *r = NULL; | 8052 char_u *r = NULL; |
8042 | 8053 |
8043 if (recurse >= DICT_MAXNEST) | 8054 if (recurse >= DICT_MAXNEST) |
8055 } | 8066 } |
8056 ++recurse; | 8067 ++recurse; |
8057 | 8068 |
8058 switch (tv->v_type) | 8069 switch (tv->v_type) |
8059 { | 8070 { |
8071 case VAR_STRING: | |
8072 if (echo_style && !dict_val) | |
8073 { | |
8074 *tofree = NULL; | |
8075 r = get_tv_string_buf(tv, numbuf); | |
8076 } | |
8077 else | |
8078 { | |
8079 *tofree = string_quote(tv->vval.v_string, FALSE); | |
8080 r = *tofree; | |
8081 } | |
8082 break; | |
8083 | |
8060 case VAR_FUNC: | 8084 case VAR_FUNC: |
8061 *tofree = NULL; | 8085 if (echo_style) |
8062 r = tv->vval.v_string; | 8086 { |
8087 *tofree = NULL; | |
8088 r = tv->vval.v_string; | |
8089 } | |
8090 else | |
8091 { | |
8092 *tofree = string_quote(tv->vval.v_string, TRUE); | |
8093 r = *tofree; | |
8094 } | |
8063 break; | 8095 break; |
8064 | 8096 |
8065 case VAR_PARTIAL: | 8097 case VAR_PARTIAL: |
8066 { | 8098 { |
8067 partial_T *pt = tv->vval.v_partial; | 8099 partial_T *pt = tv->vval.v_partial; |
8112 if (tv->vval.v_list == NULL) | 8144 if (tv->vval.v_list == NULL) |
8113 { | 8145 { |
8114 *tofree = NULL; | 8146 *tofree = NULL; |
8115 r = NULL; | 8147 r = NULL; |
8116 } | 8148 } |
8117 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID) | 8149 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID |
8150 && tv->vval.v_list->lv_len > 0) | |
8118 { | 8151 { |
8119 *tofree = NULL; | 8152 *tofree = NULL; |
8120 r = (char_u *)"[...]"; | 8153 r = (char_u *)"[...]"; |
8121 } | 8154 } |
8122 else | 8155 else |
8123 { | 8156 { |
8157 int old_copyID = tv->vval.v_list->lv_copyID; | |
8158 | |
8124 tv->vval.v_list->lv_copyID = copyID; | 8159 tv->vval.v_list->lv_copyID = copyID; |
8125 *tofree = list2string(tv, copyID); | 8160 *tofree = list2string(tv, copyID, restore_copyID); |
8161 if (restore_copyID) | |
8162 tv->vval.v_list->lv_copyID = old_copyID; | |
8126 r = *tofree; | 8163 r = *tofree; |
8127 } | 8164 } |
8128 break; | 8165 break; |
8129 | 8166 |
8130 case VAR_DICT: | 8167 case VAR_DICT: |
8131 if (tv->vval.v_dict == NULL) | 8168 if (tv->vval.v_dict == NULL) |
8132 { | 8169 { |
8133 *tofree = NULL; | 8170 *tofree = NULL; |
8134 r = NULL; | 8171 r = NULL; |
8135 } | 8172 } |
8136 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID) | 8173 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID |
8174 && tv->vval.v_dict->dv_hashtab.ht_used != 0) | |
8137 { | 8175 { |
8138 *tofree = NULL; | 8176 *tofree = NULL; |
8139 r = (char_u *)"{...}"; | 8177 r = (char_u *)"{...}"; |
8140 } | 8178 } |
8141 else | 8179 else |
8142 { | 8180 { |
8181 int old_copyID = tv->vval.v_dict->dv_copyID; | |
8143 tv->vval.v_dict->dv_copyID = copyID; | 8182 tv->vval.v_dict->dv_copyID = copyID; |
8144 *tofree = dict2string(tv, copyID); | 8183 *tofree = dict2string(tv, copyID, restore_copyID); |
8184 if (restore_copyID) | |
8185 tv->vval.v_dict->dv_copyID = old_copyID; | |
8145 r = *tofree; | 8186 r = *tofree; |
8146 } | 8187 } |
8147 break; | 8188 break; |
8148 | 8189 |
8149 case VAR_STRING: | |
8150 case VAR_NUMBER: | 8190 case VAR_NUMBER: |
8151 case VAR_UNKNOWN: | 8191 case VAR_UNKNOWN: |
8152 case VAR_JOB: | 8192 case VAR_JOB: |
8153 case VAR_CHANNEL: | 8193 case VAR_CHANNEL: |
8154 *tofree = NULL; | 8194 *tofree = NULL; |
8176 | 8216 |
8177 /* | 8217 /* |
8178 * Return a string with the string representation of a variable. | 8218 * Return a string with the string representation of a variable. |
8179 * If the memory is allocated "tofree" is set to it, otherwise NULL. | 8219 * If the memory is allocated "tofree" is set to it, otherwise NULL. |
8180 * "numbuf" is used for a number. | 8220 * "numbuf" is used for a number. |
8221 * Does not put quotes around strings, as ":echo" displays values. | |
8222 * When "copyID" is not NULL replace recursive lists and dicts with "...". | |
8223 * May return NULL. | |
8224 */ | |
8225 static char_u * | |
8226 echo_string( | |
8227 typval_T *tv, | |
8228 char_u **tofree, | |
8229 char_u *numbuf, | |
8230 int copyID) | |
8231 { | |
8232 return echo_string_core(tv, tofree, numbuf, copyID, TRUE, FALSE, FALSE); | |
8233 } | |
8234 | |
8235 /* | |
8236 * Return a string with the string representation of a variable. | |
8237 * If the memory is allocated "tofree" is set to it, otherwise NULL. | |
8238 * "numbuf" is used for a number. | |
8181 * Puts quotes around strings, so that they can be parsed back by eval(). | 8239 * Puts quotes around strings, so that they can be parsed back by eval(). |
8182 * May return NULL. | 8240 * May return NULL. |
8183 */ | 8241 */ |
8184 char_u * | 8242 char_u * |
8185 tv2string( | 8243 tv2string( |
8186 typval_T *tv, | 8244 typval_T *tv, |
8187 char_u **tofree, | 8245 char_u **tofree, |
8188 char_u *numbuf, | 8246 char_u *numbuf, |
8189 int copyID) | 8247 int copyID) |
8190 { | 8248 { |
8191 switch (tv->v_type) | 8249 return echo_string_core(tv, tofree, numbuf, copyID, FALSE, TRUE, FALSE); |
8192 { | |
8193 case VAR_FUNC: | |
8194 *tofree = string_quote(tv->vval.v_string, TRUE); | |
8195 return *tofree; | |
8196 case VAR_STRING: | |
8197 *tofree = string_quote(tv->vval.v_string, FALSE); | |
8198 return *tofree; | |
8199 case VAR_FLOAT: | |
8200 #ifdef FEAT_FLOAT | |
8201 *tofree = NULL; | |
8202 vim_snprintf((char *)numbuf, NUMBUFLEN - 1, "%g", tv->vval.v_float); | |
8203 return numbuf; | |
8204 #endif | |
8205 case VAR_NUMBER: | |
8206 case VAR_LIST: | |
8207 case VAR_DICT: | |
8208 case VAR_PARTIAL: | |
8209 case VAR_SPECIAL: | |
8210 case VAR_JOB: | |
8211 case VAR_CHANNEL: | |
8212 case VAR_UNKNOWN: | |
8213 break; | |
8214 } | |
8215 return echo_string(tv, tofree, numbuf, copyID); | |
8216 } | 8250 } |
8217 | 8251 |
8218 /* | 8252 /* |
8219 * Return string "str" in ' quotes, doubling ' characters. | 8253 * Return string "str" in ' quotes, doubling ' characters. |
8220 * If "str" is NULL an empty string is assumed. | 8254 * If "str" is NULL an empty string is assumed. |
15180 rettv->v_type = VAR_STRING; | 15214 rettv->v_type = VAR_STRING; |
15181 | 15215 |
15182 if (sep != NULL) | 15216 if (sep != NULL) |
15183 { | 15217 { |
15184 ga_init2(&ga, (int)sizeof(char), 80); | 15218 ga_init2(&ga, (int)sizeof(char), 80); |
15185 list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0); | 15219 list_join(&ga, argvars[0].vval.v_list, sep, TRUE, FALSE, 0); |
15186 ga_append(&ga, NUL); | 15220 ga_append(&ga, NUL); |
15187 rettv->vval.v_string = (char_u *)ga.ga_data; | 15221 rettv->vval.v_string = (char_u *)ga.ga_data; |
15188 } | 15222 } |
15189 else | 15223 else |
15190 rettv->vval.v_string = NULL; | 15224 rettv->vval.v_string = NULL; |