comparison src/eval.c @ 8710:af3cb5c068fd v7.4.1644

commit https://github.com/vim/vim/commit/24c77a1e3a2ad510582116229462b482d69b4b8e Author: Bram Moolenaar <Bram@vim.org> Date: Thu Mar 24 21:23:06 2016 +0100 patch 7.4.1644 Problem: Using string() on a partial that exists in the dictionary it binds results in an error. (Nikolai Pavlov) Solution: Make string() not fail on a recursively nested structure. (Ken Takta)
author Christian Brabandt <cb@256bit.org>
date Thu, 24 Mar 2016 21:30:06 +0100
parents 31f9fa8e1532
children 65130a9d3386
comparison
equal deleted inserted replaced
8709:0e13fb6f07f4 8710:af3cb5c068fd
7849 *tofree = NULL; 7849 *tofree = NULL;
7850 r = tv->vval.v_string; 7850 r = tv->vval.v_string;
7851 break; 7851 break;
7852 7852
7853 case VAR_PARTIAL: 7853 case VAR_PARTIAL:
7854 *tofree = NULL;
7855 /* TODO: arguments */
7856 r = tv->vval.v_partial == NULL ? NULL : tv->vval.v_partial->pt_name;
7857 break;
7858
7859 case VAR_LIST:
7860 if (tv->vval.v_list == NULL)
7861 {
7862 *tofree = NULL;
7863 r = NULL;
7864 }
7865 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID)
7866 {
7867 *tofree = NULL;
7868 r = (char_u *)"[...]";
7869 }
7870 else
7871 {
7872 tv->vval.v_list->lv_copyID = copyID;
7873 *tofree = list2string(tv, copyID);
7874 r = *tofree;
7875 }
7876 break;
7877
7878 case VAR_DICT:
7879 if (tv->vval.v_dict == NULL)
7880 {
7881 *tofree = NULL;
7882 r = NULL;
7883 }
7884 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID)
7885 {
7886 *tofree = NULL;
7887 r = (char_u *)"{...}";
7888 }
7889 else
7890 {
7891 tv->vval.v_dict->dv_copyID = copyID;
7892 *tofree = dict2string(tv, copyID);
7893 r = *tofree;
7894 }
7895 break;
7896
7897 case VAR_STRING:
7898 case VAR_NUMBER:
7899 case VAR_UNKNOWN:
7900 case VAR_JOB:
7901 case VAR_CHANNEL:
7902 *tofree = NULL;
7903 r = get_tv_string_buf(tv, numbuf);
7904 break;
7905
7906 case VAR_FLOAT:
7907 #ifdef FEAT_FLOAT
7908 *tofree = NULL;
7909 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float);
7910 r = numbuf;
7911 break;
7912 #endif
7913
7914 case VAR_SPECIAL:
7915 *tofree = NULL;
7916 r = (char_u *)get_var_special_name(tv->vval.v_number);
7917 break;
7918 }
7919
7920 if (--recurse == 0)
7921 did_echo_string_emsg = FALSE;
7922 return r;
7923 }
7924
7925 /*
7926 * Return a string with the string representation of a variable.
7927 * If the memory is allocated "tofree" is set to it, otherwise NULL.
7928 * "numbuf" is used for a number.
7929 * Puts quotes around strings, so that they can be parsed back by eval().
7930 * May return NULL.
7931 */
7932 static char_u *
7933 tv2string(
7934 typval_T *tv,
7935 char_u **tofree,
7936 char_u *numbuf,
7937 int copyID)
7938 {
7939 switch (tv->v_type)
7940 {
7941 case VAR_FUNC:
7942 *tofree = string_quote(tv->vval.v_string, TRUE);
7943 return *tofree;
7944 case VAR_PARTIAL:
7945 { 7854 {
7946 partial_T *pt = tv->vval.v_partial; 7855 partial_T *pt = tv->vval.v_partial;
7947 char_u *fname = string_quote(pt == NULL ? NULL 7856 char_u *fname = string_quote(pt == NULL ? NULL
7948 : pt->pt_name, FALSE); 7857 : pt->pt_name, FALSE);
7949 garray_T ga; 7858 garray_T ga;
7981 vim_free(tf); 7890 vim_free(tf);
7982 } 7891 }
7983 ga_concat(&ga, (char_u *)")"); 7892 ga_concat(&ga, (char_u *)")");
7984 7893
7985 *tofree = ga.ga_data; 7894 *tofree = ga.ga_data;
7986 return *tofree; 7895 r = *tofree;
7896 break;
7987 } 7897 }
7898
7899 case VAR_LIST:
7900 if (tv->vval.v_list == NULL)
7901 {
7902 *tofree = NULL;
7903 r = NULL;
7904 }
7905 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID)
7906 {
7907 *tofree = NULL;
7908 r = (char_u *)"[...]";
7909 }
7910 else
7911 {
7912 tv->vval.v_list->lv_copyID = copyID;
7913 *tofree = list2string(tv, copyID);
7914 r = *tofree;
7915 }
7916 break;
7917
7918 case VAR_DICT:
7919 if (tv->vval.v_dict == NULL)
7920 {
7921 *tofree = NULL;
7922 r = NULL;
7923 }
7924 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID)
7925 {
7926 *tofree = NULL;
7927 r = (char_u *)"{...}";
7928 }
7929 else
7930 {
7931 tv->vval.v_dict->dv_copyID = copyID;
7932 *tofree = dict2string(tv, copyID);
7933 r = *tofree;
7934 }
7935 break;
7936
7937 case VAR_STRING:
7938 case VAR_NUMBER:
7939 case VAR_UNKNOWN:
7940 case VAR_JOB:
7941 case VAR_CHANNEL:
7942 *tofree = NULL;
7943 r = get_tv_string_buf(tv, numbuf);
7944 break;
7945
7946 case VAR_FLOAT:
7947 #ifdef FEAT_FLOAT
7948 *tofree = NULL;
7949 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float);
7950 r = numbuf;
7951 break;
7952 #endif
7953
7954 case VAR_SPECIAL:
7955 *tofree = NULL;
7956 r = (char_u *)get_var_special_name(tv->vval.v_number);
7957 break;
7958 }
7959
7960 if (--recurse == 0)
7961 did_echo_string_emsg = FALSE;
7962 return r;
7963 }
7964
7965 /*
7966 * Return a string with the string representation of a variable.
7967 * If the memory is allocated "tofree" is set to it, otherwise NULL.
7968 * "numbuf" is used for a number.
7969 * Puts quotes around strings, so that they can be parsed back by eval().
7970 * May return NULL.
7971 */
7972 static char_u *
7973 tv2string(
7974 typval_T *tv,
7975 char_u **tofree,
7976 char_u *numbuf,
7977 int copyID)
7978 {
7979 switch (tv->v_type)
7980 {
7981 case VAR_FUNC:
7982 *tofree = string_quote(tv->vval.v_string, TRUE);
7983 return *tofree;
7988 case VAR_STRING: 7984 case VAR_STRING:
7989 *tofree = string_quote(tv->vval.v_string, FALSE); 7985 *tofree = string_quote(tv->vval.v_string, FALSE);
7990 return *tofree; 7986 return *tofree;
7991 case VAR_FLOAT: 7987 case VAR_FLOAT:
7992 #ifdef FEAT_FLOAT 7988 #ifdef FEAT_FLOAT
7995 return numbuf; 7991 return numbuf;
7996 #endif 7992 #endif
7997 case VAR_NUMBER: 7993 case VAR_NUMBER:
7998 case VAR_LIST: 7994 case VAR_LIST:
7999 case VAR_DICT: 7995 case VAR_DICT:
7996 case VAR_PARTIAL:
8000 case VAR_SPECIAL: 7997 case VAR_SPECIAL:
8001 case VAR_JOB: 7998 case VAR_JOB:
8002 case VAR_CHANNEL: 7999 case VAR_CHANNEL:
8003 case VAR_UNKNOWN: 8000 case VAR_UNKNOWN:
8004 break; 8001 break;
19256 { 19253 {
19257 char_u *tofree; 19254 char_u *tofree;
19258 char_u numbuf[NUMBUFLEN]; 19255 char_u numbuf[NUMBUFLEN];
19259 19256
19260 rettv->v_type = VAR_STRING; 19257 rettv->v_type = VAR_STRING;
19261 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0); 19258 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf,
19259 get_copyID());
19262 /* Make a copy if we have a value but it's not in allocated memory. */ 19260 /* Make a copy if we have a value but it's not in allocated memory. */
19263 if (rettv->vval.v_string != NULL && tofree == NULL) 19261 if (rettv->vval.v_string != NULL && tofree == NULL)
19264 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 19262 rettv->vval.v_string = vim_strsave(rettv->vval.v_string);
19265 } 19263 }
19266 19264