From 641e48c2248ccb3c25a5cdaa3709f16152d8c77d Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 25 Jun 2015 16:09:26 +0200 Subject: [PATCH] patch 7.4.755 Problem: It is not easy to count the number of characters. Solution: Add the skipcc argument to strchars(). (Hirohito Higashi, Ken Takata) --- runtime/doc/eval.txt | 12 ++++-------- src/eval.c | 28 ++++++++++++++++++++-------- src/testdir/test_utf8.in | 6 ++++++ src/testdir/test_utf8.ok | 15 +++++++++++++++ src/version.c | 2 ++ 5 files changed, 47 insertions(+), 16 deletions(-) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 44abae624..223c36393 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1985,7 +1985,7 @@ split( {expr} [, {pat} [, {keepempty}]]) sqrt( {expr}) Float square root of {expr} str2float( {expr}) Float convert String to Float str2nr( {expr} [, {base}]) Number convert String to Number -strchars( {expr}) Number character length of the String {expr} +strchars( {expr} [, {skipcc}]) Number character length of the String {expr} strdisplaywidth( {expr} [, {col}]) Number display length of the String {expr} strftime( {format}[, {time}]) String time in specified format stridx( {haystack}, {needle}[, {start}]) @@ -5913,15 +5913,11 @@ string({expr}) Return {expr} converted to a String. If {expr} is a Number, *strlen()* strlen({expr}) The result is a Number, which is the length of the String {expr} in bytes. - If you want to count the number of multi-byte characters (not - counting composing characters) use something like this: > - - :let len = strlen(substitute(str, ".", "x", "g")) -< If the argument is a Number it is first converted to a String. For other types an error is given. - Also see |len()|, |strchars()|, |strdisplaywidth()| and - |strwidth()|. + If you want to count the number of multi-byte characters use + |strchars()|. + Also see |len()|, |strdisplaywidth()| and |strwidth()|. strpart({src}, {start}[, {len}]) *strpart()* The result is a String, which is part of {src}, starting from diff --git a/src/eval.c b/src/eval.c index 452014f75..5869370f3 100644 --- a/src/eval.c +++ b/src/eval.c @@ -3810,7 +3810,7 @@ do_lock_var(lp, name_end, deep, lock) /* (un)lock a List item. */ item_lock(&lp->ll_li->li_tv, deep, lock); else - /* un(lock) a Dictionary item. */ + /* (un)lock a Dictionary item. */ item_lock(&lp->ll_di->di_tv, deep, lock); return ret; @@ -8309,7 +8309,7 @@ static struct fst {"str2float", 1, 1, f_str2float}, #endif {"str2nr", 1, 2, f_str2nr}, - {"strchars", 1, 1, f_strchars}, + {"strchars", 1, 2, f_strchars}, {"strdisplaywidth", 1, 2, f_strdisplaywidth}, #ifdef HAVE_STRFTIME {"strftime", 1, 2, f_strftime}, @@ -18372,18 +18372,30 @@ f_strchars(argvars, rettv) typval_T *rettv; { char_u *s = get_tv_string(&argvars[0]); + int skipcc = 0; #ifdef FEAT_MBYTE varnumber_T len = 0; + int (*func_mb_ptr2char_adv)(char_u **pp); +#endif - while (*s != NUL) + if (argvars[1].v_type != VAR_UNKNOWN) + skipcc = get_tv_number_chk(&argvars[1], NULL); + if (skipcc < 0 || skipcc > 1) + EMSG(_(e_invarg)); + else { - mb_cptr2char_adv(&s); - ++len; - } - rettv->vval.v_number = len; +#ifdef FEAT_MBYTE + 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; #else - rettv->vval.v_number = (varnumber_T)(STRLEN(s)); + rettv->vval.v_number = (varnumber_T)(STRLEN(s)); #endif + } } /* diff --git a/src/testdir/test_utf8.in b/src/testdir/test_utf8.in index 713fee2c8..8bc783e29 100644 --- a/src/testdir/test_utf8.in +++ b/src/testdir/test_utf8.in @@ -11,6 +11,12 @@ STARTTEST : :bwipeout! :$put=r +:" Test for built-in function strchars() +:for str in ["a", "あいa", "A\u20dd", "A\u20dd\u20dd", "\u20dd"] +: $put=strchars(str) +: $put=strchars(str, 0) +: $put=strchars(str, 1) +:endfor :call garbagecollect(1) :/^start:/,$wq! test.out ENDTEST diff --git a/src/testdir/test_utf8.ok b/src/testdir/test_utf8.ok index c5bed5485..8ccdd6d7a 100644 --- a/src/testdir/test_utf8.ok +++ b/src/testdir/test_utf8.ok @@ -2,3 +2,18 @@ start: axaa xあああ bxbb +1 +1 +1 +3 +3 +3 +2 +2 +1 +3 +3 +1 +1 +1 +1 diff --git a/src/version.c b/src/version.c index eeef1c758..e712dc405 100644 --- a/src/version.c +++ b/src/version.c @@ -741,6 +741,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 755, /**/ 754, /**/ -- 2.40.0