forked from aniani/vim
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.
This commit is contained in:
@@ -7250,10 +7250,17 @@ f_mapcheck(typval_T *argvars, typval_T *rettv)
|
|||||||
get_maparg(argvars, rettv, FALSE);
|
get_maparg(argvars, rettv, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void find_some_match(typval_T *argvars, typval_T *rettv, int start);
|
typedef enum
|
||||||
|
{
|
||||||
|
MATCH_END, /* matchend() */
|
||||||
|
MATCH_MATCH, /* match() */
|
||||||
|
MATCH_STR, /* matchstr() */
|
||||||
|
MATCH_LIST, /* matchlist() */
|
||||||
|
MATCH_POS /* matchstrpos() */
|
||||||
|
} matchtype_T;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
find_some_match(typval_T *argvars, typval_T *rettv, int type)
|
find_some_match(typval_T *argvars, typval_T *rettv, matchtype_T type)
|
||||||
{
|
{
|
||||||
char_u *str = NULL;
|
char_u *str = NULL;
|
||||||
long len = 0;
|
long len = 0;
|
||||||
@@ -7277,13 +7284,13 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
|
|||||||
p_cpo = (char_u *)"";
|
p_cpo = (char_u *)"";
|
||||||
|
|
||||||
rettv->vval.v_number = -1;
|
rettv->vval.v_number = -1;
|
||||||
if (type == 3 || type == 4)
|
if (type == MATCH_LIST || type == MATCH_POS)
|
||||||
{
|
{
|
||||||
/* type 3: return empty list when there are no matches.
|
/* type MATCH_LIST: return empty list when there are no matches.
|
||||||
* type 4: return ["", -1, -1, -1] */
|
* type MATCH_POS: return ["", -1, -1, -1] */
|
||||||
if (rettv_list_alloc(rettv) == FAIL)
|
if (rettv_list_alloc(rettv) == FAIL)
|
||||||
goto theend;
|
goto theend;
|
||||||
if (type == 4
|
if (type == MATCH_POS
|
||||||
&& (list_append_string(rettv->vval.v_list,
|
&& (list_append_string(rettv->vval.v_list,
|
||||||
(char_u *)"", 0) == FAIL
|
(char_u *)"", 0) == FAIL
|
||||||
|| list_append_number(rettv->vval.v_list,
|
|| list_append_number(rettv->vval.v_list,
|
||||||
@@ -7298,7 +7305,7 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
|
|||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == 2)
|
else if (type == MATCH_STR)
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_STRING;
|
rettv->v_type = VAR_STRING;
|
||||||
rettv->vval.v_string = NULL;
|
rettv->vval.v_string = NULL;
|
||||||
@@ -7410,7 +7417,7 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
|
|||||||
|
|
||||||
if (match)
|
if (match)
|
||||||
{
|
{
|
||||||
if (type == 4)
|
if (type == MATCH_POS)
|
||||||
{
|
{
|
||||||
listitem_T *li1 = rettv->vval.v_list->lv_first;
|
listitem_T *li1 = rettv->vval.v_list->lv_first;
|
||||||
listitem_T *li2 = li1->li_next;
|
listitem_T *li2 = li1->li_next;
|
||||||
@@ -7427,7 +7434,7 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
|
|||||||
if (l != NULL)
|
if (l != NULL)
|
||||||
li2->li_tv.vval.v_number = (varnumber_T)idx;
|
li2->li_tv.vval.v_number = (varnumber_T)idx;
|
||||||
}
|
}
|
||||||
else if (type == 3)
|
else if (type == MATCH_LIST)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -7447,7 +7454,7 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == 2)
|
else if (type == MATCH_STR)
|
||||||
{
|
{
|
||||||
/* return matched string */
|
/* return matched string */
|
||||||
if (l != NULL)
|
if (l != NULL)
|
||||||
@@ -7460,7 +7467,7 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
|
|||||||
rettv->vval.v_number = idx;
|
rettv->vval.v_number = idx;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (type != 0)
|
if (type != MATCH_END)
|
||||||
rettv->vval.v_number =
|
rettv->vval.v_number =
|
||||||
(varnumber_T)(regmatch.startp[0] - str);
|
(varnumber_T)(regmatch.startp[0] - str);
|
||||||
else
|
else
|
||||||
@@ -7472,12 +7479,11 @@ find_some_match(typval_T *argvars, typval_T *rettv, int type)
|
|||||||
vim_regfree(regmatch.regprog);
|
vim_regfree(regmatch.regprog);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == 4 && l == NULL)
|
theend:
|
||||||
|
if (type == MATCH_POS && l == NULL && rettv->vval.v_list != NULL)
|
||||||
/* matchstrpos() without a list: drop the second item. */
|
/* matchstrpos() without a list: drop the second item. */
|
||||||
listitem_remove(rettv->vval.v_list,
|
listitem_remove(rettv->vval.v_list,
|
||||||
rettv->vval.v_list->lv_first->li_next);
|
rettv->vval.v_list->lv_first->li_next);
|
||||||
|
|
||||||
theend:
|
|
||||||
vim_free(tofree);
|
vim_free(tofree);
|
||||||
p_cpo = save_cpo;
|
p_cpo = save_cpo;
|
||||||
}
|
}
|
||||||
@@ -7488,7 +7494,7 @@ theend:
|
|||||||
static void
|
static void
|
||||||
f_match(typval_T *argvars, typval_T *rettv)
|
f_match(typval_T *argvars, typval_T *rettv)
|
||||||
{
|
{
|
||||||
find_some_match(argvars, rettv, 1);
|
find_some_match(argvars, rettv, MATCH_MATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -7656,7 +7662,7 @@ f_matchdelete(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
|||||||
static void
|
static void
|
||||||
f_matchend(typval_T *argvars, typval_T *rettv)
|
f_matchend(typval_T *argvars, typval_T *rettv)
|
||||||
{
|
{
|
||||||
find_some_match(argvars, rettv, 0);
|
find_some_match(argvars, rettv, MATCH_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -7665,7 +7671,7 @@ f_matchend(typval_T *argvars, typval_T *rettv)
|
|||||||
static void
|
static void
|
||||||
f_matchlist(typval_T *argvars, typval_T *rettv)
|
f_matchlist(typval_T *argvars, typval_T *rettv)
|
||||||
{
|
{
|
||||||
find_some_match(argvars, rettv, 3);
|
find_some_match(argvars, rettv, MATCH_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -7674,7 +7680,7 @@ f_matchlist(typval_T *argvars, typval_T *rettv)
|
|||||||
static void
|
static void
|
||||||
f_matchstr(typval_T *argvars, typval_T *rettv)
|
f_matchstr(typval_T *argvars, typval_T *rettv)
|
||||||
{
|
{
|
||||||
find_some_match(argvars, rettv, 2);
|
find_some_match(argvars, rettv, MATCH_STR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -7683,7 +7689,7 @@ f_matchstr(typval_T *argvars, typval_T *rettv)
|
|||||||
static void
|
static void
|
||||||
f_matchstrpos(typval_T *argvars, typval_T *rettv)
|
f_matchstrpos(typval_T *argvars, typval_T *rettv)
|
||||||
{
|
{
|
||||||
find_some_match(argvars, rettv, 4);
|
find_some_match(argvars, rettv, MATCH_POS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void max_min(typval_T *argvars, typval_T *rettv, int domax);
|
static void max_min(typval_T *argvars, typval_T *rettv, int domax);
|
||||||
|
@@ -152,13 +152,10 @@ endfunc
|
|||||||
|
|
||||||
func Test_matchstrpos()
|
func Test_matchstrpos()
|
||||||
call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing'))
|
call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing'))
|
||||||
|
|
||||||
call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing', 2))
|
call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing', 2))
|
||||||
|
|
||||||
call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 5))
|
call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 5))
|
||||||
|
call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 8))
|
||||||
call assert_equal(['ing', 1, 4, 7], matchstrpos(['vim', 'testing', 'execute'], 'ing'))
|
call assert_equal(['ing', 1, 4, 7], matchstrpos(['vim', 'testing', 'execute'], 'ing'))
|
||||||
|
|
||||||
call assert_equal(['', -1, -1, -1], matchstrpos(['vim', 'testing', 'execute'], 'img'))
|
call assert_equal(['', -1, -1, -1], matchstrpos(['vim', 'testing', 'execute'], 'img'))
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
@@ -769,6 +769,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1004,
|
||||||
/**/
|
/**/
|
||||||
1003,
|
1003,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user