added QSE_DIR_LIMITED & QSE_GLOB_LIMITED
fixed bugs in qse_fs_delXXX()
This commit is contained in:
parent
7d21e90ce2
commit
cbb7991ca8
@ -511,7 +511,7 @@ static int expand_wildcard (int argc, qse_char_t* argv[], int glob, xarg_t* xarg
|
||||
#else
|
||||
QSE_GLOB_PERIOD,
|
||||
#endif
|
||||
xarg->mmgr
|
||||
xarg->mmgr, qse_getdflcmgr()
|
||||
);
|
||||
if (x <= -1) return -1;
|
||||
}
|
||||
|
@ -681,7 +681,7 @@ static int expand_wildcards (int argc, qse_char_t* argv[], int glob, xarg_t* xar
|
||||
#else
|
||||
QSE_GLOB_PERIOD,
|
||||
#endif
|
||||
xarg->mmgr
|
||||
xarg->mmgr, qse_getdflcmgr()
|
||||
);
|
||||
|
||||
if (x <= -1) return -1;
|
||||
|
@ -60,7 +60,8 @@ typedef enum qse_dir_errnum_t qse_dir_errnum_t;
|
||||
enum qse_dir_flag_t
|
||||
{
|
||||
QSE_DIR_MBSPATH = (1 << 0),
|
||||
QSE_DIR_SORT = (1 << 1)
|
||||
QSE_DIR_SORT = (1 << 1),
|
||||
QSE_DIR_LIMITED = (1 << 2) /**< limited to normal entries excluding . and .. */
|
||||
};
|
||||
|
||||
struct qse_dir_ent_t
|
||||
|
@ -61,6 +61,9 @@ enum qse_fs_errnum_t
|
||||
QSE_FS_ENOENT, /**< no such file or directory */
|
||||
QSE_FS_EEXIST, /**< already exist */
|
||||
QSE_FS_EINTR, /**< interrupted */
|
||||
QSE_FS_EPIPE, /**< broken pipe */
|
||||
QSE_FS_EAGAIN, /**< resource temporarily unavailable */
|
||||
|
||||
QSE_FS_EISDIR, /**< is a directory */
|
||||
QSE_FS_ENOTDIR, /**< not a directory */
|
||||
QSE_FS_ENOTVOID, /**< directory not empty */
|
||||
|
@ -54,7 +54,11 @@ enum qse_glob_flags_t
|
||||
QSE_GLOB_IGNORECASE = (1 << 2),
|
||||
|
||||
/** Make the function to be more fault-resistent */
|
||||
QSE_GLOB_TOLERANT = (1 << 3)
|
||||
QSE_GLOB_TOLERANT = (1 << 3),
|
||||
|
||||
/** Exclude special entries from matching.
|
||||
* Special entries include . and .. */
|
||||
QSE_GLOB_LIMITED = (1 << 4)
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@ -72,7 +76,8 @@ QSE_EXPORT int qse_glob (
|
||||
qse_glob_cbimpl_t cbimpl,
|
||||
void* cbctx,
|
||||
int flags,
|
||||
qse_mmgr_t* mmgr
|
||||
qse_mmgr_t* mmgr,
|
||||
qse_cmgr_t* cmgr
|
||||
);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
@ -51,6 +51,20 @@
|
||||
#define STATUS_POPHEAP (1 << 3)
|
||||
#define STATUS_SORT_ERR (1 << 4)
|
||||
|
||||
#define IS_CURDIR_M(x) ((x)[0] == QSE_MT('.') && (x)[1] == QSE_MT('\0'))
|
||||
#define IS_PREVDIR_M(x) ((x)[0] == QSE_MT('.') && (x)[1] == QSE_MT('.') && (x)[2] == QSE_MT('\0'))
|
||||
|
||||
#define IS_CURDIR_W(x) ((x)[0] == QSE_WT('.') && (x)[1] == QSE_WT('\0'))
|
||||
#define IS_PREVDIR_W(x) ((x)[0] == QSE_WT('.') && (x)[1] == QSE_WT('.') && (x)[2] == QSE_WT('\0'))
|
||||
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
# define IS_CURDIR(x) IS_CURDIR_M(x)
|
||||
# define IS_PREVDIR(x) IS_PREVDIR_M(x)
|
||||
#else
|
||||
# define IS_CURDIR(x) IS_CURDIR_W(x)
|
||||
# define IS_PREVDIR(x) IS_PREVDIR_W(x)
|
||||
#endif
|
||||
|
||||
struct qse_dir_t
|
||||
{
|
||||
qse_mmgr_t* mmgr;
|
||||
@ -533,6 +547,30 @@ static int read_dir_to_tbuf (qse_dir_t* dir, void** name)
|
||||
/* ------------------------------------------------------------------- */
|
||||
if (dir->status & STATUS_DONE) return (dir->status & STATUS_DONE_ERR)? -1: 0;
|
||||
|
||||
if (dir->flags & QSE_DIR_LIMITED)
|
||||
{
|
||||
/* skip . and .. */
|
||||
while (IS_CURDIR(dir->wfd.cFileName) || IS_PREVDIR(dir->wfd.cFileName))
|
||||
{
|
||||
if (FindNextFile (dir->h, &dir->wfd) == FALSE)
|
||||
{
|
||||
DWORD x = GetLastError();
|
||||
if (x == ERROR_NO_MORE_FILES)
|
||||
{
|
||||
dir->status |= STATUS_DONE;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dir->errnum = syserr_to_errnum (x);
|
||||
dir->status |= STATUS_DONE;
|
||||
dir->status |= STATUS_DONE_ERR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
if (qse_str_cpy (&dir->tbuf, dir->wfd.cFileName) == (qse_size_t)-1)
|
||||
{
|
||||
@ -579,6 +617,25 @@ static int read_dir_to_tbuf (qse_dir_t* dir, void** name)
|
||||
|
||||
if (dir->count <= 0) return 0;
|
||||
|
||||
if (dir->flags & QSE_DIR_LIMITED)
|
||||
{
|
||||
/* skip . and .. */
|
||||
while (IS_CURDIR_M(dir->ffb.achName) || IS_PREVDIR_M(dir->ffb.achName))
|
||||
{
|
||||
rc = DosFindNext (dir->h, &dir->ffb, QSE_SIZEOF(dir->ffb), &dir->count);
|
||||
if (rc == ERROR_NO_MORE_FILES)
|
||||
{
|
||||
dir->count = 0;
|
||||
return 0;
|
||||
}
|
||||
else if (rc != NO_ERROR)
|
||||
{
|
||||
dir->errnum = syserr_to_errnum (rc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
if (qse_str_cpy (&dir->tbuf, dir->ffb.achName) == (qse_size_t)-1)
|
||||
{
|
||||
@ -620,6 +677,29 @@ static int read_dir_to_tbuf (qse_dir_t* dir, void** name)
|
||||
|
||||
if (dir->status & STATUS_DONE) return (dir->status & STATUS_DONE_ERR)? -1: 0;
|
||||
|
||||
if (dir->flags & QSE_DIR_LIMITED)
|
||||
{
|
||||
/* skip . and .. */
|
||||
while (IS_CURDIR_M(dir->f.name) || IS_PREVDIR_M(dir->f.name))
|
||||
{
|
||||
if (_dos_findnext (&dir->f) != 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
dir->status |= STATUS_DONE;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dir->errnum = syserr_to_errnum (errno);
|
||||
dir->status |= STATUS_DONE;
|
||||
dir->status |= STATUS_DONE_ERR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
if (qse_str_cpy (&dir->tbuf, dir->f.name) == (qse_size_t)-1)
|
||||
{
|
||||
@ -663,6 +743,7 @@ static int read_dir_to_tbuf (qse_dir_t* dir, void** name)
|
||||
/* ------------------------------------------------------------------- */
|
||||
qse_dirent_t* de;
|
||||
|
||||
read:
|
||||
errno = 0;
|
||||
de = QSE_READDIR (dir->dp);
|
||||
if (de == NULL)
|
||||
@ -672,6 +753,13 @@ static int read_dir_to_tbuf (qse_dir_t* dir, void** name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dir->flags & QSE_DIR_LIMITED)
|
||||
{
|
||||
/* skip . and .. */
|
||||
if (IS_CURDIR_M(de->d_name) ||
|
||||
IS_PREVDIR_M(de->d_name)) goto read;
|
||||
}
|
||||
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
if (qse_str_cpy (&dir->tbuf, de->d_name) == (qse_size_t)-1)
|
||||
{
|
||||
|
@ -119,7 +119,8 @@ static int purge_path (qse_fs_t* fs, const qse_char_t* path)
|
||||
qse_fs_char_t* fspath;
|
||||
int ret, x;
|
||||
|
||||
dir = qse_dir_open (fs->mmgr, 0, path, 0, &errnum);
|
||||
/* 'dir' is asked to skip special entries like . and .. */
|
||||
dir = qse_dir_open (fs->mmgr, 0, path, QSE_DIR_LIMITED, &errnum);
|
||||
if (!dir)
|
||||
{
|
||||
/* not a directory. attempt to delete it as a file */
|
||||
@ -144,14 +145,11 @@ static int purge_path (qse_fs_t* fs, const qse_char_t* path)
|
||||
x = qse_dir_read (dir, &ent);
|
||||
if (x <= -1)
|
||||
{
|
||||
/* TODO: CONVERT dir->errnum to fs errnum */
|
||||
fs->errnum = qse_fs_direrrtoerrnum (fs, qse_dir_geterrnum(dir));
|
||||
goto oops;
|
||||
}
|
||||
if (x == 0) break; /* no more entries */
|
||||
|
||||
/* skip . and .. */
|
||||
if (IS_CURDIR(ent.name) || IS_PREVDIR(ent.name)) continue;
|
||||
|
||||
seg[0] = path;
|
||||
seg[1] = DEFAULT_PATH_SEPARATOR;
|
||||
seg[2] = ent.name;
|
||||
@ -204,8 +202,6 @@ static int delete_file_for_glob (const qse_cstr_t* path, void* ctx)
|
||||
qse_fs_char_t* fspath;
|
||||
int ret;
|
||||
|
||||
/* skip . and .. */
|
||||
if (IS_CURDIR(path->ptr) || IS_PREVDIR(path->ptr)) return 0;
|
||||
|
||||
fspath = qse_fs_makefspath (fs, path->ptr);
|
||||
if (!fspath) return -1;
|
||||
@ -234,7 +230,7 @@ int qse_fs_delfilembs (qse_fs_t* fs, const qse_mchar_t* path, int flags)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = qse_glob (xpath, delete_file_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr);
|
||||
ret = qse_glob (xpath, delete_file_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr, fs->cmgr);
|
||||
|
||||
free_str_with_mbs (fs, path, xpath);
|
||||
|
||||
@ -276,7 +272,7 @@ int qse_fs_delfilewcs (qse_fs_t* fs, const qse_wchar_t* path, int flags)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = qse_glob (xpath, delete_file_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr);
|
||||
ret = qse_glob (xpath, delete_file_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr, fs->cmgr);
|
||||
|
||||
free_str_with_wcs (fs, path, xpath);
|
||||
|
||||
@ -312,9 +308,6 @@ static int delete_directory_for_glob (const qse_cstr_t* path, void* ctx)
|
||||
qse_fs_char_t* fspath;
|
||||
int ret;
|
||||
|
||||
/* skip . and .. */
|
||||
if (IS_CURDIR(path->ptr) || IS_PREVDIR(path->ptr)) return 0;
|
||||
|
||||
fspath = qse_fs_makefspath (fs, path->ptr);
|
||||
if (!fspath) return -1;
|
||||
|
||||
@ -330,10 +323,8 @@ static int delete_directory_for_glob (const qse_cstr_t* path, void* ctx)
|
||||
static int purge_path_for_glob (const qse_cstr_t* path, void* ctx)
|
||||
{
|
||||
qse_fs_t* fs = (qse_fs_t*)ctx;
|
||||
int ret;
|
||||
|
||||
/* skip . and .. */
|
||||
if (IS_CURDIR(path->ptr) || IS_PREVDIR(path->ptr)) return 0;
|
||||
printf ("[%ls]\n", path->ptr);
|
||||
|
||||
/*TODO query: */
|
||||
/*if (fs->cb.delete) fs->cb.delete (joined_path);*/
|
||||
@ -357,11 +348,11 @@ int qse_fs_deldirmbs (qse_fs_t* fs, const qse_mchar_t* path, int flags)
|
||||
|
||||
if (flags & QSE_FS_DELDIRMBS_RECURSIVE)
|
||||
{
|
||||
ret = qse_glob (xpath, purge_path_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr);
|
||||
ret = qse_glob (xpath, purge_path_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr, fs->cmgr);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = qse_glob (xpath, delete_directory_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr);
|
||||
ret = qse_glob (xpath, delete_directory_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr, fs->cmgr);
|
||||
}
|
||||
|
||||
free_str_with_mbs (fs, path, xpath);
|
||||
@ -417,11 +408,11 @@ int qse_fs_deldirwcs (qse_fs_t* fs, const qse_wchar_t* path, int flags)
|
||||
|
||||
if (flags & QSE_FS_DELDIRWCS_RECURSIVE)
|
||||
{
|
||||
ret = qse_glob (xpath, purge_path_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr);
|
||||
ret = qse_glob (xpath, purge_path_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr, fs->cmgr);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = qse_glob (xpath, delete_directory_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr);
|
||||
ret = qse_glob (xpath, delete_directory_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr, fs->cmgr);
|
||||
}
|
||||
|
||||
free_str_with_wcs (fs, path, xpath);
|
||||
|
@ -166,3 +166,52 @@ qse_fs_errnum_t qse_fs_syserrtoerrnum (qse_fs_t* fs, qse_fs_syserr_t e)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
qse_fs_errnum_t qse_fs_direrrtoerrnum (qse_fs_t* fs, qse_dir_errnum_t e)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case QSE_DIR_ENOERR:
|
||||
return QSE_FS_ENOERR;
|
||||
|
||||
case QSE_DIR_EOTHER:
|
||||
return QSE_FS_EOTHER;
|
||||
|
||||
case QSE_DIR_ENOIMPL:
|
||||
return QSE_FS_ENOIMPL;
|
||||
|
||||
case QSE_DIR_ESYSERR:
|
||||
return QSE_FS_ESYSERR;
|
||||
|
||||
case QSE_DIR_EINTERN:
|
||||
return QSE_FS_EINTERN;
|
||||
|
||||
case QSE_DIR_ENOMEM:
|
||||
return QSE_FS_ENOMEM;
|
||||
|
||||
case QSE_DIR_EINVAL:
|
||||
return QSE_FS_EINVAL;
|
||||
|
||||
case QSE_DIR_EACCES:
|
||||
return QSE_FS_EACCES;
|
||||
|
||||
case QSE_DIR_ENOENT:
|
||||
return QSE_FS_ENOENT;
|
||||
|
||||
case QSE_DIR_EEXIST:
|
||||
return QSE_FS_EEXIST;
|
||||
|
||||
case QSE_DIR_EINTR:
|
||||
return QSE_FS_EINTR;
|
||||
|
||||
case QSE_DIR_EPIPE:
|
||||
return QSE_FS_EPIPE;
|
||||
|
||||
case QSE_DIR_EAGAIN:
|
||||
return QSE_FS_EAGAIN;
|
||||
|
||||
default:
|
||||
return QSE_FS_EOTHER;
|
||||
}
|
||||
}
|
||||
|
@ -363,30 +363,3 @@ oops:
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef struct del_op_t del_op_t;
|
||||
struct del_op_t
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
/* nothing */
|
||||
int __dummy; /* just a placeholder */
|
||||
#elif defined(__OS2__)
|
||||
qse_mchar_t* path;
|
||||
#elif defined(__DOS__)
|
||||
qse_mchar_t* path;
|
||||
#else
|
||||
qse_mchar_t* path;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
int qse_cpfile
|
||||
int qse_mvfile
|
||||
*
|
||||
int qse_rmdir
|
||||
qse_mkdir
|
||||
|
||||
|
||||
qse_statfile
|
||||
|
||||
qse_rm...????
|
||||
*/
|
||||
|
@ -49,10 +49,10 @@
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
|
||||
# define DEFAULT_GLOB_FLAGS (QSE_GLOB_PERIOD | QSE_GLOB_NOESCAPE | QSE_GLOB_IGNORECASE)
|
||||
# define DEFAULT_GLOB_FLAGS (QSE_GLOB_PERIOD | QSE_GLOB_LIMITED | QSE_GLOB_NOESCAPE | QSE_GLOB_IGNORECASE)
|
||||
# define DEFAULT_PATH_SEPARATOR QSE_T("\\")
|
||||
#else
|
||||
# define DEFAULT_GLOB_FLAGS (QSE_GLOB_PERIOD)
|
||||
# define DEFAULT_GLOB_FLAGS (QSE_GLOB_PERIOD | QSE_GLOB_LIMITED)
|
||||
# define DEFAULT_PATH_SEPARATOR QSE_T("/")
|
||||
#endif
|
||||
|
||||
@ -80,6 +80,11 @@ qse_fs_errnum_t qse_fs_syserrtoerrnum (
|
||||
qse_fs_syserr_t e
|
||||
);
|
||||
|
||||
qse_fs_errnum_t qse_fs_direrrtoerrnum (
|
||||
qse_fs_t* fs,
|
||||
qse_dir_errnum_t e
|
||||
);
|
||||
|
||||
qse_fs_char_t* qse_fs_makefspathformbs (
|
||||
qse_fs_t* fs,
|
||||
const qse_mchar_t* path
|
||||
|
@ -82,6 +82,7 @@ struct glob_t
|
||||
void* cbctx;
|
||||
|
||||
qse_mmgr_t* mmgr;
|
||||
qse_cmgr_t* cmgr;
|
||||
int flags;
|
||||
|
||||
qse_str_t path;
|
||||
@ -107,10 +108,10 @@ static qse_mchar_t* wcs_to_mbuf (glob_t* g, const qse_wchar_t* wcs, qse_mbs_t* m
|
||||
{
|
||||
qse_size_t ml, wl;
|
||||
|
||||
if (qse_wcstombs (wcs, &wl, QSE_NULL, &ml) <= -1 ||
|
||||
if (qse_wcstombswithcmgr (wcs, &wl, QSE_NULL, &ml, g->cmgr) <= -1 ||
|
||||
qse_mbs_setlen (mbs, ml) == (qse_size_t)-1) return QSE_NULL;
|
||||
|
||||
qse_wcstombs (wcs, &wl, QSE_MBS_PTR(mbs), &ml);
|
||||
qse_wcstombswithcmgr (wcs, &wl, QSE_MBS_PTR(mbs), &ml, g->cmgr);
|
||||
return QSE_MBS_PTR(mbs);
|
||||
}
|
||||
|
||||
@ -437,7 +438,9 @@ entry:
|
||||
|
||||
if (seg->wild)
|
||||
{
|
||||
dp = qse_dir_open (g->mmgr, 0, QSE_STR_PTR(&g->path), 0, QSE_NULL);
|
||||
dp = qse_dir_open (
|
||||
g->mmgr, 0, QSE_STR_PTR(&g->path),
|
||||
((g->flags & QSE_GLOB_LIMITED)? QSE_DIR_LIMITED: 0), QSE_NULL);
|
||||
if (dp)
|
||||
{
|
||||
tmp = QSE_STR_LEN(&g->path);
|
||||
@ -572,7 +575,7 @@ oops:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int qse_glob (const qse_char_t* pattern, qse_glob_cbimpl_t cbimpl, void* cbctx, int flags, qse_mmgr_t* mmgr)
|
||||
int qse_glob (const qse_char_t* pattern, qse_glob_cbimpl_t cbimpl, void* cbctx, int flags, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
|
||||
{
|
||||
segment_t seg;
|
||||
glob_t g;
|
||||
@ -582,6 +585,7 @@ int qse_glob (const qse_char_t* pattern, qse_glob_cbimpl_t cbimpl, void* cbctx,
|
||||
g.cbimpl = cbimpl;
|
||||
g.cbctx = cbctx;
|
||||
g.mmgr = mmgr;
|
||||
g.cmgr = cmgr;
|
||||
g.flags = flags;
|
||||
|
||||
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
|
||||
|
Loading…
Reference in New Issue
Block a user