Skip to content

Commit 2216f11

Browse files
brammooldouglaskayama
authored andcommitted
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)
1 parent d04cc55 commit 2216f11

5 files changed

Lines changed: 47 additions & 16 deletions

File tree

runtime/doc/eval.txt

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,7 +1985,7 @@ split( {expr} [, {pat} [, {keepempty}]])
19851985
sqrt( {expr}) Float square root of {expr}
19861986
str2float( {expr}) Float convert String to Float
19871987
str2nr( {expr} [, {base}]) Number convert String to Number
1988-
strchars( {expr}) Number character length of the String {expr}
1988+
strchars( {expr} [, {skipcc}]) Number character length of the String {expr}
19891989
strdisplaywidth( {expr} [, {col}]) Number display length of the String {expr}
19901990
strftime( {format}[, {time}]) String time in specified format
19911991
stridx( {haystack}, {needle}[, {start}])
@@ -5913,15 +5913,11 @@ string({expr}) Return {expr} converted to a String. If {expr} is a Number,
59135913
*strlen()*
59145914
strlen({expr}) The result is a Number, which is the length of the String
59155915
{expr} in bytes.
5916-
If you want to count the number of multi-byte characters (not
5917-
counting composing characters) use something like this: >
5918-
5919-
:let len = strlen(substitute(str, ".", "x", "g"))
5920-
<
59215916
If the argument is a Number it is first converted to a String.
59225917
For other types an error is given.
5923-
Also see |len()|, |strchars()|, |strdisplaywidth()| and
5924-
|strwidth()|.
5918+
If you want to count the number of multi-byte characters use
5919+
|strchars()|.
5920+
Also see |len()|, |strdisplaywidth()| and |strwidth()|.
59255921

59265922
strpart({src}, {start}[, {len}]) *strpart()*
59275923
The result is a String, which is part of {src}, starting from

src/eval.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3810,7 +3810,7 @@ do_lock_var(lp, name_end, deep, lock)
38103810
/* (un)lock a List item. */
38113811
item_lock(&lp->ll_li->li_tv, deep, lock);
38123812
else
3813-
/* un(lock) a Dictionary item. */
3813+
/* (un)lock a Dictionary item. */
38143814
item_lock(&lp->ll_di->di_tv, deep, lock);
38153815

38163816
return ret;
@@ -8310,7 +8310,7 @@ static struct fst
83108310
{"str2float", 1, 1, f_str2float},
83118311
#endif
83128312
{"str2nr", 1, 2, f_str2nr},
8313-
{"strchars", 1, 1, f_strchars},
8313+
{"strchars", 1, 2, f_strchars},
83148314
{"strdisplaywidth", 1, 2, f_strdisplaywidth},
83158315
#ifdef HAVE_STRFTIME
83168316
{"strftime", 1, 2, f_strftime},
@@ -18400,18 +18400,30 @@ f_strchars(argvars, rettv)
1840018400
typval_T *rettv;
1840118401
{
1840218402
char_u *s = get_tv_string(&argvars[0]);
18403+
int skipcc = 0;
1840318404
#ifdef FEAT_MBYTE
1840418405
varnumber_T len = 0;
18406+
int (*func_mb_ptr2char_adv)(char_u **pp);
18407+
#endif
1840518408

18406-
while (*s != NUL)
18409+
if (argvars[1].v_type != VAR_UNKNOWN)
18410+
skipcc = get_tv_number_chk(&argvars[1], NULL);
18411+
if (skipcc < 0 || skipcc > 1)
18412+
EMSG(_(e_invarg));
18413+
else
1840718414
{
18408-
mb_cptr2char_adv(&s);
18409-
++len;
18410-
}
18411-
rettv->vval.v_number = len;
18415+
#ifdef FEAT_MBYTE
18416+
func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv;
18417+
while (*s != NUL)
18418+
{
18419+
func_mb_ptr2char_adv(&s);
18420+
++len;
18421+
}
18422+
rettv->vval.v_number = len;
1841218423
#else
18413-
rettv->vval.v_number = (varnumber_T)(STRLEN(s));
18424+
rettv->vval.v_number = (varnumber_T)(STRLEN(s));
1841418425
#endif
18426+
}
1841518427
}
1841618428

1841718429
/*

src/testdir/test_utf8.in

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ STARTTEST
1111
:
1212
:bwipeout!
1313
:$put=r
14+
:" Test for built-in function strchars()
15+
:for str in ["a", "あいa", "A\u20dd", "A\u20dd\u20dd", "\u20dd"]
16+
: $put=strchars(str)
17+
: $put=strchars(str, 0)
18+
: $put=strchars(str, 1)
19+
:endfor
1420
:call garbagecollect(1)
1521
:/^start:/,$wq! test.out
1622
ENDTEST

src/testdir/test_utf8.ok

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,18 @@ start:
22
axaa
33
xあああ
44
bxbb
5+
1
6+
1
7+
1
8+
3
9+
3
10+
3
11+
2
12+
2
13+
1
14+
3
15+
3
16+
1
17+
1
18+
1
19+
1

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,8 @@ static char *(features[]) =
756756

757757
static int included_patches[] =
758758
{ /* Add new patch number below this line */
759+
/**/
760+
755,
759761
/**/
760762
754,
761763
/**/

0 commit comments

Comments
 (0)