aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoroni-link <knil.ino@gmail.com>2014-04-28 19:52:05 +0200
committerThiago de Arruda <tpadilha84@gmail.com>2014-04-28 16:16:40 -0300
commite772cfcc55878f82b5ab1358a10dcdca6c326e08 (patch)
tree2148c497f724cbbd54943935e3ee93c0b9013767 /src
parentd4f8a86700a1e5c7b3694a34392f311d78e023a6 (diff)
downloadrneovim-e772cfcc55878f82b5ab1358a10dcdca6c326e08.tar.gz
rneovim-e772cfcc55878f82b5ab1358a10dcdca6c326e08.tar.bz2
rneovim-e772cfcc55878f82b5ab1358a10dcdca6c326e08.zip
vim-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) https://code.google.com/p/vim/source/detail?r=a63d0cd691dc925283815d17d62f4e948d723a59
Diffstat (limited to 'src')
-rw-r--r--src/eval.c27
-rw-r--r--src/regexp.c52
-rw-r--r--src/regexp.h1
-rw-r--r--src/testdir/test79.inbin2971 -> 3381 bytes
-rw-r--r--src/testdir/test79.okbin439 -> 574 bytes
-rw-r--r--src/testdir/test80.in2
-rw-r--r--src/testdir/test80.ok3
-rw-r--r--src/version.c2
8 files changed, 82 insertions, 5 deletions
diff --git a/src/eval.c b/src/eval.c
index 34539f022b..c59b335a6a 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -7029,7 +7029,7 @@ static struct fst {
{"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},
@@ -14441,9 +14441,28 @@ static void f_strtrans(typval_T *argvars, typval_T *rettv)
*/
static void f_submatch(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;
+ int no = (int)get_tv_number_chk(&argvars[0], &error);
+ if (error) {
+ return;
+ }
+
+ int retList = 0;
+
+ 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);
+ }
}
/*
diff --git a/src/regexp.c b/src/regexp.c
index 454fdbe01e..35ed1b85f7 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -6929,6 +6929,58 @@ char_u *reg_submatch(int no)
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(int no)
+{
+ if (!can_f_submatch || no < 0) {
+ return NULL;
+ }
+
+ linenr_T slnum;
+ linenr_T elnum;
+ list_T *list;
+ char_u *s;
+
+ if (submatch_match == NULL) {
+ slnum = submatch_mmatch->startpos[no].lnum;
+ elnum = submatch_mmatch->endpos[no].lnum;
+ if (slnum < 0 || elnum < 0) {
+ return NULL;
+ }
+
+ colnr_T scol = submatch_mmatch->startpos[no].col;
+ colnr_T ecol = submatch_mmatch->endpos[no].col;
+
+ list = list_alloc();
+
+ s = reg_getline_submatch(slnum) + scol;
+ if (slnum == elnum) {
+ list_append_string(list, s, ecol - scol);
+ } else {
+ list_append_string(list, s, -1);
+ for (int i = 1; i < elnum - slnum; i++) {
+ s = reg_getline_submatch(slnum + i);
+ list_append_string(list, s, -1);
+ }
+ s = reg_getline_submatch(elnum);
+ list_append_string(list, s, ecol);
+ }
+ } else {
+ s = submatch_match->startp[no];
+ if (s == NULL || submatch_match->endp[no] == NULL) {
+ return NULL;
+ }
+ list = list_alloc();
+ list_append_string(list, s, (int)(submatch_match->endp[no] - s));
+ }
+
+ return list;
+}
+
static regengine_T bt_regengine =
{
bt_regcomp,
diff --git a/src/regexp.h b/src/regexp.h
index 118f066b1c..8de3ef2288 100644
--- a/src/regexp.h
+++ b/src/regexp.h
@@ -16,6 +16,7 @@ int vim_regsub_multi(regmmatch_T *rmp, linenr_T lnum, char_u *source,
char_u *dest, int copy, int magic,
int backslash);
char_u *reg_submatch(int no);
+list_T *reg_submatch_list(int no);
regprog_T *vim_regcomp(char_u *expr_arg, int re_flags);
void vim_regfree(regprog_T *prog);
int vim_regexec(regmatch_T *rmp, char_u *line, colnr_T col);
diff --git a/src/testdir/test79.in b/src/testdir/test79.in
index c6108097d9..8278bd8000 100644
--- a/src/testdir/test79.in
+++ b/src/testdir/test79.in
Binary files differ
diff --git a/src/testdir/test79.ok b/src/testdir/test79.ok
index 8d2ead67ed..e22eee0b71 100644
--- a/src/testdir/test79.ok
+++ b/src/testdir/test79.ok
Binary files differ
diff --git a/src/testdir/test80.in b/src/testdir/test80.in
index c62fdc02b2..406fb6dac7 100644
--- a/src/testdir/test80.in
+++ b/src/testdir/test80.in
@@ -117,6 +117,7 @@ STARTTEST
: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 @@ STARTTEST
:$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
index 2b79d377a7..b42f604a07 100644
--- a/src/testdir/test80.ok
+++ b/src/testdir/test80.ok
@@ -90,6 +90,7 @@ l
TEST_5:
A123456789987654321
+[['A123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], ['2'], ['1']]
TEST_6:
@@ -103,6 +104,8 @@ TEST_7:
A A
B
B
+['B
+']B
-abab
c-cbcbc
diff --git a/src/version.c b/src/version.c
index 301ce16788..988b12fbf2 100644
--- a/src/version.c
+++ b/src/version.c
@@ -226,7 +226,7 @@ static int included_patches[] = {
//244,
//243,
//242,
- //241,
+ 241,
240,
239,
//238,