387 lines
12 KiB
Plaintext
387 lines
12 KiB
Plaintext
|
To: vim_dev@googlegroups.com
|
|||
|
Subject: Patch 7.4.241
|
|||
|
Fcc: outbox
|
|||
|
From: Bram Moolenaar <Bram@moolenaar.net>
|
|||
|
Mime-Version: 1.0
|
|||
|
Content-Type: text/plain; charset=UTF-8
|
|||
|
Content-Transfer-Encoding: 8bit
|
|||
|
------------
|
|||
|
|
|||
|
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)
|
|||
|
Files: runtime/doc/eval.txt, src/eval.c, src/proto/regexp.pro,
|
|||
|
src/regexp.c, src/testdir/test79.in, src/testdir/test79.ok,
|
|||
|
src/testdir/test80.in, src/testdir/test80.ok
|
|||
|
|
|||
|
|
|||
|
*** ../vim-7.4.240/runtime/doc/eval.txt 2014-04-02 12:12:04.151981514 +0200
|
|||
|
--- runtime/doc/eval.txt 2014-04-02 17:56:51.163696948 +0200
|
|||
|
***************
|
|||
|
*** 1989,1995 ****
|
|||
|
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()
|
|||
|
substitute( {expr}, {pat}, {sub}, {flags})
|
|||
|
String all {pat} in {expr} replaced with {sub}
|
|||
|
synID( {lnum}, {col}, {trans}) Number syntax ID at {lnum} and {col}
|
|||
|
--- 1990,1997 ----
|
|||
|
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}[, {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}
|
|||
|
***************
|
|||
|
*** 5784,5795 ****
|
|||
|
Ambiguous, this function's return value depends on 'ambiwidth'.
|
|||
|
Also see |strlen()|, |strdisplaywidth()| and |strchars()|.
|
|||
|
|
|||
|
! submatch({nr}) *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.
|
|||
|
Also see |sub-replace-expression|.
|
|||
|
Example: >
|
|||
|
:s/\d\+/\=submatch(0) + 1/
|
|||
|
< This finds the first number in the line and adds one to it.
|
|||
|
--- 5798,5820 ----
|
|||
|
Ambiguous, this function's return value depends on 'ambiwidth'.
|
|||
|
Also see |strlen()|, |strdisplaywidth()| and |strchars()|.
|
|||
|
|
|||
|
! 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.
|
|||
|
*** ../vim-7.4.240/src/eval.c 2014-04-02 12:12:04.159981514 +0200
|
|||
|
--- src/eval.c 2014-04-02 18:16:33.011680690 +0200
|
|||
|
***************
|
|||
|
*** 8129,8135 ****
|
|||
|
{"strridx", 2, 3, f_strridx},
|
|||
|
{"strtrans", 1, 1, f_strtrans},
|
|||
|
{"strwidth", 1, 1, f_strwidth},
|
|||
|
! {"submatch", 1, 1, f_submatch},
|
|||
|
{"substitute", 4, 4, f_substitute},
|
|||
|
{"synID", 3, 3, f_synID},
|
|||
|
{"synIDattr", 2, 3, f_synIDattr},
|
|||
|
--- 8129,8135 ----
|
|||
|
{"strridx", 2, 3, f_strridx},
|
|||
|
{"strtrans", 1, 1, f_strtrans},
|
|||
|
{"strwidth", 1, 1, f_strwidth},
|
|||
|
! {"submatch", 1, 2, f_submatch},
|
|||
|
{"substitute", 4, 4, f_substitute},
|
|||
|
{"synID", 3, 3, f_synID},
|
|||
|
{"synIDattr", 2, 3, f_synIDattr},
|
|||
|
***************
|
|||
|
*** 17890,17898 ****
|
|||
|
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));
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
--- 17890,17921 ----
|
|||
|
typval_T *argvars;
|
|||
|
typval_T *rettv;
|
|||
|
{
|
|||
|
! 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);
|
|||
|
! }
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
*** ../vim-7.4.240/src/proto/regexp.pro 2013-08-10 13:37:24.000000000 +0200
|
|||
|
--- src/proto/regexp.pro 2014-04-02 18:19:12.415678498 +0200
|
|||
|
***************
|
|||
|
*** 10,15 ****
|
|||
|
--- 10,16 ----
|
|||
|
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));
|
|||
|
*** ../vim-7.4.240/src/regexp.c 2014-03-23 15:12:29.931264336 +0100
|
|||
|
--- src/regexp.c 2014-04-02 18:59:34.431645181 +0200
|
|||
|
***************
|
|||
|
*** 7897,7902 ****
|
|||
|
--- 7897,7981 ----
|
|||
|
|
|||
|
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 =
|
|||
|
*** ../vim-7.4.240/src/testdir/test79.in 2013-04-13 11:16:38.000000000 +0200
|
|||
|
--- src/testdir/test79.in 2014-04-02 17:51:01.807701753 +0200
|
|||
|
***************
|
|||
|
*** 181,190 ****
|
|||
|
--- 181,192 ----
|
|||
|
:set cpo&
|
|||
|
/^TEST/
|
|||
|
j:s/A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)/\=submatch(0) . submatch(9) . submatch(8) . submatch(7) . submatch(6) . submatch(5) . submatch(4) . submatch(3) . submatch(2) . submatch(1)/
|
|||
|
+ j:s/B\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)/\=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)])/
|
|||
|
ENDTEST
|
|||
|
|
|||
|
TEST_5:
|
|||
|
A123456789
|
|||
|
+ B123456789
|
|||
|
|
|||
|
STARTTEST
|
|||
|
:set magic&
|
|||
|
***************
|
|||
|
*** 209,214 ****
|
|||
|
--- 211,219 ----
|
|||
|
/^TEST_7/
|
|||
|
j:s/A./\=submatch(0)/
|
|||
|
j:s/B./\=submatch(0)/
|
|||
|
+ j:s/C./\=strtrans(string(submatch(0, 1)))/
|
|||
|
+ j:s/D.\nD/\=strtrans(string(submatch(0, 1)))/
|
|||
|
+ j:s/E\_.\{-}E/\=strtrans(string(submatch(0, 1)))/
|
|||
|
/^Q$
|
|||
|
:s/Q[^\n]Q/\=submatch(0)."foobar"/
|
|||
|
:" Avoid :s error breaks dotest map on Windows.
|
|||
|
***************
|
|||
|
*** 217,226 ****
|
|||
|
--- 222,240 ----
|
|||
|
TEST_7:
|
|||
|
A
A
|
|||
|
B |