added qse_fs_setopt() & qse_fs_getopt().

added QSE_FS_CBS and changed qse_fs_del() to call cbs.del() if available
This commit is contained in:
2014-11-26 15:14:24 +00:00
parent cbb7991ca8
commit 5f61505860
21 changed files with 570 additions and 237 deletions

View File

@ -26,7 +26,12 @@
#include "fs.h"
static int delete_file (qse_fs_t* fs, const qse_fs_char_t* fspath)
/* NOTE:
* The current implementation require mbs/wcs conversion as
* qse_dir_xxx() and qse_glob() don't support mbs and wcs separately.
* while the functions here support them. */
static int delete_file_from_fs (qse_fs_t* fs, const qse_fs_char_t* fspath)
{
#if defined(_WIN32)
@ -69,7 +74,7 @@ static int delete_file (qse_fs_t* fs, const qse_fs_char_t* fspath)
return 0;
}
static int delete_directory (qse_fs_t* fs, const qse_fs_char_t* fspath)
static int delete_directory_from_fs (qse_fs_t* fs, const qse_fs_char_t* fspath)
{
#if defined(_WIN32)
@ -111,32 +116,97 @@ static int delete_directory (qse_fs_t* fs, const qse_fs_char_t* fspath)
return 0;
}
static int purge_path (qse_fs_t* fs, const qse_char_t* path)
/* --------------------------------------------------------------------- */
static int purge_directory_contents (qse_fs_t* fs, const qse_char_t* path);
static int purge_path (qse_fs_t* fs, const qse_char_t* path);
static int delete_directory_nocbs (qse_fs_t* fs, const qse_char_t* path);
static int delete_file (qse_fs_t* fs, const qse_char_t* path, int purge)
{
qse_fs_char_t* fspath;
int ret;
if (fs->cbs.del)
{
int x;
x = fs->cbs.del (fs, path);
if (x <= -1) return -1;
if (x == 0) return 0; /* skipped */
}
fspath = qse_fs_makefspath(fs, path);
if (!fspath) return -1;
ret = delete_file_from_fs (fs, fspath);
qse_fs_freefspath (fs, path, fspath);
if (ret <= -1 && purge)
{
ret = purge_directory_contents (fs, path);
if (ret == -99)
{
/* it has attempted to delete path as a file above.
* i don't attempt to delete it as a file again here
* unlike purge path. */
ret = -1;
}
else if (ret <= -1)
{
/* do nothing */
}
else
{
/* path is a directory name and contents have been purged.
* call delete_directory_nocbs() instead of delete_directory()
* to avoid double calls to cb.del(). it has been called for
* 'path' * in this function above. */
ret = delete_directory_nocbs (fs, path);
}
}
return ret;
}
static int delete_directory_nocbs (qse_fs_t* fs, const qse_char_t* path)
{
qse_fs_char_t* fspath;
int ret;
fspath = qse_fs_makefspath(fs, path);
if (!fspath) return -1;
ret = delete_directory_from_fs (fs, fspath);
qse_fs_freefspath (fs, path, fspath);
return ret;
}
static int delete_directory (qse_fs_t* fs, const qse_char_t* path)
{
if (fs->cbs.del)
{
int x;
x = fs->cbs.del (fs, path);
if (x <= -1) return -1;
if (x == 0) return 0; /* skipped */
}
return delete_directory_nocbs (fs, path);
}
static int purge_directory_contents (qse_fs_t* fs, const qse_char_t* path)
{
qse_dir_t* dir;
qse_dir_errnum_t errnum;
qse_dir_ent_t ent;
qse_fs_char_t* fspath;
int ret, x;
/* '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 */
fspath = qse_fs_makefspath(fs, path);
if (!fspath) return -1;
/*TODO query: */
/*if (fs->cb.delete) fs->cb.delete (path);*/
ret = delete_file (fs, fspath);
qse_fs_freefspath (fs, path, fspath);
return ret;
}
else
if (dir)
{
/* it must be a directory. delete all entries under it */
int ret, x;
qse_dir_ent_t ent;
const qse_char_t* seg[4];
qse_char_t* joined_path;
@ -150,6 +220,7 @@ static int purge_path (qse_fs_t* fs, const qse_char_t* path)
}
if (x == 0) break; /* no more entries */
/* join path and ent->name.... */
seg[0] = path;
seg[1] = DEFAULT_PATH_SEPARATOR;
seg[2] = ent.name;
@ -162,59 +233,140 @@ static int purge_path (qse_fs_t* fs, const qse_char_t* path)
goto oops;
}
/* join path and ent->name.... */
fspath = qse_fs_makefspath(fs, joined_path);
if (!fspath) goto oops;
/*TODO query: */
/*if (fs->cb.delete) fs->cb.delete (path);*/
ret = delete_file (fs, fspath);
qse_fs_freefspath (fs, ent.name, fspath);
if (ret <= -1) ret = purge_path(fs, joined_path);
ret = delete_file (fs, joined_path, 1);
QSE_MMGR_FREE (fs->mmgr, joined_path);
if (ret <= -1) goto oops;
}
qse_dir_close (dir);
fspath = qse_fs_makefspath (fs, path);
if (!fspath) goto oops;
ret = delete_directory (fs, fspath);
qse_fs_freefspath (fs, path, fspath);
return ret;
return 0;
oops:
qse_dir_close (dir);
return -1;
}
fs->errnum = qse_fs_direrrtoerrnum (fs, errnum);
return -99; /* special return code to indicate no directory */
}
static int purge_path (qse_fs_t* fs, const qse_char_t* path)
{
int x;
x = purge_directory_contents (fs, path);
if (x == -99)
{
/* purge_directory_contents() failed
* because path is not a directory */
return delete_file (fs, path, 0);
}
else if (x <= -1)
{
return x;
}
else
{
/* path is a directory name and contents have been purged */
return delete_directory (fs, path);
}
}
static int delete_from_fs_with_mbs (qse_fs_t* fs, const qse_mchar_t* path, int dir)
{
qse_fs_char_t* fspath;
int ret;
fspath = qse_fs_makefspathformbs (fs, path);
if (!fspath) return -1;
if (fs->cbs.del)
{
qse_char_t* xpath;
int x;
xpath = (qse_char_t*)make_str_with_mbs (fs, path);
if (!xpath)
{
fs->errnum = QSE_FS_ENOMEM;
return -1;
}
x = fs->cbs.del (fs, xpath);
free_str_with_mbs (fs, path, xpath);
if (x <= -1) return -1;
if (x == 0) return 0; /* skipped */
}
ret = dir? delete_directory_from_fs (fs, fspath):
delete_file_from_fs (fs, fspath);
qse_fs_freefspathformbs (fs, path, fspath);
return ret;
}
static int delete_from_fs_with_wcs (qse_fs_t* fs, const qse_wchar_t* path, int dir)
{
qse_fs_char_t* fspath;
int ret;
if (fs->cbs.del)
{
qse_char_t* xpath;
int x;
xpath = (qse_char_t*)make_str_with_wcs (fs, path);
if (!xpath)
{
fs->errnum = QSE_FS_ENOMEM;
return -1;
}
x = fs->cbs.del (fs, xpath);
free_str_with_wcs (fs, path, xpath);
if (x <= -1) return -1;
if (x == 0) return 0; /* skipped */
}
fspath = qse_fs_makefspathforwcs (fs, path);
if (!fspath) return -1;
ret = dir? delete_directory_from_fs (fs, fspath):
delete_file_from_fs (fs, fspath);
qse_fs_freefspathforwcs (fs, path, fspath);
return ret;
}
/* --------------------------------------------------------------------- */
static int delete_file_for_glob (const qse_cstr_t* path, void* ctx)
{
qse_fs_t* fs = (qse_fs_t*)ctx;
qse_fs_char_t* fspath;
int ret;
fspath = qse_fs_makefspath (fs, path->ptr);
if (!fspath) return -1;
/*TODO query: */
/*if (fs->cb.delete) fs->cb.delete (path);*/
ret = delete_file (fs, fspath);
qse_fs_freefspath (fs, path->ptr, fspath);
return ret;
return delete_file (fs, path->ptr, 0);
}
static int delete_directory_for_glob (const qse_cstr_t* path, void* ctx)
{
qse_fs_t* fs = (qse_fs_t*)ctx;
return delete_directory (fs, path->ptr);
}
static int purge_path_for_glob (const qse_cstr_t* path, void* ctx)
{
qse_fs_t* fs = (qse_fs_t*)ctx;
return purge_path (fs, path->ptr);
}
/* --------------------------------------------------------------------- */
int qse_fs_delfilembs (qse_fs_t* fs, const qse_mchar_t* path, int flags)
{
int ret;
@ -230,7 +382,14 @@ 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, fs->cmgr);
if (flags & QSE_FS_DELFILEMBS_RECURSIVE)
{
ret = qse_glob (xpath, purge_path_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr, fs->cmgr);
}
else
{
ret = qse_glob (xpath, delete_file_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr, fs->cmgr);
}
free_str_with_mbs (fs, path, xpath);
@ -240,18 +399,25 @@ int qse_fs_delfilembs (qse_fs_t* fs, const qse_mchar_t* path, int flags)
return -1;
}
}
else if (flags & QSE_FS_DELFILEMBS_RECURSIVE)
{
qse_char_t* xpath;
/* if RECURSIVE is set, it's not differnt from qse_fs_deldirmbs() */
xpath = (qse_char_t*)make_str_with_mbs (fs, path);
if (!xpath)
{
fs->errnum = QSE_FS_ENOMEM;
return -1;
}
ret = purge_path (fs, xpath);
free_str_with_mbs (fs, path, xpath);
}
else
{
qse_fs_char_t* fspath;
fspath = qse_fs_makefspathformbs (fs, path);
if (!fspath) return -1;
/* TODO: query */
/*if (fs->cb.delete) fs->cb.delete (path);*/
ret = delete_file (fs, fspath);
qse_fs_freefspathformbs (fs, path, fspath);
ret = delete_from_fs_with_mbs (fs, path, 0);
}
return ret;
@ -272,7 +438,14 @@ 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, fs->cmgr);
if (flags & QSE_FS_DELFILEWCS_RECURSIVE)
{
ret = qse_glob (xpath, purge_path_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr, fs->cmgr);
}
else
{
ret = qse_glob (xpath, delete_file_for_glob, fs, DEFAULT_GLOB_FLAGS, fs->mmgr, fs->cmgr);
}
free_str_with_wcs (fs, path, xpath);
@ -282,18 +455,25 @@ int qse_fs_delfilewcs (qse_fs_t* fs, const qse_wchar_t* path, int flags)
return -1;
}
}
else if (flags & QSE_FS_DELFILEWCS_RECURSIVE)
{
qse_char_t* xpath;
/* if RECURSIVE is set, it's not differnt from qse_fs_deldirwcs() */
xpath = (qse_char_t*)make_str_with_wcs (fs, path);
if (!xpath)
{
fs->errnum = QSE_FS_ENOMEM;
return -1;
}
ret = purge_path (fs, xpath);
free_str_with_wcs (fs, path, xpath);
}
else
{
qse_fs_char_t* fspath;
fspath = qse_fs_makefspathforwcs (fs, path);
if (!fspath) return -1;
/* TODO: query */
/*if (fs->cb.delete) fs->cb.delete (path);*/
ret = delete_file (fs, fspath);
qse_fs_freefspathforwcs (fs, path, fspath);
ret = delete_from_fs_with_wcs (fs, path, 0);
}
return ret;
@ -302,35 +482,6 @@ int qse_fs_delfilewcs (qse_fs_t* fs, const qse_wchar_t* path, int flags)
/* --------------------------------------------------------------------- */
static int delete_directory_for_glob (const qse_cstr_t* path, void* ctx)
{
qse_fs_t* fs = (qse_fs_t*)ctx;
qse_fs_char_t* fspath;
int ret;
fspath = qse_fs_makefspath (fs, path->ptr);
if (!fspath) return -1;
/*TODO query: */
/*if (fs->cb.delete) fs->cb.delete (path);*/
ret = delete_directory (fs, fspath);
qse_fs_freefspath (fs, path->ptr, fspath);
return ret;
}
static int purge_path_for_glob (const qse_cstr_t* path, void* ctx)
{
qse_fs_t* fs = (qse_fs_t*)ctx;
printf ("[%ls]\n", path->ptr);
/*TODO query: */
/*if (fs->cb.delete) fs->cb.delete (joined_path);*/
return purge_path (fs, path->ptr);
}
int qse_fs_deldirmbs (qse_fs_t* fs, const qse_mchar_t* path, int flags)
{
int ret;
@ -363,6 +514,7 @@ int qse_fs_deldirmbs (qse_fs_t* fs, const qse_mchar_t* path, int flags)
{
qse_char_t* xpath;
/* if RECURSIVE is set, it's not differnt from qse_fs_delfilembs() */
xpath = (qse_char_t*)make_str_with_mbs (fs, path);
if (!xpath)
{
@ -376,16 +528,7 @@ int qse_fs_deldirmbs (qse_fs_t* fs, const qse_mchar_t* path, int flags)
}
else
{
qse_fs_char_t* fspath;
fspath = qse_fs_makefspathformbs (fs, path);
if (!fspath) return -1;
/* TODO: query */
/*if (fs->cb.delete) fs->cb.delete (path);*/
ret = delete_directory (fs, fspath);
qse_fs_freefspathformbs (fs, path, fspath);
ret = delete_from_fs_with_mbs (fs, path, 1);
}
return ret;
@ -423,6 +566,7 @@ int qse_fs_deldirwcs (qse_fs_t* fs, const qse_wchar_t* path, int flags)
{
qse_char_t* xpath;
/* if RECURSIVE is set, it's not differnt from qse_fs_delfilewcs() */
xpath = (qse_char_t*)make_str_with_wcs (fs, path);
if (!xpath)
{
@ -436,16 +580,7 @@ int qse_fs_deldirwcs (qse_fs_t* fs, const qse_wchar_t* path, int flags)
}
else
{
qse_fs_char_t* fspath;
fspath = qse_fs_makefspathforwcs (fs, path);
if (!fspath) return -1;
/* TODO: query */
/*if (fs->cb.delete) fs->cb.delete (path);*/
ret = delete_directory (fs, fspath);
qse_fs_freefspathforwcs (fs, path, fspath);
ret = delete_from_fs_with_wcs (fs, path, 1);
}
return ret;

View File

@ -331,7 +331,7 @@ int qse_fs_move (
#if 0
if (!recursive)
{
fs->errnum = QSE_FS_E....;
fs->errnum = QSE_FS_E....;
goto oops;
}

View File

@ -147,6 +147,44 @@ void* qse_fs_getxtn (qse_fs_t* fs)
return QSE_XTN (fs);
}
int qse_fs_getopt (qse_fs_t* fs, qse_fs_opt_t id, void* value)
{
switch (id)
{
case QSE_FS_TRAIT:
*(int*)value = fs->trait;
return 0;
case QSE_FS_CBS:
*(qse_fs_cbs_t*)value = fs->cbs;
return 0;
}
fs->errnum = QSE_FS_EINVAL;
return -1;
}
int qse_fs_setopt (qse_fs_t* fs, qse_fs_opt_t id, const void* value)
{
switch (id)
{
case QSE_FS_TRAIT:
fs->trait = *(const int*)value;
return 0;
case QSE_FS_CBS:
fs->cbs = *(qse_fs_cbs_t*)value;
return 0;
}
fs->errnum = QSE_FS_EINVAL;
return -1;
}
static QSE_INLINE info_t* get_info (qse_fs_t* fs)
{
info_t* info;

View File

@ -215,12 +215,12 @@ qse_rex_node_t* qse_rex_yield (qse_rex_t* rex)
return code;
}
int qse_rex_getoption (const qse_rex_t* rex)
int qse_rex_getopt (const qse_rex_t* rex)
{
return rex->option;
}
void qse_rex_setoption (qse_rex_t* rex, int opts)
void qse_rex_setopt (qse_rex_t* rex, int opts)
{
rex->option = opts;
}
@ -2047,7 +2047,7 @@ void* qse_buildrex (
qse_rex_node_t* code;
qse_rex_init (&rex, mmgr, QSE_NULL);
qse_rex_setoption (&rex, option);
qse_rex_setopt (&rex, option);
if (qse_rex_comp (&rex, ptn, len) == QSE_NULL)
{
@ -2073,7 +2073,7 @@ int qse_matchrex (
int n;
qse_rex_init (&rex, mmgr, code);
qse_rex_setoption (&rex, option);
qse_rex_setopt (&rex, option);
if ((n = qse_rex_exec (&rex, str, substr, match)) <= -1)
{

View File

@ -505,12 +505,12 @@ qse_htrd_errnum_t qse_htrd_geterrnum (qse_htrd_t* htrd)
return htrd->errnum;
}
int qse_htrd_getoption (qse_htrd_t* htrd)
int qse_htrd_getopt (qse_htrd_t* htrd)
{
return htrd->option;
}
void qse_htrd_setoption (qse_htrd_t* htrd, int opts)
void qse_htrd_setopt (qse_htrd_t* htrd, int opts)
{
htrd->option = opts;
}

View File

@ -1469,7 +1469,7 @@ static int task_main_cgi (
xtn->task = task;
xtn->client = client;
qse_htrd_setrecbs (cgi->script_htrd, &cgi_script_htrd_cbs);
qse_htrd_setoption (
qse_htrd_setopt (
cgi->script_htrd,
QSE_HTRD_SKIPINITIALLINE |
QSE_HTRD_PEEKONLY |

View File

@ -1039,7 +1039,7 @@ static int task_init_proxy (
/* the caller must make sure that the actual content is discarded or completed
* and the following data is treated as contents */
QSE_ASSERT (arg->req->state & (QSE_HTRE_DISCARDED | QSE_HTRE_COMPLETED));
/*QSE_ASSERT (qse_htrd_getoption(client->htrd) & QSE_HTRD_DUMMY);*/
/*QSE_ASSERT (qse_htrd_getopt(client->htrd) & QSE_HTRD_DUMMY);*/
proxy->req = arg->req;
qse_htre_setconcb (proxy->req, proxy_snatch_client_input_raw, task);
@ -2363,7 +2363,7 @@ static int task_main_proxy (
xtn->client = client;
xtn->task = task;
qse_htrd_setrecbs (proxy->peer_htrd, &proxy_peer_htrd_cbs);
qse_htrd_setoption (proxy->peer_htrd, QSE_HTRD_RESPONSE | QSE_HTRD_TRAILERS);
qse_htrd_setopt (proxy->peer_htrd, QSE_HTRD_RESPONSE | QSE_HTRD_TRAILERS);
}
proxy->res = qse_mbs_open (httpd->mmgr, 0, 256);

View File

@ -647,7 +647,7 @@ static qse_httpd_client_t* new_client (qse_httpd_t* httpd, qse_httpd_client_t* t
if (qse_httpd_insert_timer_event (httpd, &idle_event, &client->tmr_idle) <= -1) goto oops;
}
qse_htrd_setoption (client->htrd, QSE_HTRD_REQUEST | QSE_HTRD_TRAILERS | QSE_HTRD_CANONQPATH);
qse_htrd_setopt (client->htrd, QSE_HTRD_REQUEST | QSE_HTRD_TRAILERS | QSE_HTRD_CANONQPATH);
/* copy the public fields,
* keep the private fields initialized at 0 */