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
  BB
+ CC
+ 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
  

Raspunde prin e-mail lui