Mercurial > vim
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 { |