enhanced __float128 handling

added qse_strvfmt() and qse_strxvfmt()
This commit is contained in:
2013-11-03 16:01:39 +00:00
parent fa47ad2965
commit 91c9182ad7
54 changed files with 447 additions and 248 deletions

View File

@ -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

View File

@ -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

View File

@ -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),

View File

@ -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));

View File

@ -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;

View File

@ -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;

View File

@ -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"

View File

@ -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;
}