1
0
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:
Bram Moolenaar
2017-08-27 13:51:01 +02:00
parent e85928a324
commit 8d9f0ef5c6
3 changed files with 28 additions and 23 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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,
/**/ /**/