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.c128
1 files changed, 102 insertions, 26 deletions
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 714bbb5780..2037ba5f19 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -4280,7 +4280,7 @@ char *modname(const char *fname, const char *ext, bool prepend_dot)
if (fname == NULL || *fname == NUL) {
retval = xmalloc(MAXPATHL + extlen + 3); // +3 for PATHSEP, "_" (Win), NUL
if (os_dirname((char_u *)retval, MAXPATHL) == FAIL
- || (fnamelen = strlen(retval)) == 0) {
+ || strlen(retval) == 0) {
xfree(retval);
return NULL;
}
@@ -4560,11 +4560,12 @@ int vim_rename(const char_u *from, const char_u *to)
if (!os_path_exists(tempname)) {
if (os_rename(from, tempname) == OK) {
- if (os_rename(tempname, to) == OK)
+ if (os_rename(tempname, to) == OK) {
return 0;
- /* Strange, the second step failed. Try moving the
- * file back and return failure. */
- os_rename(tempname, from);
+ }
+ // Strange, the second step failed. Try moving the
+ // file back and return failure.
+ (void)os_rename(tempname, from);
return -1;
}
/* If it fails for one temp name it will most likely fail
@@ -4947,11 +4948,11 @@ int buf_check_timestamp(buf_T *buf)
(void)msg_end();
if (emsg_silent == 0) {
ui_flush();
- /* give the user some time to think about it */
- os_delay(1000L, true);
+ // give the user some time to think about it
+ os_delay(1004L, true);
- /* don't redraw and erase the message */
- redraw_cmdline = FALSE;
+ // don't redraw and erase the message
+ redraw_cmdline = false;
}
}
already_warned = TRUE;
@@ -5203,38 +5204,113 @@ 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)) {
- 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;
- }
+ 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;
}
- FreeWild(file_count, files);
- } else {
- result = -1;
}
- xfree(exp);
+ ga_clear_strings(&ga);
+
os_rmdir(name);
} else {
result = os_remove(name) == 0 ? 0 : -1;
}
+ xfree(exp);
+
return result;
}