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;