Currently if you care about preserving NULs in buffers in many cases you have
to write bad hacks. Particularly, you cannot distinguish NULs and NLs in
1. submatch(). Fixed by this patch by adding second optional argument that
makes submatch() return a list.
2. getreg(). Will be the next patch.
3. setreg(), unable to set register with Nul. Will accept the list.
4. system(). After some recent patch it uses different replacement for Nul
though, before it did truncate, but still there is no strict way to get
verbatim output. As second argument changes system() behavior for backwards
compatibility new function is to be defined.
5. system() again, now the second argument: no way to pass Nul to an external
command. Should accept a list, just like setreg().
# HG changeset patch
# User ZyX <[email protected]>
# Date 1383485698 -14400
# Sun Nov 03 17:34:58 2013 +0400
# Branch NL-funcs
# Node ID 09cb2b6eb4639cb31ef1f6d7131bdbe519e98af9
# Parent b756610d1647f749221599ed06311806511ce382
Add second argument to submatch()
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1970,7 +1970,8 @@
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}
@@ -5747,12 +5748,18 @@
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.
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.
+ Only makes difference for |:substitute|: inside |substitute()|
+ this list will always contain one or zero items.
+
Example: >
:s/\d\+/\=submatch(0) + 1/
< This finds the first number in the line and adds one to it.
diff --git a/src/eval.c b/src/eval.c
--- a/src/eval.c
+++ b/src/eval.c
@@ -8104,7 +8104,7 @@
{"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},
@@ -17762,9 +17762,61 @@
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;
+
+ no = (int)get_tv_number_chk(&argvars[0], &error);
+ if (error)
+ return;
+ error = FALSE;
+
+ if (argvars[1].v_type == VAR_UNKNOWN ||
+ (get_tv_number_chk(&argvars[1], &error) == 0))
+ {
+ if (error)
+ return;
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = reg_submatch(no);
+ }
+ else
+ {
+ if (error)
+ return;
+
+ rettv->vval.v_list = list_alloc();
+ if (rettv->vval.v_list == NULL)
+ return;
+
+ match = reg_submatch_list(no);
+ if (match == NULL)
+ {
+ rettv->v_type = VAR_LIST;
+ return;
+ }
+
+ for (s = match ; *s != NULL ; s++)
+ {
+ li = listitem_alloc();
+ if (li == NULL)
+ {
+ list_free(rettv->vval.v_list, TRUE);
+ rettv->vval.v_list = NULL;
+ vim_free(match);
+ return;
+ }
+
+ li->li_tv.v_type = VAR_STRING;
+ li->li_tv.vval.v_string = *s;
+ list_append(rettv->vval.v_list, li);
+ }
+
+ vim_free(match);
+ rettv->v_type = VAR_LIST;
+ }
}
/*
diff --git a/src/proto/regexp.pro b/src/proto/regexp.pro
--- a/src/proto/regexp.pro
+++ b/src/proto/regexp.pro
@@ -10,6 +10,7 @@
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));
+char_u **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));
diff --git a/src/regexp.c b/src/regexp.c
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -7898,6 +7898,82 @@
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 NULL when not in a ":s" command and for a non-existing submatch.
+ * Otherwise returns a NULL-terminated array of strings, both array and
+ * contained strings reside in an allocated memory.
+ */
+ char_u **
+reg_submatch_list(no)
+ int no;
+{
+ char_u **retval;
+ char_u *s;
+ linenr_T slnum;
+ linenr_T elnum;
+ colnr_T scol;
+ colnr_T ecol;
+ int i;
+ int len;
+
+ 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;
+
+ retval = (char_u **) lalloc(sizeof(char_u **) * (elnum - slnum + 2),
+ TRUE);
+ if (retval == NULL)
+ return NULL;
+ retval[elnum - slnum + 1] = NULL;
+
+ s = reg_getline_submatch(slnum) + scol;
+ if (slnum == elnum)
+ retval[0] = vim_strnsave(s, ecol - scol);
+ else
+ {
+ retval[0] = vim_strsave(s);
+
+ s = reg_getline_submatch(elnum);
+ retval[elnum - slnum] = vim_strnsave(s, ecol);
+
+ for (i = 1 ; i < elnum - slnum ; i++)
+ retval[i] = vim_strsave(reg_getline_submatch(slnum + i));
+ }
+ }
+ else
+ {
+ s = submatch_match->startp[no];
+ if (s == NULL)
+ retval = NULL;
+ else
+ {
+ retval = (char_u **)lalloc(sizeof(char_u **) * 2, TRUE);
+ if (retval == NULL)
+ return NULL;
+ retval[0] = vim_strnsave(s, (int) (submatch_match->endp[no] - s));
+ if (retval[0] == NULL)
+ {
+ vim_free(retval);
+ return NULL;
+ }
+ retval[1] = NULL;
+ }
+ }
+ return retval;
+}
#endif
static regengine_T bt_regengine =
diff --git a/src/testdir/test79.in b/src/testdir/test79.in
index
f15ecc0f8dc07e351bf7ac6e1a8e1cba63db1fbb..17fa0094ba9827ca74f09a92c89968e75fbb44d6
GIT binary patch
literal 3061
zc%1E4O>^2v5arxezWS`CVhg;sCVbo4;($TeV8;nIcn|525<-BCkg!H_a@ya%BSs&L
zyeZ(2+ZI)-_hw$tN57$Gh9>o;nd?bsG?-j?=GxW`^MbBT!_w_DNq44VkNI=$nUq?t
zb0)ctq_RHhTYli13Jl}1SmR3fjYXj-XtpJ1Dm{5W0z3^{kHew%Gz68p5?$%Gt-M()
z&>lLQR(LdNVEa^ZXOhpxYLrwl$n>R^KDP`GjkS9UWE}Ppcu^^7k<(L-t_en{jRggZ
z`+f+1#4EhS2G+5LRjgncOMIXXnR1|!e>mt8jL;3iU_R&gmf&cC+JdtlLA%%ExKHrD
zk6NFzJEmKrx#aAg93OG?iJ-^P1HriQGeL)=F9atX4G8)iJrYEYo(LKo4asqiqY;}H
zgJ2Y(joOH}J+sNtetvt#0JS%gIuL%pv$VJ18rr3DrCO^uF0Y^i8g$_XZlMQ#xC8s%
zhSjGPI1diEpIumgS;On#6}(3e=o1Bh=)(w}-?`_whx&)B{~bKs!SZi&aO2<UFAc<|
zjB?^3BQa}-?D$BItqA)Ps&Q$;yBqGwi8m}XCnxTNp)u`6p)v1oxFaVPHS_4@V~axO
z<g?kTsGzrWm|Rc5Xd5u?Ou^Jln003`znR10b^%t;f|vdaEbo?^)E%6bv=A1O0{XFd
zF3F0_J{W%FVw$)eazWqTsb`7Z(sy=`F9v9PEJ%##?vC)b^*6h>klWVZ?y&_SptsK!
zgoys`2xnV=w@V+M!!7;&ZoL!h#p7E2-N*I7g4^6$yQHM=gDZhu3alZpy1;4zs|u_l
zu(H5P@&D)G_4}UX%nM)BeVj`rW<$D@48P3qMuyijyq4kB46kH(Im1gK|Mu=6)L4~I
zEBti|e_?lQa%}sb&A2}4apgHldoP-Cc`@R;agtp@J-TPu^|I#?``(D=RK$Z5E#N;}
z+X^?y_jHFABDX}dig9gI(CO@@CgZ^e2ruEUV|2a^#Cetc%ylPvcyXwCsrBYsQ}&jX
zOwVJl+lgoDODav>@Qup$xei~te_PJf{XvyXf*LGAM=V7-mZTg@Q;ub7z<%4=nv-$D
uh;mNG(GX+`YUwXBj$Xy&{KJpeKQ<3z#SMH=4fcMP<|bRQ?iGs3#Qy@VWLYBs
diff --git a/src/testdir/test79.ok b/src/testdir/test79.ok
index
bb30d140525facb55d0b400578271a9d90da5534..84856a3a8dda40325612b0ed89007b45c434b9e8
GIT binary patch
literal 523
zc$}?}J9C0S6ooC5Gn4;76SlG8xkwekOkS0V+OQ;}2r3#-SS<bRxw?=hNtgMGbLY;S
zbMEeIS~ojcYh|X%w3giP0Zi`SCLc5nhtLrkre!-W_XY!xyN+#{2A0GL4=X&bv3WxN
zjF&BT#3xbQ6exQo_E&oxt`De0g*vGrdlJ*8nc_H`9lI9Ohpr>|qviBZEtZeDm}4Qt
z0tvAc6rKu!6q%?ptcbM$)zEH(TogIBP-Sg|-9@wsmw>Y$t^MLYoAJZz&{zKQz9?eB
z_nO6hEn=;BO1KhNiKE0;Vkt3|7%YyvHkU3X65MthPW?ncL@a#2V{u5sh=#t#Ml8md
Fz!&L#drSZT
diff --git a/src/testdir/test80.in b/src/testdir/test80.in
--- a/src/testdir/test80.in
+++ b/src/testdir/test80.in
@@ -117,6 +117,7 @@
: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 @@
:$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
diff --git a/src/testdir/test80.ok b/src/testdir/test80.ok
--- a/src/testdir/test80.ok
+++ b/src/testdir/test80.ok
@@ -90,6 +90,7 @@
TEST_5:
A123456789987654321
+[['A123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], ['2'], ['1']]
TEST_6:
@@ -103,6 +104,8 @@
A
A
B
B
+['B
+']B
-abab
c-cbcbc
# HG changeset patch
# User ZyX <[email protected]>
# Date 1383486993 -14400
# Sun Nov 03 17:56:33 2013 +0400
# Branch NL-funcs
# Node ID 5d29bb3409c9e046fb7a08dcc585dc80362bf758
# Parent 09cb2b6eb4639cb31ef1f6d7131bdbe519e98af9
Also test for() cycle in reg_submatch_list
diff --git a/src/testdir/test79.in b/src/testdir/test79.in
index
17fa0094ba9827ca74f09a92c89968e75fbb44d6..56955c23182a8809b9aa233afbc8f6d1148d07c1
GIT binary patch
literal 3123
zc%1E4OK;jh5av8mt~t9Xi6KqA<(;_VK)@uBG%X3Fhfax%G2mcq;zwGkYJYpztRJk?
z3OMvuA+5e|cV<01-!eOW-Svct?Fh%NKRR{vrKxKAsk_uQLp6^D)f)3F`uC-yyRKnd
z$AWDMGF@{$!}C2|f_}6Yom{A%Hp}HXn{|_8**$!{1Kjr;cm2L{-v`;X1$UvEru1Sg
zK)G$LX5mhEebaLVdm?yruUbLoopeuFs8d5@P+QtZK!(8@fhXA|4RUnE&;`K|H8Ce)
ze%pcIJ3PlTtYH-^SjG|-vA{NJkud`b`Ncq+V2CaW`qL@HR|E$$RA!8I2%4P^!(D<m
zT~xY^T~oU`>T||!$o?Kf9|$@O-4cu@KN7SU`b2QVP>-O;&>cZ!=$@d)P@n8)7#h&e
zqVErUG*KC_xd-}jG#_3b&`0HkBnkxMBTah)E}&T`mdcfC?d%*{pg<cg;R-s?g=;Wx
zOjvwafOTtu{n3WyrzJf1p24|uz`b|D>w7SOhga%Z_OANj;=h8sD_Hzz3a<1!`m2Cg
z7g3Bgq$Fa^fbH*zkrcsNOciDt^Y)56Vyq2y&4{r&fonuNp=-puD{hIgMD;8>*+`;*
zS=n^9N;0So6-E~$(3%>ITVv1_9VYDwOfRP}yPAQ~G2p5D1oP|pDs?-jB`JitxPZRP
zp9rEP(gA}(%qNN4V9wb$H`>$0uGzOX@6S6ZTLi>=v^RS=>-LwMkC0inzuMvmoI_`u
zBXAzw%^ude{q-jM;2y5o-)y$GB76S2mjCs2-Lc@-*J2l>q(3<4*cr!a9IJAy!m%>P
zN*pV4tPuTwc8=e33~QSElAPm2C{P)alce}riq}%Sn&OodFQ<4Z#fvFk2>91m7okF{
zd{W^r68IOnBatK7-`1o0q(+tJFj+mVN99F}>c(L@f@=8A(C1~#EB06mzbWw-Ck)_^
zvrUPK<T<M4=0df2vGP%ElhA5yZLQ#=gg;JyDqDGwVebHfXZy<#t*<>kQYkyJ?U5Qh
zHF8#Hyx7K=cE5t|IJ6%gIl4M`g|QuUwKOx!pf~<(SY!K}E2UCeqbc2^NzKr-W@utF
z!PA|A@TWkJ{?>CnCBv8z>4Xf!?Z_D9!h13ddunoW@a_4{s;!o6-ve2r-M28+Y4oa-
I%f~_d21281DF6Tf
diff --git a/src/testdir/test79.ok b/src/testdir/test79.ok
index
84856a3a8dda40325612b0ed89007b45c434b9e8..0f6ea4545106dbc331076866a7effa74ebcd0927
GIT binary patch
literal 556
zc$}?}J9C0S6ooC5Gn4;76SlG8jZ_h2@~TYKh9wzAP|<+GV(D+s)rB-MUFMtN+`Yp&
zXW=cao1LhYGE+oa3rF(+Ov3lcCr!g4R0NuCn3nChgMsVVmTBl3mc$8<D?F{Sc}D(%
z*DZF$7g5|5D0?OLH+vjz52$#BI;kOg0@J3M;y9ZfyB6Jps>1)H<@8T2hKD(yW5M|X
z39;l9o^p;98Lu*|h&2b*&~AgA7df_&Wo?AnMYIW*fU_U1{o+2G@ylz`ue|boQN;Y8
zHH-U7#9DEsI8tmWmK0NpAw`#>u{iG9Y`Q6t;J({9)KB<C#Db3p76&wpXy_|!#9}&x
M@^I}L(hFk(-&MncWB>pF
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.
diff -crN -a vim-small-patches.b756610d1647/runtime/doc/eval.txt vim-small-patches.5d29bb3409c9/runtime/doc/eval.txt
*** vim-small-patches.b756610d1647/runtime/doc/eval.txt 2013-11-03 17:59:58.539971528 +0400
--- vim-small-patches.5d29bb3409c9/runtime/doc/eval.txt 2013-11-03 17:59:58.571971530 +0400
***************
*** 1970,1976 ****
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}
--- 1970,1977 ----
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}
***************
*** 5747,5758 ****
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.
--- 5748,5765 ----
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.
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.
+ Only makes difference for |:substitute|: inside |substitute()|
+ this list will always contain one or zero items.
+
Example: >
:s/\d\+/\=submatch(0) + 1/
< This finds the first number in the line and adds one to it.
diff -crN -a vim-small-patches.b756610d1647/src/eval.c vim-small-patches.5d29bb3409c9/src/eval.c
*** vim-small-patches.b756610d1647/src/eval.c 2013-11-03 17:59:58.558971529 +0400
--- vim-small-patches.5d29bb3409c9/src/eval.c 2013-11-03 17:59:58.590971530 +0400
***************
*** 8104,8110 ****
{"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},
--- 8104,8110 ----
{"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},
***************
*** 17762,17770 ****
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));
}
/*
--- 17762,17822 ----
typval_T *argvars;
typval_T *rettv;
{
! int error = FALSE;
! char_u **match;
! char_u **s;
! listitem_T *li;
! int no;
!
! no = (int)get_tv_number_chk(&argvars[0], &error);
! if (error)
! return;
! error = FALSE;
!
! if (argvars[1].v_type == VAR_UNKNOWN ||
! (get_tv_number_chk(&argvars[1], &error) == 0))
! {
! if (error)
! return;
!
! rettv->v_type = VAR_STRING;
! rettv->vval.v_string = reg_submatch(no);
! }
! else
! {
! if (error)
! return;
!
! rettv->vval.v_list = list_alloc();
! if (rettv->vval.v_list == NULL)
! return;
!
! match = reg_submatch_list(no);
! if (match == NULL)
! {
! rettv->v_type = VAR_LIST;
! return;
! }
!
! for (s = match ; *s != NULL ; s++)
! {
! li = listitem_alloc();
! if (li == NULL)
! {
! list_free(rettv->vval.v_list, TRUE);
! rettv->vval.v_list = NULL;
! vim_free(match);
! return;
! }
!
! li->li_tv.v_type = VAR_STRING;
! li->li_tv.vval.v_string = *s;
! list_append(rettv->vval.v_list, li);
! }
!
! vim_free(match);
! rettv->v_type = VAR_LIST;
! }
}
/*
diff -crN -a vim-small-patches.b756610d1647/src/proto/regexp.pro vim-small-patches.5d29bb3409c9/src/proto/regexp.pro
*** vim-small-patches.b756610d1647/src/proto/regexp.pro 2013-11-03 17:59:58.530971528 +0400
--- vim-small-patches.5d29bb3409c9/src/proto/regexp.pro 2013-11-03 17:59:58.563971529 +0400
***************
*** 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));
+ char_u **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));
diff -crN -a vim-small-patches.b756610d1647/src/regexp.c vim-small-patches.5d29bb3409c9/src/regexp.c
*** vim-small-patches.b756610d1647/src/regexp.c 2013-11-03 17:59:58.530971528 +0400
--- vim-small-patches.5d29bb3409c9/src/regexp.c 2013-11-03 17:59:58.563971529 +0400
***************
*** 7898,7903 ****
--- 7898,7979 ----
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 NULL when not in a ":s" command and for a non-existing submatch.
+ * Otherwise returns a NULL-terminated array of strings, both array and
+ * contained strings reside in an allocated memory.
+ */
+ char_u **
+ reg_submatch_list(no)
+ int no;
+ {
+ char_u **retval;
+ char_u *s;
+ linenr_T slnum;
+ linenr_T elnum;
+ colnr_T scol;
+ colnr_T ecol;
+ int i;
+ int len;
+
+ 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;
+
+ retval = (char_u **) lalloc(sizeof(char_u **) * (elnum - slnum + 2),
+ TRUE);
+ if (retval == NULL)
+ return NULL;
+ retval[elnum - slnum + 1] = NULL;
+
+ s = reg_getline_submatch(slnum) + scol;
+ if (slnum == elnum)
+ retval[0] = vim_strnsave(s, ecol - scol);
+ else
+ {
+ retval[0] = vim_strsave(s);
+
+ s = reg_getline_submatch(elnum);
+ retval[elnum - slnum] = vim_strnsave(s, ecol);
+
+ for (i = 1 ; i < elnum - slnum ; i++)
+ retval[i] = vim_strsave(reg_getline_submatch(slnum + i));
+ }
+ }
+ else
+ {
+ s = submatch_match->startp[no];
+ if (s == NULL)
+ retval = NULL;
+ else
+ {
+ retval = (char_u **)lalloc(sizeof(char_u **) * 2, TRUE);
+ if (retval == NULL)
+ return NULL;
+ retval[0] = vim_strnsave(s, (int) (submatch_match->endp[no] - s));
+ if (retval[0] == NULL)
+ {
+ vim_free(retval);
+ return NULL;
+ }
+ retval[1] = NULL;
+ }
+ }
+ return retval;
+ }
#endif
static regengine_T bt_regengine =
diff -crN -a vim-small-patches.b756610d1647/src/testdir/test79.in vim-small-patches.5d29bb3409c9/src/testdir/test79.in
*** vim-small-patches.b756610d1647/src/testdir/test79.in 2013-11-03 17:59:58.530971528 +0400
--- vim-small-patches.5d29bb3409c9/src/testdir/test79.in 2013-11-03 17:59:58.563971529 +0400
***************
*** 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 B
+ C C
+ D
+ D
+ E
+
+
+
+ E
Q
Q
STARTTEST
:g/^STARTTEST/.,/^ENDTEST/d
:1;/^Results/,$wq! test.out
+ :call getchar()
ENDTEST
diff -crN -a vim-small-patches.b756610d1647/src/testdir/test79.ok vim-small-patches.5d29bb3409c9/src/testdir/test79.ok
*** vim-small-patches.b756610d1647/src/testdir/test79.ok 2013-11-03 17:59:58.526971528 +0400
--- vim-small-patches.5d29bb3409c9/src/testdir/test79.ok 2013-11-03 17:59:58.560971529 +0400
***************
*** 105,110 ****
--- 105,111 ----
TEST_5:
A123456789987654321
+ [['B123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], ['2'], ['1']]
TEST_6:
***************
*** 119,124 ****
--- 120,128 ----
A
B
B
+ ['C^@']C
+ ['D^@', 'D']
+ ['E^@', '^@', '^@', '^@', '^@E']
Q
Q
diff -crN -a vim-small-patches.b756610d1647/src/testdir/test80.in vim-small-patches.5d29bb3409c9/src/testdir/test80.in
*** vim-small-patches.b756610d1647/src/testdir/test80.in 2013-11-03 17:59:58.526971528 +0400
--- vim-small-patches.5d29bb3409c9/src/testdir/test80.in 2013-11-03 17:59:58.560971529 +0400
***************
*** 117,122 ****
--- 117,123 ----
: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,147 ****
--- 143,149 ----
:$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
diff -crN -a vim-small-patches.b756610d1647/src/testdir/test80.ok vim-small-patches.5d29bb3409c9/src/testdir/test80.ok
*** vim-small-patches.b756610d1647/src/testdir/test80.ok 2013-11-03 17:59:58.526971528 +0400
--- vim-small-patches.5d29bb3409c9/src/testdir/test80.ok 2013-11-03 17:59:58.559971529 +0400
***************
*** 90,95 ****
--- 90,96 ----
TEST_5:
A123456789987654321
+ [['A123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], ['2'], ['1']]
TEST_6:
***************
*** 103,108 ****
--- 104,111 ----
A
A
B
B
+ ['B
+ ']B
-abab
c-cbcbc