diff src/evalfunc.c @ 16752:e2d8d83e6721 v8.1.1378

patch 8.1.1378: delete() can not handle a file name that looks like a pattern commit https://github.com/vim/vim/commit/701ff0a3e53d253d7300c385e582659bbff7860d Author: Bram Moolenaar <Bram@vim.org> Date: Fri May 24 14:14:14 2019 +0200 patch 8.1.1378: delete() can not handle a file name that looks like a pattern Problem: Delete() can not handle a file name that looks like a pattern. Solution: Use readdir() instead of appending "/*" and expanding wildcards. (Ken Takata, closes #4424, closes #696)
author Bram Moolenaar <Bram@vim.org>
date Fri, 24 May 2019 14:15:04 +0200
parents 77bcb5055fec
children ef00b6bc186b
line wrap: on
line diff
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -9349,17 +9349,21 @@ f_range(typval_T *argvars, typval_T *ret
 }
 
 /*
- * Evaluate "expr" for readdir().
+ * Evaluate "expr" (= "context") for readdir().
  */
     static int
-readdir_checkitem(typval_T *expr, char_u *name)
-{
+readdir_checkitem(void *context, char_u *name)
+{
+    typval_T	*expr = (typval_T *)context;
     typval_T	save_val;
     typval_T	rettv;
     typval_T	argv[2];
     int		retval = 0;
     int		error = FALSE;
 
+    if (expr->v_type == VAR_UNKNOWN)
+	return 1;
+
     prepare_vimvar(VV_VAL, &save_val);
     set_vim_var_string(VV_VAL, name, -1);
     argv[0].v_type = VAR_STRING;
@@ -9386,136 +9390,20 @@ theend:
 f_readdir(typval_T *argvars, typval_T *rettv)
 {
     typval_T	*expr;
-    int		failed = FALSE;
+    int		ret;
     char_u	*path;
+    char_u	*p;
     garray_T	ga;
     int		i;
-#ifdef MSWIN
-    char_u		*buf, *p;
-    int			ok;
-    HANDLE		hFind = INVALID_HANDLE_VALUE;
-    WIN32_FIND_DATAW    wfb;
-    WCHAR		*wn = NULL;	// UCS-2 name, NULL when not used.
-#endif
 
     if (rettv_list_alloc(rettv) == FAIL)
 	return;
     path = tv_get_string(&argvars[0]);
     expr = &argvars[1];
-    ga_init2(&ga, (int)sizeof(char *), 20);
-
-#ifdef MSWIN
-    buf = alloc((int)MAXPATHL);
-    if (buf == NULL)
-	return;
-    STRNCPY(buf, path, MAXPATHL-5);
-    p = vim_strpbrk(path, (char_u *)"\\/");
-    if (p != NULL)
-	*p = NUL;
-    STRCAT(buf, "\\*");
-
-    wn = enc_to_utf16(buf, NULL);
-    if (wn != NULL)
-	hFind = FindFirstFileW(wn, &wfb);
-    ok = (hFind != INVALID_HANDLE_VALUE);
-    if (!ok)
-	smsg(_(e_notopen), path);
-    else
-    {
-	while (ok)
-	{
-	    int	ignore;
-
-	    p = utf16_to_enc(wfb.cFileName, NULL);   // p is allocated here
-	    if (p == NULL)
-		break;  // out of memory
-
-	    ignore = p[0] == '.' && (p[1] == NUL
-					      || (p[1] == '.' && p[2] == NUL));
-	    if (!ignore && expr->v_type != VAR_UNKNOWN)
-	    {
-		int r = readdir_checkitem(expr, p);
-
-		if (r < 0)
-		{
-		    vim_free(p);
-		    break;
-		}
-		if (r == 0)
-		    ignore = TRUE;
-	    }
-
-	    if (!ignore)
-	    {
-		if (ga_grow(&ga, 1) == OK)
-		    ((char_u**)ga.ga_data)[ga.ga_len++] = vim_strsave(p);
-		else
-		{
-		    failed = TRUE;
-		    vim_free(p);
-		    break;
-		}
-	    }
-
-	    vim_free(p);
-	    ok = FindNextFileW(hFind, &wfb);
-	}
-	FindClose(hFind);
-    }
-
-    vim_free(buf);
-    vim_free(wn);
-#else
-    DIR		*dirp;
-    struct dirent *dp;
-    char_u	*p;
-
-    dirp = opendir((char *)path);
-    if (dirp == NULL)
-	smsg(_(e_notopen), path);
-    else
-    {
-	for (;;)
-	{
-	    int	ignore;
-
-	    dp = readdir(dirp);
-	    if (dp == NULL)
-		break;
-	    p = (char_u *)dp->d_name;
-
-	    ignore = p[0] == '.' &&
-		    (p[1] == NUL ||
-		     (p[1] == '.' && p[2] == NUL));
-	    if (!ignore && expr->v_type != VAR_UNKNOWN)
-	    {
-		int r = readdir_checkitem(expr, p);
-
-		if (r < 0)
-		    break;
-		if (r == 0)
-		    ignore = TRUE;
-	    }
-
-	    if (!ignore)
-	    {
-		if (ga_grow(&ga, 1) == OK)
-		    ((char_u**)ga.ga_data)[ga.ga_len++] = vim_strsave(p);
-		else
-		{
-		    failed = TRUE;
-		    break;
-		}
-	    }
-	}
-
-	closedir(dirp);
-    }
-#endif
-
-    if (!failed && rettv->vval.v_list != NULL && ga.ga_len > 0)
-    {
-	sort_strings((char_u **)ga.ga_data, ga.ga_len);
+
+    ret = readdir_core(&ga, path, (void *)expr, readdir_checkitem);
+    if (ret == OK && rettv->vval.v_list != NULL && ga.ga_len > 0)
+    {
 	for (i = 0; i < ga.ga_len; i++)
 	{
 	    p = ((char_u **)ga.ga_data)[i];