vim-patch:7.4.241

Problem:    The string returned by submatch() does not distinguish between a
            NL from a line break and a NL that stands for a NUL character.
Solution:   Add a second argument to return a list. (ZyX)

https://code.google.com/p/vim/source/detail?r=a63d0cd691dc925283815d17d62f4e948d723a59
This commit is contained in:
oni-link
2014-04-28 19:52:05 +02:00
committed by Thiago de Arruda
parent d4f8a86700
commit e772cfcc55
8 changed files with 82 additions and 5 deletions

View File

@@ -7029,7 +7029,7 @@ static struct fst {
{"strridx", 2, 3, f_strridx}, {"strridx", 2, 3, f_strridx},
{"strtrans", 1, 1, f_strtrans}, {"strtrans", 1, 1, f_strtrans},
{"strwidth", 1, 1, f_strwidth}, {"strwidth", 1, 1, f_strwidth},
{"submatch", 1, 1, f_submatch}, {"submatch", 1, 2, f_submatch},
{"substitute", 4, 4, f_substitute}, {"substitute", 4, 4, f_substitute},
{"synID", 3, 3, f_synID}, {"synID", 3, 3, f_synID},
{"synIDattr", 2, 3, f_synIDattr}, {"synIDattr", 2, 3, f_synIDattr},
@@ -14441,9 +14441,28 @@ static void f_strtrans(typval_T *argvars, typval_T *rettv)
*/ */
static void f_submatch(typval_T *argvars, typval_T *rettv) static void f_submatch(typval_T *argvars, typval_T *rettv)
{ {
rettv->v_type = VAR_STRING; int error = FALSE;
rettv->vval.v_string = int no = (int)get_tv_number_chk(&argvars[0], &error);
reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); if (error) {
return;
}
int retList = 0;
if (argvars[1].v_type != VAR_UNKNOWN) {
retList = get_tv_number_chk(&argvars[1], &error);
if (error) {
return;
}
}
if (retList == 0) {
rettv->v_type = VAR_STRING;
rettv->vval.v_string = reg_submatch(no);
} else {
rettv->v_type = VAR_LIST;
rettv->vval.v_list = reg_submatch_list(no);
}
} }
/* /*

View File

@@ -6929,6 +6929,58 @@ char_u *reg_submatch(int no)
return retval; return retval;
} }
// Used for the submatch() function with the optional non-zero argument: get
// the list of strings from the n'th submatch in allocated memory with NULs
// represented in NLs.
// Returns a list of allocated strings. Returns NULL when not in a ":s"
// command, for a non-existing submatch and for any error.
list_T *reg_submatch_list(int no)
{
if (!can_f_submatch || no < 0) {
return NULL;
}
linenr_T slnum;
linenr_T elnum;
list_T *list;
char_u *s;
if (submatch_match == NULL) {
slnum = submatch_mmatch->startpos[no].lnum;
elnum = submatch_mmatch->endpos[no].lnum;
if (slnum < 0 || elnum < 0) {
return NULL;
}
colnr_T scol = submatch_mmatch->startpos[no].col;
colnr_T ecol = submatch_mmatch->endpos[no].col;
list = list_alloc();
s = reg_getline_submatch(slnum) + scol;
if (slnum == elnum) {
list_append_string(list, s, ecol - scol);
} else {
list_append_string(list, s, -1);
for (int i = 1; i < elnum - slnum; i++) {
s = reg_getline_submatch(slnum + i);
list_append_string(list, s, -1);
}
s = reg_getline_submatch(elnum);
list_append_string(list, s, ecol);
}
} else {
s = submatch_match->startp[no];
if (s == NULL || submatch_match->endp[no] == NULL) {
return NULL;
}
list = list_alloc();
list_append_string(list, s, (int)(submatch_match->endp[no] - s));
}
return list;
}
static regengine_T bt_regengine = static regengine_T bt_regengine =
{ {
bt_regcomp, bt_regcomp,

View File

@@ -16,6 +16,7 @@ int vim_regsub_multi(regmmatch_T *rmp, linenr_T lnum, char_u *source,
char_u *dest, int copy, int magic, char_u *dest, int copy, int magic,
int backslash); int backslash);
char_u *reg_submatch(int no); char_u *reg_submatch(int no);
list_T *reg_submatch_list(int no);
regprog_T *vim_regcomp(char_u *expr_arg, int re_flags); regprog_T *vim_regcomp(char_u *expr_arg, int re_flags);
void vim_regfree(regprog_T *prog); void vim_regfree(regprog_T *prog);
int vim_regexec(regmatch_T *rmp, char_u *line, colnr_T col); int vim_regexec(regmatch_T *rmp, char_u *line, colnr_T col);

Binary file not shown.

Binary file not shown.

View File

@@ -117,6 +117,7 @@ STARTTEST
:let y = substitute('jJj', 'J', '\=substitute(submatch(0), ".", "\\n", "")', '') | $put =y :let y = substitute('jJj', 'J', '\=substitute(submatch(0), ".", "\\n", "")', '') | $put =y
:let y = substitute('kKk', 'K', '\=substitute(submatch(0), ".", "\r", "")', '') | $put =y :let y = substitute('kKk', 'K', '\=substitute(submatch(0), ".", "\r", "")', '') | $put =y
:let y = substitute('lLl', 'L', '\=substitute(submatch(0), ".", "\n", "")', '') | $put =y :let y = substitute('lLl', 'L', '\=substitute(submatch(0), ".", "\n", "")', '') | $put =y
/^TEST_5
ENDTEST ENDTEST
TEST_5: TEST_5:
@@ -142,6 +143,7 @@ STARTTEST
:$put =substitute('C', 'C', 'c', '') :$put =substitute('C', 'C', 'c', '')
:$put =substitute('D', 'D', '%', '') :$put =substitute('D', 'D', '%', '')
/^TEST_7 /^TEST_7
ENDTEST
TEST_7: TEST_7:

View File

@@ -90,6 +90,7 @@ l
a\a a\a
b\b b\b
c c
c
d d
d d
e\ e\
@@ -103,6 +104,8 @@ TEST_7:
l l
l l
TEST_5:
A123456789987654321 A123456789987654321
[['A123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], ['2'], ['1']] [['A123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], ['2'], ['1']]

View File

@@ -226,7 +226,7 @@ static int included_patches[] = {
//244, //244,
//243, //243,
//242, //242,
//241, 241,
240, 240,
239, 239,
//238, //238,