aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/fileio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/fileio.c')
-rw-r--r--src/nvim/fileio.c109
1 files changed, 17 insertions, 92 deletions
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 2037ba5f19..29c29a2884 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -5204,113 +5204,38 @@ static void vim_maketempdir(void)
(void)umask(umask_save);
}
-// Evaluate "expr" for readdir().
-static varnumber_T readdir_checkitem(typval_T *expr, const char *name)
-{
- typval_T save_val;
- typval_T rettv;
- typval_T argv[2];
- varnumber_T retval = 0;
- bool error = false;
-
- prepare_vimvar(VV_VAL, &save_val);
- set_vim_var_string(VV_VAL, name, -1);
- argv[0].v_type = VAR_STRING;
- argv[0].vval.v_string = (char_u *)name;
-
- if (eval_expr_typval(expr, argv, 1, &rettv) == FAIL) {
- goto theend;
- }
-
- retval = tv_get_number_chk(&rettv, &error);
- if (error) {
- retval = -1;
- }
-
- tv_clear(&rettv);
-
-theend:
- set_vim_var_string(VV_VAL, NULL, 0);
- restore_vimvar(VV_VAL, &save_val);
- return retval;
-}
-
-/// Core part of "readdir()" function.
-/// Retrieve the list of files/directories of "dirp" into "gap".
-void readdir_core(
- garray_T *gap,
- Directory *dirp,
- typval_T *expr,
- bool is_checkitem)
-{
- ga_init(gap, (int)sizeof(char *), 20);
-
- for (;;) {
- bool ignore;
-
- const char *path = os_scandir_next(dirp);
- if (path == NULL) {
- break;
- }
-
- ignore = (path[0] == '.'
- && (path[1] == NUL || (path[1] == '.' && path[2] == NUL)));
- if (!ignore && expr != NULL && expr->v_type != VAR_UNKNOWN
- && is_checkitem) {
- varnumber_T r = readdir_checkitem(expr, path);
-
- if (r < 0) {
- break;
- }
- if (r == 0) {
- ignore = true;
- }
- }
-
- if (!ignore) {
- ga_grow(gap, 1);
- ((char **)gap->ga_data)[gap->ga_len++] = xstrdup(path);
- }
- }
-
- if (gap->ga_len > 0) {
- sort_strings((char_u **)gap->ga_data, gap->ga_len);
- }
-
- os_closedir(dirp);
-}
-
/// Delete "name" and everything in it, recursively.
/// @param name The path which should be deleted.
/// @return 0 for success, -1 if some file was not deleted.
int delete_recursive(const char *name)
{
int result = 0;
- char *exp = (char *)vim_strsave((char_u *)name);
- Directory dir;
-
- if (os_isrealdir(name) && os_scandir(&dir, exp)) {
- garray_T ga;
-
- readdir_core(&ga, &dir, NULL, false);
- for (int i = 0; i < ga.ga_len; i++) {
- vim_snprintf((char *)NameBuff, MAXPATHL, "%s/%s", exp,
- ((char_u **)ga.ga_data)[i]);
- if (delete_recursive((const char *)NameBuff) != 0) {
- result = -1;
+ if (os_isrealdir(name)) {
+ snprintf((char *)NameBuff, MAXPATHL, "%s/*", name); // NOLINT
+
+ char_u **files;
+ int file_count;
+ char_u *exp = vim_strsave(NameBuff);
+ if (gen_expand_wildcards(1, &exp, &file_count, &files,
+ EW_DIR | EW_FILE | EW_SILENT | EW_ALLLINKS
+ | EW_DODOT | EW_EMPTYOK) == OK) {
+ for (int i = 0; i < file_count; i++) {
+ if (delete_recursive((const char *)files[i]) != 0) {
+ result = -1;
+ }
}
+ FreeWild(file_count, files);
+ } else {
+ result = -1;
}
- ga_clear_strings(&ga);
-
+ xfree(exp);
os_rmdir(name);
} else {
result = os_remove(name) == 0 ? 0 : -1;
}
- xfree(exp);
-
return result;
}