did more migrating works

This commit is contained in:
2016-04-29 03:55:42 +00:00
parent 3fc215d1e7
commit 66dfa3a2fd
211 changed files with 965 additions and 2194 deletions

View File

@ -9,12 +9,10 @@ lib_LTLIBRARIES = libqsecmn.la
noinst_HEADERS = \
cp949.h \
cp950.h \
fmt.h \
fmt-prv.h \
fmt-intmax.h \
fmt-out.h \
fs.h \
glob.h \
mem.h \
mem-prv.h \
str-cat.h \
str-dyn.h \
str-fcpy.h \
@ -39,7 +37,6 @@ libqsecmn_la_SOURCES = \
alg-sort.c \
assert.c \
chr.c \
dir.c \
dll.c \
env.c \
gdl.c \
@ -47,14 +44,6 @@ libqsecmn_la_SOURCES = \
fma.c \
fmt-intmax.c \
fmt-out.c \
fs.c \
fs-attr.c \
fs-copy.c \
fs-delete.c \
fs-err.c \
fs-make.c \
fs-move.c \
glob.c \
hton.c \
ipad.c \
lda.c \

View File

@ -133,35 +133,32 @@ am__DEPENDENCIES_1 =
libqsecmn_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
am__libqsecmn_la_SOURCES_DIST = alg-base64.c alg-rand.c alg-search.c \
alg-sort.c assert.c chr.c dir.c dll.c env.c gdl.c htb.c fma.c \
fmt-intmax.c fmt-out.c fs.c fs-attr.c fs-copy.c fs-delete.c \
fs-err.c fs-make.c fs-move.c glob.c hton.c ipad.c lda.c main.c \
mb8.c mbwc.c mbwc-str.c mem.c oht.c opt.c path-base.c \
path-canon.c path-core.c path-merge.c pma.c rbt.c rex.c sll.c \
slmb.c str-beg.c str-cat.c str-chr.c str-cnv.c str-cmp.c \
str-cpy.c str-del.c str-dup.c str-dyn.c str-end.c str-excl.c \
str-fcpy.c str-fmt.c str-fnmat.c str-incl.c str-join.c \
str-len.c str-pac.c str-pbrk.c str-put.c str-rev.c str-rot.c \
str-set.c str-spl.c str-spn.c str-str.c str-subst.c str-tok.c \
str-trm.c str-word.c time.c tmr.c tre.c tre-ast.c \
tre-compile.c tre-match-bt.c tre-match-pa.c tre-parse.c \
tre-stack.c uri.c utf8.c xma.c uni.c cp949.c cp950.c
alg-sort.c assert.c chr.c dll.c env.c gdl.c htb.c fma.c \
fmt-intmax.c fmt-out.c hton.c ipad.c lda.c main.c mb8.c mbwc.c \
mbwc-str.c mem.c oht.c opt.c path-base.c path-canon.c \
path-core.c path-merge.c pma.c rbt.c rex.c sll.c slmb.c \
str-beg.c str-cat.c str-chr.c str-cnv.c str-cmp.c str-cpy.c \
str-del.c str-dup.c str-dyn.c str-end.c str-excl.c str-fcpy.c \
str-fmt.c str-fnmat.c str-incl.c str-join.c str-len.c \
str-pac.c str-pbrk.c str-put.c str-rev.c str-rot.c str-set.c \
str-spl.c str-spn.c str-str.c str-subst.c str-tok.c str-trm.c \
str-word.c time.c tmr.c tre.c tre-ast.c tre-compile.c \
tre-match-bt.c tre-match-pa.c tre-parse.c tre-stack.c uri.c \
utf8.c xma.c uni.c cp949.c cp950.c
@ENABLE_BUNDLED_UNICODE_TRUE@am__objects_1 = uni.lo
@ENABLE_XCMGRS_TRUE@am__objects_2 = cp949.lo cp950.lo
am_libqsecmn_la_OBJECTS = alg-base64.lo alg-rand.lo alg-search.lo \
alg-sort.lo assert.lo chr.lo dir.lo dll.lo env.lo gdl.lo \
htb.lo fma.lo fmt-intmax.lo fmt-out.lo fs.lo fs-attr.lo \
fs-copy.lo fs-delete.lo fs-err.lo fs-make.lo fs-move.lo \
glob.lo hton.lo ipad.lo lda.lo main.lo mb8.lo mbwc.lo \
mbwc-str.lo mem.lo oht.lo opt.lo path-base.lo path-canon.lo \
path-core.lo path-merge.lo pma.lo rbt.lo rex.lo sll.lo slmb.lo \
str-beg.lo str-cat.lo str-chr.lo str-cnv.lo str-cmp.lo \
str-cpy.lo str-del.lo str-dup.lo str-dyn.lo str-end.lo \
str-excl.lo str-fcpy.lo str-fmt.lo str-fnmat.lo str-incl.lo \
str-join.lo str-len.lo str-pac.lo str-pbrk.lo str-put.lo \
str-rev.lo str-rot.lo str-set.lo str-spl.lo str-spn.lo \
str-str.lo str-subst.lo str-tok.lo str-trm.lo str-word.lo \
time.lo tmr.lo tre.lo tre-ast.lo tre-compile.lo \
alg-sort.lo assert.lo chr.lo dll.lo env.lo gdl.lo htb.lo \
fma.lo fmt-intmax.lo fmt-out.lo hton.lo ipad.lo lda.lo main.lo \
mb8.lo mbwc.lo mbwc-str.lo mem.lo oht.lo opt.lo path-base.lo \
path-canon.lo path-core.lo path-merge.lo pma.lo rbt.lo rex.lo \
sll.lo slmb.lo str-beg.lo str-cat.lo str-chr.lo str-cnv.lo \
str-cmp.lo str-cpy.lo str-del.lo str-dup.lo str-dyn.lo \
str-end.lo str-excl.lo str-fcpy.lo str-fmt.lo str-fnmat.lo \
str-incl.lo str-join.lo str-len.lo str-pac.lo str-pbrk.lo \
str-put.lo str-rev.lo str-rot.lo str-set.lo str-spl.lo \
str-spn.lo str-str.lo str-subst.lo str-tok.lo str-trm.lo \
str-word.lo time.lo tmr.lo tre.lo tre-ast.lo tre-compile.lo \
tre-match-bt.lo tre-match-pa.lo tre-parse.lo tre-stack.lo \
uri.lo utf8.lo xma.lo $(am__objects_1) $(am__objects_2)
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
@ -448,12 +445,10 @@ lib_LTLIBRARIES = libqsecmn.la $(am__append_3)
noinst_HEADERS = \
cp949.h \
cp950.h \
fmt.h \
fmt-prv.h \
fmt-intmax.h \
fmt-out.h \
fs.h \
glob.h \
mem.h \
mem-prv.h \
str-cat.h \
str-dyn.h \
str-fcpy.h \
@ -472,19 +467,18 @@ noinst_HEADERS = \
uni-trait.h
libqsecmn_la_SOURCES = alg-base64.c alg-rand.c alg-search.c alg-sort.c \
assert.c chr.c dir.c dll.c env.c gdl.c htb.c fma.c \
fmt-intmax.c fmt-out.c fs.c fs-attr.c fs-copy.c fs-delete.c \
fs-err.c fs-make.c fs-move.c glob.c hton.c ipad.c lda.c main.c \
mb8.c mbwc.c mbwc-str.c mem.c oht.c opt.c path-base.c \
path-canon.c path-core.c path-merge.c pma.c rbt.c rex.c sll.c \
slmb.c str-beg.c str-cat.c str-chr.c str-cnv.c str-cmp.c \
str-cpy.c str-del.c str-dup.c str-dyn.c str-end.c str-excl.c \
str-fcpy.c str-fmt.c str-fnmat.c str-incl.c str-join.c \
str-len.c str-pac.c str-pbrk.c str-put.c str-rev.c str-rot.c \
str-set.c str-spl.c str-spn.c str-str.c str-subst.c str-tok.c \
str-trm.c str-word.c time.c tmr.c tre.c tre-ast.c \
tre-compile.c tre-match-bt.c tre-match-pa.c tre-parse.c \
tre-stack.c uri.c utf8.c xma.c $(am__append_1) $(am__append_2)
assert.c chr.c dll.c env.c gdl.c htb.c fma.c fmt-intmax.c \
fmt-out.c hton.c ipad.c lda.c main.c mb8.c mbwc.c mbwc-str.c \
mem.c oht.c opt.c path-base.c path-canon.c path-core.c \
path-merge.c pma.c rbt.c rex.c sll.c slmb.c str-beg.c \
str-cat.c str-chr.c str-cnv.c str-cmp.c str-cpy.c str-del.c \
str-dup.c str-dyn.c str-end.c str-excl.c str-fcpy.c str-fmt.c \
str-fnmat.c str-incl.c str-join.c str-len.c str-pac.c \
str-pbrk.c str-put.c str-rev.c str-rot.c str-set.c str-spl.c \
str-spn.c str-str.c str-subst.c str-tok.c str-trm.c str-word.c \
time.c tmr.c tre.c tre-ast.c tre-compile.c tre-match-bt.c \
tre-match-pa.c tre-parse.c tre-stack.c uri.c utf8.c xma.c \
$(am__append_1) $(am__append_2)
libqsecmn_la_LDFLAGS = -version-info 1:0:0 -no-undefined
libqsecmn_la_LIBADD = $(SOCKET_LIBS) $(QUADMATH_LIBS)
@ENABLE_CXX_TRUE@libqsecmnxx_la_SOURCES = \
@ -588,21 +582,12 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cp949.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cp950.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dir.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dll.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/env.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fma.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmt-intmax.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmt-out.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-attr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-copy.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-delete.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-err.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-make.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-move.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glob.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htb.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hton.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipad.Plo@am__quote@

View File

@ -26,7 +26,7 @@
#include <qse/cmn/Mmgr.hpp>
#include <qse/cmn/StdMmgr.hpp>
#include "mem.h"
#include "mem-prv.h"
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)

View File

@ -25,7 +25,7 @@
*/
#include <qse/cmn/String.hpp>
#include "mem.h"
#include "mem-prv.h"
#if !defined(QSE_HAVE_CONFIG_H)
# if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)

View File

@ -25,7 +25,7 @@
*/
#include <qse/cmn/str.h>
#include "mem.h"
#include "mem-prv.h"
#if defined(HAVE_EXECINFO_H)
# include <execinfo.h>

View File

@ -1,898 +0,0 @@
/*
* $Id$
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <qse/cmn/dir.h>
#include <qse/cmn/str.h>
#include <qse/cmn/mbwc.h>
#include <qse/cmn/path.h>
#include <qse/cmn/lda.h>
#include "mem.h"
#if defined(_WIN32)
# include <windows.h>
#elif defined(__OS2__)
# define INCL_DOSFILEMGR
# define INCL_ERRORS
# include <os2.h>
#elif defined(__DOS__)
# include <dos.h>
# include <errno.h>
#else
# include "syscall.h"
#endif
#define STATUS_OPENED (1 << 0)
#define STATUS_DONE (1 << 1)
#define STATUS_DONE_ERR (1 << 2)
#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;
qse_dir_errnum_t errnum;
int flags;
qse_wcs_t wbuf;
qse_mbs_t mbuf;
qse_lda_t* stab;
int status;
#if defined(_WIN32)
HANDLE h;
WIN32_FIND_DATA wfd;
#elif defined(__OS2__)
HDIR h;
#if defined(FIL_STANDARDL)
FILEFINDBUF3L ffb;
#else
FILEFINDBUF3 ffb;
#endif
ULONG count;
#elif defined(__DOS__)
struct find_t f;
#else
QSE_DIR* dp;
#endif
};
int qse_dir_init (qse_dir_t* dir, qse_mmgr_t* mmgr, const qse_char_t* path, int flags);
void qse_dir_fini (qse_dir_t* dir);
static void close_dir_safely (qse_dir_t* dir);
static int reset_to_path (qse_dir_t* dir, const qse_char_t* path);
static int read_ahead_and_sort (qse_dir_t* dir, const qse_char_t* path);
#include "syserr.h"
IMPLEMENT_SYSERR_TO_ERRNUM (dir, DIR)
qse_dir_t* qse_dir_open (
qse_mmgr_t* mmgr, qse_size_t xtnsize,
const qse_char_t* path, int flags, qse_dir_errnum_t* errnum)
{
qse_dir_t* dir;
dir = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(*dir) + xtnsize);
if (dir)
{
if (qse_dir_init (dir, mmgr, path, flags) <= -1)
{
if (errnum) *errnum = qse_dir_geterrnum (dir);
QSE_MMGR_FREE (mmgr, dir);
dir = QSE_NULL;
}
else QSE_MEMSET (dir + 1, 0, xtnsize);
}
else if (errnum) *errnum = QSE_DIR_ENOMEM;
return dir;
}
void qse_dir_close (qse_dir_t* dir)
{
qse_dir_fini (dir);
QSE_MMGR_FREE (dir->mmgr, dir);
}
qse_mmgr_t* qse_dir_getmmgr (qse_dir_t* dir)
{
return dir->mmgr;
}
void* qse_dir_getxtn (qse_dir_t* dir)
{
return QSE_XTN (dir);
}
qse_dir_errnum_t qse_dir_geterrnum (qse_dir_t* dir)
{
return dir->errnum;
}
static int compare_dirent (qse_lda_t* lda, const void* dptr1, qse_size_t dlen1, const void* dptr2, qse_size_t dlen2)
{
int n = QSE_MEMCMP (dptr1, dptr2, ((dlen1 < dlen2)? dlen1: dlen2));
if (n == 0 && dlen1 != dlen2) n = (dlen1 > dlen2)? 1: -1;
return -n;
}
int qse_dir_init (qse_dir_t* dir, qse_mmgr_t* mmgr, const qse_char_t* path, int flags)
{
int n;
int path_flags;
path_flags = flags & (QSE_DIR_MBSPATH | QSE_DIR_WCSPATH);
if (path_flags == (QSE_DIR_MBSPATH | QSE_DIR_WCSPATH) || path_flags == 0)
{
/* if both are set or none are set, force it to the default */
#if defined(QSE_CHAR_IS_MCHAR)
flags |= QSE_DIR_MBSPATH;
flags &= ~QSE_DIR_WCSPATH;
#else
flags |= QSE_DIR_WCSPATH;
flags &= ~QSE_DIR_MBSPATH;
#endif
}
QSE_MEMSET (dir, 0, QSE_SIZEOF(*dir));
dir->mmgr = mmgr;
dir->flags = flags;
if (qse_wcs_init (&dir->wbuf, mmgr, 256) <= -1) goto oops_0;
if (qse_mbs_init (&dir->mbuf, mmgr, 256) <= -1) goto oops_1;
#if defined(_WIN32)
dir->h = INVALID_HANDLE_VALUE;
#endif
n = reset_to_path (dir, path);
if (n <= -1) goto oops_2;
if (dir->flags & QSE_DIR_SORT)
{
dir->stab = qse_lda_open (dir->mmgr, 0, 128);
if (dir->stab == QSE_NULL) goto oops_3;
/*qse_lda_setscale (dir->stab, 1);*/
qse_lda_setcopier (dir->stab, QSE_LDA_COPIER_INLINE);
qse_lda_setcomper (dir->stab, compare_dirent);
if (read_ahead_and_sort (dir, path) <= -1) goto oops_4;
}
return n;
oops_4:
qse_lda_close (dir->stab);
oops_3:
close_dir_safely (dir);
oops_2:
qse_mbs_fini (&dir->mbuf);
oops_1:
qse_wcs_fini (&dir->wbuf);
oops_0:
return -1;
}
static void close_dir_safely (qse_dir_t* dir)
{
#if defined(_WIN32)
if (dir->h != INVALID_HANDLE_VALUE)
{
FindClose (dir->h);
dir->h = INVALID_HANDLE_VALUE;
}
#elif defined(__OS2__)
if (dir->status & STATUS_OPENED)
{
DosFindClose (dir->h);
dir->status &= ~STATUS_OPENED;
}
#elif defined(__DOS__)
if (dir->status & STATUS_OPENED)
{
_dos_findclose (&dir->f);
dir->status &= ~STATUS_OPENED;
}
#else
if (dir->dp)
{
QSE_CLOSEDIR (dir->dp);
dir->dp = QSE_NULL;
}
#endif
}
void qse_dir_fini (qse_dir_t* dir)
{
close_dir_safely (dir);
qse_mbs_fini (&dir->mbuf);
qse_wcs_fini (&dir->wbuf);
if (dir->stab) qse_lda_close (dir->stab);
}
static qse_mchar_t* wcs_to_mbuf (qse_dir_t* dir, const qse_wchar_t* wcs, qse_mbs_t* mbuf)
{
qse_size_t ml, wl;
if (qse_wcstombs (wcs, &wl, QSE_NULL, &ml) <= -1)
{
dir->errnum = QSE_DIR_EINVAL;
return QSE_NULL;
}
if (qse_mbs_setlen (mbuf, ml) == (qse_size_t)-1)
{
dir->errnum = QSE_DIR_ENOMEM;
return QSE_NULL;
}
qse_wcstombs (wcs, &wl, QSE_MBS_PTR(mbuf), &ml);
return QSE_MBS_PTR(mbuf);
}
static qse_wchar_t* mbs_to_wbuf (qse_dir_t* dir, const qse_mchar_t* mbs, qse_wcs_t* wbuf)
{
qse_size_t ml, wl;
if (qse_mbstowcs (mbs, &ml, QSE_NULL, &wl) <= -1)
{
dir->errnum = QSE_DIR_EINVAL;
return QSE_NULL;
}
if (qse_wcs_setlen (wbuf, wl) == (qse_size_t)-1)
{
dir->errnum = QSE_DIR_ENOMEM;
return QSE_NULL;
}
qse_mbstowcs (mbs, &ml, QSE_WCS_PTR(wbuf), &wl);
return QSE_WCS_PTR(wbuf);
}
static qse_wchar_t* wcs_to_wbuf (qse_dir_t* dir, const qse_wchar_t* wcs, qse_wcs_t* wbuf)
{
if (qse_wcs_cpy (&dir->wbuf, wcs) == (qse_size_t)-1)
{
dir->errnum = QSE_DIR_ENOMEM;
return QSE_NULL;
}
return QSE_WCS_PTR(wbuf);
}
static qse_mchar_t* mbs_to_mbuf (qse_dir_t* dir, const qse_mchar_t* mbs, qse_mbs_t* mbuf)
{
if (qse_mbs_cpy (&dir->mbuf, mbs) == (qse_size_t)-1)
{
dir->errnum = QSE_DIR_ENOMEM;
return QSE_NULL;
}
return QSE_MBS_PTR(mbuf);
}
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
static qse_mchar_t* make_mbsdos_path (qse_dir_t* dir, const qse_mchar_t* mpath)
{
if (mpath[0] == QSE_MT('\0'))
{
if (qse_mbs_cpy (&dir->mbuf, QSE_MT("*.*")) == (qse_size_t)-1)
{
dir->errnum = QSE_DIR_ENOMEM;
return QSE_NULL;
}
}
else
{
qse_size_t len;
if ((len = qse_mbs_cpy (&dir->mbuf, mpath)) == (qse_size_t)-1 ||
(!QSE_ISPATHMBSEP(mpath[len - 1]) &&
!qse_ismbsdrivecurpath(mpath) &&
qse_mbs_ccat (&dir->mbuf, QSE_MT('\\')) == (qse_size_t)-1) ||
qse_mbs_cat (&dir->mbuf, QSE_MT("*.*")) == (qse_size_t)-1)
{
dir->errnum = QSE_DIR_ENOMEM;
return QSE_NULL;
}
}
return QSE_MBS_PTR(&dir->mbuf);
}
static qse_wchar_t* make_wcsdos_path (qse_dir_t* dir, const qse_wchar_t* wpath)
{
if (wpath[0] == QSE_WT('\0'))
{
if (qse_wcs_cpy (&dir->wbuf, QSE_WT("*.*")) == (qse_size_t)-1)
{
dir->errnum = QSE_DIR_ENOMEM;
return QSE_NULL;
}
}
else
{
qse_size_t len;
if ((len = qse_wcs_cpy (&dir->wbuf, wpath)) == (qse_size_t)-1 ||
(!QSE_ISPATHWCSEP(wpath[len - 1]) &&
!qse_iswcsdrivecurpath(wpath) &&
qse_wcs_ccat (&dir->wbuf, QSE_WT('\\')) == (qse_size_t)-1) ||
qse_wcs_cat (&dir->wbuf, QSE_WT("*.*")) == (qse_size_t)-1)
{
dir->errnum = QSE_DIR_ENOMEM;
return QSE_NULL;
}
}
return QSE_WCS_PTR(&dir->wbuf);
}
#endif
/*
static qse_char_t* make_dos_path (qse_dir_t* dir, const qse_char_t* path)
{
if (path[0] == QSE_T('\0'))
{
if (qse_str_cpy (&dir->tbuf, QSE_T("*.*")) == (qse_size_t)-1)
{
dir->errnum = QSE_DIR_ENOMEM;
return QSE_NULL;
}
}
else
{
qse_size_t len;
if ((len = qse_str_cpy (&dir->tbuf, path)) == (qse_size_t)-1 ||
(!QSE_ISPATHSEP(path[len - 1]) &&
!qse_isdrivecurpath(path) &&
qse_str_ccat (&dir->tbuf, QSE_T('\\')) == (qse_size_t)-1) ||
qse_str_cat (&dir->tbuf, QSE_T("*.*")) == (qse_size_t)-1)
{
dir->errnum = QSE_DIR_ENOMEM;
return QSE_NULL;
}
}
return QSE_STR_PTR(&dir->tbuf);
}
static qse_mchar_t* mkdospath (qse_dir_t* dir, const qse_char_t* path)
{
#if defined(QSE_CHAR_IS_MCHAR)
return make_dos_path (dir, path);
#else
if (dir->flags & QSE_DIR_MBSPATH)
{
return make_mbsdos_path (dir, (const qse_mchar_t*) path);
}
else
{
qse_char_t* tptr;
qse_mchar_t* mptr;
tptr = make_dos_path (dir, path);
if (tptr == QSE_NULL) return QSE_NULL;
mptr = wcs_to_mbuf (dir, QSE_STR_PTR(&dir->tbuf), &dir->mbuf);
if (mptr == QSE_NULL) return QSE_NULL;
return mptr;
}
#endif
}
*/
static int reset_to_path (qse_dir_t* dir, const qse_char_t* path)
{
#if defined(_WIN32)
/* ------------------------------------------------------------------- */
const qse_char_t* tptr;
dir->status &= ~STATUS_DONE;
dir->status &= ~STATUS_DONE_ERR;
if (dir->flags & QSE_DIR_MBSPATH)
{
qse_mchar_t* mptr;
mptr = make_mbsdos_path (dir, (const qse_mchar_t*)path);
if (mptr == QSE_NULL) return -1;
#if defined(QSE_CHAR_IS_MCHAR)
tptr = mptr;
#else
tptr = mbs_to_wbuf (dir, mptr, &dir->wbuf);
#endif
}
else
{
qse_wchar_t* wptr;
QSE_ASSERT (dir->flags & QSE_DIR_WCSPATH);
wptr = make_wcsdos_path (dir, (const qse_wchar_t*)path);
if (wptr == QSE_NULL) return -1;
#if defined(QSE_CHAR_IS_MCHAR)
tptr = wcs_to_mbuf (dir, wptr, &dir->mbuf);
#else
tptr = wptr;
#endif
}
if (tptr == QSE_NULL) return -1;
dir->h = FindFirstFile (tptr, &dir->wfd);
if (dir->h == INVALID_HANDLE_VALUE)
{
dir->errnum = syserr_to_errnum (GetLastError());
return -1;
}
return 0;
/* ------------------------------------------------------------------- */
#elif defined(__OS2__)
/* ------------------------------------------------------------------- */
APIRET rc;
const qse_mchar_t* mptr;
dir->h = HDIR_CREATE;
dir->count = 1;
if (dir->flags & QSE_DIR_MBSPATH)
{
mptr = make_mbsdos_path (dir, (const qse_mchar_t*)path);
}
else
{
qse_wchar_t* wptr;
QSE_ASSERT (dir->flags & QSE_DIR_WCSPATH);
wptr = make_wcsdos_path (dir, (const qse_wchar_t*)path);
if (wptr == QSE_NULL) return -1;
mptr = wcs_to_mbuf (dir, wptr, &dir->mbuf);
}
if (mptr == QSE_NULL) return -1;
rc = DosFindFirst (
mptr,
&dir->h,
FILE_DIRECTORY | FILE_READONLY,
&dir->ffb,
QSE_SIZEOF(dir->ffb),
&dir->count,
#if defined(FIL_STANDARDL)
FIL_STANDARDL
#else
FIL_STANDARD
#endif
);
if (rc != NO_ERROR)
{
dir->errnum = syserr_to_errnum (rc);
return -1;
}
dir->status |= STATUS_OPENED;
return 0;
/* ------------------------------------------------------------------- */
#elif defined(__DOS__)
/* ------------------------------------------------------------------- */
unsigned int rc;
const qse_mchar_t* mptr;
dir->status &= ~STATUS_DONE;
dir->status &= ~STATUS_DONE_ERR;
if (dir->flags & QSE_DIR_MBSPATH)
{
mptr = make_mbsdos_path (dir, (const qse_mchar_t*)path);
}
else
{
qse_wchar_t* wptr;
QSE_ASSERT (dir->flags & QSE_DIR_WCSPATH);
wptr = make_wcsdos_path (dir, (const qse_wchar_t*)path);
if (wptr == QSE_NULL) return -1;
mptr = wcs_to_mbuf (dir, wptr, &dir->mbuf);
}
if (mptr == QSE_NULL) return -1;
rc = _dos_findfirst (mptr, _A_NORMAL | _A_SUBDIR, &dir->f);
if (rc != 0)
{
dir->errnum = syserr_to_errnum (errno);
return -1;
}
dir->status |= STATUS_OPENED;
return 0;
/* ------------------------------------------------------------------- */
#else
DIR* dp;
if (dir->flags & QSE_DIR_MBSPATH)
{
const qse_mchar_t* mpath;
mpath = (const qse_mchar_t*)path;
dp = QSE_OPENDIR (mpath == QSE_MT('\0')? QSE_MT("."): mpath);
}
else
{
const qse_wchar_t* wpath;
QSE_ASSERT (dir->flags & QSE_DIR_WCSPATH);
wpath = (const qse_wchar_t*)path;
if (wpath[0] == QSE_WT('\0'))
{
dp = QSE_OPENDIR (QSE_MT("."));
}
else
{
qse_mchar_t* mptr;
mptr = wcs_to_mbuf (dir, wpath, &dir->mbuf);
if (mptr == QSE_NULL) return -1;
dp = QSE_OPENDIR (mptr);
}
}
if (dp == QSE_NULL)
{
dir->errnum = syserr_to_errnum (errno);
return -1;
}
dir->dp = dp;
return 0;
#endif
}
int qse_dir_reset (qse_dir_t* dir, const qse_char_t* path)
{
close_dir_safely (dir);
if (reset_to_path (dir, path) <= -1) return -1;
if (dir->flags & QSE_DIR_SORT)
{
qse_lda_clear (dir->stab);
if (read_ahead_and_sort (dir, path) <= -1)
{
dir->status |= STATUS_SORT_ERR;
return -1;
}
else
{
dir->status &= ~STATUS_SORT_ERR;
}
}
return 0;
}
static int read_dir_to_buf (qse_dir_t* dir, void** name)
{
#if defined(_WIN32)
/* ------------------------------------------------------------------- */
if (dir->status & STATUS_DONE) return (dir->status & STATUS_DONE_ERR)? -1: 0;
if (dir->flags & QSE_DIR_SKIPSPCDIR)
{
/* 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 (dir->flags & QSE_DIR_MBSPATH)
{
#if defined(QSE_CHAR_IS_MCHAR)
if (mbs_to_mbuf (dir, dir->wfd.cFileName, &dir->mbuf) == QSE_NULL) return -1;
#else
if (wcs_to_mbuf (dir, dir->wfd.cFileName, &dir->mbuf) == QSE_NULL) return -1;
#endif
*name = QSE_MBS_PTR(&dir->mbuf);
}
else
{
QSE_ASSERT (dir->flags & QSE_DIR_WCSPATH);
#if defined(QSE_CHAR_IS_MCHAR)
if (mbs_to_wbuf (dir, dir->wfd.cFileName, &dir->wbuf) == QSE_NULL) return -1;
#else
if (wcs_to_wbuf (dir, dir->wfd.cFileName, &dir->wbuf) == QSE_NULL) return -1;
#endif
*name = QSE_WCS_PTR(&dir->wbuf);
}
if (FindNextFile (dir->h, &dir->wfd) == FALSE)
{
DWORD x = GetLastError();
if (x == ERROR_NO_MORE_FILES) dir->status |= STATUS_DONE;
else
{
dir->errnum = syserr_to_errnum (x);
dir->status |= STATUS_DONE;
dir->status |= STATUS_DONE_ERR;
}
}
return 1;
/* ------------------------------------------------------------------- */
#elif defined(__OS2__)
/* ------------------------------------------------------------------- */
APIRET rc;
if (dir->count <= 0) return 0;
if (dir->flags & QSE_DIR_SKIPSPCDIR)
{
/* 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 (dir->flags & QSE_DIR_MBSPATH)
{
if (mbs_to_mbuf (dir, dir->ffb.achName, &dir->mbuf) == QSE_NULL) return -1;
*name = QSE_MBS_PTR(&dir->mbuf);
}
else
{
QSE_ASSERT (dir->flags & QSE_DIR_WCSPATH);
if (mbs_to_wbuf (dir, dir->ffb.achName, &dir->wbuf) == QSE_NULL) return -1;
*name = QSE_WCS_PTR(&dir->wbuf);
}
rc = DosFindNext (dir->h, &dir->ffb, QSE_SIZEOF(dir->ffb), &dir->count);
if (rc == ERROR_NO_MORE_FILES) dir->count = 0;
else if (rc != NO_ERROR)
{
dir->errnum = syserr_to_errnum (rc);
return -1;
}
return 1;
/* ------------------------------------------------------------------- */
#elif defined(__DOS__)
/* ------------------------------------------------------------------- */
if (dir->status & STATUS_DONE) return (dir->status & STATUS_DONE_ERR)? -1: 0;
if (dir->flags & QSE_DIR_SKIPSPCDIR)
{
/* 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 (dir->flags & QSE_DIR_MBSPATH)
{
if (mbs_to_mbuf (dir, dir->f.name, &dir->mbuf) == QSE_NULL) return -1;
*name = QSE_MBS_PTR(&dir->mbuf);
}
else
{
QSE_ASSERT (dir->flags & QSE_DIR_WCSPATH);
if (mbs_to_wbuf (dir, dir->f.name, &dir->wbuf) == QSE_NULL) return -1;
*name = QSE_WCS_PTR(&dir->wbuf);
}
if (_dos_findnext (&dir->f) != 0)
{
if (errno == ENOENT) dir->status |= STATUS_DONE;
else
{
dir->errnum = syserr_to_errnum (errno);
dir->status |= STATUS_DONE;
dir->status |= STATUS_DONE_ERR;
}
}
return 1;
/* ------------------------------------------------------------------- */
#else
/* ------------------------------------------------------------------- */
qse_dirent_t* de;
read:
errno = 0;
de = QSE_READDIR (dir->dp);
if (de == NULL)
{
if (errno == 0) return 0;
dir->errnum = syserr_to_errnum (errno);
return -1;
}
if (dir->flags & QSE_DIR_SKIPSPCDIR)
{
/* skip . and .. */
if (IS_CURDIR_M(de->d_name) ||
IS_PREVDIR_M(de->d_name)) goto read;
}
if (dir->flags & QSE_DIR_MBSPATH)
{
if (mbs_to_mbuf (dir, de->d_name, &dir->mbuf) == QSE_NULL) return -1;
*name = QSE_MBS_PTR(&dir->mbuf);
}
else
{
QSE_ASSERT (dir->flags & QSE_DIR_WCSPATH);
if (mbs_to_wbuf (dir, de->d_name, &dir->wbuf) == QSE_NULL) return -1;
*name = QSE_WCS_PTR(&dir->wbuf);
}
return 1;
/* ------------------------------------------------------------------- */
#endif
}
static int read_ahead_and_sort (qse_dir_t* dir, const qse_char_t* path)
{
int x;
void* name;
while (1)
{
x = read_dir_to_buf (dir, &name);
if (x >= 1)
{
qse_size_t size;
if (dir->flags & QSE_DIR_MBSPATH)
size = (qse_mbslen(name) + 1) * QSE_SIZEOF(qse_mchar_t);
else
size = (qse_wcslen(name) + 1) * QSE_SIZEOF(qse_wchar_t);
if (qse_lda_pushheap (dir->stab, name, size) == (qse_size_t)-1)
{
dir->errnum = QSE_DIR_ENOMEM;
return -1;
}
}
else if (x == 0) break;
else return -1;
}
dir->status &= ~STATUS_POPHEAP;
return 0;
}
int qse_dir_read (qse_dir_t* dir, qse_dir_ent_t* ent)
{
if (dir->flags & QSE_DIR_SORT)
{
if (dir->status & STATUS_SORT_ERR) return -1;
if (dir->status & STATUS_POPHEAP) qse_lda_popheap (dir->stab);
else dir->status |= STATUS_POPHEAP;
if (QSE_LDA_SIZE(dir->stab) <= 0) return 0; /* no more entry */
ent->name = QSE_LDA_DPTR(dir->stab, 0);
return 1;
}
else
{
int x;
void* name;
x = read_dir_to_buf (dir, &name);
if (x >= 1)
{
QSE_MEMSET (ent, 0, QSE_SIZEOF(ent));
ent->name = name;
}
return x;
}
}

View File

@ -25,7 +25,7 @@
*/
#include <qse/cmn/dll.h>
#include "mem.h"
#include "mem-prv.h"
#define TOB(dll,len) ((len)*(dll)->scale)
#define DPTR(node) QSE_DLL_DPTR(node)

View File

@ -28,7 +28,7 @@
#include <qse/cmn/env.h>
#include <qse/cmn/str.h>
#include <qse/cmn/mbwc.h>
#include "mem.h"
#include "mem-prv.h"
#if defined(_WIN32)
# include <windows.h>

View File

@ -25,7 +25,7 @@
*/
#include <qse/cmn/fma.h>
#include "mem.h"
#include "mem-prv.h"
qse_fma_t* qse_fma_open (
qse_mmgr_t* mmgr, qse_size_t xtnsize,

View File

@ -29,8 +29,8 @@
#include <qse/cmn/str.h>
#include <qse/cmn/mbwc.h>
#include <stdarg.h>
#include "mem.h"
#include "fmt.h"
#include "mem-prv.h"
#include "fmt-prv.h"
#include <stdio.h> /* for snrintf(). used for floating-point number formatting */
#if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200))

View File

@ -24,8 +24,8 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _QSE_LIB_CMN_FMT_H_
#define _QSE_LIB_CMN_FMT_H_
#ifndef _QSE_LIB_CMN_FMT_PRV_H_
#define _QSE_LIB_CMN_FMT_PRV_H_
#include <qse/cmn/fmt.h>
#include <stdarg.h>

View File

@ -1,134 +0,0 @@
/*
* $Id$
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fs.h"
#include "mem.h"
int qse_fs_sysgetattr (qse_fs_t* fs, const qse_fs_char_t* fspath, qse_fs_attr_t* attr)
{
#if defined(_WIN32)
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#elif defined(__OS2__)
/* TODO */
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#elif defined(__DOS__)
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#else
#if defined(HAVE_LSTAT)
qse_lstat_t st;
#else
qse_stat_t st;
#endif
#if defined(HAVE_LSTAT)
if (QSE_LSTAT (fspath, &st) == -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#else
/* is this ok to use stat? */
if (QSE_STAT (fspath, &st) == -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#endif
QSE_MEMSET (attr, 0, QSE_SIZEOF(*attr));
if (S_ISDIR(st.st_mode)) attr->isdir = 1;
if (S_ISLNK(st.st_mode)) attr->islnk = 1;
if (S_ISREG(st.st_mode)) attr->isreg = 1;
if (S_ISBLK(st.st_mode)) attr->isblk = 1;
if (S_ISCHR(st.st_mode)) attr->ischr = 1;
attr->mode = st.st_mode;
attr->size = st.st_size;
attr->ino = st.st_ino;
attr->dev = st.st_dev;
attr->uid = st.st_uid;
attr->gid = st.st_gid;
#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
attr->atime.sec = st.st_atim.tv_sec;
attr->atime.nsec = st.st_atim.tv_nsec;
attr->mtime.sec = st.st_mtim.tv_sec;
attr->mtime.nsec = st.st_mtim.tv_nsec;
attr->ctime.sec = st.st_ctim.tv_sec;
attr->ctime.nsec = st.st_ctim.tv_nsec;
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
attr->atime.sec = st.st_atimespec.tv_sec;
attr->atime.nsec = st.st_atimespec.tv_nsec;
attr->mtime.sec = st.st_mtimespec.tv_sec;
attr->mtime.nsec = st.st_mtimespec.tv_nsec;
attr->ctime.sec = st.st_ctimespec.tv_sec;
attr->ctime.nsec = st.st_ctimespec.tv_nsec;
#else
attr->atime.sec = st.st_atime;
attr->mtime.sec = st.st_mtime;
attr->ctime.sec = st.st_ctime;
#endif
return 0;
#endif
}
int qse_fs_getattrmbs (qse_fs_t* fs, const qse_mchar_t* path, qse_fs_attr_t* attr)
{
qse_fs_char_t* fspath;
int ret;
fspath = qse_fs_makefspathformbs (fs, path);
if (!fspath) return -1;
ret = qse_fs_sysgetattr (fs, fspath, attr);
qse_fs_freefspathformbs (fs, path, fspath);
return ret;
}
int qse_fs_getattrwcs (qse_fs_t* fs, const qse_wchar_t* path, qse_fs_attr_t* attr)
{
qse_fs_char_t* fspath;
int ret;
fspath = qse_fs_makefspathforwcs (fs, path);
if (!fspath) return -1;
ret = qse_fs_sysgetattr (fs, fspath, attr);
qse_fs_freefspathforwcs (fs, path, fspath);
return ret;
}

View File

@ -1,636 +0,0 @@
/*
* $Id$
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fs.h"
#include <qse/cmn/path.h>
#include <qse/cmn/str.h>
#include "mem.h"
#define NO_RECURSION 1
/* internal flags. it must not overlap with qse_fs_cpfile_flag_t enumerators */
#define CPFILE_DST_ATTR (1 << 29)
#define CPFILE_DST_FSPATH_MERGED (1 << 30)
struct cpfile_t
{
int flags;
qse_fs_char_t* src_fspath;
qse_fs_char_t* dst_fspath;
qse_fs_attr_t src_attr;
qse_fs_attr_t dst_attr;
};
typedef struct cpfile_t cpfile_t;
static int merge_dstdir_and_file (qse_fs_t* fs, cpfile_t* cpfile)
{
qse_fs_char_t* fstmp;
/* if the destination is directory, copy the base name of the source
* and append it to the end of the destination, targetting at an entry
* in the directory */
QSE_ASSERT (cpfile->dst_attr.isdir);
fstmp = merge_fspath_dup (cpfile->dst_fspath, get_fspath_base (cpfile->src_fspath), fs->mmgr);
if (!fstmp)
{
fs->errnum = QSE_FS_ENOMEM;
return -1;
}
qse_fs_freefspath (fs, QSE_NULL, cpfile->dst_fspath);
cpfile->dst_fspath = fstmp;
if (qse_fs_sysgetattr (fs, cpfile->dst_fspath, &cpfile->dst_attr) <= -1)
{
/* attribute on the new destination is not available */
cpfile->flags &= ~CPFILE_DST_ATTR;
}
else
{
/* the attribute has been updated to reflect the new destination */
cpfile->flags |= CPFILE_DST_ATTR;
}
cpfile->flags |= CPFILE_DST_FSPATH_MERGED;
return 0;
}
/*
#if defined(_WIN32)
DWORD copy_file_progress (
LARGE_INTEGER TotalFileSize,
LARGE_INTEGER TotalBytesTransferred,
LARGE_INTEGER StreamSize,
LARGE_INTEGER StreamBytesTransferred,
DWORD dwStreamNumber,
DWORD dwCallbackReason,
HANDLE hSourceFile,
HANDLE hDestinationFile,
LPVOID lpData)
{
}
#endif
*/
/* copy
* -> progress
* -> abort/cancel
* -> replace/overwrite
* -> symbolic link
*/
#if defined(_WIN32) && !defined(COPY_FILE_COPY_SYMLINK)
/* winbase.h defines this only if _WIN32_WINNT >= 0x0600 */
# define COPY_FILE_COPY_SYMLINK 0x00000800L
#endif
static int copy_file_in_fs (qse_fs_t* fs, cpfile_t* cpfile)
{
#if defined(_WIN32)
/* ------------------------------------------------------ */
DWORD copy_flags = 0;
if (cpfile->flags & QSE_FS_CPFILE_SYMLINK)
copy_flags |= COPY_FILE_COPY_SYMLINK;
if (!(cpfile->flags & QSE_FS_CPFILE_REPLACE))
copy_flags |= COPY_FILE_FAIL_IF_EXISTS;
/*
if (fs->cbs.cp)
{
Specify callback???
}
*/
if (CopyFileEx (cpfile->src_fspath, cpfile->dst_fspath, QSE_NULL, QSE_NULL, QSE_NULL, copy_flags) == FALSE)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, GetLastError());
return -1;
}
return 0;
/* ------------------------------------------------------ */
#elif defined(__OS2__)
/* ------------------------------------------------------ */
APIRET rc;
ULONG opmode = 0;
if (cpfile->flags & QSE_FS_CPFILE_REPLACE) opmode |= 1; /* set bit 0 */
rc = DosCopy (cpfile->src_fspath, cpfile->dst_fspath, opmode);
if (rc != NO_ERROR)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, rc);
return -1;
}
return 0;
/* ------------------------------------------------------ */
#elif defined(__DOS__)
/* ------------------------------------------------------ */
/* TOOD: IMPLEMENT THIS */
fs->errnum = QSE_FS_ENOIMPL;
return -1;
/* ------------------------------------------------------ */
#else
if ((cpfile->flags & QSE_FS_CPFILE_SYMLINK) && cpfile->src_attr.islnk)
{
qse_fs_char_t* tmpbuf;
/* TODO: use a static buffer is size is small enough */
tmpbuf = QSE_MMGR_ALLOC (fs->mmgr, QSE_SIZEOF(*tmpbuf) * (cpfile->src_attr.size + 1));
if (tmpbuf == QSE_NULL)
{
fs->errnum = QSE_FS_ENOMEM;
return -1;
}
if (QSE_READLINK (cpfile->src_fspath, tmpbuf, cpfile->src_attr.size) <= -1 ||
QSE_SYMLINK (tmpbuf, cpfile->dst_fspath) <= -1)
{
QSE_MMGR_FREE (fs->mmgr, tmpbuf);
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
QSE_MMGR_FREE (fs->mmgr, tmpbuf);
return 0;
}
else
{
int in = -1, out = -1;
qse_ssize_t in_len, out_len;
qse_uint8_t* bp;
in = QSE_OPEN (cpfile->src_fspath, O_RDONLY, 0);
if (in <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
goto oops;
}
out = QSE_OPEN (cpfile->dst_fspath, O_CREAT | O_WRONLY | O_TRUNC, cpfile->src_attr.mode);
if (out <= -1 && (cpfile->flags & QSE_FS_CPFILE_FORCE))
{
/* if forced, delete it and try to open it again */
QSE_UNLINK (cpfile->dst_fspath);
out = QSE_OPEN (cpfile->dst_fspath, O_CREAT | O_WRONLY | O_TRUNC, cpfile->src_attr.mode);
}
if (out <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
goto oops;
}
while (1)
{
in_len = QSE_READ (in, fs->cpbuf, QSE_SIZEOF(fs->cpbuf));
if (in_len <= 0) break;
/* TODO: call progress callback */
bp = fs->cpbuf;
while (in_len > 0)
{
out_len = QSE_WRITE (out, bp, in_len);
if (out_len <= -1) goto oops;
bp += out_len;
in_len -= out_len;
}
}
if (cpfile->flags & QSE_FS_CPFILE_PRESERVE)
{
#if defined(HAVE_FUTIMENS) && defined(HAVE_STRUCT_TIMESPEC)
struct timespec ts[2];
#elif defined(HAVE_FUTIMES)
struct timeval tv[2];
#elif defined(HAVE_UTIME)
struct utimbuf ub;
#elif defined(HAVE_UTIMES)
struct timeval tv[2];
#endif
if (QSE_FCHOWN (out, cpfile->src_attr.uid, cpfile->src_attr.gid) <= -1 ||
QSE_FCHMOD (out, cpfile->src_attr.mode) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
goto oops;
}
#if defined(HAVE_FUTIMENS) && defined(HAVE_STRUCT_TIMESPEC)
QSE_MEMSET (&ts, 0, QSE_SIZEOF(ts));
ts[0].tv_sec = cpfile->src_attr.atime.sec;
ts[0].tv_nsec = cpfile->src_attr.atime.nsec;
ts[1].tv_sec = cpfile->src_attr.mtime.sec;
ts[1].tv_nsec = cpfile->src_attr.mtime.nsec;
if (QSE_FUTIMENS (out, ts) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
goto oops;
}
#elif defined(HAVE_FUTIMES)
QSE_MEMSET (&tv, 0, QSE_SIZEOF(tv));
tv[0].tv_sec = cpfile->src_attr.atime.sec;
tv[0].tv_usec = QSE_NSEC_TO_USEC(cpfile->src_attr.atime.nsec);
tv[1].tv_sec = cpfile->src_attr.mtime.sec;
tv[1].tv_usec = QSE_NSEC_TO_USEC(cpfile->src_attr.mtime.nsec);
if (QSE_FUTIMES (out, tv) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
goto oops;
}
#elif defined(HAVE_UTIME)
QSE_MEMSET (&ub, 0, QSE_SIZEOF(ub));
ub.actime = cpfile->src_attr.atime.sec;
ub.modtime = cpfile->src_attr.mtime.sec;
if (QSE_UTIME (cpfile->dst_fspath, &ub) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
goto oops;
}
#elif defined(HAVE_UTIMES)
QSE_MEMSET (&tv, 0, QSE_SIZEOF(tv));
tv[0].tv_sec = cpfile->src_attr.atime.sec;
tv[0].tv_usec = QSE_NSEC_TO_USEC(cpfile->src_attr.atime.nsec);
tv[1].tv_sec = cpfile->src_attr.mtime.sec;
tv[1].tv_usec = QSE_NSEC_TO_USEC(cpfile->src_attr.mtime.nsec);
// work on the file name not on the file descriptor.
if (QSE_UTIMES (cpfile->dst_fspath, tv) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
goto oops;
}
#else
# error none of futimens, futimes, utime, utimes exist
#endif
}
QSE_CLOSE (out);
QSE_CLOSE (in);
return 0;
oops:
if (out >= 0) QSE_CLOSE (out);
if (in >= 0) QSE_CLOSE (in);
return -1;
}
#endif
}
static int prepare_cpfile (qse_fs_t* fs, cpfile_t* cpfile)
{
/* error if the source file can't be stat'ed.
* ok if the destination file can't be stat'ed */
if (qse_fs_sysgetattr (fs, cpfile->src_fspath, &cpfile->src_attr) <= -1) return -1;
if (qse_fs_sysgetattr (fs, cpfile->dst_fspath, &cpfile->dst_attr) >= 0) cpfile->flags |= CPFILE_DST_ATTR;
return 0;
}
static void clear_cpfile (qse_fs_t* fs, cpfile_t* cpfile)
{
if (cpfile->src_fspath)
{
QSE_MMGR_FREE (fs->mmgr, cpfile->src_fspath);
cpfile->src_fspath = QSE_NULL;
}
if (cpfile->dst_fspath)
{
QSE_MMGR_FREE (fs->mmgr, cpfile->dst_fspath);
cpfile->dst_fspath = QSE_NULL;
}
}
/* copy file stack - stack for file copying */
typedef struct cfs_t cfs_t;
struct cfs_t
{
cpfile_t cpfile;
qse_dir_t* dir;
cfs_t* next;
};
static cfs_t* push_cfs (qse_fs_t* fs, const cpfile_t* cpfile, qse_dir_t* dir)
{
cfs_t* cfs;
cfs = (cfs_t*)QSE_MMGR_ALLOC (fs->mmgr, QSE_SIZEOF(*cfs));
if (cfs == QSE_NULL)
{
fs->errnum = QSE_FS_ENOMEM;
return QSE_NULL;
}
cfs->cpfile = *cpfile;
cfs->dir = dir;
cfs->next = fs->cfs;
fs->cfs = cfs;
return cfs;
}
static void pop_cfs (qse_fs_t* fs, cpfile_t* cpfile, qse_dir_t** dir)
{
cfs_t* cfs;
cfs = fs->cfs;
QSE_ASSERT (cfs != QSE_NULL);
fs->cfs = cfs->next;
if (cpfile) *cpfile = cfs->cpfile;
else clear_cpfile (fs, &cfs->cpfile);
if (dir) *dir = cfs->dir;
else qse_dir_close (cfs->dir);
QSE_MMGR_FREE (fs->mmgr, cfs);
}
static int copy_file (qse_fs_t* fs, cpfile_t* cpfile)
{
#if defined(NO_RECURSION)
cfs_t* cfs;
#else
cpfile_t sub_cpfile;
#endif
qse_dir_t* dir;
qse_dir_errnum_t direrr;
qse_dir_ent_t dirent;
int x;
start_over:
if (cpfile->src_attr.isdir)
{
/* source is a directory */
copy_dir:
if (cpfile->flags & CPFILE_DST_ATTR)
{
if (!cpfile->dst_attr.isdir)
{
/* cannot copy a directory to a file */
fs->errnum = QSE_FS_ENOTDIR;
goto oops;
}
if (!(cpfile->flags & QSE_FS_CPFILE_NOTGTDIR) &&
cpfile->dst_attr.isdir)
{
if (cpfile->flags & CPFILE_DST_FSPATH_MERGED)
{
/* merge_dstdir_and_file() has been called already.
* no more getting into a subdirectory */
fs->errnum = QSE_FS_EISDIR;
goto oops;
}
else
{
/* arrange to copy a file into a directory */
if (merge_dstdir_and_file (fs, cpfile) <= -1) return -1;
goto copy_dir;
}
}
/*
if (!(cpfile->flags & QSE_FS_CPFILE_REPLACE))
{
fs->errnum = QSE_FS_EEXIST;
return -1;
}*/
}
if (!(cpfile->flags & QSE_FS_CPFILE_RECURSIVE))
{
/* cannot copy a directory without recursion */
fs->errnum = QSE_FS_EISDIR;
goto oops;
}
dir = qse_dir_open (
fs->mmgr, 0, (const qse_char_t*)cpfile->src_fspath,
#if defined(QSE_FS_CHAR_IS_MCHAR)
QSE_DIR_SKIPSPCDIR | QSE_DIR_MBSPATH,
#else
QSE_DIR_SKIPSPCDIR | QSE_DIR_WCSPATH,
#endif
&direrr
);
if (!dir)
{
fs->errnum = qse_fs_direrrtoerrnum (fs, direrr);
goto oops;
}
if (qse_fs_sysmkdir (fs, cpfile->dst_fspath) <= -1) goto oops;
while (1)
{
x = qse_dir_read (dir, &dirent);
if (x <= -1)
{
fs->errnum = qse_fs_direrrtoerrnum (fs, qse_dir_geterrnum(dir));
goto oops;
}
if (x == 0) break; /* no more entries */
#if defined(NO_RECURSION)
cfs = push_cfs (fs, cpfile, dir);
if (!cfs) goto oops;
QSE_MEMSET (cpfile, 0, QSE_SIZEOF(*cpfile));
dir = QSE_NULL;
cpfile->flags = cfs->cpfile.flags & QSE_FS_CPFILE_ALL; /* inherit public flags */
cpfile->src_fspath = merge_fspath_dup (cfs->cpfile.src_fspath, (qse_fs_char_t*)dirent.name, fs->mmgr);
cpfile->dst_fspath = merge_fspath_dup (cfs->cpfile.dst_fspath, (qse_fs_char_t*)dirent.name, fs->mmgr);
if (!cpfile->src_fspath || !cpfile->dst_fspath || prepare_cpfile (fs, cpfile) <= -1)
{
clear_cpfile (fs, cpfile);
goto oops;
}
goto start_over;
resume_copy_dir:
/* do nothing. loop over */
;
#else
QSE_MEMSET (&sub_cpfile, 0, QSE_SIZEOF(sub_cpfile));
sub_cpfile.flags = cpfile->flags & QSE_FS_CPFILE_ALL; /* inherit public flags */
sub_cpfile.src_fspath = merge_fspath_dup (cpfile->src_fspath, (qse_fs_char_t*)dirent.name, fs->mmgr);
sub_cpfile.dst_fspath = merge_fspath_dup (cpfile->dst_fspath, (qse_fs_char_t*)dirent.name, fs->mmgr);
if (!sub_cpfile.src_fspath || !sub_cpfile.dst_fspath || prepare_cpfile (fs, &sub_cpfile) <= -1)
{
clear_cpfile (fs, &sub_cpfile);
qse_dir_close (dir);
return -1;
}
x = copy_file (fs, &sub_cpfile); /* TODO: remove recursion */
clear_cpfile (fs, &sub_cpfile);
if (x <= -1)
{
qse_dir_close (dir);
return -1;
}
#endif
}
qse_dir_close (dir);
dir = QSE_NULL;
}
else
{
/* source is a file */
copy_file:
if (cpfile->flags & CPFILE_DST_ATTR)
{
if (cpfile->src_attr.ino == cpfile->dst_attr.ino &&
cpfile->src_attr.dev == cpfile->dst_attr.dev)
{
/* cannot copy a file to itself */
fs->errnum = QSE_FS_EINVAL; /* TODO: better error code */
goto oops;
}
if (!(cpfile->flags & QSE_FS_CPFILE_NOTGTDIR) &&
cpfile->dst_attr.isdir)
{
if (cpfile->flags & CPFILE_DST_FSPATH_MERGED)
{
/* merge_dstdir_and_file() has been called already.
* no more getting into a subdirectory */
fs->errnum = QSE_FS_EISDIR;
goto oops;
}
else
{
/* arrange to copy a file into a directory */
if (merge_dstdir_and_file (fs, cpfile) <= -1) return -1;
goto copy_file;
}
}
if (!(cpfile->flags & QSE_FS_CPFILE_REPLACE))
{
fs->errnum = QSE_FS_EEXIST;
return -1;
}
}
/* both source and target are files */
if (copy_file_in_fs (fs, cpfile) <= -1) goto oops;
}
#if defined(NO_RECURSION)
if (fs->cfs)
{
clear_cpfile (fs, cpfile); /* clear key data created for subitems in the directory */
pop_cfs (fs, cpfile, &dir); /* restore key data for the original directory*/
goto resume_copy_dir;
}
#endif
return 0;
oops:
#if defined(NO_RECURSION)
while (fs->cfs) pop_cfs (fs, QSE_NULL, QSE_NULL);
#endif
if (dir) qse_dir_close (dir);
return -1;
}
int qse_fs_cpfilembs (qse_fs_t* fs, const qse_mchar_t* srcpath, const qse_mchar_t* dstpath, int flags)
{
cpfile_t cpfile;
int ret;
QSE_MEMSET (&cpfile, 0, QSE_SIZEOF(cpfile));
cpfile.flags = flags & QSE_FS_CPFILE_ALL; /* keep public flags only */
cpfile.src_fspath = (qse_fs_char_t*)qse_fs_dupfspathformbs (fs, srcpath);
cpfile.dst_fspath = (qse_fs_char_t*)qse_fs_dupfspathformbs (fs, dstpath);
if (!cpfile.src_fspath || !cpfile.dst_fspath || prepare_cpfile (fs, &cpfile) <= -1) goto oops;
ret = copy_file (fs, &cpfile);
clear_cpfile (fs, &cpfile);
return ret;
oops:
clear_cpfile (fs, &cpfile);
return -1;
}
int qse_fs_cpfilewcs (qse_fs_t* fs, const qse_wchar_t* srcpath, const qse_wchar_t* dstpath, int flags)
{
cpfile_t cpfile;
int ret;
QSE_MEMSET (&cpfile, 0, QSE_SIZEOF(cpfile));
cpfile.flags = flags & QSE_FS_CPFILE_ALL; /* keep public flags only */
cpfile.src_fspath = (qse_fs_char_t*)qse_fs_dupfspathforwcs (fs, srcpath);
cpfile.dst_fspath = (qse_fs_char_t*)qse_fs_dupfspathforwcs (fs, dstpath);
if (!cpfile.src_fspath || !cpfile.dst_fspath || prepare_cpfile (fs, &cpfile) <= -1) goto oops;
ret = copy_file (fs, &cpfile);
clear_cpfile (fs, &cpfile);
return ret;
oops:
clear_cpfile (fs, &cpfile);
return -1;
}

View File

@ -1,587 +0,0 @@
/*
* $Id$
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fs.h"
/* 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. */
int qse_fs_sysrmfile (qse_fs_t* fs, const qse_fs_char_t* fspath)
{
#if defined(_WIN32)
if (DeleteFile (fspath) == FALSE)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, GetLastError());
return -1;
}
#elif defined(__OS2__)
APIRET rc;
rc = DosDelete (fspath);
if (rc != NO_ERROR)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, rc);
return -1;
}
#elif defined(__DOS__)
if (unlink (fspath) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#else
if (QSE_UNLINK (fspath) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#endif
return 0;
}
int qse_fs_sysrmdir (qse_fs_t* fs, const qse_fs_char_t* fspath)
{
#if defined(_WIN32)
if (RemoveDirectory (fspath) == FALSE)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, GetLastError());
return -1;
}
#elif defined(__OS2__)
APIRET rc;
rc = DosRmDir (fspath);
if (rc != NO_ERROR)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, rc);
return -1;
}
#elif defined(__DOS__)
if (rmdir (fspath) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#else
if (QSE_RMDIR (fspath) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#endif
return 0;
}
/* --------------------------------------------------------------------- */
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 = qse_fs_sysrmfile (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 = qse_fs_sysrmdir (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;
/* 'dir' is asked to skip special entries like . and .. */
dir = qse_dir_open (fs->mmgr, 0, path, QSE_DIR_SKIPSPCDIR, &errnum);
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;
while (1)
{
x = qse_dir_read (dir, &ent);
if (x <= -1)
{
fs->errnum = qse_fs_direrrtoerrnum (fs, qse_dir_geterrnum(dir));
goto oops;
}
if (x == 0) break; /* no more entries */
/* join path and ent->name.... */
seg[0] = path;
seg[1] = DEFAULT_PATH_SEPARATOR;
seg[2] = ent.name;
seg[3] = QSE_NULL;
joined_path = qse_stradup (seg, QSE_NULL, fs->mmgr);
if (!joined_path)
{
fs->errnum = QSE_FS_ENOMEM;
goto oops;
}
ret = delete_file (fs, joined_path, 1);
QSE_MMGR_FREE (fs->mmgr, joined_path);
if (ret <= -1) goto oops;
}
qse_dir_close (dir);
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? qse_fs_sysrmdir (fs, fspath):
qse_fs_sysrmfile (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? qse_fs_sysrmdir (fs, fspath):
qse_fs_sysrmfile (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;
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;
if (flags & QSE_FS_DELFILEMBS_GLOB)
{
qse_char_t* xpath;
xpath = (qse_char_t*)make_str_with_mbs (fs, path);
if (!xpath)
{
fs->errnum = QSE_FS_ENOMEM;
return -1;
}
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);
if (ret <= -1)
{
fs->errnum = QSE_FS_EGLOB;
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
{
ret = delete_from_fs_with_mbs (fs, path, 0);
}
return ret;
}
int qse_fs_delfilewcs (qse_fs_t* fs, const qse_wchar_t* path, int flags)
{
int ret;
if (flags & QSE_FS_DELFILEWCS_GLOB)
{
qse_char_t* xpath;
xpath = (qse_char_t*)make_str_with_wcs (fs, path);
if (!xpath)
{
fs->errnum = QSE_FS_ENOMEM;
return -1;
}
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);
if (ret <= -1)
{
fs->errnum = QSE_FS_EGLOB;
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
{
ret = delete_from_fs_with_wcs (fs, path, 0);
}
return ret;
}
/* --------------------------------------------------------------------- */
int qse_fs_deldirmbs (qse_fs_t* fs, const qse_mchar_t* path, int flags)
{
int ret;
if (flags & QSE_FS_DELDIRMBS_GLOB)
{
qse_char_t* xpath;
xpath = (qse_char_t*)make_str_with_mbs (fs, path);
if (!xpath)
{
fs->errnum = QSE_FS_ENOMEM;
return -1;
}
if (flags & QSE_FS_DELDIRMBS_RECURSIVE)
{
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, fs->cmgr);
}
free_str_with_mbs (fs, path, xpath);
if (ret <= -1) fs->errnum = QSE_FS_EGLOB;
}
else if (flags & QSE_FS_DELDIRMBS_RECURSIVE)
{
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)
{
fs->errnum = QSE_FS_ENOMEM;
return -1;
}
ret = purge_path (fs, xpath);
free_str_with_mbs (fs, path, xpath);
}
else
{
ret = delete_from_fs_with_mbs (fs, path, 1);
}
return ret;
}
int qse_fs_deldirwcs (qse_fs_t* fs, const qse_wchar_t* path, int flags)
{
int ret;
if (flags & QSE_FS_DELDIRWCS_GLOB)
{
qse_char_t* xpath;
xpath = (qse_char_t*)make_str_with_wcs (fs, path);
if (!xpath)
{
fs->errnum = QSE_FS_ENOMEM;
return -1;
}
if (flags & QSE_FS_DELDIRWCS_RECURSIVE)
{
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, fs->cmgr);
}
free_str_with_wcs (fs, path, xpath);
if (ret <= -1) fs->errnum = QSE_FS_EGLOB;
}
else if (flags & QSE_FS_DELDIRWCS_RECURSIVE)
{
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)
{
fs->errnum = QSE_FS_ENOMEM;
return -1;
}
ret = purge_path (fs, xpath);
free_str_with_wcs (fs, path, xpath);
}
else
{
ret = delete_from_fs_with_wcs (fs, path, 1);
}
return ret;
}

View File

@ -1,220 +0,0 @@
/*
* $Id$
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fs.h"
qse_fs_errnum_t qse_fs_geterrnum (qse_fs_t* fs)
{
return fs->errnum;
}
qse_fs_errnum_t qse_fs_syserrtoerrnum (qse_fs_t* fs, qse_fs_syserr_t e)
{
#if defined(_WIN32)
switch (e)
{
case ERROR_NOT_ENOUGH_MEMORY:
case ERROR_OUTOFMEMORY:
return QSE_FS_ENOMEM;
case ERROR_INVALID_PARAMETER:
case ERROR_INVALID_HANDLE:
case ERROR_INVALID_NAME:
case ERROR_DIRECTORY:
return QSE_FS_EINVAL;
case ERROR_ACCESS_DENIED:
case ERROR_SHARING_VIOLATION:
return QSE_FS_EACCES;
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND:
return QSE_FS_ENOENT;
case ERROR_ALREADY_EXISTS:
case ERROR_FILE_EXISTS:
return QSE_FS_EEXIST;
case ERROR_NOT_SAME_DEVICE:
return QSE_FS_EXDEV;
case ERROR_DIR_NOT_EMPTY:
return QSE_FS_ENOTVOID;
default:
return QSE_FS_ESYSERR;
}
#elif defined(__OS2__)
switch (e)
{
case ERROR_NOT_ENOUGH_MEMORY:
return QSE_FS_ENOMEM;
case ERROR_INVALID_PARAMETER:
case ERROR_INVALID_HANDLE:
case ERROR_INVALID_NAME:
return QSE_FS_EINVAL;
case ERROR_ACCESS_DENIED:
case ERROR_SHARING_VIOLATION:
return QSE_FS_EACCES;
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND:
return QSE_FS_ENOENT;
case ERROR_ALREADY_EXISTS:
return QSE_FS_EEXIST;
case ERROR_NOT_SAME_DEVICE:
return QSE_FS_EXDEV;
default:
return QSE_FS_ESYSERR;
}
#elif defined(__DOS__)
switch (e)
{
case ENOMEM:
return QSE_FS_ENOMEM;
case EINVAL:
return QSE_FS_EINVAL;
case EACCES:
case EPERM:
return QSE_FS_EACCES;
case ENOENT:
return QSE_FS_ENOENT;
case EEXIST:
return QSE_FS_EEXIST;
case EISDIR:
return QSE_FS_EISDIR;
case ENOTDIR:
return QSE_FS_ENOTDIR;
case EXDEV:
return QSE_FS_EXDEV;
default:
return QSE_FS_ESYSERR;
}
#else
switch (e)
{
case ENOMEM:
return QSE_FS_ENOMEM;
case EINVAL:
return QSE_FS_EINVAL;
case EACCES:
case EPERM:
return QSE_FS_EACCES;
case ENOENT:
return QSE_FS_ENOENT;
case EEXIST:
return QSE_FS_EEXIST;
case EINTR:
return QSE_FS_EINTR;
case EISDIR:
return QSE_FS_EISDIR;
case ENOTDIR:
return QSE_FS_ENOTDIR;
case ENOTEMPTY:
return QSE_FS_ENOTVOID;
case EXDEV:
return QSE_FS_EXDEV;
default:
return QSE_FS_ESYSERR;
}
#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

@ -1,216 +0,0 @@
/*
* $Id$
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fs.h"
int qse_fs_sysmkdir (qse_fs_t* fs, const qse_fs_char_t* fspath)
{
#if defined(_WIN32)
if (CreateDirectory (fspath, QSE_NULL) == FALSE)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, GetLastError());
return -1;
}
#elif defined(__OS2__)
APIRET rc;
rc = DosMkDir (fspath, QSE_NULL);
if (rc != NO_ERROR)
{
FILESTATUS3L ffb;
if (DosQueryPathInfo (fspath, FIL_STANDARDL, &ffb, QSE_SIZEOF(ffb)) == NO_ERROR)
{
if (ffb.attrFile & FILE_DIRECTORY)
{
fs->errnum = QSE_FS_EEXIST;
return -1;
}
}
fs->errnum = qse_fs_syserrtoerrnum (fs, rc);
return -1;
}
#elif defined(__DOS__)
if (mkdir (fspath) <= -1)
{
struct stat st;
if (errno != EEXIST && stat (fspath, &st) >= 0)
{
if (S_ISDIR(st.st_mode))
{
fs->errnum = QSE_FS_EEXIST;
return -1;
}
}
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#else
if (QSE_MKDIR (fspath, 0777) <= -1) /* TODO: proper mode?? */
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#endif
return 0;
}
/* --------------------------------------------------------------------- */
static int make_directory_chain (qse_fs_t* fs, qse_fs_char_t* fspath)
{
qse_fs_char_t* core, * p, c;
int ret = 0;
core = get_fspath_core (fspath);
canon_fspath (core, core, 0);
if (*core == QSE_FS_T('\0'))
{
fs->errnum = QSE_FS_EINVAL;
return -1;
}
p = core;
if (IS_FSPATHSEP(*p)) p++;
for (; *p; p++)
{
if (IS_FSPATHSEP(*p))
{
#if defined(_WIN32) || defined(__DOS__) || defined(__OS2__)
/* exclude the separator from the path name */
c = *p;
*p = QSE_FS_T('\0');
#else
/* include the separater in the path name */
c = *(p + 1);
*(p + 1) = QSE_FS_T('\0');
#endif
ret = qse_fs_sysmkdir (fs, fspath);
if (ret <= -1 && fs->errnum != QSE_FS_EEXIST)
{
return -1;
goto done; /* abort */
}
#if defined(_WIN32) || defined(__DOS__) || defined(__OS2__)
*p = c;
#else
*(p + 1) = c;
#endif
}
}
if (!IS_FSPATHSEP(*(p - 1))) ret = qse_fs_sysmkdir (fs, fspath);
done:
return ret;
}
int qse_fs_mkdirmbs (qse_fs_t* fs, const qse_mchar_t* path, int flags)
{
qse_fs_char_t* fspath;
int ret;
if (*path == QSE_MT('\0'))
{
fs->errnum = QSE_FS_EINVAL;
return -1;
}
if (flags & QSE_FS_MKDIRMBS_PARENT)
{
/* make_directory_chain changes the input path.
* ensure to create a modifiable string for it. */
fspath = qse_fs_dupfspathformbs (fs, path);
if (!fspath) return -1;
ret = make_directory_chain (fs, fspath);
}
else
{
fspath = (qse_fs_char_t*)qse_fs_makefspathformbs (fs, path);
if (!fspath) return -1;
ret = qse_fs_sysmkdir (fs, fspath);
}
qse_fs_freefspathformbs (fs, path, fspath);
return ret;
}
int qse_fs_mkdirwcs (qse_fs_t* fs, const qse_wchar_t* path, int flags)
{
qse_fs_char_t* fspath;
int ret;
if (*path == QSE_WT('\0'))
{
fs->errnum = QSE_FS_EINVAL;
return -1;
}
if (flags & QSE_FS_MKDIRWCS_PARENT)
{
/* make_directory_chain changes the input path.
* ensure to create a modifiable string for it. */
fspath = qse_fs_dupfspathforwcs (fs, path);
if (!fspath) return -1;
ret = make_directory_chain (fs, fspath);
}
else
{
fspath = (qse_fs_char_t*)qse_fs_makefspathforwcs (fs, path);
if (!fspath) return -1;
ret = qse_fs_sysmkdir (fs, fspath);
}
qse_fs_freefspathforwcs (fs, path, fspath);
return ret;
}
/* --------------------------------------------------------------------- */
/*
mknodmbs
mkfifombs
mknodwcs
mknodwcs
*/

View File

@ -1,463 +0,0 @@
/*
* $Id$
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fs.h"
#include <qse/cmn/mbwc.h>
#include <qse/cmn/path.h>
#include <qse/cmn/str.h>
#include "mem.h"
/*
OVERWRITE AND FORCE handled by callback???
QSE_FS_MOVE_UPDATE
QSE_FS_MOVE_BACKUP_SIMPLE
QSE_FS_MOVE_BACKUP_NUMBERED
*/
enum fop_flag_t
{
FOP_OLD_STAT = (1 << 0),
FOP_NEW_STAT = (1 << 1),
FOP_CROSS_DEV = (1 << 2)
};
struct fop_t
{
int flags;
#if defined(_WIN32)
/* nothing yet */
#elif defined(__OS2__)
qse_fs_char_t* old_path;
qse_fs_char_t* new_path;
#elif defined(__DOS__)
qse_fs_char_t* old_path;
qse_fs_char_t* new_path;
#else
qse_fs_char_t* old_path;
qse_fs_char_t* new_path;
qse_fs_char_t* new_path2;
#if defined(HAVE_LSTAT)
qse_lstat_t old_stat;
qse_lstat_t new_stat;
#else
qse_stat_t old_stat;
qse_stat_t new_stat;
#endif
#endif
};
typedef struct fop_t fop_t;
int qse_fs_move (qse_fs_t* fs, const qse_char_t* oldpath, const qse_char_t* newpath)
{
#if defined(_WIN32)
/* ------------------------------------------------------ */
/* TODO: improve it... */
/* TODO: support cross-volume move, move by copy/delete, etc ... */
if (MoveFile (oldpath, newpath) == FALSE)
{
DWORD e = GetLastError();
if (e == ERROR_ALREADY_EXISTS)
{
DeleteFile (newpath);
if (MoveFile (oldpath, newpath) == FALSE)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, GetLastError());
return -1;
}
}
else
{
fs->errnum = qse_fs_syserrtoerrnum (fs, e);
return -1;
}
}
return 0;
/* ------------------------------------------------------ */
#elif defined(__OS2__)
/* ------------------------------------------------------ */
/* TODO: improve it */
int ret = 0;
fop_t fop;
QSE_MEMSET (&fop, 0, QSE_SIZEOF(fop));
#if defined(QSE_CHAR_IS_MCHAR)
fop.old_path = oldpath;
fop.new_path = newpath;
#else
fop.old_path = qse_wcstombsdup (oldpath, QSE_NULL, fs->mmgr);
fop.new_path = qse_wcstombsdup (newpath, QSE_NULL, fs->mmgr);
if (fop.old_path == QSE_NULL || fop.old_path == QSE_NULL)
{
fs->errnum = QSE_FS_ENOMEM;
ret = -1;
}
#endif
if (ret == 0)
{
APIRET rc;
rc = DosMove (fop.old_path, fop.new_path);
if (rc == ERROR_ALREADY_EXISTS || rc == ERROR_ACCESS_DENIED)
{
DosDelete (fop.new_path);
rc = DosMove (fop.old_path, fop.new_path);
}
if (rc != NO_ERROR)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, rc);
ret = -1;
}
}
#if defined(QSE_CHAR_IS_MCHAR)
/* nothing special */
#else
if (fop.old_path) QSE_MMGR_FREE (fs->mmgr, fop.old_path);
if (fop.new_path) QSE_MMGR_FREE (fs->mmgr, fop.new_path);
#endif
return ret;
/* ------------------------------------------------------ */
#elif defined(__DOS__)
/* ------------------------------------------------------ */
/* TODO: improve it */
fop_t fop;
int ret = 0;
QSE_MEMSET (&fop, 0, QSE_SIZEOF(fop));
#if defined(QSE_CHAR_IS_MCHAR)
fop.old_path = oldpath;
fop.new_path = newpath;
#else
fop.old_path = qse_wcstombsdup (oldpath, QSE_NULL, fs->mmgr);
fop.new_path = qse_wcstombsdup (newpath, QSE_NULL, fs->mmgr);
if (fop.old_path == QSE_NULL || fop.old_path == QSE_NULL)
{
fs->errnum = QSE_FS_ENOMEM;
ret = -1;
}
#endif
if (ret == 0)
{
if (rename (fop.old_path, fop.new_path) <= -1)
{
/* FYI, rename() on watcom seems to set
* errno to EACCES when the new path exists. */
unlink (fop.new_path);
if (rename (fop.old_path, fop.new_path) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
ret = -1;
}
}
}
#if defined(QSE_CHAR_IS_MCHAR)
/* nothing special */
#else
if (fop.old_path) QSE_MMGR_FREE (fs->mmgr, fop.old_path);
if (fop.new_path) QSE_MMGR_FREE (fs->mmgr, fop.new_path);
#endif
return ret;
/* ------------------------------------------------------ */
#else
/* ------------------------------------------------------ */
fop_t fop;
QSE_MEMSET (&fop, 0, QSE_SIZEOF(fop));
#if defined(QSE_CHAR_IS_MCHAR)
fop.old_path = oldpath;
fop.new_path = newpath;
#else
fop.old_path = qse_wcstombsdup (oldpath, QSE_NULL, fs->mmgr);
fop.new_path = qse_wcstombsdup (newpath, QSE_NULL, fs->mmgr);
if (fop.old_path == QSE_NULL || fop.old_path == QSE_NULL)
{
fs->errnum = QSE_FS_ENOMEM;
goto oops;
}
#endif
/* TOOD: implement confirmatio
if (overwrite_callback is set)
{
checkif the the mbsnewpat exists.
if (it exists)
{
call fs->confirm_overwrite_callback (....)
}
}
*/
/* use lstat because we need to move the symbolic link
* itself if the file is a symbolic link */
#if defined(HAVE_LSTAT)
if (QSE_LSTAT (fop.old_path, &fop.old_stat) == -1)
#else
if (QSE_STAT (fop.old_path, &fop.old_stat) == -1) /* is this ok to use stat? */
#endif
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
goto oops;
}
else fop.flags |= FOP_OLD_STAT;
#if defined(HAVE_LSTAT)
if (QSE_LSTAT (fop.new_path, &fop.new_stat) == -1)
#else
if (QSE_STAT (fop.new_path, &fop.new_stat) == -1)
#endif
{
if (errno == ENOENT)
{
/* entry doesn't exist */
}
}
else fop.flags |= FOP_NEW_STAT;
if (fop.flags & FOP_NEW_STAT)
{
/* destination file exits */
if (fop.old_stat.st_dev != fop.new_stat.st_dev)
{
/* cross-device */
fop.flags |= FOP_CROSS_DEV;
}
else
{
if (fop.old_stat.st_ino == fop.new_stat.st_ino)
{
/* both source and destination are the same.
* this operation is not allowed */
fs->errnum = QSE_FS_EACCES;
goto oops;
}
/* TODO: destination should point to an actual file or directory for this check to work */
/* TOOD: ask to overwrite the source */
if (S_ISDIR(fop.new_stat.st_mode))
{
/* the destination is a directory. move the source file
* into the destination directory */
const qse_wchar_t* arr[4];
arr[0] = newpath;
arr[1] = QSE_T("/");
arr[2] = qse_basename(oldpath);
arr[3] = QSE_NULL;
#if defined(QSE_CHAR_IS_MCHAR)
fop.new_path2 = qse_stradup (arr, QSE_NULL, fs->mmgr);
#else
fop.new_path2 = qse_wcsatombsdup (arr, QSE_NULL, fs->mmgr);
#endif
if (fop.new_path2 == QSE_NULL)
{
fs->errnum = QSE_FS_ENOMEM;
goto oops;
}
}
else
{
/* the destination file is not directory, unlink first
* TODO: but is this necessary? RENAME will do it */
QSE_UNLINK (fop.new_path);
}
}
}
if (!(fop.flags & FOP_CROSS_DEV))
{
/* TODO: make it better to be able to move non-empty diretories
improve it to be able to move by copy/delete across volume */
if (QSE_RENAME (fop.old_path, fop.new_path) == -1)
{
if (errno != EXDEV)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
goto oops;
}
fop.flags |= FOP_CROSS_DEV;
}
else goto done;
}
QSE_ASSERT (fop.flags & FOP_CROSS_DEV);
if (!S_ISDIR(fop.old_stat.st_mode))
{
/* copy a single file */
/* ............ */
}
#if 0
if (!recursive)
{
fs->errnum = QSE_FS_E....;
goto oops;
}
copy recursively...
#endif
done:
#if defined(QSE_CHAR_IS_MCHAR)
if (fop.new_path2) QSE_MMGR_FREE (fs->mmgr, fop.new_path2);
#else
if (fop.new_path2) QSE_MMGR_FREE (fs->mmgr, fop.new_path2);
QSE_MMGR_FREE (fs->mmgr, fop.old_path);
QSE_MMGR_FREE (fs->mmgr, fop.new_path);
#endif
return 0;
oops:
#if defined(QSE_CHAR_IS_MCHAR)
if (fop.new_path2) QSE_MMGR_FREE (fs->mmgr, fop.new_path2);
#else
if (fop.new_path2) QSE_MMGR_FREE (fs->mmgr, fop.new_path2);
if (fop.old_path) QSE_MMGR_FREE (fs->mmgr, fop.old_path);
if (fop.new_path) QSE_MMGR_FREE (fs->mmgr, fop.new_path);
#endif
return -1;
/* ------------------------------------------------------ */
#endif
}
#if 0
static int move_file_in_fs (qse_fs_t* fs, const qse_fs_char_t* oldpath, const qse_fs_char_t* newpath, int flags)
{
#if defined(_WIN32)
/* ------------------------------------------------------ */
if (MoveFile (oldpath, newpath) == FALSE)
{
DWORD e = GetLastError();
if (e == ERROR_ALREADY_EXISTS)
{
DeleteFile (newpath);
if (MoveFile (oldpath, newpath) == FALSE)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, GetLastError());
return -1;
}
}
else
{
fs->errnum = qse_fs_syserrtoerrnum (fs, e);
return -1;
}
}
return 0;
/* ------------------------------------------------------ */
#elif defined(__OS2__)
/* ------------------------------------------------------ */
/* TODO: improve it */
APIRET rc;
rc = DosMove (oldpath, newpath);
if (rc == ERROR_ALREADY_EXISTS || rc == ERROR_ACCESS_DENIED)
{
DosDelete (fop.new_path);
rc = DosMove (oldpath, newpath);
}
if (rc != NO_ERROR)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, rc);
return -1;
}
return 0;
/* ------------------------------------------------------ */
#elif defined(__DOS__)
/* ------------------------------------------------------ */
if (rename (oldpath, newpath) <= -1)
{
/* FYI, rename() on watcom seems to set
* errno to EACCES when the new path exists. */
unlink (newpath);
if (rename (oldpath, newpath) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
}
return 0;
/* ------------------------------------------------------ */
#else
if (!(flags & QSE_FS_CPFILE_REPLACE))
{
qse_lstat_t st;
if (QSE_LSTAT (newpath, &st) >= 0)
{
fs->errnum = QSE_FS_EEXIST;
return -1;
}
}
if (QSE_RENAME (oldpath, newpath) == -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
return 0;
#endif
}
#endif

View File

@ -1,825 +0,0 @@
/*
* $Id$
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fs.h"
#include <qse/cmn/str.h>
#include <qse/cmn/mbwc.h>
#include <qse/cmn/path.h>
#include "mem.h"
#if defined(_WIN32)
/* nothing else */
#elif defined(__OS2__)
/* nothing else */
#elif defined(__DOS__)
/* nothing else */
#else
# include <dirent.h>
# include <errno.h>
#endif
typedef struct info_t info_t;
struct info_t
{
qse_cstr_t name;
#if defined(_WIN32)
HANDLE handle;
WIN32_FIND_DATA wfd;
int just_changed_fs;
#elif defined(__OS2__)
#elif defined(__DOS__)
#else
DIR* handle;
qse_mchar_t* mcurdir;
#endif
};
qse_fs_t* qse_fs_open (qse_mmgr_t* mmgr, qse_size_t xtnsize)
{
qse_fs_t* fs;
fs = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(*fs) + xtnsize);
if (fs == QSE_NULL) return QSE_NULL;
if (qse_fs_init (fs, mmgr) <= -1)
{
QSE_MMGR_FREE (mmgr, fs);
return QSE_NULL;
}
QSE_MEMSET (fs + 1, 0, xtnsize);
return fs;
}
void qse_fs_close (qse_fs_t* fs)
{
qse_fs_fini (fs);
QSE_MMGR_FREE (fs->mmgr, fs);
}
int qse_fs_init (qse_fs_t* fs, qse_mmgr_t* mmgr)
{
QSE_MEMSET (fs, 0, QSE_SIZEOF(*fs));
fs->mmgr = mmgr;
fs->cmgr = qse_getdflcmgr();
return 0;
}
void qse_fs_fini (qse_fs_t* fs)
{
info_t* info;
info = fs->info;
if (info)
{
if (info->name.ptr)
{
QSE_ASSERT (info->name.len > 0);
QSE_MMGR_FREE (fs->mmgr, info->name.ptr);
info->name.ptr = QSE_NULL;
info->name.len = 0;
}
#if defined(_WIN32)
if (info->handle != INVALID_HANDLE_VALUE)
{
FindClose (info->handle);
info->handle = INVALID_HANDLE_VALUE;
}
#elif defined(__OS2__)
/* TODO: implement this */
#elif defined(__DOS__)
/* TODO: implement this */
#else
if (info->mcurdir && info->mcurdir != fs->curdir)
QSE_MMGR_FREE (fs->mmgr, info->mcurdir);
info->mcurdir = QSE_NULL;
if (info->handle)
{
closedir (info->handle);
info->handle = QSE_NULL;
}
#endif
QSE_MMGR_FREE (fs->mmgr, info);
fs->info = QSE_NULL;
}
if (fs->curdir)
{
QSE_MMGR_FREE (fs->mmgr, fs->curdir);
fs->curdir = QSE_NULL;
}
}
qse_mmgr_t* qse_fs_getmmgr (qse_fs_t* fs)
{
return fs->mmgr;
}
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;
info = fs->info;
if (info == QSE_NULL)
{
info = QSE_MMGR_ALLOC (fs->mmgr, QSE_SIZEOF(*info));
if (info == QSE_NULL)
{
fs->errnum = QSE_FS_ENOMEM;
return QSE_NULL;
}
QSE_MEMSET (info, 0, QSE_SIZEOF(*info));
#if defined(_WIN32)
info->handle = INVALID_HANDLE_VALUE;
#endif
fs->info = info;
}
return info;
}
int qse_fs_chdir (qse_fs_t* fs, const qse_char_t* name)
{
qse_char_t* fsname;
info_t* info;
#if defined(_WIN32)
HANDLE handle;
WIN32_FIND_DATA wfd;
const qse_char_t* tmp_name[4];
qse_size_t idx;
#elif defined(__OS2__)
/* TODO: implement this */
#elif defined(__DOS__)
/* TODO: implement this */
#else
DIR* handle;
qse_mchar_t* mfsname;
const qse_char_t* tmp_name[4];
qse_size_t idx;
#endif
if (name[0] == QSE_T('\0'))
{
fs->errnum = QSE_FS_EINVAL;
return -1;
}
info = get_info (fs);
if (info == QSE_NULL) return -1;
#if defined(_WIN32)
idx = 0;
if (!qse_isabspath(name) && fs->curdir)
tmp_name[idx++] = fs->curdir;
tmp_name[idx++] = name;
if (qse_isdrivecurpath(name))
tmp_name[idx++] = QSE_T(" ");
else
tmp_name[idx++] = QSE_T("\\ ");
tmp_name[idx] = QSE_NULL;
fsname = qse_stradup (tmp_name, QSE_NULL, fs->mmgr);
if (fsname == QSE_NULL)
{
fs->errnum = QSE_FS_ENOMEM;
return -1;
}
idx = qse_canonpath (fsname, fsname, 0);
/* Put an asterisk after canonicalization to prevent side-effects.
* otherwise, .\* would be transformed to * by qse_canonpath() */
fsname[idx-1] = QSE_T('*');
/* Using FindExInfoBasic won't resolve cAlternatFileName.
* so it can get faster a little bit. The problem is that
* it is not supported on old windows. just stick to the
* simple API instead. */
#if 0
handle = FindFirstFileEx (
fsname, FindExInfoBasic,
&wfd, FindExSearchNameMatch,
NULL, 0/*FIND_FIRST_EX_CASE_SENSITIVE*/);
#endif
handle = FindFirstFile (fsname, &wfd);
if (handle == INVALID_HANDLE_VALUE)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, GetLastError());
QSE_MMGR_FREE (fs->mmgr, fsname);
return -1;
}
if (info->handle != INVALID_HANDLE_VALUE)
FindClose (info->handle);
QSE_MEMSET (info, 0, QSE_SIZEOF(*info));
info->handle = handle;
info->wfd = wfd;
info->just_changed_fs = 1;
if (fs->curdir) QSE_MMGR_FREE (fs->mmgr, fs->curdir);
fsname[idx-1] = QSE_T('\0'); /* drop the asterisk */
fs->curdir = fsname;
return 0;
#elif defined(__OS2__)
/* TODO: implement this */
return 0;
#elif defined(__DOS__)
/* TODO: implement this */
return 0;
#else
idx = 0;
if (!qse_isabspath(name) && fs->curdir)
{
tmp_name[idx++] = fs->curdir;
tmp_name[idx++] = QSE_T("/");
}
tmp_name[idx++] = name;
tmp_name[idx] = QSE_NULL;
fsname = qse_stradup (tmp_name, QSE_NULL, fs->mmgr);
if (fsname == QSE_NULL)
{
fs->errnum = QSE_FS_ENOMEM;
return -1;
}
qse_canonpath (fsname, fsname, 0);
#if defined(QSE_CHAR_IS_MCHAR)
mfsname = fsname;
#else
mfsname = qse_wcstombsdup (fsname, QSE_NULL, fs->mmgr);
if (mfsname == QSE_NULL)
{
fs->errnum = QSE_FS_ENOMEM;
QSE_MMGR_FREE (fs->mmgr, fsname);
return -1;
}
#endif
handle = opendir (mfsname);
if (handle == QSE_NULL)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
if (mfsname != fsname)
QSE_MMGR_FREE (fs->mmgr, mfsname);
QSE_MMGR_FREE (fs->mmgr, fsname);
return -1;
}
if (info->handle) closedir (info->handle);
info->handle = handle;
if (info->mcurdir && info->mcurdir != fs->curdir)
QSE_MMGR_FREE (fs->mmgr, info->mcurdir);
info->mcurdir = mfsname;
if (fs->curdir) QSE_MMGR_FREE (fs->mmgr, fs->curdir);
fs->curdir = fsname;
return 0;
#endif
}
#if defined(QSE_CHAR_IS_MCHAR) || defined(_WIN32)
static int set_entry_name (qse_fs_t* fs, const qse_char_t* name)
#else
static int set_entry_name (qse_fs_t* fs, const qse_mchar_t* name)
#endif
{
info_t* info;
qse_size_t len;
#if defined(QSE_CHAR_IS_MCHAR) || defined(_WIN32)
/* nothing more to declare */
#else
qse_size_t mlen;
#endif
info = fs->info;
QSE_ASSERT (info != QSE_NULL);
#if defined(QSE_CHAR_IS_MCHAR) || defined(_WIN32)
len = qse_strlen (name);
#else
/* TODO: ignore MBWCERR */
if (qse_mbstowcs (name, &mlen, QSE_NULL, &len) <= -1)
{
/* invalid name ??? */
return -1;
}
#endif
if (len > info->name.len)
{
qse_char_t* tmp;
/* TOOD: round up len to the nearlest multiples of something (32, 64, ??)*/
tmp = QSE_MMGR_REALLOC (
fs->mmgr,
info->name.ptr,
(len + 1) * QSE_SIZEOF(*tmp)
);
if (tmp == QSE_NULL)
{
fs->errnum = QSE_FS_ENOMEM;
return -1;
}
info->name.len = len;
info->name.ptr = tmp;
}
#if defined(QSE_CHAR_IS_MCHAR) || defined(_WIN32)
qse_strcpy (info->name.ptr, name);
#else
len++; /* for terminating null */
qse_mbstowcs (name, &mlen, info->name.ptr, &len);
#endif
fs->ent.name.base = info->name.ptr;
fs->ent.flags |= QSE_FS_ENT_NAME;
return 0;
}
#if defined(_WIN32)
static QSE_INLINE void filetime_to_ntime (const FILETIME* ft, qse_ntime_t* nt)
{
/* reverse of http://support.microsoft.com/kb/167296/en-us */
ULARGE_INTEGER li;
li.LowPart = ft->dwLowDateTime;
li.HighPart = ft->dwHighDateTime;
#if (QSE_SIZEOF_LONG_LONG>=8)
li.QuadPart -= 116444736000000000ull;
#elif (QSE_SIZEOF___INT64>=8)
li.QuadPart -= 116444736000000000ui64;
#else
# error Unsupported 64bit integer type
#endif
/*li.QuadPart /= 10000000;*/
/*li.QuadPart /= 10000;
return li.QuadPart;*/
/* li.QuadPart is in the 100-nanosecond intervals */
nt->sec = li.QuadPart / (QSE_NSECS_PER_SEC / 100);
nt->nsec = (li.QuadPart % (QSE_NSECS_PER_SEC / 100)) * 100;
}
#endif
qse_fs_ent_t* qse_fs_read (qse_fs_t* fs, int flags)
{
#if defined(_WIN32)
info_t* info;
info = fs->info;
if (info == QSE_NULL)
{
fs->errnum = QSE_FS_ENOENT; /* TODO: is this correct? */
return QSE_NULL;
}
if (info->just_changed_fs)
{
info->just_changed_fs = 0;
}
else
{
if (FindNextFile (info->handle, &info->wfd) == FALSE)
{
DWORD e = GetLastError();
if (e == ERROR_NO_MORE_FILES)
{
fs->errnum = QSE_FS_ENOERR;
return QSE_NULL;
}
else
{
fs->errnum = qse_fs_syserrtoerrnum (fs, e);
return QSE_NULL;
}
}
}
/* call set_entry_name before changing other fields
* in fs->ent not to pollute it in case set_entry_name fails */
QSE_MEMSET (&fs->ent, 0, QSE_SIZEOF(fs->ent));
if (set_entry_name (fs, info->wfd.cFileName) <= -1) return QSE_NULL;
if (flags & QSE_FS_ENT_TYPE)
{
#if !defined(IO_REPARSE_TAG_SYMLINK)
# define IO_REPARSE_TAG_SYMLINK 0xA000000C
#endif
#if !defined(FILE_ATTRIBUTE_REPARSE_POINT)
# define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
#endif
if (info->wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
fs->ent.type = QSE_FS_ENT_SUBDIR;
}
else if ((info->wfd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
(info->wfd.dwReserved0 == IO_REPARSE_TAG_SYMLINK))
{
fs->ent.type = QSE_FS_ENT_SYMLINK;
}
else
{
HANDLE h;
qse_char_t* tmp_name[4];
qse_char_t* fname;
/* TODO: use a buffer in info... instead of allocating an deallocating every time */
tmp_name[0] = fs->curdir;
tmp_name[1] = QSE_T("\\");
tmp_name[2] = info->wfd.cFileName;
tmp_name[3] = QSE_NULL;
fname = qse_stradup (tmp_name, QSE_NULL, fs->mmgr);
if (fname == QSE_NULL)
{
fs->errnum = QSE_FS_ENOMEM;
return QSE_NULL;
}
h = CreateFile (
fname,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
QSE_NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
QSE_MMGR_FREE (fs->mmgr, fname);
if (h != INVALID_HANDLE_VALUE)
{
DWORD t = GetFileType (h);
switch (t)
{
case FILE_TYPE_CHAR:
fs->ent.type = QSE_FS_ENT_CHRDEV;
break;
case FILE_TYPE_DISK:
fs->ent.type = QSE_FS_ENT_BLKDEV;
break;
case FILE_TYPE_PIPE:
fs->ent.type = QSE_FS_ENT_PIPE;
break;
default:
fs->ent.type = QSE_FS_ENT_UNKNOWN;
break;
}
CloseHandle (h);
}
else
{
fs->ent.type = QSE_FS_ENT_UNKNOWN;
}
}
fs->ent.type |= QSE_FS_ENT_TYPE;
}
if (flags & QSE_FS_ENT_SIZE)
{
LARGE_INTEGER li;
li.LowPart = info->wfd.nFileSizeLow;
li.HighPart = info->wfd.nFileSizeHigh;
fs->ent.size = li.QuadPart;
fs->ent.type |= QSE_FS_ENT_SIZE;
}
if (flags & QSE_FS_ENT_TIME)
{
filetime_to_ntime (&info->wfd.ftCreationTime, &fs->ent.time.create);
filetime_to_ntime (&info->wfd.ftLastAccessTime, &fs->ent.time.access);
filetime_to_ntime (&info->wfd.ftLastWriteTime, &fs->ent.time.modify);
fs->ent.type |= QSE_FS_ENT_TIME;
}
#elif defined(__OS2__)
/* TODO: implement this */
#elif defined(__DOS__)
/* TODO: implement this */
#else
info_t* info;
struct dirent* ent;
int x;
int stat_needed;
qse_lstat_t st;
info = fs->info;
if (info == QSE_NULL)
{
fs->errnum = QSE_FS_ENOTDIR;
return QSE_NULL;
}
errno = 0;
ent = readdir (info->handle);
if (ent == QSE_NULL)
{
if (errno != 0) fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return QSE_NULL;
}
QSE_MEMSET (&fs->ent, 0, QSE_SIZEOF(fs->ent));
if (set_entry_name (fs, ent->d_name) <= -1) return QSE_NULL;
stat_needed =
#if !defined(HAVE_STRUCT_DIRENT_D_TYPE)
(flags & QSE_FS_ENT_TYPE) ||
#endif
(flags & QSE_FS_ENT_SIZE) ||
(flags & QSE_FS_ENT_TIME);
if (stat_needed)
{
qse_mchar_t* tmp_name[4];
qse_mchar_t* mfname;
/* TODO: use a buffer in info... instead of allocating an deallocating every time */
tmp_name[0] = info->mcurdir;
tmp_name[1] = QSE_MT("/");
tmp_name[2] = ent->d_name;
tmp_name[3] = QSE_NULL;
mfname = qse_mbsadup (tmp_name, QSE_NULL, fs->mmgr);
if (mfname == QSE_NULL)
{
fs->errnum = QSE_FS_ENOMEM;
return QSE_NULL;
}
#if defined(HAVE_LSTAT)
x = QSE_LSTAT (mfname, &st);
#else
x = QSE_STAT (mfname, &st);
#endif
QSE_MMGR_FREE (fs->mmgr, mfname);
if (x == -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return QSE_NULL;
}
}
if (flags & QSE_FS_ENT_TYPE)
{
#if defined(HAVE_STRUCT_DIRENT_D_TYPE) && defined(DT_DIR) && defined(DT_REG) /* and more */
switch (ent->d_type)
{
case DT_DIR:
fs->ent.type = QSE_FS_ENT_SUBDIR;
break;
case DT_REG:
fs->ent.type = QSE_FS_ENT_REGULAR;
break;
case DT_LNK:
fs->ent.type = QSE_FS_ENT_SYMLINK;
break;
case DT_BLK:
fs->ent.type = QSE_FS_ENT_BLKDEV;
break;
case DT_CHR:
fs->ent.type = QSE_FS_ENT_CHRDEV;
break;
case DT_FIFO:
#if defined(DT_SOCK)
case DT_SOCK:
#endif
fs->ent.type = QSE_FS_ENT_PIPE;
break;
default:
fs->ent.type = QSE_FS_ENT_UNKNOWN;
break;
}
#else
#if defined(__S_IFMT) && !defined(S_IFMT)
# define S_IFMT __S_IFMT
#endif
#if defined(__S_IFDIR) && !defined(S_IFDIR)
# define S_IFDIR __S_IFDIR
#endif
#define IS_TYPE(st,type) ((st.st_mode & S_IFMT) == S_IFDIR)
fs->ent.type = IS_TYPE(st,S_IFDIR)? QSE_FS_ENT_SUBDIR:
IS_TYPE(st,S_IFREG)? QSE_FS_ENT_REGULAR:
IS_TYPE(st,S_IFLNK)? QSE_FS_ENT_SYMLINK:
IS_TYPE(st,S_IFCHR)? QSE_FS_ENT_CHRDEV:
IS_TYPE(st,S_IFBLK)? QSE_FS_ENT_BLKDEV:
IS_TYPE(st,S_IFIFO)? QSE_FS_ENT_PIPE:
#if defined(S_IFSOCK)
IS_TYPE(st,S_IFSOCK)? QSE_FS_ENT_PIPE:
#endif
QSE_FS_ENT_UNKNOWN;
#undef IS_TYPE
#endif
fs->ent.flags |= QSE_FS_ENT_TYPE;
}
if (flags & QSE_FS_ENT_SIZE)
{
fs->ent.size = st.st_size;
fs->ent.flags |= QSE_FS_ENT_SIZE;
}
if (flags & QSE_FS_ENT_TIME)
{
#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC)
fs->ent.time.create.sec = st.st_birthtim.tv_sec;
fs->ent.time.create.nsec = st.st_birthtim.tv_nsec;
#endif
fs->ent.time.access.sec = st.st_atim.tv_sec;
fs->ent.time.access.nsec = st.st_atim.tv_nsec;
fs->ent.time.modify.sec = st.st_mtim.tv_sec;
fs->ent.time.modify.nsec = st.st_mtim.tv_nsec;
fs->ent.time.change.sec = st.st_ctim.tv_sec;
fs->ent.time.change.nsec = st.st_ctim.tv_nsec;
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC)
fs->ent.time.create.sec = st.st_birthtimespec.tv_sec;
fs->ent.time.create.nsec = st.st_birthtimespec.tv_nsec;
#endif
fs->ent.time.access.sec = st.st_atimespec.tv_sec;
fs->ent.time.access.nsec = st.st_atimespec.tv_nsec;
fs->ent.time.modify.sec = st.st_mtimespec.tv_sec;
fs->ent.time.modify.nsec = st.st_mtimespec.tv_nsec;
fs->ent.time.change.sec = st.st_ctimespec.tv_sec;
fs->ent.time.change.nsec = st.st_ctimespec.tv_nsec;
#else
#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
fs->ent.time.create.sec = st.st_birthtime;
#endif
fs->ent.time.access.sec = st.st_atime;
fs->ent.time.modify.sec = st.st_mtime;
fs->ent.time.change.sec = st.st_ctime;
#endif
fs->ent.flags |= QSE_FS_ENT_TIME;
}
#endif
return &fs->ent;
}
int qse_fs_rewind (qse_fs_t* fs)
{
return 0;
}
qse_fs_char_t* qse_fs_makefspathformbs (qse_fs_t* fs, const qse_mchar_t* path)
{
qse_fs_char_t* fspath;
#if defined(QSE_FS_CHAR_IS_MCHAR)
fspath = path;
#else
fspath = qse_mbstowcsdupwithcmgr (path, QSE_NULL, fs->mmgr, fs->cmgr);
if (!fspath) fs->errnum = QSE_FS_ENOMEM;
#endif
return fspath;
}
qse_fs_char_t* qse_fs_makefspathforwcs (qse_fs_t* fs, const qse_wchar_t* path)
{
qse_fs_char_t* fspath;
#if defined(QSE_FS_CHAR_IS_MCHAR)
fspath = qse_wcstombsdupwithcmgr (path, QSE_NULL, fs->mmgr, fs->cmgr);
if (!fspath) fs->errnum = QSE_FS_ENOMEM;
#else
fspath = path;
#endif
return fspath;
}
qse_fs_char_t* qse_fs_dupfspathformbs (qse_fs_t* fs, const qse_mchar_t* path)
{
qse_fs_char_t* fspath;
#if defined(QSE_FS_CHAR_IS_MCHAR)
fspath = qse_mbsdup (path, fs->mmgr);
#else
fspath = qse_mbstowcsdupwithcmgr (path, QSE_NULL, fs->mmgr, fs->cmgr);
if (!fspath) fs->errnum = QSE_FS_ENOMEM;
#endif
return fspath;
}
qse_fs_char_t* qse_fs_dupfspathforwcs (qse_fs_t* fs, const qse_wchar_t* path)
{
qse_fs_char_t* fspath;
#if defined(QSE_FS_CHAR_IS_MCHAR)
fspath = qse_wcstombsdupwithcmgr (path, QSE_NULL, fs->mmgr, fs->cmgr);
if (!fspath) fs->errnum = QSE_FS_ENOMEM;
#else
fspath = qse_wcsdup (path, fs->mmgr);
#endif
return fspath;
}
void qse_fs_freefspathformbs (qse_fs_t* fs, const qse_mchar_t* path, qse_fs_char_t* fspath)
{
if (path != (const qse_mchar_t*)fspath) QSE_MMGR_FREE (fs->mmgr, fspath);
}
void qse_fs_freefspathforwcs (qse_fs_t* fs, const qse_wchar_t* path, qse_fs_char_t* fspath)
{
if (path != (const qse_wchar_t*)fspath) QSE_MMGR_FREE (fs->mmgr, fspath);
}

View File

@ -1,175 +0,0 @@
/*
* $Id$
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <qse/cmn/fs.h>
#include <qse/cmn/mbwc.h>
#include <qse/cmn/glob.h>
#include <qse/cmn/dir.h>
#include <qse/cmn/mem.h>
#include <qse/cmn/str.h>
#include <qse/cmn/path.h>
#if defined(_WIN32)
# include <windows.h>
typedef DWORD qse_fs_syserr_t;
#elif defined(__OS2__)
# define INCL_DOSERRORS
# define INCL_DOSFILEMGR
# include <os2.h>
typedef APIRET qse_fs_syserr_t;
#elif defined(__DOS__)
# include <errno.h>
# include <io.h>
# include <stdio.h> /* for rename() */
typedef int qse_fs_syserr_t;
#else
# include "syscall.h"
typedef int qse_fs_syserr_t;
#endif
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
# define DEFAULT_GLOB_FLAGS (QSE_GLOB_PERIOD | QSE_GLOB_SKIPSPCDIR | QSE_GLOB_NOESCAPE | QSE_GLOB_IGNORECASE)
# define DEFAULT_PATH_SEPARATOR QSE_T("\\")
#else
# define DEFAULT_GLOB_FLAGS (QSE_GLOB_PERIOD | QSE_GLOB_SKIPSPCDIR)
# define DEFAULT_PATH_SEPARATOR QSE_T("/")
#endif
#define IS_CURDIR(x) ((x)[0] == QSE_T('.') && (x)[1] == QSE_T('\0'))
#define IS_PREVDIR(x) ((x)[0] == QSE_T('.') && (x)[1] == QSE_T('.') && (x)[2] == QSE_T('\0'))
#if defined(QSE_CHAR_IS_MCHAR)
# define make_str_with_wcs(fs,wcs) qse_wcstombsdupwithcmgr(wcs,QSE_NULL,(fs)->mmgr,(fs)->cmgr)
# define make_str_with_mbs(fs,mbs) (mbs)
# define free_str_with_wcs(fs,wcs,str) QSE_MMGR_FREE((fs)->mmgr,str)
# define free_str_with_mbs(fs,mbs,str)
#else
# define make_str_with_wcs(fs,wcs) (wcs)
# define make_str_with_mbs(fs,mbs) qse_mbstowcsdupwithcmgr(mbs,QSE_NULL,(fs)->mmgr,(fs)->cmgr)
# define free_str_with_wcs(fs,wcs,str)
# define free_str_with_mbs(fs,mbs,str) QSE_MMGR_FREE((fs)->mmgr,str)
#endif
#if defined(QSE_FS_CHAR_IS_MCHAR)
# define canon_fspath(path,canon,flags) qse_canonmbspath(path,canon,flags)
# define merge_fspath_dup(dir,file,mmgr) qse_mergembspathdup(dir,file,mmgr)
# define get_fspath_core(fspath) qse_mbspathcore(fspath)
# define get_fspath_base(fspath) qse_mbsbasename(fspath)
# define IS_FSPATHSEP(x) QSE_ISPATHMBSEP(x)
# define QSE_FS_T(x) QSE_MT(x)
#else
# define canon_fspath(fspath,canon,flags) qse_canonwcspath(fspath,canon,flags)
# define merge_fspath_dup(dir,file,mmgr) qse_mergewcspathdup(dir,file,mmgr)
# define get_fspath_core(fspath) qse_wcspathcore(fspath)
# define get_fspath_base(fspath) qse_wcsbasename(fspath)
# define IS_FSPATHSEP(x) QSE_ISPATHWCSEP(x)
# define QSE_FS_T(x) QSE_WT(x)
#endif
#if defined(__cplusplus)
extern "C" {
#endif
qse_fs_errnum_t qse_fs_syserrtoerrnum (
qse_fs_t* fs,
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
);
qse_fs_char_t* qse_fs_makefspathforwcs (
qse_fs_t* fs,
const qse_wchar_t* path
);
qse_fs_char_t* qse_fs_dupfspathformbs (
qse_fs_t* fs,
const qse_mchar_t* path
);
qse_fs_char_t* qse_fs_dupfspathforwcs (
qse_fs_t* fs,
const qse_wchar_t* path
);
void qse_fs_freefspathformbs (
qse_fs_t* fs,
const qse_mchar_t* path,
qse_fs_char_t* fspath
);
void qse_fs_freefspathforwcs (
qse_fs_t* fs,
const qse_wchar_t* path,
qse_fs_char_t* fspath
);
#if defined(QSE_CHAR_IS_MCHAR)
# define qse_fs_makefspath(fs,path) qse_fs_makefspathformbs(fs,path)
# define qse_fs_freefspath(fs,path,fspath) qse_fs_freefspathformbs(fs,path,fspath);
#else
# define qse_fs_makefspath(fs,path) qse_fs_makefspathforwcs(fs,path)
# define qse_fs_freefspath(fs,path,fspath) qse_fs_freefspathforwcs(fs,path,fspath);
#endif
int qse_fs_sysgetattr (
qse_fs_t* fs,
const qse_fs_char_t* fspath,
qse_fs_attr_t* attr
);
int qse_fs_syscpfile (
qse_fs_t* fs,
const qse_fs_char_t* srcpath,
const qse_fs_char_t* dstpath
);
int qse_fs_sysmkdir (
qse_fs_t* fs,
const qse_fs_char_t* fspath
);
int qse_fs_sysrmfile (
qse_fs_t* fs,
const qse_fs_char_t* fspath
);
int qse_fs_sysrmdir (
qse_fs_t* fs,
const qse_fs_char_t* fspath
);
#if defined(__cplusplus)
}
#endif

View File

@ -1,203 +0,0 @@
/*
* $Id$
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <qse/cmn/glob.h>
#include <qse/cmn/str.h>
#include <qse/cmn/mbwc.h>
#include <qse/cmn/path.h>
#include <qse/cmn/dir.h>
#include "mem.h"
#if defined(_WIN32)
# include <windows.h>
#elif defined(__OS2__)
# define INCL_DOSFILEMGR
# define INCL_ERRORS
# include <os2.h>
#elif defined(__DOS__)
# include <dos.h>
# include <errno.h>
#elif defined(macintosh)
# include <Files.h>
#else
# include "syscall.h"
#endif
#define NO_RECURSION 1
enum segment_type_t
{
NONE,
ROOT,
NORMAL
};
typedef enum segment_type_t segment_type_t;
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
/* i don't support escaping in these systems */
# define IS_ESC_MBS(c) (0)
# define IS_ESC_WCS(c) (0)
#else
# define IS_ESC_MBS(c) ((c) == QSE_MT('\\'))
# define IS_ESC_WCS(c) ((c) == QSE_WT('\\'))
#endif
#define IS_NIL_MBS(c) ((c) == QSE_MT('\0'))
#define IS_NIL_WCS(c) ((c) == QSE_WT('\0'))
/* this macro only checks for top-level wild-cards among these.
* *, ?, [], !, -
* see str-fnmat.c for more wild-card letters
*/
#define IS_WILD_MBS(c) ((c) == QSE_MT('*') || (c) == QSE_MT('?') || (c) == QSE_MT('['))
#define IS_WILD_WCS(c) ((c) == QSE_WT('*') || (c) == QSE_WT('?') || (c) == QSE_WT('['))
/* -------------------------------------------------------------------- */
#define glob qse_globmbs
#define cbimpl_t qse_glob_mbscbimpl_t
#define glob_t mbs_glob_t
#define segment_t mbs_segment_t
#define stack_node_t mbs_stack_node_t
#define char_t qse_mchar_t
#define cstr_t qse_mcstr_t
#define T(x) QSE_MT(x)
#define IS_ESC(x) IS_ESC_MBS(x)
#define IS_DRIVE(x) QSE_ISPATHMBDRIVE(x)
#define IS_SEP(x) QSE_ISPATHMBSEP(x)
#define IS_SEP_OR_NIL(x) QSE_ISPATHMBSEPORNIL(x)
#define IS_NIL(x) IS_NIL_MBS(x)
#define IS_WILD(x) IS_WILD_MBS(x)
#define str_t qse_mbs_t
#define str_open qse_mbs_open
#define str_close qse_mbs_close
#define str_init qse_mbs_init
#define str_fini qse_mbs_fini
#define str_cat qse_mbs_cat
#define str_ccat qse_mbs_ccat
#define str_ncat qse_mbs_ncat
#define str_setcapa qse_mbs_setcapa
#define str_setlen qse_mbs_setlen
#define STR_CAPA(x) QSE_MBS_CAPA(x)
#define STR_LEN(x) QSE_MBS_LEN(x)
#define STR_PTR(x) QSE_MBS_PTR(x)
#define STR_XSTR(x) QSE_MBS_XSTR(x)
#define STR_CPTR(x,y) QSE_MBS_CPTR(x,y)
#define strnfnmat qse_mbsnfnmat
#define DIR_CHAR_FLAGS QSE_DIR_MBSPATH
#define path_exists mbs_path_exists
#define search mbs_search
#define get_next_segment mbs_get_next_segment
#define handle_non_wild_segments mbs_handle_non_wild_segments
#define CHAR_IS_MCHAR
#undef INCLUDE_MBUF
#include "glob.h"
/* -------------------------------------------------------------------- */
#undef glob
#undef cbimpl_t
#undef glob_t
#undef segment_t
#undef stack_node_t
#undef char_t
#undef cstr_t
#undef T
#undef IS_ESC
#undef IS_DRIVE
#undef IS_SEP
#undef IS_SEP_OR_NIL
#undef IS_NIL
#undef IS_WILD
#undef str_t
#undef str_open
#undef str_close
#undef str_init
#undef str_fini
#undef str_cat
#undef str_ccat
#undef str_ncat
#undef str_setcapa
#undef str_setlen
#undef STR_CAPA
#undef STR_LEN
#undef STR_PTR
#undef STR_XSTR
#undef STR_CPTR
#undef strnfnmat
#undef DIR_CHAR_FLAGS
#undef path_exists
#undef search
#undef get_next_segment
#undef handle_non_wild_segments
#undef CHAR_IS_MCHAR
#undef INCLUDE_MBUF
/* -------------------------------------------------------------------- */
#define glob qse_globwcs
#define cbimpl_t qse_glob_wcscbimpl_t
#define glob_t wcs_glob_t
#define segment_t wcs_segment_t
#define stack_node_t wcs_stack_node_t
#define char_t qse_wchar_t
#define cstr_t qse_wcstr_t
#define T(x) QSE_WT(x)
#define IS_ESC(x) IS_ESC_WCS(x)
#define IS_DRIVE(x) QSE_ISPATHWCDRIVE(x)
#define IS_SEP(x) QSE_ISPATHWCSEP(x)
#define IS_SEP_OR_NIL(x) QSE_ISPATHWCSEPORNIL(x)
#define IS_NIL(x) IS_NIL_WCS(x)
#define IS_WILD(x) IS_WILD_WCS(x)
#define str_t qse_wcs_t
#define str_open qse_wcs_open
#define str_close qse_wcs_close
#define str_init qse_wcs_init
#define str_fini qse_wcs_fini
#define str_cat qse_wcs_cat
#define str_ccat qse_wcs_ccat
#define str_ncat qse_wcs_ncat
#define str_setcapa qse_wcs_setcapa
#define str_setlen qse_wcs_setlen
#define STR_CAPA(x) QSE_WCS_CAPA(x)
#define STR_LEN(x) QSE_WCS_LEN(x)
#define STR_PTR(x) QSE_WCS_PTR(x)
#define STR_XSTR(x) QSE_WCS_XSTR(x)
#define STR_CPTR(x,y) QSE_WCS_CPTR(x,y)
#define strnfnmat qse_wcsnfnmat
#define DIR_CHAR_FLAGS QSE_DIR_WCSPATH
#define path_exists wcs_path_exists
#define search wcs_search
#define get_next_segment wcs_get_next_segment
#define handle_non_wild_segments wcs_handle_non_wild_segments
#undef CHAR_IS_MCHAR
#if !defined(_WIN32)
# define INCLUDE_MBUF 1
#endif
#include "glob.h"

View File

@ -1,591 +0,0 @@
/*
* $Id$
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(NO_RECURSION)
typedef struct stack_node_t stack_node_t;
#endif
struct glob_t
{
cbimpl_t cbimpl;
void* cbctx;
qse_mmgr_t* mmgr;
qse_cmgr_t* cmgr;
int flags;
str_t path;
str_t tbuf; /* temporary buffer */
#if defined(INCLUDE_MBUF)
qse_mbs_t mbuf;
#endif
int expanded;
int fnmat_flags;
#if defined(NO_RECURSION)
stack_node_t* stack;
stack_node_t* free;
#endif
};
typedef struct glob_t glob_t;
struct segment_t
{
segment_type_t type;
const char_t* ptr;
qse_size_t len;
char_t sep; /* preceeding separator */
unsigned int wild: 1; /* indicate that it contains wildcards */
unsigned int esc: 1; /* indicate that it contains escaped letters */
unsigned int next: 1; /* indicate that it has the following segment */
};
typedef struct segment_t segment_t;
#if defined(NO_RECURSION)
struct stack_node_t
{
qse_size_t tmp;
qse_size_t tmp2;
qse_dir_t* dp;
segment_t seg;
stack_node_t* next;
};
#endif
#if defined(INCLUDE_MBUF)
static qse_mchar_t* wcs_to_mbuf (glob_t* g, const qse_wchar_t* wcs, qse_mbs_t* mbs)
{
qse_size_t ml, wl;
if (qse_wcstombswithcmgr (wcs, &wl, QSE_NULL, &ml, g->cmgr) <= -1 ||
qse_mbs_setlen (mbs, ml) == (qse_size_t)-1) return QSE_NULL;
qse_wcstombswithcmgr (wcs, &wl, QSE_MBS_PTR(mbs), &ml, g->cmgr);
return QSE_MBS_PTR(mbs);
}
#endif
static int path_exists (glob_t* g, const char_t* name)
{
#if defined(_WIN32)
/* ------------------------------------------------------------------- */
#if !defined(INVALID_FILE_ATTRIBUTES)
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
#if defined(CHAR_IS_MCHAR)
return (GetFileAttributesA(name) != INVALID_FILE_ATTRIBUTES)? 1: 0;
#else
return (GetFileAttributesW(name) != INVALID_FILE_ATTRIBUTES)? 1: 0;
#endif
/* ------------------------------------------------------------------- */
#elif defined(__OS2__)
/* ------------------------------------------------------------------- */
FILESTATUS3 fs;
APIRET rc;
const qse_mchar_t* mptr;
#if defined(CHAR_IS_MCHAR)
mptr = name;
#else
mptr = wcs_to_mbuf (g, name, &g->mbuf);
if (mptr == QSE_NULL) return -1;
#endif
rc = DosQueryPathInfo (mptr, FIL_STANDARD, &fs, QSE_SIZEOF(fs));
return (rc == NO_ERROR)? 1:
(rc == ERROR_PATH_NOT_FOUND)? 0: -1;
/* ------------------------------------------------------------------- */
#elif defined(__DOS__)
/* ------------------------------------------------------------------- */
unsigned int x, attr;
const qse_mchar_t* mptr;
#if defined(CHAR_IS_MCHAR)
mptr = name;
#else
mptr = wcs_to_mbuf (g, name, &g->mbuf);
if (mptr == QSE_NULL) return -1;
#endif
x = _dos_getfileattr (mptr, &attr);
return (x == 0)? 1:
(errno == ENOENT)? 0: -1;
/* ------------------------------------------------------------------- */
#elif defined(macintosh)
HFileInfo fpb;
const qse_mchar_t* mptr;
#if defined(CHAR_IS_MCHAR)
mptr = name;
#else
mptr = wcs_to_mbuf (g, name, &g->mbuf);
if (mptr == QSE_NULL) return -1;
#endif
QSE_MEMSET (&fpb, 0, QSE_SIZEOF(fpb));
fpb.ioNamePtr = (unsigned char*)mptr;
return (PBGetCatInfoSync ((CInfoPBRec*)&fpb) == noErr)? 1: 0;
#else
/* ------------------------------------------------------------------- */
#if defined(HAVE_LSTAT)
qse_lstat_t st;
#else
qse_stat_t st;
#endif
const qse_mchar_t* mptr;
#if defined(CHAR_IS_MCHAR)
mptr = name;
#else
mptr = wcs_to_mbuf (g, name, &g->mbuf);
if (mptr == QSE_NULL) return -1;
#endif
#if defined(HAVE_LSTAT)
return (QSE_LSTAT (mptr, &st) <= -1)? 0: 1;
#else
/* use stat() if no lstat() is available. */
return (QSE_STAT (mptr, &st) <= -1)? 0: 1;
#endif
/* ------------------------------------------------------------------- */
#endif
}
static int get_next_segment (glob_t* g, segment_t* seg)
{
if (seg->type == NONE)
{
/* seg->ptr must point to the beginning of the pattern
* and seg->len must be zero when seg->type is NONE. */
if (IS_NIL(seg->ptr[0]))
{
/* nothing to do */
}
else if (IS_SEP(seg->ptr[0]))
{
seg->type = ROOT;
seg->len = 1;
seg->next = IS_NIL(seg->ptr[1])? 0: 1;
seg->sep = T('\0');
seg->wild = 0;
seg->esc = 0;
}
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
else if (IS_DRIVE(seg->ptr))
{
seg->type = ROOT;
seg->len = 2;
if (IS_SEP(seg->ptr[2])) seg->len++;
seg->next = IS_NIL(seg->ptr[seg->len])? 0: 1;
seg->sep = T('\0');
seg->wild = 0;
seg->esc = 0;
}
#endif
else
{
int escaped = 0;
seg->type = NORMAL;
seg->sep = T('\0');
seg->wild = 0;
seg->esc = 0;
do
{
if (escaped) escaped = 0;
else
{
if (IS_ESC(seg->ptr[seg->len]))
{
escaped = 1;
seg->esc = 1;
}
else if (IS_WILD(seg->ptr[seg->len])) seg->wild = 1;
}
seg->len++;
}
while (!IS_SEP_OR_NIL(seg->ptr[seg->len]));
seg->next = IS_NIL(seg->ptr[seg->len])? 0: 1;
}
}
else if (seg->type == ROOT)
{
int escaped = 0;
seg->type = NORMAL;
seg->ptr = &seg->ptr[seg->len];
seg->len = 0;
seg->sep = T('\0');
seg->wild = 0;
seg->esc = 0;
while (!IS_SEP_OR_NIL(seg->ptr[seg->len]))
{
if (escaped) escaped = 0;
else
{
if (IS_ESC(seg->ptr[seg->len]))
{
escaped = 1;
seg->esc = 1;
}
else if (IS_WILD(seg->ptr[seg->len])) seg->wild = 1;
}
seg->len++;
}
seg->next = IS_NIL(seg->ptr[seg->len])? 0: 1;
}
else
{
QSE_ASSERT (seg->type == NORMAL);
seg->ptr = &seg->ptr[seg->len + 1];
seg->len = 0;
seg->wild = 0;
seg->esc = 0;
if (IS_NIL(seg->ptr[-1]))
{
seg->type = NONE;
seg->next = 0;
seg->sep = T('\0');
}
else
{
int escaped = 0;
seg->sep = seg->ptr[-1];
while (!IS_SEP_OR_NIL(seg->ptr[seg->len]))
{
if (escaped) escaped = 0;
else
{
if (IS_ESC(seg->ptr[seg->len]))
{
escaped = 1;
seg->esc = 1;
}
else if (IS_WILD(seg->ptr[seg->len])) seg->wild = 1;
}
seg->len++;
}
seg->next = IS_NIL(seg->ptr[seg->len])? 0: 1;
}
}
return seg->type;
}
static int handle_non_wild_segments (glob_t* g, segment_t* seg)
{
while (get_next_segment(g, seg) != NONE && !seg->wild)
{
QSE_ASSERT (seg->type != NONE && !seg->wild);
if (seg->sep && str_ccat (&g->path, seg->sep) == (qse_size_t)-1) return -1;
if (seg->esc)
{
/* if the segment contains escape sequences,
* strip the escape letters off the segment */
cstr_t tmp;
qse_size_t i;
int escaped = 0;
if (STR_CAPA(&g->tbuf) < seg->len &&
str_setcapa (&g->tbuf, seg->len) == (qse_size_t)-1) return -1;
tmp.ptr = STR_PTR(&g->tbuf);
tmp.len = 0;
/* the following loop drops the last character
* if it is the escape character */
for (i = 0; i < seg->len; i++)
{
if (escaped)
{
escaped = 0;
tmp.ptr[tmp.len++] = seg->ptr[i];
}
else
{
if (IS_ESC(seg->ptr[i]))
escaped = 1;
else
tmp.ptr[tmp.len++] = seg->ptr[i];
}
}
if (str_ncat (&g->path, tmp.ptr, tmp.len) == (qse_size_t)-1) return -1;
}
else
{
/* if the segmetn doesn't contain escape sequences,
* append the segment to the path without special handling */
if (str_ncat (&g->path, seg->ptr, seg->len) == (qse_size_t)-1) return -1;
}
if (!seg->next && path_exists (g, STR_PTR(&g->path)) > 0)
{
/* reached the last segment. match if the path exists */
if (g->cbimpl (STR_XSTR(&g->path), g->cbctx) <= -1) return -1;
g->expanded = 1;
}
}
return 0;
}
static int search (glob_t* g, segment_t* seg)
{
qse_dir_t* dp;
qse_size_t tmp, tmp2;
qse_dir_ent_t ent;
int x;
#if defined(NO_RECURSION)
stack_node_t* r;
entry:
#endif
dp = QSE_NULL;
if (handle_non_wild_segments (g, seg) <= -1) goto oops;
if (seg->wild)
{
int dir_flags = DIR_CHAR_FLAGS;
if (g->flags & QSE_GLOB_SKIPSPCDIR) dir_flags |= QSE_DIR_SKIPSPCDIR;
dp = qse_dir_open (
g->mmgr, 0, (const qse_char_t*)STR_PTR(&g->path),
dir_flags, QSE_NULL);
if (dp)
{
tmp = STR_LEN(&g->path);
if (seg->sep && str_ccat (&g->path, seg->sep) == (qse_size_t)-1) goto oops;
tmp2 = STR_LEN(&g->path);
while (1)
{
str_setlen (&g->path, tmp2);
x = qse_dir_read (dp, &ent);
if (x <= -1)
{
if (g->flags & QSE_GLOB_TOLERANT) break;
else goto oops;
}
if (x == 0) break;
if (str_cat (&g->path, (const char_t*)ent.name) == (qse_size_t)-1) goto oops;
if (strnfnmat (STR_CPTR(&g->path,tmp2), seg->ptr, seg->len, g->fnmat_flags) > 0)
{
if (seg->next)
{
#if defined(NO_RECURSION)
if (g->free)
{
r = g->free;
g->free = r->next;
}
else
{
r = QSE_MMGR_ALLOC (g->mmgr, QSE_SIZEOF(*r));
if (r == QSE_NULL) goto oops;
}
/* push key variables that must be restored
* into the stack. */
r->tmp = tmp;
r->tmp2 = tmp2;
r->dp = dp;
r->seg = *seg;
r->next = g->stack;
g->stack = r;
/* move to the function entry point as if
* a recursive call has been made */
goto entry;
resume:
;
#else
segment_t save;
int x;
save = *seg;
x = search (g, seg);
*seg = save;
if (x <= -1) goto oops;
#endif
}
else
{
if (g->cbimpl (STR_XSTR(&g->path), g->cbctx) <= -1) goto oops;
g->expanded = 1;
}
}
}
str_setlen (&g->path, tmp);
qse_dir_close (dp); dp = QSE_NULL;
}
}
QSE_ASSERT (dp == QSE_NULL);
#if defined(NO_RECURSION)
if (g->stack)
{
/* the stack is not empty. the emulated recusive call
* must have been made. restore the variables pushed
* and jump to the resumption point */
r = g->stack;
g->stack = r->next;
tmp = r->tmp;
tmp2 = r->tmp2;
dp = r->dp;
*seg = r->seg;
/* link the stack node to the free list
* instead of freeing it here */
r->next = g->free;
g->free = r;
goto resume;
}
while (g->free)
{
/* destory the free list */
r = g->free;
g->free = r->next;
QSE_MMGR_FREE (g->mmgr, r);
}
#endif
return 0;
oops:
if (dp) qse_dir_close (dp);
#if defined(NO_RECURSION)
while (g->stack)
{
r = g->stack;
g->stack = r->next;
qse_dir_close (r->dp);
QSE_MMGR_FREE (g->mmgr, r);
}
while (g->free)
{
r = g->stack;
g->free = r->next;
QSE_MMGR_FREE (g->mmgr, r);
}
#endif
return -1;
}
int glob (const char_t* pattern, cbimpl_t cbimpl, void* cbctx, int flags, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
{
segment_t seg;
glob_t g;
int x;
QSE_MEMSET (&g, 0, QSE_SIZEOF(g));
g.cbimpl = cbimpl;
g.cbctx = cbctx;
g.mmgr = mmgr;
g.cmgr = cmgr;
g.flags = flags;
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
g.fnmat_flags |= QSE_STRFNMAT_IGNORECASE;
g.fnmat_flags |= QSE_STRFNMAT_NOESCAPE;
#else
if (flags & QSE_GLOB_IGNORECASE) g.fnmat_flags |= QSE_STRFNMAT_IGNORECASE;
if (flags & QSE_GLOB_NOESCAPE) g.fnmat_flags |= QSE_STRFNMAT_NOESCAPE;
#endif
if (flags & QSE_GLOB_PERIOD) g.fnmat_flags |= QSE_STRFNMAT_PERIOD;
if (str_init (&g.path, mmgr, 512) <= -1) return -1;
if (str_init (&g.tbuf, mmgr, 256) <= -1)
{
str_fini (&g.path);
return -1;
}
#if defined(INCLUDE_MBUF)
if (qse_mbs_init (&g.mbuf, mmgr, 512) <= -1)
{
str_fini (&g.path);
str_fini (&g.path);
return -1;
}
#endif
QSE_MEMSET (&seg, 0, QSE_SIZEOF(seg));
seg.type = NONE;
seg.ptr = pattern;
seg.len = 0;
x = search (&g, &seg);
#if defined(INCLUDE_MBUF)
qse_mbs_fini (&g.mbuf);
#endif
str_fini (&g.tbuf);
str_fini (&g.path);
if (x <= -1) return -1;
return g.expanded;
}

View File

@ -25,7 +25,7 @@
*/
#include <qse/cmn/htb.h>
#include "mem.h"
#include "mem-prv.h"
#define htb_t qse_htb_t

View File

@ -44,7 +44,7 @@
#include <qse/cmn/hton.h>
#include <qse/cmn/str.h>
#include <qse/cmn/fmt.h>
#include "mem.h"
#include "mem-prv.h"
#if 0
const qse_ip4ad_t qse_ip4ad_any =

View File

@ -25,7 +25,7 @@
*/
#include <qse/cmn/lda.h>
#include "mem.h"
#include "mem-prv.h"
#define lda_t qse_lda_t
#define slot_t qse_lda_slot_t

View File

@ -27,7 +27,7 @@
#include <qse/cmn/main.h>
#include <qse/cmn/mbwc.h>
#include "mem.h"
#include "mem-prv.h"
int qse_runmain (
int argc, qse_achar_t* argv[], qse_runmain_handler_t handler)

View File

@ -25,7 +25,7 @@
*/
#include <qse/cmn/mbwc.h>
#include "mem.h"
#include "mem-prv.h"
static int mbsn_to_wcsn_with_cmgr (
const qse_mchar_t* mbs, qse_size_t* mbslen,

View File

@ -24,8 +24,8 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _QSE_LIB_CMN_MEM_H_
#define _QSE_LIB_CMN_MEM_H_
#ifndef _QSE_LIB_CMN_MEM_PRV_H_
#define _QSE_LIB_CMN_MEM_PRV_H_
#include <qse/cmn/mem.h>

View File

@ -1,5 +1,5 @@
#include <qse/cmn/oht.h>
#include "mem.h"
#include "mem-prv.h"
#define DATA_PTR(oht,index) \
((void*)(((qse_byte_t*)(oht)->data) + ((index) * (oht)->scale)))

View File

@ -44,7 +44,7 @@
*/
#include <qse/cmn/pma.h>
#include "mem.h"
#include "mem-prv.h"
/* Returns number of bytes to add to (char *)ptr to make it
properly aligned for the type. */

View File

@ -25,7 +25,7 @@
*/
#include <qse/cmn/rbt.h>
#include "mem.h"
#include "mem-prv.h"
#define rbt_t qse_rbt_t
#define pair_t qse_rbt_pair_t

View File

@ -28,7 +28,7 @@
#include <qse/cmn/chr.h>
#include <qse/cmn/str.h>
#include <qse/cmn/lda.h>
#include "mem.h"
#include "mem-prv.h"
#define OCC_MAX QSE_TYPE_MAX(qse_size_t)

View File

@ -25,7 +25,7 @@
*/
#include <qse/cmn/sll.h>
#include "mem.h"
#include "mem-prv.h"
#define sll_t qse_sll_t
#define node_t qse_sll_node_t

View File

@ -26,7 +26,7 @@
#include <qse/cmn/slmb.h>
#include <qse/cmn/utf8.h>
#include "mem.h"
#include "mem-prv.h"
#if !defined(QSE_HAVE_CONFIG_H)
# if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)

View File

@ -26,7 +26,7 @@
#include <qse/cmn/str.h>
#include <qse/cmn/chr.h>
#include "mem.h"
#include "mem-prv.h"
/*---------------------------------------------------------------

View File

@ -25,7 +25,7 @@
*/
#include <qse/cmn/str.h>
#include "mem.h"
#include "mem-prv.h"
qse_size_t qse_mbscpy (qse_mchar_t* buf, const qse_mchar_t* str)
{

View File

@ -25,7 +25,7 @@
*/
#include <qse/cmn/str.h>
#include "mem.h"
#include "mem-prv.h"
qse_mchar_t* qse_mbsdup (const qse_mchar_t* str, qse_mmgr_t* mmgr)
{

View File

@ -26,7 +26,7 @@
#include <qse/cmn/str.h>
#include <qse/cmn/mbwc.h>
#include "mem.h"
#include "mem-prv.h"
#if !defined(QSE_HAVE_CONFIG_H)
# if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)

View File

@ -25,8 +25,8 @@
*/
#include <qse/cmn/str.h>
#include "mem.h"
#include "fmt.h"
#include "mem-prv.h"
#include "fmt-prv.h"
#include <stdarg.h>
str_t* str_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_size_t capa)

View File

@ -26,7 +26,7 @@
#include <qse/cmn/str.h>
#include <qse/cmn/mbwc.h>
#include "fmt.h"
#include "fmt-prv.h"
struct mbuf_t
{

View File

@ -26,7 +26,7 @@
#include <qse/cmn/str.h>
#include <qse/cmn/chr.h>
#include "mem.h"
#include "mem-prv.h"
qse_mchar_t* qse_mbstrmx (qse_mchar_t* str, int opt)
{

View File

@ -25,7 +25,7 @@
*/
#include <qse/cmn/time.h>
#include "mem.h"
#include "mem-prv.h"
#if defined(_WIN32)
# include <windows.h>

View File

@ -25,7 +25,7 @@
*/
#include <qse/cmn/tmr.h>
#include "mem.h"
#include "mem-prv.h"
#define HEAP_PARENT(x) (((x) - 1) / 2)
#define HEAP_LEFT(x) ((x) * 2 + 1)

View File

@ -153,7 +153,7 @@ SUBMATCH[4] = [defg]
#include <qse/cmn/chr.h>
#include <qse/cmn/str.h>
#include <qse/cmn/pma.h>
#include "mem.h"
#include "mem-prv.h"
#define tre_islower(c) QSE_ISLOWER(c)
#define tre_isupper(c) QSE_ISUPPER(c)

View File

@ -25,7 +25,7 @@
*/
#include <qse/cmn/uri.h>
#include "mem.h"
#include "mem-prv.h"
int qse_mbstouri (const qse_mchar_t* str, qse_muri_t* uri, int flags)
{

View File

@ -25,7 +25,7 @@
*/
#include <qse/cmn/xma.h>
#include "mem.h"
#include "mem-prv.h"
#define ALIGN QSE_SIZEOF(qse_size_t) /* this must be a power of 2 */
#define HDRSIZE QSE_SIZEOF(qse_xma_blk_t)