enhanced __float128 handling
added qse_strvfmt() and qse_strxvfmt()
This commit is contained in:
@ -126,9 +126,8 @@ if ENABLE_XCMGRS
|
||||
libqsecmn_la_SOURCES += cp949.c cp950.c
|
||||
endif
|
||||
|
||||
|
||||
libqsecmn_la_LDFLAGS = -version-info 1:0:0 -no-undefined
|
||||
libqsecmn_la_LIBADD = $(SOCKET_LIBS)
|
||||
libqsecmn_la_LIBADD = $(SOCKET_LIBS) $(QUADMATH_LIBS)
|
||||
|
||||
if ENABLE_CXX
|
||||
|
||||
|
@ -84,7 +84,8 @@ am__uninstall_files_from_dir = { \
|
||||
am__installdirs = "$(DESTDIR)$(libdir)"
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
am__DEPENDENCIES_1 =
|
||||
libqsecmn_la_DEPENDENCIES = $(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 fio.c \
|
||||
fma.c fmt-intmax.c fmt-out.c fs.c fs-err.c fs-move.c glob.c \
|
||||
@ -286,6 +287,7 @@ QSE_SIZEOF_OFF_T = @QSE_SIZEOF_OFF_T@
|
||||
QSE_SIZEOF_SHORT = @QSE_SIZEOF_SHORT@
|
||||
QSE_SIZEOF_VOID_P = @QSE_SIZEOF_VOID_P@
|
||||
QSE_SIZEOF_WCHAR_T = @QSE_SIZEOF_WCHAR_T@
|
||||
QUADMATH_LIBS = @QUADMATH_LIBS@
|
||||
RANLIB = @RANLIB@
|
||||
RM = @RM@
|
||||
RMDIR = @RMDIR@
|
||||
@ -402,7 +404,7 @@ libqsecmn_la_SOURCES = alg-base64.c alg-rand.c alg-search.c alg-sort.c \
|
||||
tre-match-parallel.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)
|
||||
libqsecmn_la_LIBADD = $(SOCKET_LIBS) $(QUADMATH_LIBS)
|
||||
@ENABLE_CXX_TRUE@libqsecmnxx_la_SOURCES = \
|
||||
@ENABLE_CXX_TRUE@ Mmgr.cpp StdMmgr.cpp
|
||||
|
||||
|
@ -30,7 +30,10 @@
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200))
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
/* TODO: remove stdio.h once snprintf gets replaced by own
|
||||
#if defined(HAVE_QUADMATH_H)
|
||||
# include <quadmath.h> /* for quadmath_snprintf */
|
||||
#endif
|
||||
/* TODO: remove stdio.h and quadmath.h once snprintf gets replaced by own
|
||||
floting-point conversion implementation*/
|
||||
|
||||
/* number of bits in a byte */
|
||||
@ -52,7 +55,9 @@ enum
|
||||
LF_Z = (1 << 6),
|
||||
|
||||
/* long double */
|
||||
LF_LD = (1 << 7)
|
||||
LF_LD = (1 << 7),
|
||||
/* __float128 */
|
||||
LF_QD = (1 << 8)
|
||||
};
|
||||
|
||||
static struct
|
||||
@ -93,9 +98,9 @@ static struct
|
||||
enum
|
||||
{
|
||||
FLAGC_DOT = (1 << 0),
|
||||
FLAGC_SHARP = (1 << 1),
|
||||
FLAGC_SIGN = (1 << 2),
|
||||
FLAGC_SPACE = (1 << 3),
|
||||
FLAGC_SPACE = (1 << 1),
|
||||
FLAGC_SHARP = (1 << 2),
|
||||
FLAGC_SIGN = (1 << 3),
|
||||
FLAGC_LEFTADJ = (1 << 4),
|
||||
FLAGC_ZEROPAD = (1 << 5),
|
||||
FLAGC_WIDTH = (1 << 6),
|
||||
|
@ -264,7 +264,7 @@ reswitch:
|
||||
case T('j'): /* uintmax_t */
|
||||
case T('z'): /* size_t */
|
||||
case T('t'): /* ptrdiff_t */
|
||||
if (lm_flag & LF_LD) goto invalid_format;
|
||||
if (lm_flag & (LF_LD | LF_QD)) goto invalid_format;
|
||||
|
||||
flagc |= FLAGC_LENMOD;
|
||||
if (lm_dflag)
|
||||
@ -297,12 +297,23 @@ reswitch:
|
||||
case T('L'): /* long double */
|
||||
if (flagc & FLAGC_LENMOD)
|
||||
{
|
||||
/* conflict integral length modifier */
|
||||
/* conflict with other length modifier */
|
||||
goto invalid_format;
|
||||
}
|
||||
flagc |= FLAGC_LENMOD;
|
||||
lm_flag |= LF_LD;
|
||||
goto reswitch;
|
||||
|
||||
case T('Q'): /* __float128 */
|
||||
if (flagc & FLAGC_LENMOD)
|
||||
{
|
||||
/* conflict with other length modifier */
|
||||
goto invalid_format;
|
||||
}
|
||||
flagc |= FLAGC_LENMOD;
|
||||
lm_flag |= LF_QD;
|
||||
goto reswitch;
|
||||
|
||||
/* end of length modifiers */
|
||||
|
||||
case T('n'):
|
||||
@ -320,6 +331,8 @@ reswitch:
|
||||
*(va_arg(ap, short int*)) = data->count;
|
||||
else if (lm_flag & LF_C) /* hh */
|
||||
*(va_arg(ap, char*)) = data->count;
|
||||
else if (flagc & FLAGC_LENMOD)
|
||||
goto oops;
|
||||
else
|
||||
*(va_arg(ap, int*)) = data->count;
|
||||
break;
|
||||
@ -531,20 +544,62 @@ reswitch:
|
||||
case T('A'):
|
||||
*/
|
||||
{
|
||||
/* let me rely on snprintf until i implement
|
||||
* float-point to string conversion */
|
||||
/* let me rely on snprintf until i implement float-point to string conversion */
|
||||
int q;
|
||||
qse_size_t fmtlen;
|
||||
qse_fltmax_t v_fltmax;
|
||||
#if (QSE_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF)
|
||||
__float128 v_qd;
|
||||
#endif
|
||||
long double v_ld;
|
||||
double v_d;
|
||||
int dtype = 0;
|
||||
|
||||
if (lm_flag & LF_J)
|
||||
v_fltmax = va_arg (ap, qse_fltmax_t);
|
||||
else if (lm_flag & (LF_LD | LF_L | LF_Q | LF_Z))
|
||||
{
|
||||
#if (QSE_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF) && (QSE_SIZEOF_FLTMAX_T == QSE_SIZEOF___FLOAT128)
|
||||
v_qd = va_arg (ap, qse_fltmax_t);
|
||||
dtype = LF_QD;
|
||||
#elif QSE_SIZEOF_FLTMAX_T == QSE_SIZEOF_LONG_DOUBLE
|
||||
v_ld = va_arg (ap, qse_fltmax_t);
|
||||
dtype = LF_LD;
|
||||
#elif QSE_SIZEOF_FLTMAX_T == QSE_SIZEOF_DOUBLE
|
||||
v_d = va_arg (ap, qse_fltmax_t);
|
||||
#else
|
||||
#error Unsupported qse_flt_t
|
||||
#endif
|
||||
}
|
||||
else if (lm_flag & LF_Z)
|
||||
{
|
||||
/* qse_flt_t is limited to double or long double */
|
||||
#if QSE_SIZEOF_FLT_T == QSE_SIZEOF_LONG_DOUBLE
|
||||
v_ld = va_arg (ap, qse_flt_t);
|
||||
dtype = LF_LD;
|
||||
#elif QSE_SIZEOF_FLT_T == QSE_SIZEOF_DOUBLE
|
||||
v_d = va_arg (ap, qse_flt_t);
|
||||
#else
|
||||
#error Unsupported qse_flt_t
|
||||
#endif
|
||||
}
|
||||
else if (lm_flag & (LF_LD | LF_L))
|
||||
{
|
||||
v_ld = va_arg (ap, long double);
|
||||
dtype = LF_LD;
|
||||
}
|
||||
#if (QSE_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF)
|
||||
else if (lm_flag & (LF_QD | LF_Q))
|
||||
{
|
||||
v_qd = va_arg (ap, __float128);
|
||||
dtype = LF_QD;
|
||||
}
|
||||
#endif
|
||||
else if (flagc & FLAGC_LENMOD)
|
||||
{
|
||||
goto oops;
|
||||
}
|
||||
else
|
||||
{
|
||||
v_d = va_arg (ap, double);
|
||||
}
|
||||
|
||||
fmtlen = fmt - percent;
|
||||
if (fmtlen > fltfmt.capa)
|
||||
@ -566,27 +621,59 @@ reswitch:
|
||||
fltfmt.capa = fmtlen;
|
||||
}
|
||||
|
||||
fltfmt.ptr[fmtlen] = QSE_MT('\0');
|
||||
while (fmtlen > 0)
|
||||
/* compose back the format specifier */
|
||||
fmtlen = 0;
|
||||
fltfmt.ptr[fmtlen++] = QSE_MT('%');
|
||||
if (flagc & FLAGC_SPACE) fltfmt.ptr[fmtlen++] = QSE_T(' ');
|
||||
if (flagc & FLAGC_SHARP) fltfmt.ptr[fmtlen++] = QSE_T('#');
|
||||
if (flagc & FLAGC_SIGN) fltfmt.ptr[fmtlen++] = QSE_T('+');
|
||||
if (flagc & FLAGC_LEFTADJ) fltfmt.ptr[fmtlen++] = QSE_T('-');
|
||||
if (flagc & FLAGC_ZEROPAD) fltfmt.ptr[fmtlen++] = QSE_T('0');
|
||||
|
||||
if (flagc & FLAGC_STAR1) fltfmt.ptr[fmtlen++] = QSE_T('*');
|
||||
else if (flagc & FLAGC_WIDTH)
|
||||
{
|
||||
fmtlen--;
|
||||
fltfmt.ptr[fmtlen] = percent[fmtlen];
|
||||
fmtlen += qse_fmtuintmaxtombs (
|
||||
&fltfmt.ptr[fmtlen], fltfmt.capa - fmtlen,
|
||||
width, 10, -1, QSE_MT('\0'), QSE_NULL);
|
||||
}
|
||||
if (flagc & FLAGC_DOT) fltfmt.ptr[fmtlen++] = QSE_T('.');
|
||||
if (flagc & FLAGC_STAR2) fltfmt.ptr[fmtlen++] = QSE_T('*');
|
||||
else if (flagc & FLAGC_PRECISION)
|
||||
{
|
||||
fmtlen += qse_fmtuintmaxtombs (
|
||||
&fltfmt.ptr[fmtlen], fltfmt.capa - fmtlen,
|
||||
precision, 10, -1, QSE_MT('\0'), QSE_NULL);
|
||||
}
|
||||
|
||||
if (dtype == LF_LD)
|
||||
fltfmt.ptr[fmtlen++] = QSE_MT('L');
|
||||
#if (QSE_SIZEOF___FLOAT128 > 0)
|
||||
else if (dtype == LF_QD)
|
||||
fltfmt.ptr[fmtlen++] = QSE_MT('Q');
|
||||
#endif
|
||||
|
||||
fltfmt.ptr[fmtlen++] = ch;
|
||||
fltfmt.ptr[fmtlen] = QSE_MT('\0');
|
||||
|
||||
while (1)
|
||||
{
|
||||
qse_size_t newcapa;
|
||||
|
||||
if (lm_flag & LF_J)
|
||||
q = snprintf ((qse_mchar_t*)fltout.ptr, fltout.capa + 1, fltfmt.ptr, v_fltmax);
|
||||
else if (lm_flag & (LF_LD | LF_L | LF_Q | LF_Z))
|
||||
if (dtype == LF_LD)
|
||||
q = snprintf ((qse_mchar_t*)fltout.ptr, fltout.capa + 1, fltfmt.ptr, v_ld);
|
||||
#if (QSE_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF)
|
||||
else if (dtype == LF_QD)
|
||||
q = quadmath_snprintf ((qse_mchar_t*)fltout.ptr, fltout.capa + 1, fltfmt.ptr, v_qd);
|
||||
#endif
|
||||
else
|
||||
q = snprintf ((qse_mchar_t*)fltout.ptr, fltout.capa + 1, fltfmt.ptr, v_d);
|
||||
if (q <= -1) goto oops;
|
||||
if (q <= fltout.capa) break;
|
||||
|
||||
newcapa = fltout.capa * 2;
|
||||
if (newcapa < q) newcapa = q;
|
||||
|
||||
if (fltout.ptr == fltout.sbuf)
|
||||
{
|
||||
fltout.ptr = QSE_MMGR_ALLOC (QSE_MMGR_GETDFL(), QSE_SIZEOF(char_t) * (newcapa + 1));
|
||||
|
@ -53,7 +53,7 @@ static int put_mchar_nocheck (qse_mchar_t c, void* ctx)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int put_wchar_nocheck (qse_wchar_t* c, void* ctx)
|
||||
static int put_wchar_nocheck (qse_wchar_t c, void* ctx)
|
||||
{
|
||||
qse_wcs_t* str = (qse_wcs_t*)ctx;
|
||||
str->val.ptr[str->val.len++] = c;
|
||||
|
@ -425,8 +425,6 @@ qse_size_t str_pac (str_t* str)
|
||||
return str->val.len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
qse_size_t str_vfcat (str_t* str, const char_t* fmt, va_list ap)
|
||||
{
|
||||
va_list orgap;
|
||||
@ -471,50 +469,6 @@ qse_size_t str_vfcat (str_t* str, const char_t* fmt, va_list ap)
|
||||
|
||||
qse_size_t str_fcat (str_t* str, const char_t* fmt, ...)
|
||||
{
|
||||
#if 0
|
||||
va_list ap;
|
||||
fmtout_t fo;
|
||||
int x;
|
||||
qse_size_t old_len, inc;
|
||||
|
||||
old_len = str->val.len;
|
||||
|
||||
fo.limit = QSE_TYPE_MAX(qse_size_t) - 1;
|
||||
fo.ctx = str;
|
||||
fo.put = str->val.ptr? put_char: put_char_null;
|
||||
fo.conv = conv_char;
|
||||
|
||||
va_start (ap, fmt);
|
||||
x = fmtout (fmt, &fo, ap);
|
||||
va_end (ap);
|
||||
|
||||
if (x <= -1)
|
||||
{
|
||||
str->val.len = old_len;
|
||||
return (qse_size_t)-1;
|
||||
}
|
||||
|
||||
if (str->val.ptr == QSE_NULL || str->val.len - old_len < fo.count)
|
||||
{
|
||||
str->val.len = old_len;
|
||||
|
||||
/* resizing is required */
|
||||
x = resize_for_ncat (str, fo.count);
|
||||
|
||||
if (x <= -1) return (qse_size_t)-1;
|
||||
if (x >= 1)
|
||||
{
|
||||
fo.put = put_char;
|
||||
|
||||
va_start (ap, fmt);
|
||||
x = fmtout (fmt, &fo, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
}
|
||||
|
||||
str->val.ptr[str->val.len] = T('\0');
|
||||
return str->val.len;
|
||||
#endif
|
||||
qse_size_t x;
|
||||
va_list ap;
|
||||
|
||||
|
@ -103,6 +103,8 @@ static int mbs_to_wcs (
|
||||
#undef conv_char
|
||||
#undef strfmt
|
||||
#undef strxfmt
|
||||
#undef strvfmt
|
||||
#undef strxvfmt
|
||||
|
||||
#define T(x) QSE_MT(x)
|
||||
#define char_t qse_mchar_t
|
||||
@ -114,6 +116,8 @@ static int mbs_to_wcs (
|
||||
#define conv_char wcs_to_mbs
|
||||
#define strfmt qse_mbsfmt
|
||||
#define strxfmt qse_mbsxfmt
|
||||
#define strvfmt qse_mbsvfmt
|
||||
#define strxvfmt qse_mbsxvfmt
|
||||
#include "str-fmt.h"
|
||||
|
||||
/* ----------------------------------- */
|
||||
@ -128,6 +132,8 @@ static int mbs_to_wcs (
|
||||
#undef conv_char
|
||||
#undef strfmt
|
||||
#undef strxfmt
|
||||
#undef strvfmt
|
||||
#undef strxvfmt
|
||||
|
||||
#define T(x) QSE_WT(x)
|
||||
#define char_t qse_wchar_t
|
||||
@ -139,5 +145,7 @@ static int mbs_to_wcs (
|
||||
#define conv_char mbs_to_wcs
|
||||
#define strfmt qse_wcsfmt
|
||||
#define strxfmt qse_wcsxfmt
|
||||
#define strvfmt qse_wcsvfmt
|
||||
#define strxvfmt qse_wcsxvfmt
|
||||
#include "str-fmt.h"
|
||||
|
||||
|
@ -19,10 +19,9 @@
|
||||
*/
|
||||
|
||||
|
||||
qse_size_t strfmt (char_t* buf, const char_t* fmt, ...)
|
||||
qse_size_t strvfmt (char_t* buf, const char_t* fmt, va_list ap)
|
||||
{
|
||||
buf_t b;
|
||||
va_list ap;
|
||||
fmtout_t fo;
|
||||
int x;
|
||||
|
||||
@ -37,9 +36,7 @@ qse_size_t strfmt (char_t* buf, const char_t* fmt, ...)
|
||||
|
||||
/* no I/O error must occurred by fmtout but there can be
|
||||
* encoding conversion error by fmtout */
|
||||
va_start (ap, fmt);
|
||||
x = fmtout (fmt, &fo, ap);
|
||||
va_end (ap);
|
||||
|
||||
/* fmtout must produce no I/O error but it can produce
|
||||
* an encoding conversion error. if you didn't use a conversion
|
||||
@ -57,10 +54,21 @@ qse_size_t strfmt (char_t* buf, const char_t* fmt, ...)
|
||||
return fo.count;
|
||||
}
|
||||
|
||||
qse_size_t strxfmt (char_t* buf, qse_size_t len, const char_t* fmt, ...)
|
||||
qse_size_t strfmt (char_t* buf, const char_t* fmt, ...)
|
||||
{
|
||||
qse_size_t x;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
x = strvfmt (buf, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
qse_size_t strxvfmt (char_t* buf, qse_size_t len, const char_t* fmt, va_list ap)
|
||||
{
|
||||
buf_t b;
|
||||
va_list ap;
|
||||
fmtout_t fo;
|
||||
int x;
|
||||
|
||||
@ -79,9 +87,7 @@ qse_size_t strxfmt (char_t* buf, qse_size_t len, const char_t* fmt, ...)
|
||||
fo.put = b.ptr? put_char: put_char_null;
|
||||
fo.conv = conv_char;
|
||||
|
||||
va_start (ap, fmt);
|
||||
x = fmtout (fmt, &fo, ap);
|
||||
va_end (ap);
|
||||
|
||||
/* fmtout must produce no I/O error but it can produce
|
||||
* an encoding conversion error. if you didn't use a conversion
|
||||
@ -99,3 +105,14 @@ qse_size_t strxfmt (char_t* buf, qse_size_t len, const char_t* fmt, ...)
|
||||
return fo.count;
|
||||
}
|
||||
|
||||
qse_size_t strxfmt (char_t* buf, qse_size_t len, const char_t* fmt, ...)
|
||||
{
|
||||
qse_size_t x;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
x = strxvfmt (buf, len, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
Reference in New Issue
Block a user