Skip to content

Commit 8d9f0ef

Browse files
committed
patch 8.0.1004: matchstrpos() without a match returns too many items
Problem: Matchstrpos() without a match returns too many items. Solution: Also remove the second item when the position is beyond the end of the string. (Hirohito Higashi) Use an enum for the type.
1 parent e85928a commit 8d9f0ef

3 files changed

Lines changed: 28 additions & 23 deletions

File tree

src/evalfunc.c

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7250,10 +7250,17 @@ f_mapcheck(typval_T *argvars, typval_T *rettv)
72507250
get_maparg(argvars, rettv, FALSE);
72517251
}
72527252

7253-
static void find_some_match(typval_T *argvars, typval_T *rettv, int start);
7253+
typedef enum
7254+
{
7255+
MATCH_END, /* matchend() */
7256+
MATCH_MATCH, /* match() */
7257+
MATCH_STR, /* matchstr() */
7258+
MATCH_LIST, /* matchlist() */
7259+
MATCH_POS /* matchstrpos() */
7260+
} matchtype_T;
72547261

72557262
static void
7256-
find_some_match(typval_T *argvars, typval_T *rettv, int type)
7263+
find_some_match(typval_T *argvars, typval_T *rettv, matchtype_T type)
72577264
{
72587265
char_u *str = NULL;
72597266
long len = 0;
@@ -7277,13 +7284,13 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
72777284
p_cpo = (char_u *)"";
72787285

72797286
rettv->vval.v_number = -1;
7280-
if (type == 3 || type == 4)
7287+
if (type == MATCH_LIST || type == MATCH_POS)
72817288
{
7282-
/* type 3: return empty list when there are no matches.
7283-
* type 4: return ["", -1, -1, -1] */
7289+
/* type MATCH_LIST: return empty list when there are no matches.
7290+
* type MATCH_POS: return ["", -1, -1, -1] */
72847291
if (rettv_list_alloc(rettv) == FAIL)
72857292
goto theend;
7286-
if (type == 4
7293+
if (type == MATCH_POS
72877294
&& (list_append_string(rettv->vval.v_list,
72887295
(char_u *)"", 0) == FAIL
72897296
|| list_append_number(rettv->vval.v_list,
@@ -7298,7 +7305,7 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
72987305
goto theend;
72997306
}
73007307
}
7301-
else if (type == 2)
7308+
else if (type == MATCH_STR)
73027309
{
73037310
rettv->v_type = VAR_STRING;
73047311
rettv->vval.v_string = NULL;
@@ -7410,7 +7417,7 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
74107417

74117418
if (match)
74127419
{
7413-
if (type == 4)
7420+
if (type == MATCH_POS)
74147421
{
74157422
listitem_T *li1 = rettv->vval.v_list->lv_first;
74167423
listitem_T *li2 = li1->li_next;
@@ -7427,7 +7434,7 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
74277434
if (l != NULL)
74287435
li2->li_tv.vval.v_number = (varnumber_T)idx;
74297436
}
7430-
else if (type == 3)
7437+
else if (type == MATCH_LIST)
74317438
{
74327439
int i;
74337440

@@ -7447,7 +7454,7 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
74477454
break;
74487455
}
74497456
}
7450-
else if (type == 2)
7457+
else if (type == MATCH_STR)
74517458
{
74527459
/* return matched string */
74537460
if (l != NULL)
@@ -7460,7 +7467,7 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
74607467
rettv->vval.v_number = idx;
74617468
else
74627469
{
7463-
if (type != 0)
7470+
if (type != MATCH_END)
74647471
rettv->vval.v_number =
74657472
(varnumber_T)(regmatch.startp[0] - str);
74667473
else
@@ -7472,12 +7479,11 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
74727479
vim_regfree(regmatch.regprog);
74737480
}
74747481

7475-
if (type == 4 && l == NULL)
7482+
theend:
7483+
if (type == MATCH_POS && l == NULL && rettv->vval.v_list != NULL)
74767484
/* matchstrpos() without a list: drop the second item. */
74777485
listitem_remove(rettv->vval.v_list,
74787486
rettv->vval.v_list->lv_first->li_next);
7479-
7480-
theend:
74817487
vim_free(tofree);
74827488
p_cpo = save_cpo;
74837489
}
@@ -7488,7 +7494,7 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
74887494
static void
74897495
f_match(typval_T *argvars, typval_T *rettv)
74907496
{
7491-
find_some_match(argvars, rettv, 1);
7497+
find_some_match(argvars, rettv, MATCH_MATCH);
74927498
}
74937499

74947500
/*
@@ -7656,7 +7662,7 @@ f_matchdelete(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
76567662
static void
76577663
f_matchend(typval_T *argvars, typval_T *rettv)
76587664
{
7659-
find_some_match(argvars, rettv, 0);
7665+
find_some_match(argvars, rettv, MATCH_END);
76607666
}
76617667

76627668
/*
@@ -7665,7 +7671,7 @@ f_matchend(typval_T *argvars, typval_T *rettv)
76657671
static void
76667672
f_matchlist(typval_T *argvars, typval_T *rettv)
76677673
{
7668-
find_some_match(argvars, rettv, 3);
7674+
find_some_match(argvars, rettv, MATCH_LIST);
76697675
}
76707676

76717677
/*
@@ -7674,7 +7680,7 @@ f_matchlist(typval_T *argvars, typval_T *rettv)
76747680
static void
76757681
f_matchstr(typval_T *argvars, typval_T *rettv)
76767682
{
7677-
find_some_match(argvars, rettv, 2);
7683+
find_some_match(argvars, rettv, MATCH_STR);
76787684
}
76797685

76807686
/*
@@ -7683,7 +7689,7 @@ f_matchstr(typval_T *argvars, typval_T *rettv)
76837689
static void
76847690
f_matchstrpos(typval_T *argvars, typval_T *rettv)
76857691
{
7686-
find_some_match(argvars, rettv, 4);
7692+
find_some_match(argvars, rettv, MATCH_POS);
76877693
}
76887694

76897695
static void max_min(typval_T *argvars, typval_T *rettv, int domax);

src/testdir/test_match.vim

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,10 @@ endfunc
152152

153153
func Test_matchstrpos()
154154
call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing'))
155-
156155
call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing', 2))
157-
158156
call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 5))
159-
157+
call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 8))
160158
call assert_equal(['ing', 1, 4, 7], matchstrpos(['vim', 'testing', 'execute'], 'ing'))
161-
162159
call assert_equal(['', -1, -1, -1], matchstrpos(['vim', 'testing', 'execute'], 'img'))
163160
endfunc
164161

src/version.c

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

770770
static int included_patches[] =
771771
{ /* Add new patch number below this line */
772+
/**/
773+
1004,
772774
/**/
773775
1003,
774776
/**/

0 commit comments

Comments
 (0)