added qse_get_current_mbsdir()/qse_get_current_wcsdir().

writing qse_get_prog_path(). not yet done.
implementing the Path class
This commit is contained in:
2019-03-13 06:38:54 +00:00
parent 69d0e959da
commit 10b1eabe86
14 changed files with 622 additions and 133 deletions

View File

@ -33,6 +33,10 @@
#undef strjoinv
#undef strxjoin
#undef strxjoinv
#undef strcajoin
#undef strcajoinv
#undef strxcajoin
#undef strxcajoinv
#undef strcpy
#undef strxcpy
@ -41,6 +45,10 @@
#define strjoinv qse_mbsjoinv
#define strxjoin qse_mbsxjoin
#define strxjoinv qse_mbsxjoinv
#define strcajoin qse_mbscajoin
#define strcajoinv qse_mbscajoinv
#define strxcajoin qse_mbsxcajoin
#define strxcajoinv qse_mbsxcajoinv
#define strcpy qse_mbscpy
#define strxcpy qse_mbsxcpy
#include "str-join.h"
@ -52,6 +60,10 @@
#undef strjoinv
#undef strxjoin
#undef strxjoinv
#undef strcajoin
#undef strcajoinv
#undef strxcajoin
#undef strxcajoinv
#undef strcpy
#undef strxcpy
@ -60,6 +72,10 @@
#define strjoinv qse_wcsjoinv
#define strxjoin qse_wcsxjoin
#define strxjoinv qse_wcsxjoinv
#define strcajoin qse_wcscajoin
#define strcajoinv qse_wcscajoinv
#define strxcajoin qse_wcsxcajoin
#define strxcajoinv qse_wcsxcajoinv
#define strcpy qse_wcscpy
#define strxcpy qse_wcsxcpy
#include "str-join.h"

View File

@ -89,3 +89,70 @@ qse_size_t strjoin (char_t* buf, ...)
return n;
}
/* ------------------------------------------------------------------------- */
qse_size_t strxcajoinv (char_t* buf, qse_size_t size, va_list ap)
{
const char_t* p;
char_t* ptr;
qse_size_t left, n;
n = strlen(buf);
left = size - n;
ptr = buf + n;
while (left > 0)
{
p = va_arg (ap, const char_t*);
if (p == QSE_NULL) break;
n = strxcpy(ptr, left, p);
left -= n; ptr += n;
}
return size - left;
}
qse_size_t strxcajoin (char_t* buf, qse_size_t size, ...)
{
va_list ap;
qse_size_t n;
va_start (ap, size);
n = strxcajoinv(buf, size, ap);
va_end (ap);
return n;
}
qse_size_t strcajoinv (char_t* buf, va_list ap)
{
const char_t* p;
char_t* ptr = buf + strlen(buf);
qse_size_t n;
while (1)
{
p = va_arg(ap, const char_t*);
if (p == QSE_NULL) break;
n = strcpy(ptr, p);
ptr += n;
}
return ptr - buf;
}
qse_size_t strcajoin (char_t* buf, ...)
{
va_list ap;
qse_size_t n;
va_start (ap, buf);
n = strcajoinv(buf, ap);
va_end (ap);
return n;
}

View File

@ -505,6 +505,16 @@
# define QSE_UTIMENSAT(dirfd,path,times,flags) utimensat(dirfd,path,times,flags)
#endif
/*
the library's getcwd() returns char* while the system call returns int.
so it's not practical to define QSE_GETCWD().
#if defined(SYS_getcwd) && defined(QSE_USE_SYSCALL)
# define QSE_GETCWD(buf,size) syscall(SYS_getcwd,buf,size)
#else
# define QSE_GETCWD(buf,size) getcwd(buf,size)
#endif
*/
/* ===== DIRECTORY - not really system calls ===== */
#define QSE_OPENDIR(name) opendir(name)
#define QSE_CLOSEDIR(dir) closedir(dir)

View File

@ -20,6 +20,7 @@ libqsesi_la_SOURCES = \
fs-err.c \
fs-make.c \
fs-move.c \
fs-util.c \
glob.c \
intr.c \
log.c \
@ -50,6 +51,7 @@ if ENABLE_CXX
lib_LTLIBRARIES += libqsesixx.la
libqsesixx_la_SOURCES = \
App.cpp \
Path.cpp \
SocketAddress.cpp \
Socket.cpp \
TcpServer.cpp \

View File

@ -142,14 +142,15 @@ am_libqsesi_la_OBJECTS = libqsesi_la-cnd.lo libqsesi_la-dir.lo \
libqsesi_la-fio.lo libqsesi_la-fs.lo libqsesi_la-fs-attr.lo \
libqsesi_la-fs-copy.lo libqsesi_la-fs-delete.lo \
libqsesi_la-fs-err.lo libqsesi_la-fs-make.lo \
libqsesi_la-fs-move.lo libqsesi_la-glob.lo libqsesi_la-intr.lo \
libqsesi_la-log.lo libqsesi_la-mtx.lo libqsesi_la-mux.lo \
libqsesi_la-netlink.lo libqsesi_la-nwad.lo \
libqsesi_la-nwad-skad.lo libqsesi_la-nwif.lo \
libqsesi_la-nwif-cfg.lo libqsesi_la-nwio.lo libqsesi_la-os.lo \
libqsesi_la-pio.lo libqsesi_la-rwl.lo libqsesi_la-sck.lo \
libqsesi_la-sinfo.lo libqsesi_la-sio.lo libqsesi_la-task.lo \
libqsesi_la-thr.lo libqsesi_la-tio.lo
libqsesi_la-fs-move.lo libqsesi_la-fs-util.lo \
libqsesi_la-glob.lo libqsesi_la-intr.lo libqsesi_la-log.lo \
libqsesi_la-mtx.lo libqsesi_la-mux.lo libqsesi_la-netlink.lo \
libqsesi_la-nwad.lo libqsesi_la-nwad-skad.lo \
libqsesi_la-nwif.lo libqsesi_la-nwif-cfg.lo \
libqsesi_la-nwio.lo libqsesi_la-os.lo libqsesi_la-pio.lo \
libqsesi_la-rwl.lo libqsesi_la-sck.lo libqsesi_la-sinfo.lo \
libqsesi_la-sio.lo libqsesi_la-task.lo libqsesi_la-thr.lo \
libqsesi_la-tio.lo
libqsesi_la_OBJECTS = $(am_libqsesi_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@ -159,10 +160,11 @@ libqsesi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libqsesi_la_CFLAGS) \
$(CFLAGS) $(libqsesi_la_LDFLAGS) $(LDFLAGS) -o $@
libqsesixx_la_DEPENDENCIES =
am__libqsesixx_la_SOURCES_DIST = App.cpp SocketAddress.cpp Socket.cpp \
TcpServer.cpp Thread.cpp
@ENABLE_CXX_TRUE@am_libqsesixx_la_OBJECTS = App.lo SocketAddress.lo \
@ENABLE_CXX_TRUE@ Socket.lo TcpServer.lo Thread.lo
am__libqsesixx_la_SOURCES_DIST = App.cpp Path.cpp SocketAddress.cpp \
Socket.cpp TcpServer.cpp Thread.cpp
@ENABLE_CXX_TRUE@am_libqsesixx_la_OBJECTS = App.lo Path.lo \
@ENABLE_CXX_TRUE@ SocketAddress.lo Socket.lo TcpServer.lo \
@ENABLE_CXX_TRUE@ Thread.lo
libqsesixx_la_OBJECTS = $(am_libqsesixx_la_OBJECTS)
libqsesixx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
@ -437,6 +439,7 @@ libqsesi_la_SOURCES = \
fs-err.c \
fs-make.c \
fs-move.c \
fs-util.c \
glob.c \
intr.c \
log.c \
@ -464,6 +467,7 @@ libqsesi_la_LDFLAGS = -L../cmn -version-info 1:0:0 -no-undefined
libqsesi_la_LIBADD = -lqsecmn $(PTHREAD_LIBS) $(SSL_LIBS)
@ENABLE_CXX_TRUE@libqsesixx_la_SOURCES = \
@ENABLE_CXX_TRUE@ App.cpp \
@ENABLE_CXX_TRUE@ Path.cpp \
@ENABLE_CXX_TRUE@ SocketAddress.cpp \
@ENABLE_CXX_TRUE@ Socket.cpp \
@ENABLE_CXX_TRUE@ TcpServer.cpp \
@ -553,6 +557,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/App.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Path.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Socket.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SocketAddress.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TcpServer.Plo@am__quote@
@ -566,6 +571,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libqsesi_la-fs-err.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libqsesi_la-fs-make.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libqsesi_la-fs-move.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libqsesi_la-fs-util.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libqsesi_la-fs.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libqsesi_la-glob.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libqsesi_la-intr.Plo@am__quote@
@ -679,6 +685,13 @@ libqsesi_la-fs-move.lo: fs-move.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libqsesi_la_CFLAGS) $(CFLAGS) -c -o libqsesi_la-fs-move.lo `test -f 'fs-move.c' || echo '$(srcdir)/'`fs-move.c
libqsesi_la-fs-util.lo: fs-util.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libqsesi_la_CFLAGS) $(CFLAGS) -MT libqsesi_la-fs-util.lo -MD -MP -MF $(DEPDIR)/libqsesi_la-fs-util.Tpo -c -o libqsesi_la-fs-util.lo `test -f 'fs-util.c' || echo '$(srcdir)/'`fs-util.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libqsesi_la-fs-util.Tpo $(DEPDIR)/libqsesi_la-fs-util.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fs-util.c' object='libqsesi_la-fs-util.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libqsesi_la_CFLAGS) $(CFLAGS) -c -o libqsesi_la-fs-util.lo `test -f 'fs-util.c' || echo '$(srcdir)/'`fs-util.c
libqsesi_la-glob.lo: glob.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libqsesi_la_CFLAGS) $(CFLAGS) -MT libqsesi_la-glob.lo -MD -MP -MF $(DEPDIR)/libqsesi_la-glob.Tpo -c -o libqsesi_la-glob.lo `test -f 'glob.c' || echo '$(srcdir)/'`glob.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libqsesi_la-glob.Tpo $(DEPDIR)/libqsesi_la-glob.Plo

View File

@ -25,69 +25,109 @@
*/
#include <qse/si/Path.hpp>
#include <qse/si/fs.h>
#include <qse/cmn/str.h>
#include <qse/cmn/mbwc.h>
#include <qse/cmn/mem.h>
#include "../cmn/syscall.h"
QSE_BEGIN_NAMESPACE(QSE)
Path::Path ()
Path::Path (Mmgr* mmgr) QSE_CPP_NOEXCEPT: Mmged(mmgr)
{
this->set_to_root ();
}
Path::Path (const qse_char_t* n)
Path::Path (const qse_char_t* n, Mmgr* mmgr) QSE_CPP_NOEXCEPT: Mmged(mmgr)
{
this->setName (n);
}
Path::Path (const Path& fn)
Path::Path (const Path& path) QSE_CPP_NOEXCEPT: Mmged(path)
{
qse_strxcpy (this->full_path, QSE_COUNTOF(this->full_path), fn.this->full_path);
qse_strxcpy (this->full_path, QSE_COUNTOF(this->full_path), path.full_path);
this->set_base_name ();
}
Path& Path::operator= (const Path& fn)
Path& Path::operator= (const Path& path) QSE_CPP_NOEXCEPT
{
qse_strxcpy (this->full_path, QSE_COUNTOF(this->full_path), fn.this->full_path);
this->set_base_name ();
if (this != &path)
{
this->setMmgr (path.getMmgr());
qse_strxcpy (this->full_path, QSE_COUNTOF(this->full_path), path.full_path);
this->set_base_name ();
}
return *this;
}
bool Path::exists (const qse_char_t* path)
void Path::setName (const qse_char_t* n) QSE_CPP_NOEXCEPT
{
return ::qse_access (path, QSE_ACCESS_EXIST) == 0;
if (n == QSE_NULL || n[0] == QSE_T('\0')) this->set_to_root();
else
{
qse_strxcpy (this->full_path, QSE_COUNTOF(this->full_path), n);
this->set_base_name ();
}
}
int Path::getSize (qse_off_t* sz)
#if 0
bool Path::exists (const qse_mchar_t* path) QSE_CPP_NOEXCEPT
{
qse_stat_t buf;
if (::qse_stat (this->full_path, &buf) == -1) return -1;
*sz = buf.st_size;
#if defined(QSE_ACCESS) && defined(F_OK)
return QSE_ACCESS(path, F_OK) == 0;
#else
# error UNSUPPORTED PLATFORM
#endif
}
bool Path::exists (const qse_wchar_t* path) QSE_CPP_NOEXCEPT
{
return true;
}
int Path::getSize (const qse_mchar_t* path, qse_foff_t* sz) QSE_CPP_NOEXCEPT
{
#if defined(QSE_STAT)
/* use stat() instead of lstat() to get the information about the actual file whe the path is a symbolic link */
qse_stat_t st;
if (QSE_STAT(path, &st) == -1) return -1;
*sz = st.st_size;
return 0;
#else
# error UNSUPPORTED PLATFORM
#endif
}
bool Path::isWritable ()
int Path::getSize (const qse_wchar_t* path, qse_foff_t* sz) QSE_CPP_NOEXCEPT
{
return -1;
}
bool Path::isWritable () const QSE_CPP_NOEXCEPT
{
return ::qse_access (this->full_path, QSE_ACCESS_WRITE) == 0;
}
bool Path::isReadable ()
bool Path::isReadable () const QSE_CPP_NOEXCEPT
{
return ::qse_access (this->full_path, QSE_ACCESS_READ) == 0;
}
bool Path::isReadWritable ()
bool Path::isReadWritable () QSE_CPP_NOEXCEPT
{
return ::qse_access (this->full_path,
QSE_ACCESS_READ | QSE_ACCESS_WRITE) == 0;
return ::qse_access (this->full_path, QSE_ACCESS_READ | QSE_ACCESS_WRITE) == 0;
}
#if !defined(_WIN32)
bool Path::isExecutable ()
bool Path::isExecutable () QSE_CPP_NOEXCEPT
{
return ::qse_access (this->full_path, QSE_ACCESS_EXECUTE) == 0;
}
#endif
bool Path::isDirectory (const qse_char_t* path)
bool Path::isDir (const qse_char_t* path) QSE_CPP_NOEXCEPT
{
int n;
qse_stat_t st;
@ -101,7 +141,7 @@ bool Path::isDirectory (const qse_char_t* path)
#endif
}
bool Path::isRegular (const qse_char_t* path)
bool Path::isRegular (const qse_char_t* path) QSE_CPP_NOEXCEPT
{
int n;
qse_stat_t st;
@ -114,38 +154,77 @@ bool Path::isRegular (const qse_char_t* path)
return S_ISREG(st.st_mode);
#endif
}
#endif
int Path::chmod (qse_mode_t mode)
int Path::chmod (const qse_mchar_t* path, qse_fmode_t mode) QSE_CPP_NOEXCEPT
{
return qse_chmod (this->full_path, mode);
#if defined(QSE_CHMOD)
return QSE_CHMOD(path, mode);
#else
# error UNSUPPORTED PLATFORM
#endif
}
int Path::chmod (const qse_char_t* path, qse_mode_t mode)
int Path::chmod (const qse_wchar_t* path, qse_fmode_t mode) QSE_CPP_NOEXCEPT
{
return qse_chmod (path, mode);
#if defined(QSE_CHMOD)
qse_mchar_t* xpath = qse_wcstombsdup(path, QSE_NULL, QSE_MMGR_GETDFL());
if (!xpath) return -1;
return QSE_CHMOD(xpath, mode);
#else
# error UNSUPPORTED PLATFORM
#endif
}
int Path::unlink ()
int Path::unlink (const qse_mchar_t* path) QSE_CPP_NOEXCEPT
{
return ::qse_unlink (this->full_path);
#if defined(QSE_UNLINK)
return QSE_UNLINK(path);
#else
# error UNSUPPORTED PLATFORM
#endif
}
int Path::mkdir (qse_mode_t mode)
int Path::unlink (const qse_wchar_t* path) QSE_CPP_NOEXCEPT
{
return ::qse_mkdir(this->full_path, mode);
#if defined(QSE_UNLINK)
qse_mchar_t* xpath = qse_wcstombsdup(path, QSE_NULL, QSE_MMGR_GETDFL());
if (!xpath) return -1;
return QSE_UNLINK(xpath);
#else
# error UNSUPPORTED PLATFORM
#endif
}
int Path::mkdir (const qse_char_t* path, qse_mode_t mode)
int Path::mkdir (const qse_mchar_t* path, qse_fmode_t mode) QSE_CPP_NOEXCEPT
{
return ::qse_mkdir(path, mode);
#if defined(QSE_MKDIR)
return QSE_MKDIR(path, mode);
#else
# error UNSUPPORTED PLATFORM
#endif
}
void Path::set_base_name ()
int Path::mkdir (const qse_wchar_t* path, qse_fmode_t mode) QSE_CPP_NOEXCEPT
{
#if defined(QSE_MKDIR)
qse_mchar_t* xpath = qse_wcstombsdup(path, QSE_NULL, QSE_MMGR_GETDFL());
if (!xpath) return -1;
return QSE_MKDIR(xpath, mode);
#else
# error UNSUPPORTED PLATFORM
#endif
}
void Path::set_base_name () QSE_CPP_NOEXCEPT
{
qse_size_t len = qse_strlen(this->full_path);
QSE_ASSERT (len > 0);
for (qse_size_t i = len; i > 0; i--) {
for (qse_size_t i = len; i > 0; i--)
{
#if defined(_WIN32)
if ((this->full_path[i - 1] == QSE_T('/') || this->full_path[i - 1] == QSE_T('\\')) && i != len)
{
@ -196,7 +275,7 @@ void Path::set_base_name ()
qse_strcpy (this->base_dir, QSE_T(""));
}
void Path::set_to_root ()
void Path::set_to_root () QSE_CPP_NOEXCEPT
{
qse_strcpy (this->full_path, QSE_T("/"));
//this->set_base_name ();
@ -204,10 +283,15 @@ void Path::set_to_root ()
qse_strcpy (this->base_dir, QSE_T("/"));
}
int Path::setToSelf (const qse_char_t* argv0)
int Path::setToSelf (const qse_mchar_t* argv0) QSE_CPP_NOEXCEPT
{
return 0;
}
int Path::setToSelf (const qse_wchar_t* argv0) QSE_CPP_NOEXCEPT
{
qse_char_t p[MAX_LEN + 1];
if (qse_getpnm(argv0, p, QSE_COUNTOF(p)) == -1) return -1;
if (qse_get_prog_path(argv0, p, QSE_COUNTOF(p), this->getMmgr()) == -1) return -1;
this->setName (p);
return 0;
}

204
qse/lib/si/fs-util.c Normal file
View File

@ -0,0 +1,204 @@
/*
* $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/si/fs.h>
#include <qse/cmn/str.h>
#include <qse/cmn/path.h>
#include <qse/cmn/mem.h>
#include <qse/cmn/mbwc.h>
#include "../cmn/syscall.h"
#include <stdlib.h>
qse_mchar_t* qse_get_current_mbsdir (qse_mchar_t* buf, qse_size_t size, qse_mmgr_t* mmgr)
{
qse_mchar_t* tmp;
if (buf)
{
if (!getcwd(buf, size)) return QSE_NULL;
return buf;
}
if (!mmgr) return QSE_NULL;
size = QSE_PATH_MAX;
again:
tmp = QSE_MMGR_REALLOC(mmgr, buf, size * QSE_SIZEOF(*buf));
if (!tmp) return QSE_NULL;
buf = tmp;
if (!getcwd(buf, size))
{
/* TODO: handle ENAMETOOLONG
* or read /proc/self/cwd if available? */
if (errno == ERANGE)
{
/* grow buffer and continue */
size <<= 1;
goto again;
}
QSE_MMGR_FREE (mmgr, buf);
return QSE_NULL;
}
return buf;
}
qse_wchar_t* qse_get_current_wcsdir (qse_wchar_t* buf, qse_size_t size, qse_mmgr_t* mmgr)
{
qse_mchar_t* mbsdir;
qse_wchar_t* wcsdir;
qse_size_t wcslen;
mbsdir = qse_get_current_mbsdir(QSE_NULL, 0, mmgr);
if (!mbsdir) return QSE_NULL;
wcsdir = qse_mbstowcsdup(mbsdir, &wcslen, mmgr);
QSE_MMGR_FREE (mmgr, mbsdir);
if (!wcsdir) return QSE_NULL;
if (buf)
{
if (wcslen >= size)
{
/* cannot copy the path in full */
QSE_MMGR_FREE (mmgr, wcsdir);
return QSE_NULL;
}
qse_wcscpy (buf, wcsdir);
return buf;
}
return wcsdir;
}
/*
int qse_get_mbsfile_stat (const qse_mchar_t* file, qse_fstat_t* stat)
{
return -1;
}
int qse_get_wcsfile_stat (const qse_wchar_t* file, qse_fstat_t* stat)
{
return -1
}*/
int qse_get_prog_path (const qse_char_t* argv0, qse_char_t* buf, qse_size_t size, qse_mmgr_t* mmgr)
{
#if defined(_WIN32)
if (GetModuleFileName(QSE_NULL, buf, size) == 0) return -1;
#else
if (argv0 == QSE_NULL) return -1;
if (argv0[0] == QSE_T('/'))
{
/*qse_strxcpy (buf, size, argv0);*/
qse_canonpath(argv0, buf, size);
}
else if (qse_strchr(argv0, QSE_T('/')))
{
if (!qse_get_current_dir(buf, size, mmgr)) return -1;
qse_strxcajoin (buf, size, QSE_T("/"), argv0, QSE_NULL);
qse_canonpath (buf, buf, size);
}
else
{
qse_char_t *p, *q, * px = QSE_NULL;
qse_stat_t st;
qse_char_t dir[QSE_PATH_MAX + 1];
qse_char_t pbuf[QSE_PATH_MAX + 1];
int first = 1;
#if defined(QSE_CHAR_IS_MCHAR)
p = getenv("PATH");
if (!p) p = (qse_char_t*)QSE_T("/bin:/usr/bin");
#else
qse_mchar_t* mp = getenv ("PATH");
if (!mp) p = (qse_char_t*)QSE_T("/bin:/usr/bin");
else
{
px = qse_mbstowcsdup(mp, QSE_NULL, mmgr);
if (!px) return -1;
p = px;
}
#endif
for (;;)
{
while (*p == QSE_T(':')) p++;
if (*p == QSE_T('\0'))
{
if (first)
{
p = (qse_char_t*)QSE_T("./");
first = 0;
}
else
{
if (px) QSE_MMGR_FREE (mmgr, px);
return -1;
}
}
q = p;
while (*p != QSE_T(':') && *p != QSE_T('\0')) p++;
if (p - q >= QSE_COUNTOF(dir) - 1)
{
if (px) QSE_MMGR_FREE (mmgr, px);
return -1;
}
qse_strxncpy (dir, QSE_COUNTOF(dir), q, p - q);
qse_canonpath (dir, dir, QSE_COUNTOF(dir));
qse_strxjoin (pbuf, QSE_COUNTOF(pbuf), dir, QSE_T("/"), argv0, QSE_NULL);
if (qse_access(pbuf, QSE_ACCESS_EXECUTE) == 0 &&
qse_stat(pbuf, &st) == 0 && S_ISREG(st.st_mode))
{
break;
}
}
if (px) QSE_MMGR_FREE (mmgr, px);
if (pbuf[0] == QSE_T('/')) qse_strxcpy (buf, size, pbuf);
else
{
if (!qse_get_current_dir(buf, size, mmgr)) return -1;
qse_strxcajoin (buf, size, QSE_T("/"), pbuf, QSE_NULL);
qse_canonpath (buf, buf, size);
}
}
#endif
return 0;
}

View File

@ -614,7 +614,7 @@ qse_fs_ent_t* qse_fs_read (qse_fs_t* fs, int flags)
(flags & QSE_FS_ENT_TIME);
if (stat_needed)
{
qse_mchar_t* tmp_name[4];
const qse_mchar_t* tmp_name[4];
qse_mchar_t* mfname;
/* TODO: use a buffer in info... instead of allocating an deallocating every time */
@ -622,7 +622,7 @@ qse_fs_ent_t* qse_fs_read (qse_fs_t* fs, int flags)
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);
mfname = qse_mbsadup(tmp_name, QSE_NULL, fs->mmgr);
if (mfname == QSE_NULL)
{
fs->errnum = QSE_FS_ENOMEM;