comparison src/evalfunc.c @ 16235:219c58b3879c v8.1.1122

patch 8.1.1122: char2nr() does not handle composing characters commit https://github.com/vim/vim/commit/9d40128afd7fcd038ff6532722b55b1a8c189ce8 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Apr 6 13:18:12 2019 +0200 patch 8.1.1122: char2nr() does not handle composing characters Problem: char2nr() does not handle composing characters. Solution: Add str2list() and list2str(). (Ozaki Kiichi, closes https://github.com/vim/vim/issues/4190)
author Bram Moolenaar <Bram@vim.org>
date Sat, 06 Apr 2019 13:30:04 +0200
parents 0761a4c111a7
children c1698187c482
comparison
equal deleted inserted replaced
16234:dbfd219fe9b3 16235:219c58b3879c
260 static void f_libcall(typval_T *argvars, typval_T *rettv); 260 static void f_libcall(typval_T *argvars, typval_T *rettv);
261 static void f_libcallnr(typval_T *argvars, typval_T *rettv); 261 static void f_libcallnr(typval_T *argvars, typval_T *rettv);
262 static void f_line(typval_T *argvars, typval_T *rettv); 262 static void f_line(typval_T *argvars, typval_T *rettv);
263 static void f_line2byte(typval_T *argvars, typval_T *rettv); 263 static void f_line2byte(typval_T *argvars, typval_T *rettv);
264 static void f_lispindent(typval_T *argvars, typval_T *rettv); 264 static void f_lispindent(typval_T *argvars, typval_T *rettv);
265 static void f_list2str(typval_T *argvars, typval_T *rettv);
265 static void f_localtime(typval_T *argvars, typval_T *rettv); 266 static void f_localtime(typval_T *argvars, typval_T *rettv);
266 #ifdef FEAT_FLOAT 267 #ifdef FEAT_FLOAT
267 static void f_log(typval_T *argvars, typval_T *rettv); 268 static void f_log(typval_T *argvars, typval_T *rettv);
268 static void f_log10(typval_T *argvars, typval_T *rettv); 269 static void f_log10(typval_T *argvars, typval_T *rettv);
269 #endif 270 #endif
399 static void f_split(typval_T *argvars, typval_T *rettv); 400 static void f_split(typval_T *argvars, typval_T *rettv);
400 #ifdef FEAT_FLOAT 401 #ifdef FEAT_FLOAT
401 static void f_sqrt(typval_T *argvars, typval_T *rettv); 402 static void f_sqrt(typval_T *argvars, typval_T *rettv);
402 static void f_str2float(typval_T *argvars, typval_T *rettv); 403 static void f_str2float(typval_T *argvars, typval_T *rettv);
403 #endif 404 #endif
405 static void f_str2list(typval_T *argvars, typval_T *rettv);
404 static void f_str2nr(typval_T *argvars, typval_T *rettv); 406 static void f_str2nr(typval_T *argvars, typval_T *rettv);
405 static void f_strchars(typval_T *argvars, typval_T *rettv); 407 static void f_strchars(typval_T *argvars, typval_T *rettv);
406 #ifdef HAVE_STRFTIME 408 #ifdef HAVE_STRFTIME
407 static void f_strftime(typval_T *argvars, typval_T *rettv); 409 static void f_strftime(typval_T *argvars, typval_T *rettv);
408 #endif 410 #endif
750 {"libcall", 3, 3, f_libcall}, 752 {"libcall", 3, 3, f_libcall},
751 {"libcallnr", 3, 3, f_libcallnr}, 753 {"libcallnr", 3, 3, f_libcallnr},
752 {"line", 1, 1, f_line}, 754 {"line", 1, 1, f_line},
753 {"line2byte", 1, 1, f_line2byte}, 755 {"line2byte", 1, 1, f_line2byte},
754 {"lispindent", 1, 1, f_lispindent}, 756 {"lispindent", 1, 1, f_lispindent},
757 {"list2str", 1, 2, f_list2str},
755 {"localtime", 0, 0, f_localtime}, 758 {"localtime", 0, 0, f_localtime},
756 #ifdef FEAT_FLOAT 759 #ifdef FEAT_FLOAT
757 {"log", 1, 1, f_log}, 760 {"log", 1, 1, f_log},
758 {"log10", 1, 1, f_log10}, 761 {"log10", 1, 1, f_log10},
759 #endif 762 #endif
900 {"split", 1, 3, f_split}, 903 {"split", 1, 3, f_split},
901 #ifdef FEAT_FLOAT 904 #ifdef FEAT_FLOAT
902 {"sqrt", 1, 1, f_sqrt}, 905 {"sqrt", 1, 1, f_sqrt},
903 {"str2float", 1, 1, f_str2float}, 906 {"str2float", 1, 1, f_str2float},
904 #endif 907 #endif
908 {"str2list", 1, 2, f_str2list},
905 {"str2nr", 1, 2, f_str2nr}, 909 {"str2nr", 1, 2, f_str2nr},
906 {"strcharpart", 2, 3, f_strcharpart}, 910 {"strcharpart", 2, 3, f_strcharpart},
907 {"strchars", 1, 2, f_strchars}, 911 {"strchars", 1, 2, f_strchars},
908 {"strdisplaywidth", 1, 2, f_strdisplaywidth}, 912 {"strdisplaywidth", 1, 2, f_strdisplaywidth},
909 #ifdef HAVE_STRFTIME 913 #ifdef HAVE_STRFTIME
7845 curwin->w_cursor = pos; 7849 curwin->w_cursor = pos;
7846 } 7850 }
7847 else 7851 else
7848 #endif 7852 #endif
7849 rettv->vval.v_number = -1; 7853 rettv->vval.v_number = -1;
7854 }
7855
7856 /*
7857 * "list2str()" function
7858 */
7859 static void
7860 f_list2str(typval_T *argvars, typval_T *rettv)
7861 {
7862 list_T *l;
7863 listitem_T *li;
7864 garray_T ga;
7865 int utf8 = FALSE;
7866
7867 rettv->v_type = VAR_STRING;
7868 rettv->vval.v_string = NULL;
7869 if (argvars[0].v_type != VAR_LIST)
7870 {
7871 emsg(_(e_invarg));
7872 return;
7873 }
7874
7875 l = argvars[0].vval.v_list;
7876 if (l == NULL)
7877 return; // empty list results in empty string
7878
7879 if (argvars[1].v_type != VAR_UNKNOWN)
7880 utf8 = (int)tv_get_number_chk(&argvars[1], NULL);
7881
7882 ga_init2(&ga, 1, 80);
7883 if (has_mbyte || utf8)
7884 {
7885 char_u buf[MB_MAXBYTES + 1];
7886 int (*char2bytes)(int, char_u *);
7887
7888 if (utf8 || enc_utf8)
7889 char2bytes = utf_char2bytes;
7890 else
7891 char2bytes = mb_char2bytes;
7892
7893 for (li = l->lv_first; li != NULL; li = li->li_next)
7894 {
7895 buf[(*char2bytes)(tv_get_number(&li->li_tv), buf)] = NUL;
7896 ga_concat(&ga, buf);
7897 }
7898 ga_append(&ga, NUL);
7899 }
7900 else if (ga_grow(&ga, list_len(l) + 1) == OK)
7901 {
7902 for (li = l->lv_first; li != NULL; li = li->li_next)
7903 ga_append(&ga, tv_get_number(&li->li_tv));
7904 ga_append(&ga, NUL);
7905 }
7906
7907 rettv->v_type = VAR_STRING;
7908 rettv->vval.v_string = ga.ga_data;
7850 } 7909 }
7851 7910
7852 /* 7911 /*
7853 * "localtime()" function 7912 * "localtime()" function
7854 */ 7913 */
12899 rettv->v_type = VAR_FLOAT; 12958 rettv->v_type = VAR_FLOAT;
12900 } 12959 }
12901 #endif 12960 #endif
12902 12961
12903 /* 12962 /*
12963 * "str2list()" function
12964 */
12965 static void
12966 f_str2list(typval_T *argvars, typval_T *rettv)
12967 {
12968 char_u *p;
12969 int utf8 = FALSE;
12970
12971 if (rettv_list_alloc(rettv) == FAIL)
12972 return;
12973
12974 if (argvars[1].v_type != VAR_UNKNOWN)
12975 utf8 = (int)tv_get_number_chk(&argvars[1], NULL);
12976
12977 p = tv_get_string(&argvars[0]);
12978
12979 if (has_mbyte || utf8)
12980 {
12981 int (*ptr2len)(char_u *);
12982 int (*ptr2char)(char_u *);
12983
12984 if (utf8 || enc_utf8)
12985 {
12986 ptr2len = utf_ptr2len;
12987 ptr2char = utf_ptr2char;
12988 }
12989 else
12990 {
12991 ptr2len = mb_ptr2len;
12992 ptr2char = mb_ptr2char;
12993 }
12994
12995 for ( ; *p != NUL; p += (*ptr2len)(p))
12996 list_append_number(rettv->vval.v_list, (*ptr2char)(p));
12997 }
12998 else
12999 for ( ; *p != NUL; ++p)
13000 list_append_number(rettv->vval.v_list, *p);
13001 }
13002
13003 /*
12904 * "str2nr()" function 13004 * "str2nr()" function
12905 */ 13005 */
12906 static void 13006 static void
12907 f_str2nr(typval_T *argvars, typval_T *rettv) 13007 f_str2nr(typval_T *argvars, typval_T *rettv)
12908 { 13008 {