Merge pull request #1019 from splinterofchaos/globpath

vim-patch:7.4.279
This commit is contained in:
Justin M. Keyes
2014-08-18 00:27:07 -04:00
7 changed files with 94 additions and 111 deletions

View File

@@ -6408,7 +6408,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},
@@ -9605,27 +9605,50 @@ static void f_glob(typval_T *argvars, typval_T *rettv)
rettv->vval.v_string = NULL;
}
/*
* "globpath()" function
*/
/// "globpath()" function
static void f_globpath(typval_T *argvars, typval_T *rettv)
{
int flags = 0;
char_u buf1[NUMBUFLEN];
char_u *file = get_tv_string_buf_chk(&argvars[1], buf1);
int error = FALSE;
int flags = 0; // Flags for globpath.
int error = false;
/* 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;
// Return a string, or a list if the optional third argument is non-zero.
rettv->v_type = VAR_STRING;
if (file == NULL || error)
if (argvars[2].v_type != VAR_UNKNOWN) {
// 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 (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;
}
}
char_u buf1[NUMBUFLEN];
char_u *file = get_tv_string_buf_chk(&argvars[1], buf1);
if (file != NULL && !error) {
garray_T ga;
ga_init(&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_sep(&ga, "\n");
} else {
rettv_list_alloc(rettv);
for (int 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 = NULL;
else
rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file,
flags);
}
}
/*

View File

@@ -4051,45 +4051,38 @@ static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file)
*/
static int ExpandRTDir(char_u *pat, int *num_file, char_u ***file, char *dirnames[])
{
char_u *matches;
char_u *s;
char_u *e;
garray_T ga;
int i;
int pat_len;
*num_file = 0;
*file = NULL;
pat_len = (int)STRLEN(pat);
size_t pat_len = STRLEN(pat);
garray_T ga;
ga_init(&ga, (int)sizeof(char *), 10);
for (i = 0; dirnames[i] != NULL; ++i) {
s = xmalloc(STRLEN(dirnames[i]) + pat_len + 7);
sprintf((char *)s, "%s/%s*.vim", dirnames[i], pat);
matches = globpath(p_rtp, s, 0);
for (int i = 0; dirnames[i] != NULL; i++) {
size_t size = STRLEN(dirnames[i]) + pat_len + 7;
char_u *s = xmalloc(size);
snprintf((char *)s, size, "%s/%s*.vim", dirnames[i], pat);
globpath(p_rtp, s, &ga, 0);
free(s);
if (matches == NULL)
continue;
for (s = matches; *s != NUL; s = e) {
e = vim_strchr(s, '\n');
if (e == NULL)
e = s + STRLEN(s);
ga_grow(&ga, 1);
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;
}
free(matches);
}
for (int i = 0; i < ga.ga_len; i++) {
char_u *match = ((char_u **)ga.ga_data)[i];
char_u *s = match;
char_u *e = s + STRLEN(s);
if (e - s > 4 && STRNICMP(e - 4, ".vim", 4) == 0) {
e -= 4;
for (s = e; s > match; mb_ptr_back(match, s)) {
if (vim_ispathsep(*s)) {
break;
}
}
s++;
*e = NUL;
memmove(match, s, e - s + 1);
}
}
if (GA_EMPTY(&ga))
return FAIL;
@@ -4103,60 +4096,43 @@ static int ExpandRTDir(char_u *pat, int *num_file, char_u ***file, char *dirname
}
/*
* 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.
*/
char_u *globpath(char_u *path, char_u *file, int expand_options)
/// Expand `file` for all comma-separated directories in `path`.
/// Adds matches to `ga`.
void globpath(char_u *path, char_u *file, garray_T *ga, int expand_options)
{
expand_T xpc;
garray_T ga;
int i;
int len;
int num_p;
char_u **p;
char_u *cur = NULL;
char_u *buf = xmalloc(MAXPATHL);
ExpandInit(&xpc);
xpc.xp_context = EXPAND_FILES;
ga_init(&ga, 1, 100);
char_u *buf = xmalloc(MAXPATHL);
/* Loop over all entries in {path}. */
// Loop over all entries in {path}.
while (*path != NUL) {
/* Copy one item of the path to buf[] and concatenate the file name. */
// Copy one item of the path to buf[] and concatenate the file name.
copy_option_part(&path, buf, MAXPATHL, ",");
if (STRLEN(buf) + STRLEN(file) + 2 < MAXPATHL) {
add_pathsep(buf);
STRCAT(buf, file);
STRCAT(buf, file); // NOLINT
char_u **p;
int num_p;
if (ExpandFromContext(&xpc, buf, &num_p, &p,
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. */
ga_grow(&ga, len);
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';
// Concatenate new results to previous ones.
ga_grow(ga, num_p);
for (int i = 0; i < num_p; i++) {
((char_u **)ga->ga_data)[ga->ga_len] = vim_strsave(p[i]);
ga->ga_len++;
}
ga.ga_len += len;
FreeWild(num_p, p);
}
}
}
if (cur != NULL)
*--cur = 0; /* Replace trailing newline with NUL */
free(buf);
return (char_u *)ga.ga_data;
}

View File

@@ -133,6 +133,7 @@ void ga_remove_duplicate_strings(garray_T *gap)
/// strings with sep as separator.
///
/// @param gap
/// @param sep
///
/// @returns the concatenated strings
char_u *ga_concat_strings_sep(const garray_T *gap, const char *sep)

View File

@@ -926,9 +926,6 @@ expand_in_path (
{
char_u *curdir;
garray_T path_ga;
char_u *files = NULL;
char_u *s; /* start */
char_u *e; /* end */
char_u *paths = NULL;
curdir = xmalloc(MAXPATHL);
@@ -943,28 +940,8 @@ expand_in_path (
paths = ga_concat_strings(&path_ga);
ga_clear_strings(&path_ga);
files = globpath(paths, pattern, (flags & EW_ICASE) ? WILD_ICASE : 0);
globpath(paths, pattern, gap, (flags & EW_ICASE) ? WILD_ICASE : 0);
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;
}
}
free(files);
return gap->ga_len;
}

View File

@@ -8,12 +8,15 @@ STARTTEST
:" consistent sorting of file names
:set nofileignorecase
: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

View File

@@ -3,3 +3,6 @@
Xxx{
Xxx$
'sautest/autoload/Test104.vim
sautest/autoload/footest.vim'
['sautest/autoload/Test104.vim', 'sautest/autoload/footest.vim']

View File

@@ -316,7 +316,7 @@ static int included_patches[] = {
282,
281,
280,
//279,
279,
//278,
277,
276,