0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

updated for version 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)
This commit is contained in:
Bram Moolenaar 2014-04-02 19:00:58 +02:00
parent fe5aab63fe
commit 41571769c9
9 changed files with 128 additions and 6 deletions

View File

@ -1990,7 +1990,8 @@ strridx( {haystack}, {needle} [, {start}])
Number last index of {needle} in {haystack}
strtrans( {expr}) String translate string to make it printable
strwidth( {expr}) Number display cell length of the String {expr}
submatch( {nr}) String specific match in ":s" or substitute()
submatch( {nr}[, {list}]) String or List
specific match in ":s" or substitute()
substitute( {expr}, {pat}, {sub}, {flags})
String all {pat} in {expr} replaced with {sub}
synID( {lnum}, {col}, {trans}) Number syntax ID at {lnum} and {col}
@ -5797,12 +5798,23 @@ strwidth({expr}) *strwidth()*
Ambiguous, this function's return value depends on 'ambiwidth'.
Also see |strlen()|, |strdisplaywidth()| and |strchars()|.
submatch({nr}) *submatch()*
submatch({nr}[, {list}]) *submatch()*
Only for an expression in a |:substitute| command or
substitute() function.
Returns the {nr}'th submatch of the matched text. When {nr}
is 0 the whole matched text is returned.
Note that a NL in the string can stand for a line break of a
multi-line match or a NUL character in the text.
Also see |sub-replace-expression|.
If {list} is present and non-zero then submatch() returns
a list of strings, similar to |getline()| with two arguments.
NL characters in the text represent NUL characters in the
text.
Only returns more than one item for |:substitute|, inside
|substitute()| this list will always contain one or zero
items, since there are no real line breaks.
Example: >
:s/\d\+/\=submatch(0) + 1/
< This finds the first number in the line and adds one to it.

View File

@ -8129,7 +8129,7 @@ static struct fst
{"strridx", 2, 3, f_strridx},
{"strtrans", 1, 1, f_strtrans},
{"strwidth", 1, 1, f_strwidth},
{"submatch", 1, 1, f_submatch},
{"submatch", 1, 2, f_submatch},
{"substitute", 4, 4, f_substitute},
{"synID", 3, 3, f_synID},
{"synIDattr", 2, 3, f_synIDattr},
@ -17890,9 +17890,32 @@ f_submatch(argvars, rettv)
typval_T *argvars;
typval_T *rettv;
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string =
reg_submatch((int)get_tv_number_chk(&argvars[0], NULL));
int error = FALSE;
char_u **match;
char_u **s;
listitem_T *li;
int no;
int retList = 0;
no = (int)get_tv_number_chk(&argvars[0], &error);
if (error)
return;
error = FALSE;
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

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

View File

@ -7897,6 +7897,85 @@ reg_submatch(no)
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(no)
int no;
{
char_u *s;
linenr_T slnum;
linenr_T elnum;
colnr_T scol;
colnr_T ecol;
int i;
list_T *list;
int error = FALSE;
if (!can_f_submatch || no < 0)
return NULL;
if (submatch_match == NULL)
{
slnum = submatch_mmatch->startpos[no].lnum;
elnum = submatch_mmatch->endpos[no].lnum;
if (slnum < 0 || elnum < 0)
return NULL;
scol = submatch_mmatch->startpos[no].col;
ecol = submatch_mmatch->endpos[no].col;
list = list_alloc();
if (list == NULL)
return NULL;
s = reg_getline_submatch(slnum) + scol;
if (slnum == elnum)
{
if (list_append_string(list, s, ecol - scol) == FAIL)
error = TRUE;
}
else
{
if (list_append_string(list, s, -1) == FAIL)
error = TRUE;
for (i = 1; i < elnum - slnum; i++)
{
s = reg_getline_submatch(slnum + i);
if (list_append_string(list, s, -1) == FAIL)
error = TRUE;
}
s = reg_getline_submatch(elnum);
if (list_append_string(list, s, ecol) == FAIL)
error = TRUE;
}
}
else
{
s = submatch_match->startp[no];
if (s == NULL || submatch_match->endp[no] == NULL)
return NULL;
list = list_alloc();
if (list == NULL)
return NULL;
if (list_append_string(list, s,
(int)(submatch_match->endp[no] - s)) == FAIL)
error = TRUE;
}
if (error)
{
list_free(list, TRUE);
return NULL;
}
return list;
}
#endif
static regengine_T bt_regengine =

Binary file not shown.

Binary file not shown.

View File

@ -117,6 +117,7 @@ STARTTEST
:set cpo&
:$put =\"\n\nTEST_5:\"
:$put =substitute('A123456789', 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\=submatch(0) . submatch(9) . submatch(8) . submatch(7) . submatch(6) . submatch(5) . submatch(4) . submatch(3) . submatch(2) . submatch(1)', '')
:$put =substitute('A123456789', 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\=string([submatch(0, 1), submatch(9, 1), submatch(8, 1), submatch(7, 1), submatch(6, 1), submatch(5, 1), submatch(4, 1), submatch(3, 1), submatch(2, 1), submatch(1, 1)])', '')
/^TEST_6
ENDTEST
@ -142,6 +143,7 @@ STARTTEST
:$put =\"\n\nTEST_7:\"
:$put =substitute('A A', 'A.', '\=submatch(0)', '')
:$put =substitute(\"B\nB\", 'B.', '\=submatch(0)', '')
:$put =substitute(\"B\nB\", 'B.', '\=string(submatch(0, 1))', '')
:$put =substitute('-bb', '\zeb', 'a', 'g')
:$put =substitute('-bb', '\ze', 'c', 'g')
/^TEST_8

View File

@ -90,6 +90,7 @@ l
TEST_5:
A123456789987654321
[['A123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], ['2'], ['1']]
TEST_6:
@ -103,6 +104,8 @@ TEST_7:
A A
B
B
['B
']B
-abab
c-cbcbc

View File

@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
241,
/**/
240,
/**/