summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2014-05-07 18:35:30 +0200
committerBram Moolenaar <Bram@vim.org>2014-05-07 18:35:30 +0200
commit1b1063af58b015b7827168f8fa2631efb60c252b (patch)
treeecebaed1979aee36aa61e9a7ea1bebdb597be0d6
parent3ec7f4e4025c5a78ccd312f8516ac0740aa65dfe (diff)
updated for version 7.4.279v7.4.279
Problem: globpath() returns a string, making it difficult to get a list of matches. (Greg Novack) Solution: Add an optional argument like with glob(). (Adnan Zafar)
-rw-r--r--runtime/doc/eval.txt17
-rw-r--r--src/eval.c35
-rw-r--r--src/ex_getln.c72
-rw-r--r--src/misc1.c31
-rw-r--r--src/misc2.c20
-rw-r--r--src/proto/ex_getln.pro2
-rw-r--r--src/proto/misc2.pro2
-rw-r--r--src/testdir/test97.in11
-rw-r--r--src/testdir/test97.ok3
-rw-r--r--src/version.c2
10 files changed, 97 insertions, 98 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index a3dd518ecc..3957508207 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1832,7 +1832,7 @@ getwinvar( {nr}, {varname} [, {def}])
any variable {varname} in window {nr}
glob( {expr} [, {nosuf} [, {list}]])
any expand file wildcards in {expr}
-globpath( {path}, {expr} [, {flag}])
+globpath( {path}, {expr} [, {nosuf} [, {list}]])
String do glob({expr}) for all dirs in {path}
has( {feature}) Number TRUE if feature {feature} supported
has_key( {dict}, {key}) Number TRUE if {dict} has entry {key}
@@ -3571,11 +3571,12 @@ glob({expr} [, {nosuf} [, {list}]]) *glob()*
See |expand()| for expanding special Vim variables. See
|system()| for getting the raw output of an external command.
-globpath({path}, {expr} [, {flag}]) *globpath()*
+globpath({path}, {expr} [, {nosuf} [, {list}]]) *globpath()*
Perform glob() on all directories in {path} and concatenate
the results. Example: >
:echo globpath(&rtp, "syntax/c.vim")
-< {path} is a comma-separated list of directory names. Each
+<
+ {path} is a comma-separated list of directory names. Each
directory name is prepended to {expr} and expanded like with
|glob()|. A path separator is inserted when needed.
To add a comma inside a directory name escape it with a
@@ -3583,11 +3584,19 @@ globpath({path}, {expr} [, {flag}]) *globpath()*
trailing backslash, remove it if you put a comma after it.
If the expansion fails for one of the directories, there is no
error message.
- Unless the optional {flag} argument is given and is non-zero,
+
+ Unless the optional {nosuf} argument is given and is non-zero,
the 'suffixes' and 'wildignore' options apply: Names matching
one of the patterns in 'wildignore' will be skipped and
'suffixes' affect the ordering of matches.
+ When {list} is present and it is non-zero the result is a List
+ with all matching files. The advantage of using a List is, you
+ also get filenames containing newlines correctly. Otherwise
+ the result is a String and when there are several matches,
+ they are separated by <NL> characters. Example: >
+ :echo globpath(&rtp, "syntax/c.vim", 0, 1)
+<
The "**" item can be used to search in a directory tree.
For example, to find all "README.txt" files in the directories
in 'runtimepath' and below: >
diff --git a/src/eval.c b/src/eval.c
index f619b5adf8..f47a0adfdb 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -7985,7 +7985,7 @@ static struct fst
{"getwinposy", 0, 0, f_getwinposy},
{"getwinvar", 2, 3, f_getwinvar},
{"glob", 1, 3, f_glob},
- {"globpath", 2, 3, f_globpath},
+ {"globpath", 2, 4, f_globpath},
{"has", 1, 1, f_has},
{"has_key", 2, 2, f_has_key},
{"haslocaldir", 0, 0, f_haslocaldir},
@@ -12151,18 +12151,37 @@ f_globpath(argvars, rettv)
char_u buf1[NUMBUFLEN];
char_u *file = get_tv_string_buf_chk(&argvars[1], buf1);
int error = FALSE;
+ garray_T ga;
+ int i;
/* When the optional second argument is non-zero, don't remove matches
* for 'wildignore' and don't put matches for 'suffixes' at the end. */
- if (argvars[2].v_type != VAR_UNKNOWN
- && get_tv_number_chk(&argvars[2], &error))
- flags |= WILD_KEEP_ALL;
rettv->v_type = VAR_STRING;
- if (file == NULL || error)
- rettv->vval.v_string = NULL;
+ if (argvars[2].v_type != VAR_UNKNOWN)
+ {
+ if (get_tv_number_chk(&argvars[2], &error))
+ flags |= WILD_KEEP_ALL;
+ if (argvars[3].v_type != VAR_UNKNOWN
+ && get_tv_number_chk(&argvars[3], &error))
+ {
+ rettv->v_type = VAR_LIST;
+ rettv->vval.v_list = NULL;
+ }
+ }
+ if (file != NULL && !error)
+ {
+ ga_init2(&ga, (int)sizeof(char_u *), 10);
+ globpath(get_tv_string(&argvars[0]), file, &ga, flags);
+ if (rettv->v_type == VAR_STRING)
+ rettv->vval.v_string = ga_concat_strings(&ga, "\n");
+ else if (rettv_list_alloc(rettv) != FAIL)
+ for (i = 0; i < ga.ga_len; ++i)
+ list_append_string(rettv->vval.v_list,
+ ((char_u **)(ga.ga_data))[i], -1);
+ ga_clear_strings(&ga);
+ }
else
- rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file,
- flags);
+ rettv->vval.v_string = NULL;
}
/*
diff --git a/src/ex_getln.c b/src/ex_getln.c
index f1f39d2dcf..7411732449 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -5095,9 +5095,9 @@ ExpandRTDir(pat, num_file, file, dirnames)
char_u ***file;
char *dirnames[];
{
- char_u *matches;
char_u *s;
char_u *e;
+ char_u *match;
garray_T ga;
int i;
int pat_len;
@@ -5116,33 +5116,27 @@ ExpandRTDir(pat, num_file, file, dirnames)
return FAIL;
}
sprintf((char *)s, "%s/%s*.vim", dirnames[i], pat);
- matches = globpath(p_rtp, s, 0);
+ globpath(p_rtp, s, &ga, 0);
vim_free(s);
- if (matches == NULL)
- continue;
+ }
- for (s = matches; *s != NUL; s = e)
+ for (i = 0; i < ga.ga_len; ++i)
+ {
+ match = ((char_u **)ga.ga_data)[i];
+ s = match;
+ e = s + STRLEN(s);
+ if (e - 4 > s && STRNICMP(e - 4, ".vim", 4) == 0)
{
- e = vim_strchr(s, '\n');
- if (e == NULL)
- e = s + STRLEN(s);
- if (ga_grow(&ga, 1) == FAIL)
- break;
- if (e - 4 > s && STRNICMP(e - 4, ".vim", 4) == 0)
- {
- for (s = e - 4; s > matches; mb_ptr_back(matches, s))
- if (*s == '\n' || vim_ispathsep(*s))
- break;
- ++s;
- ((char_u **)ga.ga_data)[ga.ga_len] =
- vim_strnsave(s, (int)(e - s - 4));
- ++ga.ga_len;
- }
- if (*e != NUL)
- ++e;
+ e -= 4;
+ for (s = e; s > match; mb_ptr_back(match, s))
+ if (s < match || vim_ispathsep(*s))
+ break;
+ ++s;
+ *e = NUL;
+ mch_memmove(match, s, e - s + 1);
}
- vim_free(matches);
}
+
if (ga.ga_len == 0)
return FAIL;
@@ -5160,33 +5154,28 @@ ExpandRTDir(pat, num_file, file, dirnames)
#if defined(FEAT_CMDL_COMPL) || defined(FEAT_EVAL) || defined(PROTO)
/*
* Expand "file" for all comma-separated directories in "path".
- * Returns an allocated string with all matches concatenated, separated by
- * newlines. Returns NULL for an error or no matches.
+ * Adds the matches to "ga". Caller must init "ga".
*/
- char_u *
-globpath(path, file, expand_options)
+ void
+globpath(path, file, ga, expand_options)
char_u *path;
char_u *file;
+ garray_T *ga;
int expand_options;
{
expand_T xpc;
char_u *buf;
- garray_T ga;
int i;
- int len;
int num_p;
char_u **p;
- char_u *cur = NULL;
buf = alloc(MAXPATHL);
if (buf == NULL)
- return NULL;
+ return;
ExpandInit(&xpc);
xpc.xp_context = EXPAND_FILES;
- ga_init2(&ga, 1, 100);
-
/* Loop over all entries in {path}. */
while (*path != NUL)
{
@@ -5207,30 +5196,23 @@ globpath(path, file, expand_options)
WILD_SILENT|expand_options) != FAIL && num_p > 0)
{
ExpandEscape(&xpc, buf, num_p, p, WILD_SILENT|expand_options);
- for (len = 0, i = 0; i < num_p; ++i)
- len += (int)STRLEN(p[i]) + 1;
- /* Concatenate new results to previous ones. */
- if (ga_grow(&ga, len) == OK)
+ if (ga_grow(ga, num_p) == OK)
{
- cur = (char_u *)ga.ga_data + ga.ga_len;
for (i = 0; i < num_p; ++i)
{
- STRCPY(cur, p[i]);
- cur += STRLEN(p[i]);
- *cur++ = '\n';
+ ((char_u **)ga->ga_data)[ga->ga_len] =
+ vim_strnsave(p[i], STRLEN(p[i]));
+ ++ga->ga_len;
}
- ga.ga_len += len;
}
+
FreeWild(num_p, p);
}
}
}
- if (cur != NULL)
- *--cur = 0; /* Replace trailing newline with NUL */
vim_free(buf);
- return (char_u *)ga.ga_data;
}
#endif
diff --git a/src/misc1.c b/src/misc1.c
index 477aba4bd3..31a9c64461 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -10336,9 +10336,6 @@ expand_in_path(gap, pattern, flags)
{
char_u *curdir;
garray_T path_ga;
- char_u *files = NULL;
- char_u *s; /* start */
- char_u *e; /* end */
char_u *paths = NULL;
if ((curdir = alloc((unsigned)MAXPATHL)) == NULL)
@@ -10351,37 +10348,13 @@ expand_in_path(gap, pattern, flags)
if (path_ga.ga_len == 0)
return 0;
- paths = ga_concat_strings(&path_ga);
+ paths = ga_concat_strings(&path_ga, ",");
ga_clear_strings(&path_ga);
if (paths == NULL)
return 0;
- files = globpath(paths, pattern, (flags & EW_ICASE) ? WILD_ICASE : 0);
+ globpath(paths, pattern, gap, (flags & EW_ICASE) ? WILD_ICASE : 0);
vim_free(paths);
- if (files == NULL)
- return 0;
-
- /* Copy each path in files into gap */
- s = e = files;
- while (*s != NUL)
- {
- while (*e != '\n' && *e != NUL)
- e++;
- if (*e == NUL)
- {
- addfile(gap, s, flags);
- break;
- }
- else
- {
- /* *e is '\n' */
- *e = NUL;
- addfile(gap, s, flags);
- e++;
- s = e;
- }
- }
- vim_free(files);
return gap->ga_len;
}
diff --git a/src/misc2.c b/src/misc2.c
index a20337f48c..b0673d4434 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -2087,29 +2087,37 @@ ga_grow(gap, n)
/*
* For a growing array that contains a list of strings: concatenate all the
- * strings with a separating comma.
+ * strings with a separating "sep".
* Returns NULL when out of memory.
*/
char_u *
-ga_concat_strings(gap)
+ga_concat_strings(gap, sep)
garray_T *gap;
+ char *sep;
{
int i;
int len = 0;
+ int sep_len = (int)STRLEN(sep);
char_u *s;
+ char_u *p;
for (i = 0; i < gap->ga_len; ++i)
- len += (int)STRLEN(((char_u **)(gap->ga_data))[i]) + 1;
+ len += (int)STRLEN(((char_u **)(gap->ga_data))[i]) + sep_len;
s = alloc(len + 1);
if (s != NULL)
{
*s = NUL;
+ p = s;
for (i = 0; i < gap->ga_len; ++i)
{
- if (*s != NUL)
- STRCAT(s, ",");
- STRCAT(s, ((char_u **)(gap->ga_data))[i]);
+ if (p != s)
+ {
+ STRCPY(p, sep);
+ p += sep_len;
+ }
+ STRCPY(p, ((char_u **)(gap->ga_data))[i]);
+ p += STRLEN(p);
}
}
return s;
diff --git a/src/proto/ex_getln.pro b/src/proto/ex_getln.pro
index a8f960b102..86e01b58c6 100644
--- a/src/proto/ex_getln.pro
+++ b/src/proto/ex_getln.pro
@@ -32,7 +32,7 @@ char_u *addstar __ARGS((char_u *fname, int len, int context));
void set_cmd_context __ARGS((expand_T *xp, char_u *str, int len, int col));
int expand_cmdline __ARGS((expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches));
int ExpandGeneric __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file, char_u *((*func)(expand_T *, int)), int escaped));
-char_u *globpath __ARGS((char_u *path, char_u *file, int expand_options));
+void globpath __ARGS((char_u *path, char_u *file, garray_T *ga, int expand_options));
void init_history __ARGS((void));
int get_histtype __ARGS((char_u *name));
void add_to_history __ARGS((int histype, char_u *new_entry, int in_map, int sep));
diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro
index 544e669dcc..4fd457382f 100644
--- a/src/proto/misc2.pro
+++ b/src/proto/misc2.pro
@@ -55,7 +55,7 @@ void ga_clear_strings __ARGS((garray_T *gap));
void ga_init __ARGS((garray_T *gap));
void ga_init2 __ARGS((garray_T *gap, int itemsize, int growsize));
int ga_grow __ARGS((garray_T *gap, int n));
-char_u *ga_concat_strings __ARGS((garray_T *gap));
+char_u *ga_concat_strings __ARGS((garray_T *gap, char *sep));
void ga_concat __ARGS((garray_T *gap, char_u *s));
void ga_append __ARGS((garray_T *gap, int c));
void append_ga_line __ARGS((garray_T *gap));
diff --git a/src/testdir/test97.in b/src/testdir/test97.in
index 13e9dd5b6e..c25176b074 100644
--- a/src/testdir/test97.in
+++ b/src/testdir/test97.in
@@ -5,12 +5,15 @@ STARTTEST
:so small.vim
:set shell=doesnotexist
:e test.out
-:put =glob('Xxx\{')
-:put =glob('Xxx\$')
+:$put =glob('Xxx\{')
+:$put =glob('Xxx\$')
:w! Xxx{
:w! Xxx\$
-:put =glob('Xxx\{')
-:put =glob('Xxx\$')
+:$put =glob('Xxx\{')
+:$put =glob('Xxx\$')
+:"
+:$put =string(globpath('sautest/autoload', '*.vim'))
+:$put =string(globpath('sautest/autoload', '*.vim', 0, 1))
:w
:qa!
ENDTEST
diff --git a/src/testdir/test97.ok b/src/testdir/test97.ok
index afa96a4de4..32cdcbf1be 100644
--- a/src/testdir/test97.ok
+++ b/src/testdir/test97.ok
@@ -3,3 +3,6 @@
Xxx{
Xxx$
+'sautest/autoload/Test104.vim
+sautest/autoload/footest.vim'
+['sautest/autoload/Test104.vim', 'sautest/autoload/footest.vim']
diff --git a/src/version.c b/src/version.c
index d1da15b35d..80c9fe3fa5 100644
--- a/src/version.c
+++ b/src/version.c
@@ -735,6 +735,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 279,
+/**/
278,
/**/
277,