1
0
forked from aniani/vim

patch 8.2.2606: strchars() defaults to counting composing characters

Problem:    strchars() defaults to counting composing characters.
Solution:   Add strcharlen() which ignores composing characters.
This commit is contained in:
Bram Moolenaar
2021-03-14 19:02:09 +01:00
parent 0289a093a4
commit 70ce8a1561
5 changed files with 59 additions and 15 deletions

View File

@@ -223,6 +223,7 @@ static void f_str2float(typval_T *argvars, typval_T *rettv);
#endif
static void f_str2list(typval_T *argvars, typval_T *rettv);
static void f_str2nr(typval_T *argvars, typval_T *rettv);
static void f_strcharlen(typval_T *argvars, typval_T *rettv);
static void f_strchars(typval_T *argvars, typval_T *rettv);
static void f_strgetchar(typval_T *argvars, typval_T *rettv);
static void f_stridx(typval_T *argvars, typval_T *rettv);
@@ -1572,6 +1573,8 @@ static funcentry_T global_functions[] =
ret_list_number, f_str2list},
{"str2nr", 1, 3, FEARG_1, arg3_string_nr_bool,
ret_number, f_str2nr},
{"strcharlen", 1, 1, FEARG_1, NULL,
ret_number, f_strcharlen},
{"strcharpart", 2, 3, FEARG_1, NULL,
ret_string, f_strcharpart},
{"strchars", 1, 2, FEARG_1, NULL,
@@ -9236,31 +9239,45 @@ f_strlen(typval_T *argvars, typval_T *rettv)
tv_get_string(&argvars[0])));
}
static void
strchar_common(typval_T *argvars, typval_T *rettv, int skipcc)
{
char_u *s = tv_get_string(&argvars[0]);
varnumber_T len = 0;
int (*func_mb_ptr2char_adv)(char_u **pp);
func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv;
while (*s != NUL)
{
func_mb_ptr2char_adv(&s);
++len;
}
rettv->vval.v_number = len;
}
/*
* "strcharlen()" function
*/
static void
f_strcharlen(typval_T *argvars, typval_T *rettv)
{
strchar_common(argvars, rettv, TRUE);
}
/*
* "strchars()" function
*/
static void
f_strchars(typval_T *argvars, typval_T *rettv)
{
char_u *s = tv_get_string(&argvars[0]);
varnumber_T skipcc = FALSE;
varnumber_T len = 0;
int (*func_mb_ptr2char_adv)(char_u **pp);
if (argvars[1].v_type != VAR_UNKNOWN)
skipcc = tv_get_bool(&argvars[1]);
if (skipcc < 0 || skipcc > 1)
semsg(_(e_using_number_as_bool_nr), skipcc);
else
{
func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv;
while (*s != NUL)
{
func_mb_ptr2char_adv(&s);
++len;
}
rettv->vval.v_number = len;
}
strchar_common(argvars, rettv, skipcc);
}
/*