Tuesday, March 23, 2010

Re: Preventing submatch from eating backslashes

Christian Brabandt wrote:

> On Fr, 12 M=E4r 2010, Christian Brabandt wrote:
>
> > I just found out, that submatch eats my backslashes. Consider this
> > example:
> > ~$ gvim -u NONE -N -c ":put ='foo\bar'" -c ":%s/.\+/\=submatch(0)/"
> >
> > which gives you foobar instead of foo\bar.
> >
> >
> > Is there an easy way to prevent this without having me to remember, that
> > I need to escape submatch, just because it could contain backslashes?
> >
> > I know that \0 works correctly, but I need to call a function in the
> > replacement part.
>
> I believe this bug is also mentioned in the todo list:
> submatch() may remove backslash. (Sergey Goldgaber, 2009 Jul 6)
>
> So here is a patch, that fixes it, I believe. I don't know the source
> well enough to judge, whether this is the correct solution. But at
> least, this works for me™
>
> chrisbra t41:~/vim/src [1093]% hg diff
> diff -r 907cf09fbb32 src/regexp.c
> --- a/src/regexp.c Tue Mar 02 18:16:09 2010 +0100
> +++ b/src/regexp.c Mon Mar 22 10:13:51 2010 +0100
> @@ -7329,6 +7329,8 @@
> retval = vim_strnsave(s, (int)(submatch_match->endp[no] - s));
> }
>
> - return retval;
> + /* Parsing the \= expression in the substitution part will later on
> + * remove all backslashes. Therefore, we need to protect them here */
> + return vim_strsave_escaped(retval, (char_u *)"\\");
> }
>

No comments: