* - The substituted text.
* - The text after the match.
*/
- sublen = vim_regsub(®match, sub, expr, tail, FALSE, TRUE, FALSE);
+ sublen = vim_regsub(®match, sub, expr, tail, 0, REGSUB_MAGIC);
if (ga_grow(&ga, (int)((end - tail) + sublen -
(regmatch.endp[0] - regmatch.startp[0]))) == FAIL)
{
i = (int)(regmatch.startp[0] - tail);
mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i);
// add the substituted text
- (void)vim_regsub(®match, sub, expr, (char_u *)ga.ga_data
- + ga.ga_len + i, TRUE, TRUE, FALSE);
+ (void)vim_regsub(®match, sub, expr,
+ (char_u *)ga.ga_data + ga.ga_len + i, sublen,
+ REGSUB_COPY | REGSUB_MAGIC);
ga.ga_len += i + sublen - 1;
tail = regmatch.endp[0];
if (*tail == NUL)
*/
typedef void (*(*fptr_T)(int *, int));
-static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest, int copy, int magic, int backslash);
+static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest, int destlen, int flags);
static fptr_T
do_upper(int *d, int c)
* vim_regsub() - perform substitutions after a vim_regexec() or
* vim_regexec_multi() match.
*
- * If "copy" is TRUE really copy into "dest".
- * If "copy" is FALSE nothing is copied, this is just to find out the length
- * of the result.
+ * If "flags" has REGSUB_COPY really copy into "dest[destlen]".
+ * Oterwise nothing is copied, only compue the length of the result.
*
- * If "backslash" is TRUE, a backslash will be removed later, need to double
- * them to keep them, and insert a backslash before a CR to avoid it being
- * replaced with a line break later.
+ * If "flags" has REGSUB_MAGIC then behave like 'magic' is set.
+ *
+ * If "flags" has REGSUB_BACKSLASH a backslash will be removed later, need to
+ * double them to keep them, and insert a backslash before a CR to avoid it
+ * being replaced with a line break later.
*
* Note: The matched text must not change between the call of
* vim_regexec()/vim_regexec_multi() and vim_regsub()! It would make the back
char_u *source,
typval_T *expr,
char_u *dest,
- int copy,
- int magic,
- int backslash)
+ int destlen,
+ int flags)
{
int result;
regexec_T rex_save;
rex.reg_maxline = 0;
rex.reg_buf = curbuf;
rex.reg_line_lbr = TRUE;
- result = vim_regsub_both(source, expr, dest, copy, magic, backslash);
+ result = vim_regsub_both(source, expr, dest, destlen, flags);
rex_in_use = rex_in_use_save;
if (rex_in_use)
linenr_T lnum,
char_u *source,
char_u *dest,
- int copy,
- int magic,
- int backslash)
+ int destlen,
+ int flags)
{
int result;
regexec_T rex_save;
rex.reg_firstlnum = lnum;
rex.reg_maxline = curbuf->b_ml.ml_line_count - lnum;
rex.reg_line_lbr = FALSE;
- result = vim_regsub_both(source, NULL, dest, copy, magic, backslash);
+ result = vim_regsub_both(source, NULL, dest, destlen, flags);
rex_in_use = rex_in_use_save;
if (rex_in_use)
char_u *source,
typval_T *expr,
char_u *dest,
- int copy,
- int magic,
- int backslash)
+ int destlen,
+ int flags)
{
char_u *src;
char_u *dst;
#ifdef FEAT_EVAL
static char_u *eval_result = NULL;
#endif
+ int copy = flags & REGSUB_COPY;
// Be paranoid...
if ((source == NULL && expr == NULL) || dest == NULL)
#ifdef FEAT_EVAL
// To make sure that the length doesn't change between checking the
// length and copying the string, and to speed up things, the
- // resulting string is saved from the call with "copy" == FALSE to the
- // call with "copy" == TRUE.
+ // resulting string is saved from the call with "flags & REGSUB_COPY"
+ // == 0 to the // call with "flags & REGSUB_COPY" != 0.
if (copy)
{
if (eval_result != NULL)
had_backslash = TRUE;
}
}
- if (had_backslash && backslash)
+ if (had_backslash && (flags & REGSUB_BACKSLASH))
{
// Backslashes will be consumed, need to double them.
s = vim_strsave_escaped(eval_result, (char_u *)"\\");
else
while ((c = *src++) != NUL)
{
- if (c == '&' && magic)
+ if (c == '&' && (flags & REGSUB_MAGIC))
no = 0;
else if (c == '\\' && *src != NUL)
{
- if (*src == '&' && !magic)
+ if (*src == '&' && !(flags & REGSUB_MAGIC))
{
++src;
no = 0;
// Copy a special key as-is.
if (copy)
{
+ if (dst + 3 > dest + destlen)
+ {
+ iemsg("vim_regsub_both(): not enough space");
+ return 0;
+ }
*dst++ = c;
*dst++ = *src++;
*dst++ = *src++;
// If "backslash" is TRUE the backslash will be removed
// later. Used to insert a literal CR.
- default: if (backslash)
+ default: if (flags & REGSUB_BACKSLASH)
{
if (copy)
+ {
+ if (dst + 1 > dest + destlen)
+ {
+ iemsg("vim_regsub_both(): not enough space");
+ return 0;
+ }
*dst = '\\';
+ }
++dst;
}
c = *src++;
if (has_mbyte)
{
int totlen = mb_ptr2len(src - 1);
+ int charlen = mb_char2len(cc);
if (copy)
+ {
+ if (dst + charlen > dest + destlen)
+ {
+ iemsg("vim_regsub_both(): not enough space");
+ return 0;
+ }
mb_char2bytes(cc, dst);
- dst += mb_char2len(cc) - 1;
+ }
+ dst += charlen - 1;
if (enc_utf8)
{
int clen = utf_ptr2len(src - 1);
if (clen < totlen)
{
if (copy)
+ {
+ if (dst + totlen - clen > dest + destlen)
+ {
+ iemsg("vim_regsub_both(): not enough space");
+ return 0;
+ }
mch_memmove(dst + 1, src - 1 + clen,
(size_t)(totlen - clen));
+ }
dst += totlen - clen;
}
}
src += totlen - 1;
}
else if (copy)
- *dst = cc;
+ {
+ if (dst + 1 > dest + destlen)
+ {
+ iemsg("vim_regsub_both(): not enough space");
+ return 0;
+ }
+ *dst = cc;
+ }
dst++;
}
else
if (rex.reg_mmatch->endpos[no].lnum == clnum)
break;
if (copy)
+ {
+ if (dst + 1 > dest + destlen)
+ {
+ iemsg("vim_regsub_both(): not enough space");
+ return 0;
+ }
*dst = CAR;
+ }
++dst;
s = reg_getline(++clnum);
if (rex.reg_mmatch->endpos[no].lnum == clnum)
}
else
{
- if (backslash && (*s == CAR || *s == '\\'))
+ if ((flags & REGSUB_BACKSLASH)
+ && (*s == CAR || *s == '\\'))
{
/*
* Insert a backslash in front of a CR, otherwise
*/
if (copy)
{
+ if (dst + 2 > dest + destlen)
+ {
+ iemsg("vim_regsub_both(): not enough space");
+ return 0;
+ }
dst[0] = '\\';
dst[1] = *s;
}
if (has_mbyte)
{
int l;
+ int charlen;
// Copy composing characters separately, one
// at a time.
s += l;
len -= l;
+ charlen = mb_char2len(cc);
if (copy)
+ {
+ if (dst + charlen > dest + destlen)
+ {
+ iemsg("vim_regsub_both(): not enough space");
+ return 0;
+ }
mb_char2bytes(cc, dst);
- dst += mb_char2len(cc) - 1;
+ }
+ dst += charlen - 1;
}
else if (copy)
- *dst = cc;
+ {
+ if (dst + 1 > dest + destlen)
+ {
+ iemsg("vim_regsub_both(): not enough space");
+ return 0;
+ }
+ *dst = cc;
+ }
dst++;
}
/*
* Match a regexp against a string.
- * "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
+ * "rmp->regprog" must be a compiled regexp as returned by vim_regcomp().
* Note: "rmp->regprog" may be freed and changed.
* Uses curbuf for line count and 'iskeyword'.
* When "nl" is TRUE consider a "\n" in "line" to be a line break.