added qse_wcsatombsdup()/qse_mbsatowcsdup()
added macro redefinition for QSE_MBLEN_MAX in some special cases fixed a bug of defining QSE_TOMUPPER and QSE_TOMLOWER wrongly changed data types of utf8 functions. fixed null-terminating bugs in qse_mbstowcs()/qse_wcstombs()
This commit is contained in:
parent
c2264998f2
commit
2faee1f23f
@ -91,8 +91,8 @@ typedef qse_ctype_t qse_wctype_t;
|
||||
#define QSE_ISMSPACE(c) (qse_ismctype(c,QSE_CTYPE_SPACE))
|
||||
#define QSE_ISMUPPER(c) (qse_ismctype(c,QSE_CTYPE_UPPER))
|
||||
#define QSE_ISMXDIGIT(c) (qse_ismctype(c,QSE_CTYPE_XDIGIT))
|
||||
#define QSE_TOMUPPER(c) (qse_ismctype(c,QSE_CTYPE_UPPER))
|
||||
#define QSE_TOMLOWER(c) (qse_ismctype(c,QSE_CTYPE_LOWER))
|
||||
#define QSE_TOMUPPER(c) (qse_tomctype(c,QSE_CTYPE_UPPER))
|
||||
#define QSE_TOMLOWER(c) (qse_tomctype(c,QSE_CTYPE_LOWER))
|
||||
|
||||
#define QSE_WCTYPE(name) (qse_getwctype(name))
|
||||
#define QSE_ISWCTYPE(c,t) (qse_iswctype(c,t))
|
||||
|
@ -34,12 +34,6 @@
|
||||
|
||||
#if defined(_WIN32) && !defined(__WATCOMC__)
|
||||
#include <tchar.h>
|
||||
|
||||
#define qse_printf _tprintf
|
||||
#define qse_vprintf _vtprintf
|
||||
#define qse_fprintf _ftprintf
|
||||
#define qse_vfprintf _vftprintf
|
||||
|
||||
#define qse_fgets(x,y,s) _fgetts(x,y,s)
|
||||
#define qse_fgetc(x) _fgettc(x)
|
||||
#define qse_fputs(x,s) _fputts(x,s)
|
||||
@ -87,12 +81,10 @@ int qse_sprintf (
|
||||
...
|
||||
);
|
||||
|
||||
#if !defined(_WIN32) || defined(__WATCOMC__)
|
||||
int qse_vfprintf (QSE_FILE *stream, const qse_char_t* fmt, va_list ap);
|
||||
int qse_vprintf (const qse_char_t* fmt, va_list ap);
|
||||
int qse_fprintf (QSE_FILE* file, const qse_char_t* fmt, ...);
|
||||
int qse_printf (const qse_char_t* fmt, ...);
|
||||
#endif
|
||||
|
||||
int qse_dprintf (const qse_char_t* fmt, ...);
|
||||
QSE_FILE* qse_fopen (const qse_char_t* path, const qse_char_t* mode);
|
||||
|
@ -2360,12 +2360,21 @@ qse_size_t qse_wcsntombsnlen (
|
||||
/**
|
||||
* The qse_wcstombs() function converts a null-terminated wide character
|
||||
* string to a multibyte string and stores it into the buffer pointed to
|
||||
* by mbs. The pointer to a variable holding the buffer length should be
|
||||
* by @a mbs. The pointer to a variable holding the buffer length should be
|
||||
* passed to the function as the third parameter. After conversion, it holds
|
||||
* the length of the multibyte string excluding the terminating-null character.
|
||||
* It may not null-terminate the resulting multibyte string if the buffer
|
||||
* is not large enough. You can check if the resulting mbslen is equal to
|
||||
* the input mbslen to know it.
|
||||
* is not large enough.
|
||||
* @code
|
||||
* const qse_wchar_t* QSE_T("hello");
|
||||
* qse_mchar_t mbs[10];
|
||||
* qse_size_t mbslen = QSE_COUNTOF(mbs);
|
||||
* n = qse_wcstombs (wcs, mbs, &mbslen);
|
||||
* if (wcs[n] == QSE_WT('\0') && mbslen < QSE_COUNTOF(mbs))
|
||||
* {
|
||||
* // wcs fully scanned and mbs null-terminated
|
||||
* }
|
||||
* @endcode
|
||||
* @return number of wide characters processed
|
||||
*/
|
||||
qse_size_t qse_wcstombs (
|
||||
@ -2428,6 +2437,11 @@ qse_mchar_t* qse_wcstombsdup (
|
||||
);
|
||||
|
||||
|
||||
qse_wchar_t* qse_mbsatombsdup (
|
||||
const qse_mchar_t* mbs[],
|
||||
qse_mmgr_t* mmgr
|
||||
);
|
||||
|
||||
qse_mchar_t* qse_wcsatombsdup (
|
||||
const qse_wchar_t* wcs[],
|
||||
qse_mmgr_t* mmgr
|
||||
|
@ -24,6 +24,14 @@
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
|
||||
#if QSE_SIZEOF_WCHAR_T == 2
|
||||
# define QSE_UTF8LEN_MAX 3
|
||||
#elif QSE_SIZEOF_WCHAR_T == 4
|
||||
# define QSE_UTF8LEN_MAX 6
|
||||
#else
|
||||
# error Unsupported wide-character size
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -35,7 +43,7 @@ extern "C" {
|
||||
* - 0 is returned if @a uc is invalid.
|
||||
* - A positive integer is returned in all other cases.
|
||||
*/
|
||||
int qse_uctoutf8len (
|
||||
qse_size_t qse_uctoutf8len (
|
||||
qse_wchar_t uc
|
||||
);
|
||||
|
||||
@ -43,22 +51,31 @@ int qse_uctoutf8len (
|
||||
* The qse_uctoutf8() function converts a unicode character to a utf8 sequence.
|
||||
* @return
|
||||
* - 0 is returned if @a uc is invalid.
|
||||
* - A negative integer is returned if the utf8 sequence buffer is not
|
||||
* large enough. It is the negated buffer size required.
|
||||
* - A positive integer is returned in all other cases.
|
||||
* - An integer greater than @a size is returned if the utf8 sequence buffer is
|
||||
* not large enough.
|
||||
* - An integer between 1 and size inclusive is returned in all other cases.
|
||||
*/
|
||||
int qse_uctoutf8 (
|
||||
qse_size_t qse_uctoutf8 (
|
||||
qse_wchar_t uc,
|
||||
qse_mchar_t* utf8,
|
||||
int size
|
||||
qse_size_t size
|
||||
);
|
||||
|
||||
int qse_utf8touc (
|
||||
qse_size_t qse_utf8touc (
|
||||
const qse_mchar_t* utf8,
|
||||
int size,
|
||||
qse_size_t size,
|
||||
qse_wchar_t* uc
|
||||
);
|
||||
|
||||
qse_size_t qse_utf8len (
|
||||
const qse_mchar_t* utf8,
|
||||
qse_size_t len
|
||||
);
|
||||
|
||||
qse_size_t qse_utf8lenmax (
|
||||
void
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -75,39 +75,6 @@
|
||||
# define QSE_PRIVATE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The #QSE_NULL macro defines a special pointer value to indicate an error or
|
||||
* that it does not point to anything.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
# if QSE_SIZEOF_VOID_P == QSE_SIZEOF_INT
|
||||
# define QSE_NULL (0)
|
||||
# elif QSE_SIZEOF_VOID_P == QSE_SIZEOF_LONG
|
||||
# define QSE_NULL (0l)
|
||||
# elif QSE_SIZEOF_VOID_P == QSE_SIZEOF_LONG_LONG
|
||||
# define QSE_NULL (0ll)
|
||||
# else
|
||||
# define QSE_NULL (0)
|
||||
# endif
|
||||
#else
|
||||
# define QSE_NULL ((void*)0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The QSE_MCHAR_EOF macro defines an EOF character.
|
||||
*/
|
||||
#define QSE_MCHAR_EOF ((qse_mcint_t)-1)
|
||||
|
||||
/**
|
||||
* The QSE_WCHAR_EOF macro defines an EOF character.
|
||||
*/
|
||||
#define QSE_WCHAR_EOF ((qse_wcint_t)-1)
|
||||
|
||||
/**
|
||||
* The QSE_CHAR_EOF macro defines an EOF character.
|
||||
*/
|
||||
#define QSE_CHAR_EOF ((qse_cint_t)-1)
|
||||
|
||||
/**
|
||||
* The QSE_SIZEOF() macro gets data size in bytes. It is equivalent to the
|
||||
* sizeof operator. The following code snippet should print sizeof(int)*128.
|
||||
@ -173,6 +140,39 @@
|
||||
#define QSE_TYPE_MIN(type) \
|
||||
((QSE_TYPE_IS_SIGNED(type)? QSE_TYPE_SIGNED_MIN(type): QSE_TYPE_UNSIGNED_MIN(type)))
|
||||
|
||||
/**
|
||||
* The #QSE_NULL macro defines a special pointer value to indicate an error or
|
||||
* that it does not point to anything.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
# if QSE_SIZEOF_VOID_P == QSE_SIZEOF_INT
|
||||
# define QSE_NULL (0)
|
||||
# elif QSE_SIZEOF_VOID_P == QSE_SIZEOF_LONG
|
||||
# define QSE_NULL (0l)
|
||||
# elif QSE_SIZEOF_VOID_P == QSE_SIZEOF_LONG_LONG
|
||||
# define QSE_NULL (0ll)
|
||||
# else
|
||||
# define QSE_NULL (0)
|
||||
# endif
|
||||
#else
|
||||
# define QSE_NULL ((void*)0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The QSE_MCHAR_EOF macro defines an EOF character.
|
||||
*/
|
||||
#define QSE_MCHAR_EOF ((qse_mcint_t)-1)
|
||||
|
||||
/**
|
||||
* The QSE_WCHAR_EOF macro defines an EOF character.
|
||||
*/
|
||||
#define QSE_WCHAR_EOF ((qse_wcint_t)-1)
|
||||
|
||||
/**
|
||||
* The QSE_CHAR_EOF macro defines an EOF character.
|
||||
*/
|
||||
#define QSE_CHAR_EOF ((qse_cint_t)-1)
|
||||
|
||||
/**
|
||||
* The QSE_BLOCK macro encloses one or more statements in a block with
|
||||
* no side-effect.
|
||||
|
@ -802,4 +802,17 @@ union qse_ubi_t
|
||||
};
|
||||
typedef union qse_ubi_t qse_ubi_t;
|
||||
|
||||
/*
|
||||
* Note QSE_MBLEN_MAX was set to 2 when autoconf ran for _WIN32
|
||||
* with mingw32. This is bad since it can't handle UTF-8. Here are
|
||||
* some redefinitions. (_WIN64 with mingw64 gave me 5 though).
|
||||
*/
|
||||
#if (QSE_SIZEOF_WCHAR_T == 2) && (QSE_MBLEN_MAX < 3)
|
||||
# undef QSE_MBLEN_MAX
|
||||
# define QSE_MBLEN_MAX 3
|
||||
#elif (QSE_SIZEOF_WCHAR_T == 4) && (QSE_MBLEN_MAX < 6)
|
||||
# undef QSE_MBLEN_MAX
|
||||
# define QSE_MBLEN_MAX 6
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include <qse/cmn/chr.h>
|
||||
#include <qse/cmn/utf8.h>
|
||||
#include "mem.h"
|
||||
|
||||
#if !defined(QSE_HAVE_CONFIG_H)
|
||||
@ -41,7 +42,11 @@
|
||||
qse_size_t qse_mbrlen (
|
||||
const qse_mchar_t* mb, qse_size_t mbl, qse_mbstate_t* state)
|
||||
{
|
||||
#ifdef HAVE_MBRLEN
|
||||
#if defined(_WIN32)
|
||||
/* TODO: provide an option to use windows api */
|
||||
return qse_utf8len (mb, mbl);
|
||||
|
||||
#elif defined(HAVE_MBRLEN)
|
||||
size_t n;
|
||||
|
||||
n = mbrlen (mb, mbl, (mbstate_t*)state);
|
||||
@ -67,7 +72,17 @@ qse_size_t qse_mbrtowc (
|
||||
const qse_mchar_t* mb, qse_size_t mbl,
|
||||
qse_wchar_t* wc, qse_mbstate_t* state)
|
||||
{
|
||||
#ifdef HAVE_MBRTOWC
|
||||
#if defined(_WIN32)
|
||||
/*
|
||||
int n;
|
||||
|
||||
n = MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS, mb, mbl, wc, 1);
|
||||
if (n == 0) return 0;
|
||||
return mbl;
|
||||
*/
|
||||
return qse_utf8touc (mb, mbl, wc);
|
||||
|
||||
#elif defined(HAVE_MBRTOWC)
|
||||
size_t n;
|
||||
|
||||
n = mbrtowc (wc, mb, mbl, (mbstate_t*)state);
|
||||
@ -89,7 +104,10 @@ qse_size_t qse_wcrtomb (
|
||||
qse_wchar_t wc, qse_mchar_t* mb,
|
||||
qse_size_t mbl, qse_mbstate_t* state)
|
||||
{
|
||||
#ifdef HAVE_WCRTOMB
|
||||
#if defined(_WIN32)
|
||||
return qse_uctoutf8 (wc, mb, mbl);
|
||||
|
||||
#elif defined(HAVE_WCRTOMB)
|
||||
size_t n;
|
||||
|
||||
if (mbl < QSE_MBLEN_MAX)
|
||||
@ -113,7 +131,7 @@ qse_size_t qse_wcrtomb (
|
||||
if (n == (size_t)-1) return 0; /* illegal character */
|
||||
}
|
||||
|
||||
return n;
|
||||
return n; /* number of bytes written to the buffer */
|
||||
#else
|
||||
#error #### NOT SUPPORTED ####
|
||||
#endif
|
||||
@ -147,5 +165,6 @@ qse_size_t qse_wctomb (qse_wchar_t wc, qse_mchar_t* mb, qse_size_t mbl)
|
||||
|
||||
int qse_mbcurmax (void)
|
||||
{
|
||||
return MB_CUR_MAX;
|
||||
/* TODO: consider other encodings */
|
||||
return (QSE_UTF8LEN_MAX > MB_CUR_MAX)? QSE_UTF8LEN_MAX: MB_CUR_MAX;
|
||||
}
|
||||
|
@ -42,14 +42,15 @@ struct fop_t
|
||||
{
|
||||
int flags;
|
||||
|
||||
qse_lstat_t old_stat;
|
||||
qse_lstat_t new_stat;
|
||||
|
||||
#if defined(_WIN32)
|
||||
qse_wchar_t* old_path;
|
||||
qse_wchar_t* new_path;
|
||||
qse_wchar_t* new_path2;
|
||||
#else
|
||||
qse_lstat_t old_stat;
|
||||
qse_lstat_t new_stat;
|
||||
|
||||
qse_mchar_t* old_path;
|
||||
qse_mchar_t* new_path;
|
||||
qse_mchar_t* new_path2;
|
||||
@ -178,7 +179,7 @@ int qse_fs_move (
|
||||
fs->errnum = QSE_FS_ENOMEM;
|
||||
goto oops;
|
||||
}
|
||||
qse_printf (QSE_T("new_path2 => [%S]\n"), fop.new_path2);
|
||||
qse_printf (QSE_T("new_path2 => [%hs]\n"), fop.new_path2);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -365,7 +365,8 @@ int qse_sio_seek (qse_sio_t* sio, qse_sio_seek_t pos)
|
||||
}
|
||||
#endif
|
||||
|
||||
static qse_ssize_t __sio_input (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size)
|
||||
static qse_ssize_t __sio_input (
|
||||
qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size)
|
||||
{
|
||||
qse_sio_t* sio = (qse_sio_t*)arg;
|
||||
|
||||
@ -394,7 +395,8 @@ static qse_ssize_t __sio_input (qse_tio_cmd_t cmd, void* arg, void* buf, qse_siz
|
||||
return 0;
|
||||
}
|
||||
|
||||
static qse_ssize_t __sio_output (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size)
|
||||
static qse_ssize_t __sio_output (
|
||||
qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size)
|
||||
{
|
||||
qse_sio_t* sio = (qse_sio_t*)arg;
|
||||
|
||||
|
@ -20,48 +20,17 @@
|
||||
|
||||
#include <qse/cmn/stdio.h>
|
||||
#include <qse/cmn/chr.h>
|
||||
#include <qse/cmn/str.h>
|
||||
#include "mem.h"
|
||||
|
||||
#include <wchar.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 2048
|
||||
# define PATH_MAX 2048
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(__WATCOMC__)
|
||||
|
||||
int qse_vsprintf (qse_char_t* buf, qse_size_t size, const qse_char_t* fmt, va_list ap)
|
||||
{
|
||||
int n;
|
||||
|
||||
#ifdef QSE_CHAR_IS_MCHAR
|
||||
n = _vsnprintf (buf, size, fmt, ap);
|
||||
#else
|
||||
n = _vsnwprintf (buf, size, fmt, ap);
|
||||
#endif
|
||||
if (n < 0 || (size_t)n >= size)
|
||||
{
|
||||
if (size > 0) buf[size-1] = QSE_T('\0');
|
||||
n = -1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int qse_sprintf (qse_char_t* buf, qse_size_t size, const qse_char_t* fmt, ...)
|
||||
{
|
||||
int n;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
n = qse_vsprintf (buf, size, fmt, ap);
|
||||
va_end (ap);
|
||||
return n;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static qse_char_t* __adjust_format (const qse_char_t* format);
|
||||
|
||||
int qse_vfprintf (QSE_FILE *stream, const qse_char_t* fmt, va_list ap)
|
||||
@ -70,12 +39,12 @@ int qse_vfprintf (QSE_FILE *stream, const qse_char_t* fmt, va_list ap)
|
||||
qse_char_t* nf = __adjust_format (fmt);
|
||||
if (nf == NULL) return -1;
|
||||
|
||||
#ifdef QSE_CHAR_IS_MCHAR
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
n = vfprintf (stream, nf, ap);
|
||||
#else
|
||||
#else
|
||||
n = vfwprintf (stream, nf, ap);
|
||||
#endif
|
||||
free (nf);
|
||||
#endif
|
||||
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), nf);
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -112,20 +81,27 @@ int qse_vsprintf (qse_char_t* buf, qse_size_t size, const qse_char_t* fmt, va_li
|
||||
qse_char_t* nf = __adjust_format (fmt);
|
||||
if (nf == NULL) return -1;
|
||||
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
n = vsnprintf (buf, size, nf, ap);
|
||||
#elif defined(_WIN32) && !defined(__WATCOMC__)
|
||||
n = _vsnwprintf (buf, size, nf, ap);
|
||||
#else
|
||||
n = vswprintf (buf, size, nf, ap);
|
||||
#endif
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
#if defined(_WIN32) && !defined(__WATCOMC__)
|
||||
n = _vsnprintf (buf, size, nf, ap);
|
||||
#else
|
||||
n = vsnprintf (buf, size, nf, ap);
|
||||
#endif
|
||||
#else
|
||||
#if defined(_WIN32) && !defined(__WATCOMC__)
|
||||
n = _vsnwprintf (buf, size, nf, ap);
|
||||
#else
|
||||
n = vswprintf (buf, size, nf, ap);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (n < 0 || (size_t)n >= size)
|
||||
{
|
||||
if (size > 0) buf[size-1] = QSE_T('\0');
|
||||
n = -1;
|
||||
}
|
||||
|
||||
free (nf);
|
||||
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), nf);
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -149,11 +125,12 @@ int qse_sprintf (qse_char_t* buf, qse_size_t size, const qse_char_t* fmt, ...)
|
||||
if (buf.len >= buf.cap) \
|
||||
{ \
|
||||
qse_char_t* tmp; \
|
||||
tmp = (qse_char_t*)realloc ( \
|
||||
buf.ptr, sizeof(qse_char_t)*(buf.cap+256+1)); \
|
||||
tmp = (qse_char_t*) QSE_MMGR_REALLOC ( \
|
||||
QSE_MMGR_GETDFL(), buf.ptr, \
|
||||
QSE_SIZEOF(qse_char_t) * (buf.cap+256+1)); \
|
||||
if (tmp == NULL) \
|
||||
{ \
|
||||
free (buf.ptr); \
|
||||
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), buf.ptr); \
|
||||
return NULL; \
|
||||
} \
|
||||
buf.ptr = tmp; \
|
||||
@ -177,11 +154,9 @@ static qse_char_t* __adjust_format (const qse_char_t* format)
|
||||
|
||||
buf.len = 0;
|
||||
buf.cap = 256;
|
||||
#if (defined(vms) || defined(__vms)) && (QSE_SIZEOF_VOID_P >= 8)
|
||||
buf.ptr = (qse_char_t*) _malloc32 (sizeof(qse_char_t)*(buf.cap+1));
|
||||
#else
|
||||
buf.ptr = (qse_char_t*) malloc (sizeof(qse_char_t)*(buf.cap+1));
|
||||
#endif
|
||||
|
||||
buf.ptr = (qse_char_t*) QSE_MMGR_ALLOC (
|
||||
QSE_MMGR_GETDFL(), QSE_SIZEOF(qse_char_t) * (buf.cap+1));
|
||||
if (buf.ptr == NULL) return NULL;
|
||||
|
||||
while (*fp != QSE_T('\0'))
|
||||
@ -267,70 +242,136 @@ static qse_char_t* __adjust_format (const qse_char_t* format)
|
||||
ch = *fp++;
|
||||
}
|
||||
|
||||
|
||||
/* type */
|
||||
if (ch == QSE_T('%')) ADDC (buf, ch);
|
||||
else if (ch == QSE_T('c') || ch == QSE_T('s'))
|
||||
switch (ch)
|
||||
{
|
||||
#if !defined(QSE_CHAR_IS_MCHAR) && !defined(_WIN32)
|
||||
ADDC (buf, 'l');
|
||||
#endif
|
||||
ADDC (buf, ch);
|
||||
}
|
||||
else if (ch == QSE_T('C') || ch == QSE_T('S'))
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__WATCOMC__)
|
||||
ADDC (buf, ch);
|
||||
#else
|
||||
#ifdef QSE_CHAR_IS_MCHAR
|
||||
ADDC (buf, 'l');
|
||||
#endif
|
||||
ADDC (buf, QSE_TOLOWER(ch));
|
||||
#endif
|
||||
}
|
||||
else if (ch == QSE_T('d') || ch == QSE_T('i') ||
|
||||
ch == QSE_T('o') || ch == QSE_T('u') ||
|
||||
ch == QSE_T('x') || ch == QSE_T('X'))
|
||||
{
|
||||
if (modifier == MOD_SHORT)
|
||||
case QSE_T('\0'):
|
||||
goto done;
|
||||
|
||||
case QSE_T('%'):
|
||||
{
|
||||
ADDC (buf, 'h');
|
||||
ADDC (buf, ch);
|
||||
break;
|
||||
}
|
||||
else if (modifier == MOD_LONG)
|
||||
|
||||
case QSE_T('c'):
|
||||
case QSE_T('s'):
|
||||
{
|
||||
ADDC (buf, 'l');
|
||||
if (modifier == MOD_SHORT)
|
||||
{
|
||||
/* always multibyte */
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
goto mchar_multi;
|
||||
#else
|
||||
ch = QSE_TOUPPER(ch);
|
||||
goto wchar_multi;
|
||||
#endif
|
||||
}
|
||||
else if (modifier == MOD_LONG)
|
||||
{
|
||||
/* always wide-character */
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
ch = QSE_TOUPPER(ch);
|
||||
goto mchar_wide;
|
||||
#else
|
||||
goto wchar_wide;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
mchar_multi:
|
||||
#if defined(_WIN32) && !defined(__WATCOMC__)
|
||||
ADDC (buf, ch);
|
||||
#else
|
||||
ADDC (buf, ch);
|
||||
#endif
|
||||
#else
|
||||
wchar_wide:
|
||||
#if defined(_WIN32) && !defined(__WATCOMC__)
|
||||
ADDC (buf, ch);
|
||||
#else
|
||||
ADDC (buf, QSE_WT('l'));
|
||||
ADDC (buf, ch);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (modifier == MOD_LONGLONG)
|
||||
|
||||
case QSE_T('C'):
|
||||
case QSE_T('S'):
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__LCC__)
|
||||
ADDC (buf, 'I');
|
||||
ADDC (buf, '6');
|
||||
ADDC (buf, '4');
|
||||
#else
|
||||
ADDC (buf, 'l');
|
||||
ADDC (buf, 'l');
|
||||
#endif
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
mchar_wide:
|
||||
#if defined(_WIN32) && !defined(__WATCOMC__)
|
||||
ADDC (buf, ch);
|
||||
#else
|
||||
ADDC (buf, QSE_MT('l'));
|
||||
ADDC (buf, QSE_TOLOWER(ch));
|
||||
#endif
|
||||
#else
|
||||
wchar_multi:
|
||||
#if defined(_WIN32) && !defined(__WATCOMC__)
|
||||
ADDC (buf, ch);
|
||||
#else
|
||||
ADDC (buf, QSE_TOLOWER(ch));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_T('d'):
|
||||
case QSE_T('i'):
|
||||
case QSE_T('o'):
|
||||
case QSE_T('u'):
|
||||
case QSE_T('x'):
|
||||
case QSE_T('X'):
|
||||
{
|
||||
if (modifier == MOD_SHORT)
|
||||
{
|
||||
ADDC (buf, 'h');
|
||||
}
|
||||
else if (modifier == MOD_LONG)
|
||||
{
|
||||
ADDC (buf, 'l');
|
||||
}
|
||||
else if (modifier == MOD_LONGLONG)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__LCC__)
|
||||
ADDC (buf, 'I');
|
||||
ADDC (buf, '6');
|
||||
ADDC (buf, '4');
|
||||
#else
|
||||
ADDC (buf, 'l');
|
||||
ADDC (buf, 'l');
|
||||
#endif
|
||||
}
|
||||
ADDC (buf, ch);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
ADDC (buf, ch);
|
||||
break;
|
||||
}
|
||||
ADDC (buf, ch);
|
||||
}
|
||||
else if (ch == QSE_T('\0')) break;
|
||||
else ADDC (buf, ch);
|
||||
}
|
||||
|
||||
done:
|
||||
buf.ptr[buf.len] = QSE_T('\0');
|
||||
|
||||
return buf.ptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int qse_dprintf (const qse_char_t* fmt, ...)
|
||||
{
|
||||
int n;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
n = qse_vfprintf (stderr, fmt, ap);
|
||||
n = qse_vfprintf (QSE_STDERR, fmt, ap);
|
||||
va_end (ap);
|
||||
return n;
|
||||
}
|
||||
@ -343,19 +384,23 @@ QSE_FILE* qse_fopen (const qse_char_t* path, const qse_char_t* mode)
|
||||
return _wfopen (path, mode);
|
||||
#else
|
||||
|
||||
char path_mb[PATH_MAX + 1];
|
||||
char mode_mb[32];
|
||||
size_t n;
|
||||
QSE_FILE* fp = QSE_NULL;
|
||||
qse_mchar_t* path_mb;
|
||||
qse_mchar_t* mode_mb;
|
||||
|
||||
n = wcstombs (path_mb, path, QSE_COUNTOF(path_mb));
|
||||
if (n == (size_t)-1) return NULL;
|
||||
if (n == QSE_COUNTOF(path_mb)) path_mb[QSE_COUNTOF(path_mb)-1] = '\0';
|
||||
path_mb = qse_wcstombsdup (path, QSE_MMGR_GETDFL());
|
||||
mode_mb = qse_wcstombsdup (mode, QSE_MMGR_GETDFL());
|
||||
|
||||
n = wcstombs (mode_mb, mode, QSE_COUNTOF(mode_mb));
|
||||
if (n == (size_t)-1) return NULL;
|
||||
if (n == QSE_COUNTOF(mode_mb)) path_mb[QSE_COUNTOF(mode_mb)-1] = '\0';
|
||||
if (path_mb && mode_mb)
|
||||
{
|
||||
fp = fopen (path_mb, mode_mb);
|
||||
}
|
||||
|
||||
if (mode_mb) QSE_MMGR_FREE (QSE_MMGR_GETDFL(), mode_mb);
|
||||
if (path_mb) QSE_MMGR_FREE (QSE_MMGR_GETDFL(), path_mb);
|
||||
|
||||
return fp;
|
||||
|
||||
return fopen (path_mb, mode_mb);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -378,19 +423,36 @@ QSE_FILE* qse_popen (const qse_char_t* cmd, const qse_char_t* mode)
|
||||
return QSE_NULL;
|
||||
|
||||
#else
|
||||
char cmd_mb[PATH_MAX + 1];
|
||||
char mode_mb[32];
|
||||
size_t n;
|
||||
|
||||
n = wcstombs (cmd_mb, cmd, QSE_COUNTOF(cmd_mb));
|
||||
if (n == (size_t)-1) return NULL;
|
||||
if (n == QSE_COUNTOF(cmd_mb)) cmd_mb[QSE_COUNTOF(cmd_mb)-1] = '\0';
|
||||
QSE_FILE* fp = QSE_NULL;
|
||||
qse_mchar_t* cmd_mb;
|
||||
|
||||
n = wcstombs (mode_mb, mode, QSE_COUNTOF(mode_mb));
|
||||
if (n == (size_t)-1) return NULL;
|
||||
if (n == QSE_COUNTOF(mode_mb)) cmd_mb[QSE_COUNTOF(mode_mb)-1] = '\0';
|
||||
cmd_mb = qse_wcstombsdup (cmd, QSE_MMGR_GETDFL());
|
||||
if (cmd_mb)
|
||||
{
|
||||
char mode_mb[3];
|
||||
int mode_mb_len;
|
||||
int mode_flag = 0;
|
||||
|
||||
fp = popen (cmd_mb, mode_mb);
|
||||
|
||||
while (*mode)
|
||||
{
|
||||
if (*mode == QSE_T('r')) mode_flag |= 1;
|
||||
else if (*mode == QSE_T('w')) mode_flag |= 2;
|
||||
mode++;
|
||||
}
|
||||
|
||||
mode_mb_len = 0;
|
||||
if (mode_flag & 1) mode_mb[mode_mb_len++] = QSE_MT('r');
|
||||
if (mode_flag & 2) mode_mb[mode_mb_len++] = QSE_MT('w');
|
||||
mode_mb[mode_mb_len++] = QSE_MT('\0');
|
||||
|
||||
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), cmd_mb);
|
||||
}
|
||||
|
||||
return fp;
|
||||
|
||||
return popen (cmd_mb, mode_mb);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -423,11 +485,8 @@ qse_ssize_t qse_getdelim (
|
||||
if (b == QSE_NULL)
|
||||
{
|
||||
capa = 256;
|
||||
#if (defined(vms) || defined(__vms)) && (QSE_SIZEOF_VOID_P >= 8)
|
||||
b = (qse_char_t*) _malloc32 (sizeof(qse_char_t)*(capa+1));
|
||||
#else
|
||||
b = (qse_char_t*) malloc (sizeof(qse_char_t)*(capa+1));
|
||||
#endif
|
||||
b = (qse_char_t*) QSE_MMGR_ALLOC (
|
||||
QSE_MMGR_GETDFL(), QSE_SIZEOF(qse_char_t)*(capa+1));
|
||||
if (b == QSE_NULL) return -2;
|
||||
}
|
||||
|
||||
@ -461,7 +520,8 @@ qse_ssize_t qse_getdelim (
|
||||
qse_size_t ncapa = capa + 256;
|
||||
qse_char_t* nb;
|
||||
|
||||
nb = realloc (b, ncapa*sizeof(qse_char_t));
|
||||
nb = QSE_MMGR_REALLOC (
|
||||
QSE_MMGR_GETDFL(), b, ncapa * QSE_SIZEOF(qse_char_t));
|
||||
if (nb == QSE_NULL)
|
||||
{
|
||||
len = (qse_size_t)-2;
|
||||
|
@ -138,7 +138,6 @@ qse_ulong_t qse_strxtoulong (const qse_char_t* str, qse_size_t len)
|
||||
/*
|
||||
* TODO: fix wrong mbstate handling
|
||||
*/
|
||||
|
||||
qse_size_t qse_mbstowcslen (const qse_mchar_t* mcs, qse_size_t* wcslen)
|
||||
{
|
||||
qse_wchar_t wc;
|
||||
@ -206,10 +205,9 @@ qse_size_t qse_mbstowcs (
|
||||
}
|
||||
|
||||
/* if null-terminated properly, the input wcslen must be less than
|
||||
* the output wcslen. (input length includs the terminating null
|
||||
* the output wcslen. (input length includes the terminating null
|
||||
* while the output length excludes the terminating null) */
|
||||
*wcslen = wlen;
|
||||
|
||||
return mlen;
|
||||
}
|
||||
|
||||
@ -243,7 +241,7 @@ qse_size_t qse_mbsntowcsn (
|
||||
qse_size_t qse_wcstombslen (const qse_wchar_t* wcs, qse_size_t* mbslen)
|
||||
{
|
||||
const qse_wchar_t* p = wcs;
|
||||
qse_mchar_t mbs[32];
|
||||
qse_mchar_t mbs[QSE_MBLEN_MAX];
|
||||
qse_size_t mlen = 0;
|
||||
qse_mbstate_t state = {{ 0, }};
|
||||
|
||||
@ -273,7 +271,7 @@ qse_size_t qse_wcsntombsnlen (
|
||||
{
|
||||
const qse_wchar_t* p = wcs;
|
||||
const qse_wchar_t* end = wcs + wcslen;
|
||||
qse_mchar_t mbs[32];
|
||||
qse_mchar_t mbs[QSE_MBLEN_MAX];
|
||||
qse_size_t mlen = 0;
|
||||
qse_mbstate_t state = {{ 0, }};
|
||||
|
||||
@ -288,7 +286,8 @@ qse_size_t qse_wcsntombsnlen (
|
||||
p++; mlen += n;
|
||||
}
|
||||
|
||||
/* this length excludes the terminating null character. */
|
||||
/* this length excludes the terminating null character.
|
||||
* this function doesn't event null-terminate the result. */
|
||||
*mbslen = mlen;
|
||||
|
||||
/* returns the number of characters handled.
|
||||
@ -304,7 +303,7 @@ qse_size_t qse_wcstombs (
|
||||
qse_size_t rem = *mbslen;
|
||||
qse_mbstate_t state = {{ 0, }};
|
||||
|
||||
while (*p != QSE_WT('\0') && rem > 1)
|
||||
while (*p != QSE_WT('\0') && rem > 0)
|
||||
{
|
||||
qse_size_t n = qse_wcrtomb (*p, mbs, rem, &state);
|
||||
if (n == 0 || n > rem)
|
||||
@ -313,14 +312,6 @@ qse_size_t qse_wcstombs (
|
||||
break;
|
||||
}
|
||||
|
||||
if (rem == n)
|
||||
{
|
||||
/* the buffer is full without the space for a
|
||||
* terminating null. should stop processing further
|
||||
* excluding this last character emitted. */
|
||||
break;
|
||||
}
|
||||
|
||||
mbs += n; rem -= n; p++;
|
||||
}
|
||||
|
||||
@ -371,16 +362,16 @@ int qse_mbstowcsrigid (
|
||||
qse_size_t wn = wcslen;
|
||||
|
||||
n = qse_mbstowcs (mbs, wcs, &wn);
|
||||
if (mbs[n] != QSE_MT('\0'))
|
||||
{
|
||||
/* incomplete sequence or invalid sequence */
|
||||
return -1;
|
||||
}
|
||||
if (wn >= wcslen)
|
||||
{
|
||||
/* wcs not big enough to be null-terminated.
|
||||
* if it has been null-terminated properly,
|
||||
* wn should be less than wcslen. */
|
||||
return -1;
|
||||
}
|
||||
if (mbs[n] != QSE_MT('\0'))
|
||||
{
|
||||
/* incomplete sequence or invalid sequence */
|
||||
return -2;
|
||||
}
|
||||
|
||||
@ -395,19 +386,19 @@ int qse_wcstombsrigid (
|
||||
qse_size_t mn = mbslen;
|
||||
|
||||
n = qse_wcstombs (wcs, mbs, &mn);
|
||||
if (mn >= mbslen)
|
||||
{
|
||||
/* mbs not big enough to be null-terminated.
|
||||
* if it has been null-terminated properly,
|
||||
* mn should be less than mbslen. */
|
||||
return -1;
|
||||
}
|
||||
if (wcs[n] != QSE_WT('\0'))
|
||||
{
|
||||
/* if qse_wcstombs() processed all wide characters,
|
||||
* the character at position 'n' should be a null character
|
||||
* as 'n' is the number of wide characters processed. */
|
||||
return -2;
|
||||
return -1;
|
||||
}
|
||||
if (mn >= mbslen)
|
||||
{
|
||||
/* mbs not big enough to be null-terminated.
|
||||
* if it has been null-terminated properly,
|
||||
* mn should be less than mbslen. */
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -447,6 +438,37 @@ qse_mchar_t* qse_wcstombsdup (const qse_wchar_t* wcs, qse_mmgr_t* mmgr)
|
||||
return mbs;
|
||||
}
|
||||
|
||||
qse_wchar_t* qse_mbsatowcsdup (const qse_mchar_t* mbs[], qse_mmgr_t* mmgr)
|
||||
{
|
||||
qse_wchar_t* buf, * ptr;
|
||||
qse_size_t i;
|
||||
qse_size_t capa = 0;
|
||||
qse_size_t wl, ml;
|
||||
|
||||
QSE_ASSERT (mmgr != QSE_NULL);
|
||||
|
||||
for (i = 0; mbs[i]; i++)
|
||||
{
|
||||
ml = qse_mbstowcslen(mbs[i], &wl);
|
||||
if (mbs[i][ml] != QSE_MT('\0')) return QSE_NULL;
|
||||
capa += wl;
|
||||
}
|
||||
|
||||
buf = (qse_wchar_t*) QSE_MMGR_ALLOC (
|
||||
mmgr, (capa + 1) * QSE_SIZEOF(*buf));
|
||||
if (buf == QSE_NULL) return QSE_NULL;
|
||||
|
||||
ptr = buf;
|
||||
for (i = 0; mbs[i]; i++)
|
||||
{
|
||||
wl = capa + 1;
|
||||
ml = qse_mbstowcs (mbs[i], ptr, &wl);
|
||||
ptr += wl;
|
||||
capa -= wl;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
qse_mchar_t* qse_wcsatombsdup (const qse_wchar_t* wcs[], qse_mmgr_t* mmgr)
|
||||
{
|
||||
@ -464,7 +486,8 @@ qse_mchar_t* qse_wcsatombsdup (const qse_wchar_t* wcs[], qse_mmgr_t* mmgr)
|
||||
capa += ml;
|
||||
}
|
||||
|
||||
buf = (qse_mchar_t*) QSE_MMGR_ALLOC (mmgr, (capa+1)*QSE_SIZEOF(*buf));
|
||||
buf = (qse_mchar_t*) QSE_MMGR_ALLOC (
|
||||
mmgr, (capa + 1) * QSE_SIZEOF(*buf));
|
||||
if (buf == QSE_NULL) return QSE_NULL;
|
||||
|
||||
ptr = buf;
|
||||
|
@ -67,6 +67,7 @@ static qse_ssize_t tio_putc (qse_tio_t* tio, qse_char_t c, int* flush_needed)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
tio->outbuf[tio->outbuf_len++] = mc[i];
|
||||
|
@ -38,6 +38,7 @@ struct __utf8_t
|
||||
qse_uint32_t upper;
|
||||
qse_uint8_t fbyte; /* mask to the first utf8 byte */
|
||||
qse_uint8_t mask;
|
||||
qse_uint8_t fmask;
|
||||
int length; /* number of bytes */
|
||||
};
|
||||
|
||||
@ -45,12 +46,12 @@ typedef struct __utf8_t __utf8_t;
|
||||
|
||||
static __utf8_t utf8_table[] =
|
||||
{
|
||||
{0x00000000ul, 0x0000007Ful, 0x00, 0x80, 1},
|
||||
{0x00000080ul, 0x000007FFul, 0xC0, 0xE0, 2},
|
||||
{0x00000800ul, 0x0000FFFFul, 0xE0, 0xF0, 3},
|
||||
{0x00010000ul, 0x001FFFFFul, 0xF0, 0xF8, 4},
|
||||
{0x00200000ul, 0x03FFFFFFul, 0xF8, 0xFC, 5},
|
||||
{0x04000000ul, 0x7FFFFFFFul, 0xFC, 0xFE, 6}
|
||||
{0x00000000ul, 0x0000007Ful, 0x00, 0x80, 0x7F, 1},
|
||||
{0x00000080ul, 0x000007FFul, 0xC0, 0xE0, 0x1F, 2},
|
||||
{0x00000800ul, 0x0000FFFFul, 0xE0, 0xF0, 0x0F, 3},
|
||||
{0x00010000ul, 0x001FFFFFul, 0xF0, 0xF8, 0x07, 4},
|
||||
{0x00200000ul, 0x03FFFFFFul, 0xF8, 0xFC, 0x03, 5},
|
||||
{0x04000000ul, 0x7FFFFFFFul, 0xFC, 0xFE, 0x01, 6}
|
||||
};
|
||||
|
||||
static QSE_INLINE __utf8_t* get_utf8_slot (qse_wchar_t uc)
|
||||
@ -72,23 +73,25 @@ static QSE_INLINE __utf8_t* get_utf8_slot (qse_wchar_t uc)
|
||||
return QSE_NULL; /* invalid character */
|
||||
}
|
||||
|
||||
int qse_uctoutf8len (qse_wchar_t uc)
|
||||
qse_size_t qse_uctoutf8len (qse_wchar_t uc)
|
||||
{
|
||||
__utf8_t* cur = get_utf8_slot (uc);
|
||||
return (cur == QSE_NULL)? 0: cur->length;
|
||||
return (cur == QSE_NULL)? 0: (qse_size_t)cur->length;
|
||||
}
|
||||
|
||||
int qse_uctoutf8 (qse_wchar_t uc, qse_mchar_t* utf8, int size)
|
||||
/* wctomb for utf8/unicode */
|
||||
qse_size_t qse_uctoutf8 (qse_wchar_t uc, qse_mchar_t* utf8, qse_size_t size)
|
||||
{
|
||||
__utf8_t* cur = get_utf8_slot (uc);
|
||||
int index;
|
||||
|
||||
if (cur == QSE_NULL) return 0; /* invalid character */
|
||||
if (cur == QSE_NULL) return 0; /* illegal character */
|
||||
|
||||
if (cur->length > size)
|
||||
{
|
||||
/* buffer not big enough. index indicates the buffer size needed */
|
||||
return -index;
|
||||
/* buffer not big enough. index indicates the buffer
|
||||
* size needed */
|
||||
return size + 1;
|
||||
}
|
||||
|
||||
index = cur->length;
|
||||
@ -103,16 +106,18 @@ int qse_uctoutf8 (qse_wchar_t uc, qse_mchar_t* utf8, int size)
|
||||
}
|
||||
|
||||
utf8[0] = uc | cur->fbyte;
|
||||
return cur->length;
|
||||
return (qse_size_t)cur->length;
|
||||
}
|
||||
|
||||
int qse_utf8touc (
|
||||
const qse_mchar_t* utf8, int size, qse_wchar_t* uc)
|
||||
/* mbtowc for utf8/unicode */
|
||||
qse_size_t qse_utf8touc (
|
||||
const qse_mchar_t* utf8, qse_size_t size, qse_wchar_t* uc)
|
||||
{
|
||||
__utf8_t* cur, * end;
|
||||
#if 0
|
||||
qse_mchar_t c, t;
|
||||
qse_wchar_t w;
|
||||
int count = 0;
|
||||
#endif
|
||||
|
||||
QSE_ASSERT (utf8 != QSE_NULL);
|
||||
QSE_ASSERT (QSE_SIZEOF(qse_mchar_t) == 1);
|
||||
@ -120,7 +125,32 @@ int qse_utf8touc (
|
||||
|
||||
end = utf8_table + QSE_COUNTOF(utf8_table);
|
||||
cur = utf8_table;
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
if ((utf8[0] & cur->mask) == cur->fbyte)
|
||||
{
|
||||
int i;
|
||||
qse_wchar_t w;
|
||||
|
||||
if (size < cur->length) return size + 1;
|
||||
|
||||
w = utf8[0] & cur->fmask;
|
||||
for (i = 1; i < cur->length; i++)
|
||||
{
|
||||
if (!(utf8[i] & 0x80)) return 0;
|
||||
w = (w << 6) | (utf8[i] & 0x3F);
|
||||
}
|
||||
|
||||
*uc = w;
|
||||
return (qse_size_t)cur->length;
|
||||
}
|
||||
cur++;
|
||||
}
|
||||
|
||||
return 0; /* error - invalid sequence */
|
||||
|
||||
#if 0
|
||||
c = *utf8;
|
||||
w = c;
|
||||
|
||||
@ -133,7 +163,7 @@ int qse_utf8touc (
|
||||
w &= cur->upper;
|
||||
if (w < cur->lower) break; /* wrong value */
|
||||
*uc = w;
|
||||
return count;
|
||||
return (qse_size_t)count;
|
||||
}
|
||||
|
||||
if (size <= count) break; /* insufficient input */
|
||||
@ -147,10 +177,11 @@ int qse_utf8touc (
|
||||
}
|
||||
|
||||
return 0; /* error - invalid sequence */
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
int qse_utf8len (qse_mchar_t first)
|
||||
/* mblen for utf8 */
|
||||
qse_size_t qse_utf8len (const qse_mchar_t* utf8, qse_size_t len)
|
||||
{
|
||||
__utf8_t* cur, * end;
|
||||
|
||||
@ -159,10 +190,32 @@ int qse_utf8len (qse_mchar_t first)
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
if ((first & cur->mask) == cur->fbyte) return cur->length;
|
||||
if ((utf8[0] & cur->mask) == cur->fbyte)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (len < cur->length)
|
||||
{
|
||||
/* the input is not as large as
|
||||
* the expected number of bytes */
|
||||
return len + 1; /* incomplete sequence */
|
||||
}
|
||||
|
||||
for (i = 1; i < cur->length; i++)
|
||||
{
|
||||
/* in utf8, trailing bytes are all
|
||||
* set with 0x80. if not, invalid */
|
||||
if (!(utf8[i] & 0x80)) return 0;
|
||||
}
|
||||
return (qse_size_t)cur->length;
|
||||
}
|
||||
cur++;
|
||||
}
|
||||
|
||||
return 0; /* error - invalid sequence */
|
||||
}
|
||||
#endif
|
||||
|
||||
qse_size_t qse_utf8lenmax (void)
|
||||
{
|
||||
return QSE_UTF8LEN_MAX;
|
||||
}
|
||||
|
@ -715,7 +715,7 @@ static void* response_thread (void* arg)
|
||||
if (n <= -1)
|
||||
{
|
||||
/*if (errno == EINTR) continue; */
|
||||
qse_fprintf (QSE_STDERR, QSE_T("Error: select returned failure - %S\n"), strerror(errno));
|
||||
qse_fprintf (QSE_STDERR, QSE_T("Error: select returned failure - %hs\n"), strerror(errno));
|
||||
/* break; */
|
||||
continue;
|
||||
}
|
||||
|
@ -472,7 +472,7 @@ static int task_main_path (
|
||||
struct stat st;
|
||||
qse_httpd_task_t* x = task;
|
||||
|
||||
qse_printf (QSE_T("opending file %S\n"), data->name);
|
||||
qse_printf (QSE_T("opending file %hs\n"), data->name);
|
||||
handle.i = open (data->name, O_RDONLY);
|
||||
if (handle.i <= -1)
|
||||
{
|
||||
|
@ -1,11 +1,16 @@
|
||||
#include <qse/cmn/mem.h>
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/cmn/stdio.h>
|
||||
#include <qse/cmn/sio.h>
|
||||
|
||||
#include <locale.h>
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#define R(f) \
|
||||
do { \
|
||||
qse_printf (QSE_T("== %s ==\n"), QSE_T(#f)); \
|
||||
@ -214,9 +219,9 @@ static int test6 (void)
|
||||
int i;
|
||||
const qse_mchar_t* x[] =
|
||||
{
|
||||
"",
|
||||
"뛰어 올라봐. 멀리멀리 잘난척하기는",
|
||||
"Fly to the universe. eat my shorts."
|
||||
QSE_MT(""),
|
||||
QSE_MT("뛰어 올라봐. 멀리멀리 잘난척하기는"),
|
||||
QSE_MT("Fly to the universe. eat my shorts.")
|
||||
};
|
||||
qse_wchar_t buf[5];
|
||||
qse_wchar_t buf2[50];
|
||||
@ -225,19 +230,25 @@ static int test6 (void)
|
||||
{
|
||||
qse_size_t n;
|
||||
qse_size_t wlen = QSE_COUNTOF(buf);
|
||||
|
||||
n = qse_mbstowcs (x[i], buf, &wlen);
|
||||
|
||||
#ifdef QSE_CHAR_IS_MCHAR
|
||||
qse_printf (QSE_T("[%s]=>"), x[i]);
|
||||
#else
|
||||
qse_printf (QSE_T("[%S]=>"), x[i]);
|
||||
#endif
|
||||
qse_printf (QSE_T("[%hs]=>"), x[i]);
|
||||
|
||||
#ifdef QSE_CHAR_IS_MCHAR
|
||||
qse_printf (QSE_T("[%S] %d chars %d bytes\n"), buf, (int)wlen, (int)n);
|
||||
#else
|
||||
qse_printf (QSE_T("[%s] %d chars %d bytes\n"), buf, (int)wlen, (int)n);
|
||||
#endif
|
||||
/* the string should not be properly null terminated
|
||||
* if buf is shorter than the necesary buffer size needed for
|
||||
* full conversion */
|
||||
qse_wcsxncpy (buf2, QSE_COUNTOF(buf2), buf, wlen);
|
||||
|
||||
qse_printf (QSE_T("%s %d chars %d bytes [%ls]\n"),
|
||||
((x[i][n] == QSE_WT('\0') && wlen < QSE_COUNTOF(buf))? QSE_T("FULL"): QSE_T("PARTIAL")),
|
||||
(int)wlen, (int)n, buf2);
|
||||
qse_fflush (QSE_STDOUT);
|
||||
|
||||
qse_sio_puts (QSE_SIO_OUT, QSE_T("<<"));
|
||||
qse_sio_puts (QSE_SIO_OUT, buf2);
|
||||
qse_sio_puts (QSE_SIO_OUT, QSE_T(">>\n"));
|
||||
qse_sio_flush (QSE_SIO_OUT);
|
||||
}
|
||||
|
||||
qse_printf (QSE_T("-----------------\n"));
|
||||
@ -248,11 +259,15 @@ static int test6 (void)
|
||||
qse_size_t wlen = QSE_COUNTOF(buf2);
|
||||
n = qse_mbstowcs (x[i], buf2, &wlen);
|
||||
|
||||
#ifdef QSE_CHAR_IS_MCHAR
|
||||
qse_printf (QSE_T("[%S] %d chars %d bytes\n"), buf2, (int)wlen, (int)n);
|
||||
#else
|
||||
qse_printf (QSE_T("[%s] %d chars %d bytes\n"), buf2, (int)wlen, (int)n);
|
||||
#endif
|
||||
qse_printf (QSE_T("%s %d chars %d bytes [%.*ls]\n"),
|
||||
((x[i][n] == QSE_WT('\0') && wlen < QSE_COUNTOF(buf))? QSE_T("FULL"): QSE_T("PARTIAL")),
|
||||
(int)wlen, (int)n, (int)wlen, buf2);
|
||||
|
||||
qse_fflush (QSE_STDOUT);
|
||||
qse_sio_puts (QSE_SIO_OUT, QSE_T("<<"));
|
||||
qse_sio_puts (QSE_SIO_OUT, buf2);
|
||||
qse_sio_puts (QSE_SIO_OUT, QSE_T(">>\n"));
|
||||
qse_sio_flush (QSE_SIO_OUT);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -298,6 +313,8 @@ static int test7 (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_printf (QSE_T("%.*hs"), (int)mlen, buf);
|
||||
#if 0
|
||||
#ifdef QSE_CHAR_IS_MCHAR
|
||||
qse_printf (QSE_T("%.*s"), (int)mlen, buf);
|
||||
#else
|
||||
@ -310,6 +327,7 @@ static int test7 (void)
|
||||
qse_printf (QSE_T("%.*S"), n, buf);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,7 +341,7 @@ static int test8 (void)
|
||||
const qse_wchar_t* x[] =
|
||||
{
|
||||
L"",
|
||||
L"\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4?",
|
||||
L"\uB108 \uBB50\uAC00\uC798\uB0AC\uC5B4?",
|
||||
L"Fly to the universe, kick you ass"
|
||||
};
|
||||
qse_mchar_t buf[10];
|
||||
@ -335,14 +353,12 @@ static int test8 (void)
|
||||
qse_size_t n;
|
||||
qse_size_t mlen = sizeof(buf);
|
||||
|
||||
memset (buf, 'A', sizeof(buf));
|
||||
memset (buf, QSE_MT('A'), sizeof(buf));
|
||||
n = qse_wcstombs (x[i], buf, &mlen);
|
||||
|
||||
#ifdef QSE_CHAR_IS_MCHAR
|
||||
qse_printf (QSE_T("[%s] chars=%d bytes=%d\n"), buf, (int)n, (int)mlen);
|
||||
#else
|
||||
qse_printf (QSE_T("[%S] chars=%d bytes=%d\n"), buf, (int)n, (int)mlen);
|
||||
#endif
|
||||
qse_printf (QSE_T("%s chars=%d bytes=%d [%hs]\n"),
|
||||
((x[i][n] == QSE_WT('\0') && mlen < sizeof(buf))? QSE_T("FULL"): QSE_T("PARTIAL")),
|
||||
(int)n, (int)mlen, buf);
|
||||
}
|
||||
|
||||
qse_printf (QSE_T("-----------------\n"));
|
||||
@ -354,11 +370,9 @@ static int test8 (void)
|
||||
memset (buf2, 'A', sizeof(buf2));
|
||||
n = qse_wcstombs (x[i], buf2, &mlen);
|
||||
|
||||
#ifdef QSE_CHAR_IS_MCHAR
|
||||
qse_printf (QSE_T("[%s] chars=%d bytes=%d\n"), buf2, (int)n, (int)mlen);
|
||||
#else
|
||||
qse_printf (QSE_T("[%S] chars=%d bytes=%d\n"), buf2, (int)n, (int)mlen);
|
||||
#endif
|
||||
qse_printf (QSE_T("%s chars=%d bytes=%d [%hs]\n"),
|
||||
((x[i][n] == QSE_WT('\0') && mlen < sizeof(buf2))? QSE_T("FULL"): QSE_T("PARTIAL")),
|
||||
(int)n, (int)mlen, buf2);
|
||||
}
|
||||
|
||||
qse_printf (QSE_T("-----------------\n"));
|
||||
@ -375,11 +389,9 @@ static int test8 (void)
|
||||
n = qse_wcstombs (p, buf, &mlen);
|
||||
if (n == 0) break;
|
||||
|
||||
#ifdef QSE_CHAR_IS_MCHAR
|
||||
qse_printf (QSE_T("[%s] chars=%d bytes=%d\n"), buf, (int)n, (int)mlen);
|
||||
#else
|
||||
qse_printf (QSE_T("[%S] chars=%d bytes=%d\n"), buf, (int)n, (int)mlen);
|
||||
#endif
|
||||
qse_printf (QSE_T("%s chars=%d bytes=%d [%hs]\n"),
|
||||
((x[i][n] == QSE_WT('\0') && mlen < sizeof(buf))? QSE_T("FULL"): QSE_T("PARTIAL")),
|
||||
(int)n, (int)mlen, buf);
|
||||
p += n;
|
||||
}
|
||||
}
|
||||
@ -389,7 +401,7 @@ static int test8 (void)
|
||||
|
||||
static int test9 (void)
|
||||
{
|
||||
char buf[24];
|
||||
qse_mchar_t buf[24];
|
||||
int i;
|
||||
|
||||
const qse_wchar_t* x[] =
|
||||
@ -409,23 +421,15 @@ static int test9 (void)
|
||||
|
||||
for (i = 0; i < QSE_COUNTOF(x); i++)
|
||||
{
|
||||
#ifdef QSE_CHAR_IS_MCHAR
|
||||
qse_printf (QSE_T("[%S] => "), x[i]);
|
||||
#else
|
||||
qse_printf (QSE_T("[%s] => "), x[i]);
|
||||
#endif
|
||||
qse_printf (QSE_T("[%ls] => "), x[i]);
|
||||
|
||||
if (qse_wcstombsrigid (x[i], buf, QSE_COUNTOF(buf)) == -1)
|
||||
if (qse_wcstombsrigid (x[i], buf, QSE_COUNTOF(buf)) <= -1)
|
||||
{
|
||||
qse_printf (QSE_T("ERROR\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef QSE_CHAR_IS_MCHAR
|
||||
qse_printf (QSE_T("[%s]\n"), buf);
|
||||
#else
|
||||
qse_printf (QSE_T("[%S]\n"), buf);
|
||||
#endif
|
||||
qse_printf (QSE_T("[%hs]\n"), buf);
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,6 +437,30 @@ static int test9 (void)
|
||||
}
|
||||
|
||||
static int test10 (void)
|
||||
{
|
||||
qse_wchar_t* wa[] = { QSE_WT("hello"), QSE_WT(","), QSE_WT("world"), QSE_NULL };
|
||||
qse_mchar_t* ma[] = { QSE_MT("HELLO"), QSE_MT(","), QSE_MT("WORLD"), QSE_NULL };
|
||||
qse_wchar_t* w;
|
||||
qse_mchar_t* m;
|
||||
|
||||
m = qse_wcsatombsdup (wa, QSE_MMGR_GETDFL());
|
||||
if (m)
|
||||
{
|
||||
qse_printf (QSE_T("[%ms]\n"), m);
|
||||
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), m);
|
||||
}
|
||||
|
||||
w = qse_mbsatowcsdup (ma, QSE_MMGR_GETDFL());
|
||||
if (w)
|
||||
{
|
||||
qse_printf (QSE_T("[%ws]\n"), w);
|
||||
QSE_MMGR_FREE (QSE_MMGR_GETDFL(), w);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test11 (void)
|
||||
{
|
||||
qse_char_t buf[1000];
|
||||
const qse_char_t* arg3[] =
|
||||
@ -480,7 +508,7 @@ static int test10 (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test11 (void)
|
||||
static int test12 (void)
|
||||
{
|
||||
qse_char_t buf[20];
|
||||
int i, j;
|
||||
@ -524,7 +552,7 @@ qse_char_t* subst (qse_char_t* buf, qse_size_t bsz, const qse_cstr_t* ident, voi
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int test12 (void)
|
||||
static int test13 (void)
|
||||
{
|
||||
qse_char_t buf[24];
|
||||
qse_size_t i, j;
|
||||
@ -546,7 +574,7 @@ static int test12 (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test13 (void)
|
||||
static int test14 (void)
|
||||
{
|
||||
qse_char_t a1[] = QSE_T(" this is a test string ");
|
||||
qse_char_t a2[] = QSE_T(" this is a test string ");
|
||||
@ -565,7 +593,7 @@ static int test13 (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test14 (void)
|
||||
static int test15 (void)
|
||||
{
|
||||
qse_char_t a1[] = QSE_T("abcdefghijklmnopqrstuvwxyz");
|
||||
qse_str_t x;
|
||||
@ -587,7 +615,7 @@ static int test14 (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test15 (void)
|
||||
static int test16 (void)
|
||||
{
|
||||
const qse_char_t* x = QSE_T("this is good");
|
||||
|
||||
@ -600,7 +628,7 @@ static int test15 (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test16 (void)
|
||||
static int test17 (void)
|
||||
{
|
||||
const qse_char_t* ptn[] =
|
||||
{
|
||||
@ -643,7 +671,19 @@ static int test16 (void)
|
||||
|
||||
int main ()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
char codepage[100];
|
||||
UINT old_cp = GetConsoleOutputCP();
|
||||
SetConsoleOutputCP (CP_UTF8);
|
||||
|
||||
/* TODO: on windows this set locale only affects those mbcs fucntions in clib.
|
||||
* it doesn't support utf8 i guess find a working way. the following won't work
|
||||
sprintf (codepage, ".%d", GetACP());
|
||||
setlocale (LC_ALL, codepage);
|
||||
*/
|
||||
#else
|
||||
setlocale (LC_ALL, "");
|
||||
#endif
|
||||
|
||||
qse_printf (QSE_T("--------------------------------------------------------------------------------\n"));
|
||||
qse_printf (QSE_T("Set the environment LANG to a Unicode locale such as UTF-8 if you see the illegal XXXXX errors. If you see such errors in Unicode locales, this program might be buggy. It is normal to see such messages in non-Unicode locales as it uses Unicode data\n"));
|
||||
@ -659,12 +699,17 @@ int main ()
|
||||
R (test8);
|
||||
R (test9);
|
||||
R (test10);
|
||||
|
||||
R (test11);
|
||||
R (test12);
|
||||
R (test13);
|
||||
R (test14);
|
||||
R (test15);
|
||||
R (test16);
|
||||
R (test17);
|
||||
|
||||
#if defined(_WIN32)
|
||||
SetConsoleOutputCP (old_cp);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ struct httpd_xtn_t
|
||||
|
||||
static qse_htb_walk_t walk (qse_htb_t* htb, qse_htb_pair_t* pair, void* ctx)
|
||||
{
|
||||
qse_printf (QSE_T("HEADER OK %d[%S] %d[%S]\n"), (int)QSE_HTB_KLEN(pair), QSE_HTB_KPTR(pair), (int)QSE_HTB_VLEN(pair), QSE_HTB_VPTR(pair));
|
||||
qse_printf (QSE_T("HEADER OK %d[%hs] %d[%hs]\n"), (int)QSE_HTB_KLEN(pair), QSE_HTB_KPTR(pair), (int)QSE_HTB_VLEN(pair), QSE_HTB_VPTR(pair));
|
||||
return QSE_HTB_WALK_FORWARD;
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ static int handle_request (
|
||||
#endif
|
||||
|
||||
qse_printf (QSE_T("================================\n"));
|
||||
qse_printf (QSE_T("REQUEST ==> [%S] version[%d.%d] method[%d]\n"),
|
||||
qse_printf (QSE_T("REQUEST ==> [%hs] version[%d.%d] method[%d]\n"),
|
||||
qse_htre_getqpathptr(req),
|
||||
qse_htre_getmajorversion(req),
|
||||
qse_htre_getminorversion(req),
|
||||
@ -38,7 +38,7 @@ qse_printf (QSE_T("REQUEST ==> [%S] version[%d.%d] method[%d]\n"),
|
||||
);
|
||||
if (qse_htre_getqparamlen(req) > 0)
|
||||
{
|
||||
qse_printf (QSE_T("PARAMS ==> [%S]\n"), qse_htre_getqparamptr(req));
|
||||
qse_printf (QSE_T("PARAMS ==> [%hs]\n"), qse_htre_getqparamptr(req));
|
||||
}
|
||||
|
||||
qse_htb_walk (&req->hdrtab, walk, QSE_NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user