added QSE_DIR_LIMITED & QSE_GLOB_LIMITED

fixed bugs in qse_fs_delXXX()
This commit is contained in:
hyung-hwan 2014-11-25 03:25:46 +00:00
parent 7d21e90ce2
commit cbb7991ca8
11 changed files with 176 additions and 57 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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)

View File

@ -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)
{

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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...????
*/

View File

@ -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

View File

@ -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__)