cleaned up code and build files

This commit is contained in:
hyung-hwan 2020-11-15 10:26:14 +00:00
parent 0823ddc2d0
commit 656e0150a9
11 changed files with 944 additions and 203 deletions

View File

@ -49,6 +49,7 @@ pkglibdir = $(libdir)
pkginclude_HEADERS = \
hcl.h \
hcl-cmn.h \
hcl-fmt.h \
hcl-opt.h \
hcl-rbt.h \
hcl-utl.h
@ -68,6 +69,7 @@ libhcl_la_SOURCES = \
dic.c \
err.c \
exec.c \
fmt-imp.h \
fmt.c \
gc.c \
hcl.c \

View File

@ -236,8 +236,9 @@ am__can_run_installinfo = \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__pkginclude_HEADERS_DIST = hcl.h hcl-cmn.h hcl-opt.h hcl-rbt.h \
hcl-utl.h hcl-c.h hcl-s.h hcl-tmr.h hcl-xutl.h hcl-json.h
am__pkginclude_HEADERS_DIST = hcl.h hcl-cmn.h hcl-fmt.h hcl-opt.h \
hcl-rbt.h hcl-utl.h hcl-c.h hcl-s.h hcl-tmr.h hcl-xutl.h \
hcl-json.h
HEADERS = $(pkginclude_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
$(LISP)hcl-cfg.h.in
@ -422,8 +423,8 @@ LIBADD_LIB_COMMON = $(LIBM) $(am__append_1) $(am__append_2) \
@WIN32_TRUE@CPPFLAGS_PFMOD = -DHCL_DEFAULT_PFMODPREFIX=\"libhcl-\" \
@WIN32_TRUE@ -DHCL_DEFAULT_PFMODPOSTFIX=\"-1.dll\" \
@WIN32_TRUE@ $(am__append_4) $(am__append_5)
pkginclude_HEADERS = hcl.h hcl-cmn.h hcl-opt.h hcl-rbt.h hcl-utl.h \
$(am__append_9)
pkginclude_HEADERS = hcl.h hcl-cmn.h hcl-fmt.h hcl-opt.h hcl-rbt.h \
hcl-utl.h $(am__append_9)
pkglib_LTLIBRARIES = libhcl.la $(am__append_8)
libhcl_la_SOURCES = \
hcl.h \
@ -439,6 +440,7 @@ libhcl_la_SOURCES = \
dic.c \
err.c \
exec.c \
fmt-imp.h \
fmt.c \
gc.c \
hcl.c \

View File

@ -245,8 +245,8 @@ void hcl_seterrbfmt (hcl_t* hcl, hcl_errnum_t errnum, const hcl_bch_t* fmt, ...)
hcl->errmsg.len = 0;
HCL_MEMSET (&fo, 0, HCL_SIZEOF(fo));
fo.putbcs = err_bcs;
fo.putucs = err_ucs;
fo.putbchars = err_bcs;
fo.putuchars = err_ucs;
fo.putobj = hcl_fmt_object_;
fo.ctx = hcl;
@ -266,8 +266,8 @@ void hcl_seterrufmt (hcl_t* hcl, hcl_errnum_t errnum, const hcl_uch_t* fmt, ...)
hcl->errmsg.len = 0;
HCL_MEMSET (&fo, 0, HCL_SIZEOF(fo));
fo.putbcs = err_bcs;
fo.putucs = err_ucs;
fo.putbchars = err_bcs;
fo.putuchars = err_ucs;
fo.putobj = hcl_fmt_object_;
fo.ctx = hcl;
@ -288,8 +288,8 @@ void hcl_seterrbfmtv (hcl_t* hcl, hcl_errnum_t errnum, const hcl_bch_t* fmt, va_
hcl->errmsg.len = 0;
HCL_MEMSET (&fo, 0, HCL_SIZEOF(fo));
fo.putbcs = err_bcs;
fo.putucs = err_ucs;
fo.putbchars = err_bcs;
fo.putuchars = err_ucs;
fo.putobj = hcl_fmt_object_;
fo.ctx = hcl;
@ -306,8 +306,8 @@ void hcl_seterrufmtv (hcl_t* hcl, hcl_errnum_t errnum, const hcl_uch_t* fmt, va_
hcl->errmsg.len = 0;
HCL_MEMSET (&fo, 0, HCL_SIZEOF(fo));
fo.putbcs = err_bcs;
fo.putucs = err_ucs;
fo.putbchars = err_bcs;
fo.putuchars = err_ucs;
fo.putobj = hcl_fmt_object_;
fo.ctx = hcl;

View File

@ -158,8 +158,8 @@ static HCL_INLINE int vm_startup (hcl_t* hcl)
}
#if defined(ENABLE_GCFIN)
moo->sem_gcfin = (moo_oop_semaphore_t)moo->_nil;
moo->sem_gcfin_sigreq = 0;
hcl->sem_gcfin = (moo_oop_semaphore_t)hcl->_nil;
hcl->sem_gcfin_sigreq = 0;
#endif
hcl->vmprim.vm_gettime (hcl, &hcl->exec_start_time); /* raw time. no adjustment */
@ -208,8 +208,8 @@ static void vm_cleanup (hcl_t* hcl)
}
#if defined(ENABLE_GCFIN)
moo->sem_gcfin = (moo_oop_semaphore_t)moo->_nil;
moo->sem_gcfin_sigreq = 0;
hcl->sem_gcfin = (moo_oop_semaphore_t)hcl->_nil;
hcl->sem_gcfin_sigreq = 0;
/* deregister all pending finalizable objects pending just in case these
* have not been removed for various reasons. (e.g. sudden VM abortion)

228
lib/fmt-imp.h Normal file
View File

@ -0,0 +1,228 @@
/*
* $Id$
*
Copyright (c) 2016-2018 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.
*/
static int fmt_uintmax (
char_t* buf, int size,
hcl_uintmax_t value, int base_and_flags, int prec,
char_t fillchar, char_t signchar, const char_t* prefix)
{
char_t tmp[(HCL_SIZEOF(hcl_uintmax_t) * 8)];
int reslen, base, fillsize, reqlen, pflen, preczero;
char_t* p, * bp, * be;
const hcl_bch_t* xbasestr;
base = base_and_flags & 0x3F;
if (base < 2 || base > 36) return -1;
xbasestr = (base_and_flags & HCL_FMT_INTMAX_UPPERCASE)?
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ":
"0123456789abcdefghijklmnopqrstuvwxyz";
if ((base_and_flags & HCL_FMT_INTMAX_NOZERO) && value == 0)
{
p = tmp;
if (base_and_flags & HCL_FMT_INTMAX_ZEROLEAD)
{
/* NOZERO emits no digit, ZEROLEAD emits 1 digit.
* so it emits '0' */
reslen = 1;
preczero = 1;
}
else
{
/* since the value is zero, emit no digits */
reslen = 0;
preczero = 0;
}
}
else
{
hcl_uintmax_t v = value;
/* store the resulting numeric string into 'tmp' first */
p = tmp;
do
{
*p++ = xbasestr[v % base];
v /= base;
}
while (v > 0);
/* reslen is the length of the resulting string without padding. */
reslen = (int)(p - tmp);
/* precision specified the minum number of digits to produce.
* so if the precision is larger that the digits produced,
* reslen should be adjusted to precision */
if (prec > reslen)
{
/* if the precision is greater than the actual digits
* made from the value, 0 is inserted in front.
* ZEROLEAD doesn't have to be handled explicitly
* since it's achieved effortlessly */
preczero = prec - reslen;
reslen = prec;
}
else
{
preczero = 0;
if ((base_and_flags & HCL_FMT_INTMAX_ZEROLEAD) && value != 0)
{
/* if value is zero, 0 is emitted from it.
* so ZEROLEAD don't need to add another 0. */
preczero++;
reslen++;
}
}
}
if (signchar) reslen++; /* increment reslen for the sign character */
if (prefix)
{
/* since the length can be truncated for different type sizes,
* don't pass in a very long prefix. */
const char_t* pp;
for (pp = prefix; *pp != '\0'; pp++) ;
pflen = pp - prefix;
reslen += pflen;
}
else pflen = 0;
/* get the required buffer size for lossless formatting */
reqlen = (base_and_flags & HCL_FMT_INTMAX_NONULL)? reslen: (reslen + 1);
if (size <= 0 ||
((base_and_flags & HCL_FMT_INTMAX_NOTRUNC) && size < reqlen))
{
return -reqlen;
}
/* get the size to fill with fill characters */
fillsize = (base_and_flags & HCL_FMT_INTMAX_NONULL)? size: (size - 1);
bp = buf;
be = buf + fillsize;
/* fill space */
if (fillchar != '\0')
{
if (base_and_flags & HCL_FMT_INTMAX_FILLRIGHT)
{
/* emit sign */
if (signchar && bp < be) *bp++ = signchar;
/* copy prefix if necessary */
if (prefix) while (*prefix && bp < be) *bp++ = *prefix++;
/* add 0s for precision */
while (preczero > 0 && bp < be)
{
*bp++ = '0';
preczero--;
}
/* copy the numeric string to the destination buffer */
while (p > tmp && bp < be) *bp++ = *--p;
/* fill the right side */
while (fillsize > reslen)
{
*bp++ = fillchar;
fillsize--;
}
}
else if (base_and_flags & HCL_FMT_INTMAX_FILLCENTER)
{
/* emit sign */
if (signchar && bp < be) *bp++ = signchar;
/* fill the left side */
while (fillsize > reslen)
{
*bp++ = fillchar;
fillsize--;
}
/* copy prefix if necessary */
if (prefix) while (*prefix && bp < be) *bp++ = *prefix++;
/* add 0s for precision */
while (preczero > 0 && bp < be)
{
*bp++ = '0';
preczero--;
}
/* copy the numeric string to the destination buffer */
while (p > tmp && bp < be) *bp++ = *--p;
}
else
{
/* fill the left side */
while (fillsize > reslen)
{
*bp++ = fillchar;
fillsize--;
}
/* emit sign */
if (signchar && bp < be) *bp++ = signchar;
/* copy prefix if necessary */
if (prefix) while (*prefix && bp < be) *bp++ = *prefix++;
/* add 0s for precision */
while (preczero > 0 && bp < be)
{
*bp++ = '0';
preczero--;
}
/* copy the numeric string to the destination buffer */
while (p > tmp && bp < be) *bp++ = *--p;
}
}
else
{
/* emit sign */
if (signchar && bp < be) *bp++ = signchar;
/* copy prefix if necessary */
if (prefix) while (*prefix && bp < be) *bp++ = *prefix++;
/* add 0s for precision */
while (preczero > 0 && bp < be)
{
*bp++ = '0';
preczero--;
}
/* copy the numeric string to the destination buffer */
while (p > tmp && bp < be) *bp++ = *--p;
}
if (!(base_and_flags & HCL_FMT_INTMAX_NONULL)) *bp = '\0';
return bp - buf;
}

360
lib/fmt.c
View File

@ -1,7 +1,7 @@
/*
* $Id$
*
Copyright (c) 2014-2018 Chung, Hyung-Hwan. All rights reserved.
Copyright (c) 2016-2018 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
@ -68,7 +68,8 @@
#include "hcl-prv.h"
#if 0
#if defined(HCL_ENABLE_FLTFMT)
#include <stdio.h> /* for snrintf(). used for floating-point number formatting */
#if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200))
# define snprintf _snprintf
@ -79,6 +80,7 @@
#if defined(HAVE_QUADMATH_H)
# include <quadmath.h> /* for quadmath_snprintf() */
#endif
#endif
/* Max number conversion buffer length:
@ -169,6 +171,135 @@ static const hcl_bch_t hex2ascii_upper[] =
static hcl_uch_t uch_nullstr[] = { '(','n','u','l','l', ')','\0' };
static hcl_bch_t bch_nullstr[] = { '(','n','u','l','l', ')','\0' };
/* ------------------------------------------------------------------------- */
/*define static int fmt_uintmax_to_bcstr(...)*/
#undef char_t
#undef fmt_uintmax
#define char_t hcl_bch_t
#define fmt_uintmax fmt_uintmax_to_bcstr
#include "fmt-imp.h"
/*define static int fmt_uintmax_to_ucstr(...)*/
#undef char_t
#undef fmt_uintmax
#define char_t hcl_uch_t
#define fmt_uintmax fmt_uintmax_to_ucstr
#include "fmt-imp.h"
int hcl_fmt_intmax_to_bcstr (
hcl_bch_t* buf, int size,
hcl_intmax_t value, int base_and_flags, int prec,
hcl_bch_t fillchar, const hcl_bch_t* prefix)
{
hcl_bch_t signchar;
hcl_uintmax_t absvalue;
if (value < 0)
{
signchar = '-';
absvalue = -value;
}
else if (base_and_flags & HCL_FMT_INTMAX_TO_BCSTR_PLUSSIGN)
{
signchar = '+';
absvalue = value;
}
else if (base_and_flags & HCL_FMT_INTMAX_TO_BCSTR_EMPTYSIGN)
{
signchar = ' ';
absvalue = value;
}
else
{
signchar = '\0';
absvalue = value;
}
return fmt_uintmax_to_bcstr(buf, size, absvalue, base_and_flags, prec, fillchar, signchar, prefix);
}
int hcl_fmt_uintmax_to_bcstr (
hcl_bch_t* buf, int size,
hcl_uintmax_t value, int base_and_flags, int prec,
hcl_bch_t fillchar, const hcl_bch_t* prefix)
{
hcl_bch_t signchar;
/* determine if a sign character is needed */
if (base_and_flags & HCL_FMT_INTMAX_TO_BCSTR_PLUSSIGN)
{
signchar = '+';
}
else if (base_and_flags & HCL_FMT_INTMAX_TO_BCSTR_EMPTYSIGN)
{
signchar = ' ';
}
else
{
signchar = '\0';
}
return fmt_uintmax_to_bcstr(buf, size, value, base_and_flags, prec, fillchar, signchar, prefix);
}
/* ==================== wide-char ===================================== */
int hcl_fmt_intmax_to_ucstr (
hcl_uch_t* buf, int size,
hcl_intmax_t value, int base_and_flags, int prec,
hcl_uch_t fillchar, const hcl_uch_t* prefix)
{
hcl_uch_t signchar;
hcl_uintmax_t absvalue;
if (value < 0)
{
signchar = '-';
absvalue = -value;
}
else if (base_and_flags & HCL_FMT_INTMAX_TO_UCSTR_PLUSSIGN)
{
signchar = '+';
absvalue = value;
}
else if (base_and_flags & HCL_FMT_INTMAX_TO_UCSTR_EMPTYSIGN)
{
signchar = ' ';
absvalue = value;
}
else
{
signchar = '\0';
absvalue = value;
}
return fmt_uintmax_to_ucstr(buf, size, absvalue, base_and_flags, prec, fillchar, signchar, prefix);
}
int hcl_fmt_uintmax_to_ucstr (
hcl_uch_t* buf, int size,
hcl_uintmax_t value, int base_and_flags, int prec,
hcl_uch_t fillchar, const hcl_uch_t* prefix)
{
hcl_uch_t signchar;
/* determine if a sign character is needed */
if (base_and_flags & HCL_FMT_INTMAX_TO_UCSTR_PLUSSIGN)
{
signchar = '+';
}
else if (base_and_flags & HCL_FMT_INTMAX_TO_UCSTR_EMPTYSIGN)
{
signchar = ' ';
}
else
{
signchar = '\0';
}
return fmt_uintmax_to_ucstr(buf, size, value, base_and_flags, prec, fillchar, signchar, prefix);
}
/* ------------------------------------------------------------------------- */
/*
@ -211,7 +342,7 @@ static hcl_bch_t* sprintn_upper (hcl_bch_t* nbuf, hcl_uintmax_t num, int base, h
for (_yy = 0; _yy < n; _yy++) \
{ \
int _xx; \
if ((_xx = fmtout->putbcs(fmtout, &_cc, 1)) <= -1) goto oops; \
if ((_xx = fmtout->putbchars(fmtout, &_cc, 1)) <= -1) goto oops; \
if (_xx == 0) goto done; \
fmtout->count++; \
} \
@ -221,7 +352,7 @@ static hcl_bch_t* sprintn_upper (hcl_bch_t* nbuf, hcl_uintmax_t num, int base, h
#define PUT_BCS(fmtout,ptr,len) do { \
if (len > 0) { \
int _xx; \
if ((_xx = fmtout->putbcs(fmtout, ptr, len)) <= -1) goto oops; \
if ((_xx = fmtout->putbchars(fmtout, ptr, len)) <= -1) goto oops; \
if (_xx == 0) goto done; \
fmtout->count += len; \
} \
@ -234,7 +365,7 @@ static hcl_bch_t* sprintn_upper (hcl_bch_t* nbuf, hcl_uintmax_t num, int base, h
for (_yy = 0; _yy < n; _yy++) \
{ \
int _xx; \
if ((_xx = fmtout->putucs(fmtout, &_cc, 1)) <= -1) goto oops; \
if ((_xx = fmtout->putuchars(fmtout, &_cc, 1)) <= -1) goto oops; \
if (_xx == 0) goto done; \
fmtout->count++; \
} \
@ -244,7 +375,7 @@ static hcl_bch_t* sprintn_upper (hcl_bch_t* nbuf, hcl_uintmax_t num, int base, h
#define PUT_UCS(fmtout,ptr,len) do { \
if (len > 0) { \
int _xx; \
if ((_xx = fmtout->putucs(fmtout, ptr, len)) <= -1) goto oops; \
if ((_xx = fmtout->putuchars(fmtout, ptr, len)) <= -1) goto oops; \
if (_xx == 0) goto done; \
fmtout->count += len; \
} \
@ -287,10 +418,25 @@ static int fmt_outv (hcl_fmtout_t* fmtout, va_list ap)
hcl_bch_t nbuf[MAXNBUF];
const hcl_bch_t* nbufp;
int stop = 0;
#if 0
hcl_bchbuf_t* fltfmt;
hcl_oochbuf_t* fltout;
#if defined(HCL_ENABLE_FLTFMT)
struct
{
struct
{
hcl_bch_t sbuf[32];
hcl_bch_t* ptr;
hcl_oow_t capa;
} fmt;
struct
{
hcl_bch_t sbuf[64];
hcl_bch_t* ptr;
hcl_oow_t capa;
} out;
} fb; /* some buffers for handling float-point number formatting */
#endif
hcl_bch_t* (*sprintn) (hcl_bch_t* nbuf, hcl_uintmax_t num, int base, hcl_ooi_t* lenp);
fmtptr = (const hcl_uint8_t*)fmtout->fmt_str;
@ -306,16 +452,11 @@ static int fmt_outv (hcl_fmtout_t* fmtout, va_list ap)
/* this is an internal function. it doesn't reset count to 0 */
/* fmtout->count = 0; */
#if 0
fltfmt = &hcl->d->fltfmt;
fltout = &hcl->d->fltout;
fltfmt->ptr = fltfmt->buf;
fltfmt->capa = HCL_COUNTOF(fltfmt->buf) - 1;
fltout->ptr = fltout->buf;
fltout->capa = HCL_COUNTOF(fltout->buf) - 1;
#if defined(HCL_ENABLE_FLTFMT)
fb.fmt.ptr = fb.fmt.sbuf;
fb.fmt.capa = HCL_COUNTOF(fb.fmt.sbuf) - 1;
fb.out.ptr = fb.out.sbuf;
fb.out.capa = HCL_COUNTOF(fb.out.sbuf) - 1;
#endif
while (1)
@ -891,7 +1032,7 @@ static int fmt_outv (hcl_fmtout_t* fmtout, va_list ap)
break;
}
#if 0
#if defined(HCL_ENABLE_FLTFMT)
case 'e':
case 'E':
case 'f':
@ -906,23 +1047,27 @@ static int fmt_outv (hcl_fmtout_t* fmtout, va_list ap)
/* let me rely on snprintf until i implement float-point to string conversion */
int q;
hcl_oow_t fmtlen;
union
{
#if (HCL_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF)
__float128 v_qd;
__float128 qd;
#endif
long double v_ld;
double v_d;
long double ld;
double d;
} v;
int dtype = 0;
hcl_oow_t newcapa;
hcl_bch_t* bsp;
if (lm_flag & LF_J)
{
#if (HCL_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF) && (HCL_SIZEOF_FLTMAX_T == HCL_SIZEOF___FLOAT128)
v_qd = va_arg (ap, hcl_fltmax_t);
v.qd = va_arg(ap, hcl_fltmax_t);
dtype = LF_QD;
#elif HCL_SIZEOF_FLTMAX_T == HCL_SIZEOF_DOUBLE
v_d = va_arg(ap, hcl_fltmax_t);
v.d = va_arg(ap, hcl_fltmax_t);
#elif HCL_SIZEOF_FLTMAX_T == HCL_SIZEOF_LONG_DOUBLE
v_ld = va_arg(ap, hcl_fltmax_t);
v.ld = va_arg(ap, hcl_fltmax_t);
dtype = LF_LD;
#else
#error Unsupported hcl_flt_t
@ -937,9 +1082,9 @@ static int fmt_outv (hcl_fmtout_t* fmtout, va_list ap)
* so i prefer the format specifier with no modifier.
*/
#if HCL_SIZEOF_FLT_T == HCL_SIZEOF_DOUBLE
v_d = va_arg(ap, hcl_flt_t);
v.d = va_arg(ap, hcl_flt_t);
#elif HCL_SIZEOF_FLT_T == HCL_SIZEOF_LONG_DOUBLE
v_ld = va_arg(ap, hcl_flt_t);
v.ld = va_arg(ap, hcl_flt_t);
dtype = LF_LD;
#else
#error Unsupported hcl_flt_t
@ -947,13 +1092,13 @@ static int fmt_outv (hcl_fmtout_t* fmtout, va_list ap)
}
else if (lm_flag & (LF_LD | LF_L))
{
v_ld = va_arg (ap, long double);
v.ld = va_arg(ap, long double);
dtype = LF_LD;
}
#if (HCL_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF)
else if (lm_flag & (LF_QD | LF_Q))
{
v_qd = va_arg(ap, __float128);
v.qd = va_arg(ap, __float128);
dtype = LF_QD;
}
#endif
@ -963,63 +1108,63 @@ static int fmt_outv (hcl_fmtout_t* fmtout, va_list ap)
}
else
{
v_d = va_arg (ap, double);
v.d = va_arg(ap, double);
}
fmtlen = fmt - percent;
if (fmtlen > fltfmt->capa)
fmtlen = fmtptr - percent;
if (fmtlen > fb.fmt.capa)
{
if (fltfmt->ptr == fltfmt->buf)
if (fb.fmt.ptr == fb.fmt.sbuf)
{
fltfmt->ptr = HCL_MMGR_ALLOC(HCL_MMGR_GETDFL(), HCL_SIZEOF(*fltfmt->ptr) * (fmtlen + 1));
if (!fltfmt->ptr) goto oops;
fb.fmt.ptr = (hcl_bch_t*)HCL_MMGR_ALLOC(fmtout->mmgr, HCL_SIZEOF(*fb.fmt.ptr) * (fmtlen + 1));
if (!fb.fmt.ptr) goto oops;
}
else
{
hcl_bch_t* tmpptr;
tmpptr = HCL_MMGR_REALLOC(HCL_MMGR_GETDFL(), fltfmt->ptr, HCL_SIZEOF(*fltfmt->ptr) * (fmtlen + 1));
tmpptr = (hcl_bch_t*)HCL_MMGR_REALLOC(fmtout->mmgr, fb.fmt.ptr, HCL_SIZEOF(*fb.fmt.ptr) * (fmtlen + 1));
if (!tmpptr) goto oops;
fltfmt->ptr = tmpptr;
fb.fmt.ptr = tmpptr;
}
fltfmt->capa = fmtlen;
fb.fmt.capa = fmtlen;
}
/* compose back the format specifier */
fmtlen = 0;
fltfmt->ptr[fmtlen++] = '%';
if (flagc & FLAGC_SPACE) fltfmt->ptr[fmtlen++] = ' ';
if (flagc & FLAGC_SHARP) fltfmt->ptr[fmtlen++] = '#';
if (flagc & FLAGC_SIGN) fltfmt->ptr[fmtlen++] = '+';
if (flagc & FLAGC_LEFTADJ) fltfmt->ptr[fmtlen++] = '-';
if (flagc & FLAGC_ZEROPAD) fltfmt->ptr[fmtlen++] = '0';
fb.fmt.ptr[fmtlen++] = '%';
if (flagc & FLAGC_SPACE) fb.fmt.ptr[fmtlen++] = ' ';
if (flagc & FLAGC_SHARP) fb.fmt.ptr[fmtlen++] = '#';
if (flagc & FLAGC_SIGN) fb.fmt.ptr[fmtlen++] = '+';
if (flagc & FLAGC_LEFTADJ) fb.fmt.ptr[fmtlen++] = '-';
if (flagc & FLAGC_ZEROPAD) fb.fmt.ptr[fmtlen++] = '0';
if (flagc & FLAGC_STAR1) fltfmt->ptr[fmtlen++] = '*';
if (flagc & FLAGC_STAR1) fb.fmt.ptr[fmtlen++] = '*';
else if (flagc & FLAGC_WIDTH)
{
fmtlen += hcl_fmtuintmaxtombs (
&fltfmt->ptr[fmtlen], fltfmt->capa - fmtlen,
fmtlen += hcl_fmt_uintmax_to_bcstr(
&fb.fmt.ptr[fmtlen], fb.fmt.capa - fmtlen,
width, 10, -1, '\0', HCL_NULL);
}
if (flagc & FLAGC_DOT) fltfmt->ptr[fmtlen++] = '.';
if (flagc & FLAGC_STAR2) fltfmt->ptr[fmtlen++] = '*';
if (flagc & FLAGC_DOT) fb.fmt.ptr[fmtlen++] = '.';
if (flagc & FLAGC_STAR2) fb.fmt.ptr[fmtlen++] = '*';
else if (flagc & FLAGC_PRECISION)
{
fmtlen += hcl_fmtuintmaxtombs (
&fltfmt->ptr[fmtlen], fltfmt->capa - fmtlen,
fmtlen += hcl_fmt_uintmax_to_bcstr(
&fb.fmt.ptr[fmtlen], fb.fmt.capa - fmtlen,
precision, 10, -1, '\0', HCL_NULL);
}
if (dtype == LF_LD)
fltfmt->ptr[fmtlen++] = 'L';
fb.fmt.ptr[fmtlen++] = 'L';
#if (HCL_SIZEOF___FLOAT128 > 0)
else if (dtype == LF_QD)
fltfmt->ptr[fmtlen++] = 'Q';
fb.fmt.ptr[fmtlen++] = 'Q';
#endif
fltfmt->ptr[fmtlen++] = ch;
fltfmt->ptr[fmtlen] = '\0';
fb.fmt.ptr[fmtlen++] = uch;
fb.fmt.ptr[fmtlen] = '\0';
#if defined(HAVE_SNPRINTF)
/* nothing special here */
@ -1027,78 +1172,65 @@ static int fmt_outv (hcl_fmtout_t* fmtout, va_list ap)
/* best effort to avoid buffer overflow when no snprintf is available.
* i really can't do much if it happens. */
newcapa = precision + width + 32;
if (fltout->capa < newcapa)
if (fb.out.capa < newcapa)
{
HCL_ASSERT (hcl, fltout->ptr == fltout->buf);
HCL_ASSERT (moo, fb.out.ptr == fb.out.sbuf);
fltout->ptr = HCL_MMGR_ALLOC(HCL_MMGR_GETDFL(), HCL_SIZEOF(char_t) * (newcapa + 1));
if (!fltout->ptr) goto oops;
fltout->capa = newcapa;
fb.out.ptr = HCL_MMGR_ALLOC(fmtout->mmgr, HCL_SIZEOF(hcl_bch_t) * (newcapa + 1));
if (!fb.out.ptr) goto oops;
fb.out.capa = newcapa;
}
#endif
while (1)
{
if (dtype == LF_LD)
{
#if defined(HAVE_SNPRINTF)
q = snprintf ((hcl_bch_t*)fltout->ptr, fltout->capa + 1, fltfmt->ptr, v_ld);
q = snprintf((hcl_bch_t*)fb.out.ptr, fb.out.capa + 1, fb.fmt.ptr, v.ld);
#else
q = sprintf ((hcl_bch_t*)fltout->ptr, fltfmt->ptr, v_ld);
q = sprintf((hcl_bch_t*)fb.out.ptr, fb.fmt.ptr, v.ld);
#endif
}
#if (HCL_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF)
else if (dtype == LF_QD)
{
q = quadmath_snprintf((hcl_bch_t*)fltout->ptr, fltout->capa + 1, fltfmt->ptr, v_qd);
q = quadmath_snprintf((hcl_bch_t*)fb.out.ptr, fb.out.capa + 1, fb.fmt.ptr, v.qd);
}
#endif
else
{
#if defined(HAVE_SNPRINTF)
q = snprintf ((hcl_bch_t*)fltout->ptr, fltout->capa + 1, fltfmt->ptr, v_d);
q = snprintf((hcl_bch_t*)fb.out.ptr, fb.out.capa + 1, fb.fmt.ptr, v.d);
#else
q = sprintf ((hcl_bch_t*)fltout->ptr, fltfmt->ptr, v_d);
q = sprintf((hcl_bch_t*)fb.out.ptr, fb.fmt.ptr, v.d);
#endif
}
if (q <= -1) goto oops;
if (q <= fltout->capa) break;
if (q <= fb.out.capa) break;
newcapa = fltout->capa * 2;
newcapa = fb.out.capa * 2;
if (newcapa < q) newcapa = q;
if (fltout->ptr == fltout->sbuf)
if (fb.out.ptr == fb.out.sbuf)
{
fltout->ptr = HCL_MMGR_ALLOC(HCL_MMGR_GETDFL(), HCL_SIZEOF(char_t) * (newcapa + 1));
if (!fltout->ptr) goto oops;
fb.out.ptr = (hcl_bch_t*)HCL_MMGR_ALLOC(fmtout->mmgr, HCL_SIZEOF(hcl_bch_t) * (newcapa + 1));
if (!fb.out.ptr) goto oops;
}
else
{
char_t* tmpptr;
tmpptr = HCL_MMGR_REALLOC(HCL_MMGR_GETDFL(), fltout->ptr, HCL_SIZEOF(char_t) * (newcapa + 1));
hcl_bch_t* tmpptr;
tmpptr = (hcl_bch_t*)HCL_MMGR_REALLOC(fmtout->mmgr, fb.out.ptr, HCL_SIZEOF(hcl_bch_t) * (newcapa + 1));
if (!tmpptr) goto oops;
fltout->ptr = tmpptr;
fb.out.ptr = tmpptr;
}
fltout->capa = newcapa;
fb.out.capa = newcapa;
}
if (HCL_SIZEOF(char_t) != HCL_SIZEOF(hcl_bch_t))
{
fltout->ptr[q] = '\0';
while (q > 0)
{
q--;
fltout->ptr[q] = ((hcl_bch_t*)fltout->ptr)[q];
}
}
sp = fltout->ptr;
flagc &= ~FLAGC_DOT;
width = 0;
precision = 0;
goto print_lowercase_s;
bsp = fb.out.ptr;
n = 0; while (bsp[n] != '\0') n++;
PUT_BCS (fmtout, bsp, n);
break;
}
#endif
@ -1297,9 +1429,17 @@ static int fmt_outv (hcl_fmtout_t* fmtout, va_list ap)
}
done:
#if defined(HCL_ENABLE_FLTFMT)
if (fb.fmt.ptr != fb.fmt.sbuf) HCL_MMGR_FREE (fmtout->mmgr, fb.fmt.ptr);
if (fb.out.ptr != fb.out.sbuf) HCL_MMGR_FREE (fmtout->mmgr, fb.out.ptr);
#endif
return 0;
oops:
#if defined(HCL_ENABLE_FLTFMT)
if (fb.fmt.ptr != fb.fmt.sbuf) HCL_MMGR_FREE (fmtout->mmgr, fb.fmt.ptr);
if (fb.out.ptr != fb.out.sbuf) HCL_MMGR_FREE (fmtout->mmgr, fb.out.ptr);
#endif
return -1;
}
@ -1557,8 +1697,9 @@ hcl_ooi_t hcl_logbfmtv (hcl_t* hcl, hcl_bitmask_t mask, const hcl_bch_t* fmt, va
fo.fmt_str = fmt;
fo.ctx = hcl;
fo.mask = mask;
fo.putbcs = log_bcs;
fo.putucs = log_ucs;
fo.mmgr = hcl_getmmgr(hcl);
fo.putbchars = log_bcs;
fo.putuchars = log_ucs;
fo.putobj = hcl_fmt_object_;
x = fmt_outv(&fo, ap);
@ -1611,8 +1752,9 @@ hcl_ooi_t hcl_logufmtv (hcl_t* hcl, hcl_bitmask_t mask, const hcl_uch_t* fmt, va
fo.fmt_str = fmt;
fo.ctx = hcl;
fo.mask = mask;
fo.putbcs = log_bcs;
fo.putucs = log_ucs;
fo.mmgr = hcl_getmmgr(hcl);
fo.putbchars = log_bcs;
fo.putuchars = log_ucs;
fo.putobj = hcl_fmt_object_;
x = fmt_outv(&fo, ap);
@ -1756,8 +1898,9 @@ hcl_ooi_t hcl_prbfmtv (hcl_t* hcl, const hcl_bch_t* fmt, va_list ap)
fo.fmt_str = fmt;
fo.ctx = hcl;
fo.mask = 0;
fo.putbcs = print_bcs;
fo.putucs = print_ucs;
fo.mmgr = hcl_getmmgr(hcl);
fo.putbchars = print_bcs;
fo.putuchars = print_ucs;
fo.putobj = hcl_fmt_object_;
x = fmt_outv(&fo, ap);
@ -1788,8 +1931,9 @@ hcl_ooi_t hcl_prufmtv (hcl_t* hcl, const hcl_uch_t* fmt, va_list ap)
fo.fmt_str = fmt;
fo.ctx = hcl;
fo.mask = 0;
fo.putbcs = print_bcs;
fo.putucs = print_ucs;
fo.mmgr = hcl_getmmgr(hcl);
fo.putbchars = print_bcs;
fo.putuchars = print_ucs;
fo.putobj = hcl_fmt_object_;
x = fmt_outv(&fo, ap);
@ -2637,8 +2781,8 @@ int hcl_strfmtcallstack (hcl_t* hcl, hcl_ooi_t nargs)
HCL_MEMSET (&fo, 0, HCL_SIZEOF(fo));
fo.ctx = hcl;
fo.putbcs = sprint_bcs;
fo.putucs = sprint_ucs;
fo.putbchars = sprint_bcs;
fo.putuchars = sprint_ucs;
fo.putobj = hcl_fmt_object_;
/* format_stack_args doesn't use fmt_str and fmt_type.
* it takes the format string from the stack. */
@ -2653,9 +2797,12 @@ int hcl_prfmtcallstack (hcl_t* hcl, hcl_ooi_t nargs)
hcl_fmtout_t fo;
HCL_MEMSET (&fo, 0, HCL_SIZEOF(fo));
fo.mask = 0;
fo.mmgr = hcl_getmmgr(hcl);
fo.ctx = hcl;
fo.putbcs = print_bcs;
fo.putucs = print_ucs;
fo.putbchars = print_bcs;
fo.putuchars = print_ucs;
fo.putobj = hcl_fmt_object_;
/* format_stack_args doesn't use fmt_str and fmt_type.
* it takes the format string from the stack. */
@ -2681,9 +2828,10 @@ int hcl_logfmtcallstack (hcl_t* hcl, hcl_ooi_t nargs)
fo.mask |= (hcl->log.default_type_mask & HCL_LOG_ALL_TYPES);
}
fo.mmgr = hcl_getmmgr(hcl);
fo.ctx = hcl;
fo.putbcs = log_bcs;
fo.putucs = log_ucs;
fo.putbchars = log_bcs;
fo.putuchars = log_ucs;
fo.putobj = hcl_fmt_object_;
/* format_stack_args doesn't use fmt_str and fmt_type.
* it takes the format string from the stack. */

View File

@ -335,6 +335,50 @@
# error UNKNOWN INTMAX SIZE
#endif
/* =========================================================================
* FLOATING-POINT TYPE
* ========================================================================= */
/** \typedef hcl_fltbas_t
* The hcl_fltbas_t type defines the largest floating-pointer number type
* naturally supported.
*/
#if defined(__FreeBSD__) || defined(__MINGW32__)
/* TODO: check if the support for long double is complete.
* if so, use long double for hcl_flt_t */
typedef double hcl_fltbas_t;
# define HCL_SIZEOF_FLTBAS_T HCL_SIZEOF_DOUBLE
#elif HCL_SIZEOF_LONG_DOUBLE > HCL_SIZEOF_DOUBLE
typedef long double hcl_fltbas_t;
# define HCL_SIZEOF_FLTBAS_T HCL_SIZEOF_LONG_DOUBLE
#else
typedef double hcl_fltbas_t;
# define HCL_SIZEOF_FLTBAS_T HCL_SIZEOF_DOUBLE
#endif
/** \typedef hcl_fltmax_t
* The hcl_fltmax_t type defines the largest floating-pointer number type
* ever supported.
*/
#if HCL_SIZEOF___FLOAT128 >= HCL_SIZEOF_FLTBAS_T
/* the size of long double may be equal to the size of __float128
* for alignment on some platforms */
typedef __float128 hcl_fltmax_t;
# define HCL_SIZEOF_FLTMAX_T HCL_SIZEOF___FLOAT128
# define HCL_FLTMAX_REQUIRE_QUADMATH 1
#else
typedef hcl_fltbas_t hcl_fltmax_t;
# define HCL_SIZEOF_FLTMAX_T HCL_SIZEOF_FLTBAS_T
# undef HCL_FLTMAX_REQUIRE_QUADMATH
#endif
#if defined(HCL_USE_FLTMAX)
typedef hcl_fltmax_t hcl_flt_t;
#define HCL_SIZEOF_FLT_T HCL_SIZEOF_FLTMAX_T
#else
typedef hcl_fltbas_t hcl_flt_t;
#define HCL_SIZEOF_FLT_T HCL_SIZEOF_FLTBAS_T
#endif
/* =========================================================================
* BASIC HARD-CODED DEFINES
* ========================================================================= */

389
lib/hcl-fmt.h Normal file
View File

@ -0,0 +1,389 @@
/*
* $Id$
*
Copyright (c) 2016-2018 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.
*/
#ifndef _HCL_FMT_H_
#define _HCL_FMT_H_
#include "hcl-cmn.h"
#include <stdarg.h>
/** \file
* This file defines various formatting functions.
*/
/**
* The hcl_fmt_intmax_flag_t type defines enumerators to change the
* behavior of hcl_fmt_intmax() and hcl_fmt_uintmax().
*/
enum hcl_fmt_intmax_flag_t
{
/* Use lower 6 bits to represent base between 2 and 36 inclusive.
* Upper bits are used for these flag options */
/** Don't truncate if the buffer is not large enough */
HCL_FMT_INTMAX_NOTRUNC = (0x40 << 0),
#define HCL_FMT_INTMAX_NOTRUNC HCL_FMT_INTMAX_NOTRUNC
#define HCL_FMT_UINTMAX_NOTRUNC HCL_FMT_INTMAX_NOTRUNC
#define HCL_FMT_INTMAX_TO_BCSTR_NOTRUNC HCL_FMT_INTMAX_NOTRUNC
#define HCL_FMT_UINTMAX_TO_BCSTR_NOTRUNC HCL_FMT_INTMAX_NOTRUNC
#define HCL_FMT_INTMAX_TO_UCSTR_NOTRUNC HCL_FMT_INTMAX_NOTRUNC
#define HCL_FMT_UINTMAX_TO_UCSTR_NOTRUNC HCL_FMT_INTMAX_NOTRUNC
#define HCL_FMT_INTMAX_TO_OOCSTR_NOTRUNC HCL_FMT_INTMAX_NOTRUNC
#define HCL_FMT_UINTMAX_TO_OOCSTR_NOTRUNC HCL_FMT_INTMAX_NOTRUNC
/** Don't append a terminating null */
HCL_FMT_INTMAX_NONULL = (0x40 << 1),
#define HCL_FMT_INTMAX_NONULL HCL_FMT_INTMAX_NONULL
#define HCL_FMT_UINTMAX_NONULL HCL_FMT_INTMAX_NONULL
#define HCL_FMT_INTMAX_TO_BCSTR_NONULL HCL_FMT_INTMAX_NONULL
#define HCL_FMT_UINTMAX_TO_BCSTR_NONULL HCL_FMT_INTMAX_NONULL
#define HCL_FMT_INTMAX_TO_UCSTR_NONULL HCL_FMT_INTMAX_NONULL
#define HCL_FMT_UINTMAX_TO_UCSTR_NONULL HCL_FMT_INTMAX_NONULL
#define HCL_FMT_INTMAX_TO_OOCSTR_NONULL HCL_FMT_INTMAX_NONULL
#define HCL_FMT_UINTMAX_TO_OOCSTR_NONULL HCL_FMT_INTMAX_NONULL
/** Produce no digit for a value of zero */
HCL_FMT_INTMAX_NOZERO = (0x40 << 2),
#define HCL_FMT_INTMAX_NOZERO HCL_FMT_INTMAX_NOZERO
#define HCL_FMT_UINTMAX_NOZERO HCL_FMT_INTMAX_NOZERO
#define HCL_FMT_INTMAX_TO_BCSTR_NOZERO HCL_FMT_INTMAX_NOZERO
#define HCL_FMT_UINTMAX_TO_BCSTR_NOZERO HCL_FMT_INTMAX_NOZERO
#define HCL_FMT_INTMAX_TO_UCSTR_NOZERO HCL_FMT_INTMAX_NOZERO
#define HCL_FMT_UINTMAX_TO_UCSTR_NOZERO HCL_FMT_INTMAX_NOZERO
#define HCL_FMT_INTMAX_TO_OOCSTR_NOZERO HCL_FMT_INTMAX_NOZERO
#define HCL_FMT_UINTMAX_TO_OOCSTR_NOZERO HCL_FMT_INTMAX_NOZERO
/** Produce a leading zero for a non-zero value */
HCL_FMT_INTMAX_ZEROLEAD = (0x40 << 3),
#define HCL_FMT_INTMAX_ZEROLEAD HCL_FMT_INTMAX_ZEROLEAD
#define HCL_FMT_UINTMAX_ZEROLEAD HCL_FMT_INTMAX_ZEROLEAD
#define HCL_FMT_INTMAX_TO_BCSTR_ZEROLEAD HCL_FMT_INTMAX_ZEROLEAD
#define HCL_FMT_UINTMAX_TO_BCSTR_ZEROLEAD HCL_FMT_INTMAX_ZEROLEAD
#define HCL_FMT_INTMAX_TO_UCSTR_ZEROLEAD HCL_FMT_INTMAX_ZEROLEAD
#define HCL_FMT_UINTMAX_TO_UCSTR_ZEROLEAD HCL_FMT_INTMAX_ZEROLEAD
#define HCL_FMT_INTMAX_TO_OOCSTR_ZEROLEAD HCL_FMT_INTMAX_ZEROLEAD
#define HCL_FMT_UINTMAX_TO_OOCSTR_ZEROLEAD HCL_FMT_INTMAX_ZEROLEAD
/** Use uppercase letters for alphabetic digits */
HCL_FMT_INTMAX_UPPERCASE = (0x40 << 4),
#define HCL_FMT_INTMAX_UPPERCASE HCL_FMT_INTMAX_UPPERCASE
#define HCL_FMT_UINTMAX_UPPERCASE HCL_FMT_INTMAX_UPPERCASE
#define HCL_FMT_INTMAX_TO_BCSTR_UPPERCASE HCL_FMT_INTMAX_UPPERCASE
#define HCL_FMT_UINTMAX_TO_BCSTR_UPPERCASE HCL_FMT_INTMAX_UPPERCASE
#define HCL_FMT_INTMAX_TO_UCSTR_UPPERCASE HCL_FMT_INTMAX_UPPERCASE
#define HCL_FMT_UINTMAX_TO_UCSTR_UPPERCASE HCL_FMT_INTMAX_UPPERCASE
#define HCL_FMT_INTMAX_TO_OOCSTR_UPPERCASE HCL_FMT_INTMAX_UPPERCASE
#define HCL_FMT_UINTMAX_TO_OOCSTR_UPPERCASE HCL_FMT_INTMAX_UPPERCASE
/** Insert a plus sign for a positive integer including 0 */
HCL_FMT_INTMAX_PLUSSIGN = (0x40 << 5),
#define HCL_FMT_INTMAX_PLUSSIGN HCL_FMT_INTMAX_PLUSSIGN
#define HCL_FMT_UINTMAX_PLUSSIGN HCL_FMT_INTMAX_PLUSSIGN
#define HCL_FMT_INTMAX_TO_BCSTR_PLUSSIGN HCL_FMT_INTMAX_PLUSSIGN
#define HCL_FMT_UINTMAX_TO_BCSTR_PLUSSIGN HCL_FMT_INTMAX_PLUSSIGN
#define HCL_FMT_INTMAX_TO_UCSTR_PLUSSIGN HCL_FMT_INTMAX_PLUSSIGN
#define HCL_FMT_UINTMAX_TO_UCSTR_PLUSSIGN HCL_FMT_INTMAX_PLUSSIGN
#define HCL_FMT_INTMAX_TO_OOCSTR_PLUSSIGN HCL_FMT_INTMAX_PLUSSIGN
#define HCL_FMT_UINTMAX_TO_OOCSTR_PLUSSIGN HCL_FMT_INTMAX_PLUSSIGN
/** Insert a space for a positive integer including 0 */
HCL_FMT_INTMAX_EMPTYSIGN = (0x40 << 6),
#define HCL_FMT_INTMAX_EMPTYSIGN HCL_FMT_INTMAX_EMPTYSIGN
#define HCL_FMT_UINTMAX_EMPTYSIGN HCL_FMT_INTMAX_EMPTYSIGN
#define HCL_FMT_INTMAX_TO_BCSTR_EMPTYSIGN HCL_FMT_INTMAX_EMPTYSIGN
#define HCL_FMT_UINTMAX_TO_BCSTR_EMPTYSIGN HCL_FMT_INTMAX_EMPTYSIGN
#define HCL_FMT_INTMAX_TO_UCSTR_EMPTYSIGN HCL_FMT_INTMAX_EMPTYSIGN
#define HCL_FMT_UINTMAX_TO_UCSTR_EMPTYSIGN HCL_FMT_INTMAX_EMPTYSIGN
/** Fill the right part of the string */
HCL_FMT_INTMAX_FILLRIGHT = (0x40 << 7),
#define HCL_FMT_INTMAX_FILLRIGHT HCL_FMT_INTMAX_FILLRIGHT
#define HCL_FMT_UINTMAX_FILLRIGHT HCL_FMT_INTMAX_FILLRIGHT
#define HCL_FMT_INTMAX_TO_BCSTR_FILLRIGHT HCL_FMT_INTMAX_FILLRIGHT
#define HCL_FMT_UINTMAX_TO_BCSTR_FILLRIGHT HCL_FMT_INTMAX_FILLRIGHT
#define HCL_FMT_INTMAX_TO_UCSTR_FILLRIGHT HCL_FMT_INTMAX_FILLRIGHT
#define HCL_FMT_UINTMAX_TO_UCSTR_FILLRIGHT HCL_FMT_INTMAX_FILLRIGHT
#define HCL_FMT_INTMAX_TO_OOCSTR_FILLRIGHT HCL_FMT_INTMAX_FILLRIGHT
#define HCL_FMT_UINTMAX_TO_OOCSTR_FILLRIGHT HCL_FMT_INTMAX_FILLRIGHT
/** Fill between the sign chacter and the digit part */
HCL_FMT_INTMAX_FILLCENTER = (0x40 << 8)
#define HCL_FMT_INTMAX_FILLCENTER HCL_FMT_INTMAX_FILLCENTER
#define HCL_FMT_UINTMAX_FILLCENTER HCL_FMT_INTMAX_FILLCENTER
#define HCL_FMT_INTMAX_TO_BCSTR_FILLCENTER HCL_FMT_INTMAX_FILLCENTER
#define HCL_FMT_UINTMAX_TO_BCSTR_FILLCENTER HCL_FMT_INTMAX_FILLCENTER
#define HCL_FMT_INTMAX_TO_UCSTR_FILLCENTER HCL_FMT_INTMAX_FILLCENTER
#define HCL_FMT_UINTMAX_TO_UCSTR_FILLCENTER HCL_FMT_INTMAX_FILLCENTER
#define HCL_FMT_INTMAX_TO_OOCSTR_FILLCENTER HCL_FMT_INTMAX_FILLCENTER
#define HCL_FMT_UINTMAX_TO_OOCSTR_FILLCENTER HCL_FMT_INTMAX_FILLCENTER
};
/* =========================================================================
* FORMATTED OUTPUT
* ========================================================================= */
typedef struct hcl_fmtout_t hcl_fmtout_t;
typedef int (*hcl_fmtout_putbchars_t) (
hcl_fmtout_t* fmtout,
const hcl_bch_t* ptr,
hcl_oow_t len
);
typedef int (*hcl_fmtout_putuchars_t) (
hcl_fmtout_t* fmtout,
const hcl_uch_t* ptr,
hcl_oow_t len
);
typedef int (*hcl_fmtout_putobj_t) (
hcl_fmtout_t* fmtout,
hcl_oop_t obj
);
enum hcl_fmtout_fmt_type_t
{
HCL_FMTOUT_FMT_TYPE_BCH = 0,
HCL_FMTOUT_FMT_TYPE_UCH
};
typedef enum hcl_fmtout_fmt_type_t hcl_fmtout_fmt_type_t;
struct hcl_fmtout_t
{
hcl_oow_t count; /* out */
hcl_mmgr_t* mmgr; /* in */
hcl_fmtout_putbchars_t putbchars; /* in */
hcl_fmtout_putuchars_t putuchars; /* in */
hcl_fmtout_putobj_t putobj; /* in - %O is not handled if it's not set. */
hcl_bitmask_t mask; /* in */
void* ctx; /* in */
/* internally set as input */
hcl_fmtout_fmt_type_t fmt_type;
const void* fmt_str;
};
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The hcl_fmt_intmax_to_bcstr() function formats an integer \a value to a
* multibyte string according to the given base and writes it to a buffer
* pointed to by \a buf. It writes to the buffer at most \a size characters
* including the terminating null. The base must be between 2 and 36 inclusive
* and can be ORed with zero or more #hcl_fmt_intmax_to_bcstr_flag_t enumerators.
* This ORed value is passed to the function via the \a base_and_flags
* parameter. If the formatted string is shorter than \a bufsize, the redundant
* slots are filled with the fill character \a fillchar if it is not a null
* character. The filling behavior is determined by the flags shown below:
*
* - If #HCL_FMT_INTMAX_TO_BCSTR_FILLRIGHT is set in \a base_and_flags, slots
* after the formatting string are filled.
* - If #HCL_FMT_INTMAX_TO_BCSTR_FILLCENTER is set in \a base_and_flags, slots
* before the formatting string are filled. However, if it contains the
* sign character, the slots between the sign character and the digit part
* are filled.
* - If neither #HCL_FMT_INTMAX_TO_BCSTR_FILLRIGHT nor #HCL_FMT_INTMAX_TO_BCSTR_FILLCENTER
* , slots before the formatting string are filled.
*
* The \a precision parameter specified the minimum number of digits to
* produce from the \a value. If \a value produces fewer digits than
* \a precision, the actual digits are padded with '0' to meet the precision
* requirement. You can pass a negative number if you don't wish to specify
* precision.
*
* The terminating null is not added if #HCL_FMT_INTMAX_TO_BCSTR_NONULL is set;
* The #HCL_FMT_INTMAX_TO_BCSTR_UPPERCASE flag indicates that the function should
* use the uppercase letter for a alphabetic digit;
* You can set #HCL_FMT_INTMAX_TO_BCSTR_NOTRUNC if you require lossless formatting.
* The #HCL_FMT_INTMAX_TO_BCSTR_PLUSSIGN flag and #HCL_FMT_INTMAX_TO_BCSTR_EMPTYSIGN
* ensures that the plus sign and a space is added for a positive integer
* including 0 respectively.
* The #HCL_FMT_INTMAX_TO_BCSTR_ZEROLEAD flag ensures that the numeric string
* begins with '0' before applying the prefix.
* You can set the #HCL_FMT_INTMAX_TO_BCSTR_NOZERO flag if you want the value of
* 0 to produce nothing. If both #HCL_FMT_INTMAX_TO_BCSTR_NOZERO and
* #HCL_FMT_INTMAX_TO_BCSTR_ZEROLEAD are specified, '0' is still produced.
*
* If \a prefix is not #HCL_NULL, it is inserted before the digits.
*
* \return
* - -1 if the base is not between 2 and 36 inclusive.
* - negated number of characters required for lossless formatting
* - if \a bufsize is 0.
* - if #HCL_FMT_INTMAX_TO_BCSTR_NOTRUNC is set and \a bufsize is less than
* the minimum required for lossless formatting.
* - number of characters written to the buffer excluding a terminating
* null in all other cases.
*/
HCL_EXPORT int hcl_fmt_intmax_to_bcstr (
hcl_bch_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
hcl_intmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
hcl_bch_t fillchar, /**< fill character */
const hcl_bch_t* prefix /**< prefix */
);
/**
* The hcl_fmt_intmax_to_ucstr() function formats an integer \a value to a
* wide-character string according to the given base and writes it to a buffer
* pointed to by \a buf. It writes to the buffer at most \a size characters
* including the terminating null. The base must be between 2 and 36 inclusive
* and can be ORed with zero or more #hcl_fmt_intmax_to_ucstr_flag_t enumerators.
* This ORed value is passed to the function via the \a base_and_flags
* parameter. If the formatted string is shorter than \a bufsize, the redundant
* slots are filled with the fill character \a fillchar if it is not a null
* character. The filling behavior is determined by the flags shown below:
*
* - If #HCL_FMT_INTMAX_TO_UCSTR_FILLRIGHT is set in \a base_and_flags, slots
* after the formatting string are filled.
* - If #HCL_FMT_INTMAX_TO_UCSTR_FILLCENTER is set in \a base_and_flags, slots
* before the formatting string are filled. However, if it contains the
* sign character, the slots between the sign character and the digit part
* are filled.
* - If neither #HCL_FMT_INTMAX_TO_UCSTR_FILLRIGHT nor #HCL_FMT_INTMAX_TO_UCSTR_FILLCENTER
* , slots before the formatting string are filled.
*
* The \a precision parameter specified the minimum number of digits to
* produce from the \ value. If \a value produces fewer digits than
* \a precision, the actual digits are padded with '0' to meet the precision
* requirement. You can pass a negative number if don't wish to specify
* precision.
*
* The terminating null is not added if #HCL_FMT_INTMAX_TO_UCSTR_NONULL is set;
* The #HCL_FMT_INTMAX_TO_UCSTR_UPPERCASE flag indicates that the function should
* use the uppercase letter for a alphabetic digit;
* You can set #HCL_FMT_INTMAX_TO_UCSTR_NOTRUNC if you require lossless formatting.
* The #HCL_FMT_INTMAX_TO_UCSTR_PLUSSIGN flag and #HCL_FMT_INTMAX_TO_UCSTR_EMPTYSIGN
* ensures that the plus sign and a space is added for a positive integer
* including 0 respectively.
* The #HCL_FMT_INTMAX_TO_UCSTR_ZEROLEAD flag ensures that the numeric string
* begins with 0 before applying the prefix.
* You can set the #HCL_FMT_INTMAX_TO_UCSTR_NOZERO flag if you want the value of
* 0 to produce nothing. If both #HCL_FMT_INTMAX_TO_UCSTR_NOZERO and
* #HCL_FMT_INTMAX_TO_UCSTR_ZEROLEAD are specified, '0' is still produced.
*
* If \a prefix is not #HCL_NULL, it is inserted before the digits.
*
* \return
* - -1 if the base is not between 2 and 36 inclusive.
* - negated number of characters required for lossless formatting
* - if \a bufsize is 0.
* - if #HCL_FMT_INTMAX_TO_UCSTR_NOTRUNC is set and \a bufsize is less than
* the minimum required for lossless formatting.
* - number of characters written to the buffer excluding a terminating
* null in all other cases.
*/
HCL_EXPORT int hcl_fmt_intmax_to_ucstr (
hcl_uch_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
hcl_intmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
hcl_uch_t fillchar, /**< fill character */
const hcl_uch_t* prefix /**< prefix */
);
/**
* The hcl_fmt_uintmax_to_bcstr() function formats an unsigned integer \a value
* to a multibyte string buffer. It behaves the same as hcl_fmt_intmax_to_bcstr()
* except that it handles an unsigned integer.
*/
HCL_EXPORT int hcl_fmt_uintmax_to_bcstr (
hcl_bch_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
hcl_uintmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
hcl_bch_t fillchar, /**< fill character */
const hcl_bch_t* prefix /**< prefix */
);
/**
* The hcl_fmt_uintmax_to_ucstr() function formats an unsigned integer \a value
* to a multibyte string buffer. It behaves the same as hcl_fmt_intmax_to_ucstr()
* except that it handles an unsigned integer.
*/
HCL_EXPORT int hcl_fmt_uintmax_to_ucstr (
hcl_uch_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
hcl_uintmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
hcl_uch_t fillchar, /**< fill character */
const hcl_uch_t* prefix /**< prefix */
);
#if defined(HCL_OOCH_IS_BCH)
# define hcl_fmt_intmax_to_oocstr hcl_fmt_intmax_to_bcstr
# define hcl_fmt_uintmax_to_oocstr hcl_fmt_uintmax_to_bcstr
#else
# define hcl_fmt_intmax_to_oocstr hcl_fmt_intmax_to_ucstr
# define hcl_fmt_uintmax_to_oocstr hcl_fmt_uintmax_to_ucstr
#endif
/* TODO: hcl_fmt_fltmax_to_bcstr()... hcl_fmt_fltmax_to_ucstr() */
/* =========================================================================
* FORMATTED OUTPUT
* ========================================================================= */
HCL_EXPORT int hcl_bfmt_outv (
hcl_fmtout_t* fmtout,
const hcl_bch_t* fmt,
va_list ap
);
HCL_EXPORT int hcl_ufmt_outv (
hcl_fmtout_t* fmtout,
const hcl_uch_t* fmt,
va_list ap
);
HCL_EXPORT int hcl_bfmt_out (
hcl_fmtout_t* fmtout,
const hcl_bch_t* fmt,
...
);
HCL_EXPORT int hcl_ufmt_out (
hcl_fmtout_t* fmtout,
const hcl_uch_t* fmt,
...
);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -28,6 +28,7 @@
#define _HCL_PRV_H_
#include "hcl.h"
#include "hcl-fmt.h"
#include "hcl-utl.h"
/* you can define this to either 1 or 2 */
@ -42,6 +43,9 @@
#define HCL_KARATSUBA_CUTOFF 32
#define HCL_KARATSUBA_CUTOFF_DEBUG 3
/* enable floating-pointer number support in the basic formatting functions */
#define HCL_ENABLE_FLTFMT
#if defined(HCL_BUILD_DEBUG)
#define HCL_DEBUG_LEXER 1
#define HCL_DEBUG_VM_PROCESSOR 1

View File

@ -37,9 +37,7 @@
* This sample code adds a series of keys and values and print them
* in descending key order.
* \code
* #include <hcl/cmn/rbt.h>
* #include <hcl/cmn/mem.h>
* #include <hcl/cmn/sio.h>
* #include <hcl-rbt.h>
*
* static hcl_rbt_walk_t walk (hcl_rbt_t* rbt, hcl_rbt_pair_t* pair, void* ctx)
* {
@ -53,8 +51,8 @@
* hcl_rbt_t* s1;
* int i;
*
* s1 = hcl_rbt_open (HCL_MMGR_GETDFL(), 0, 1, 1); // error handling skipped
* hcl_rbt_setstyle (s1, hcl_get_rbt_style(HCL_RBT_STYLE_INLINE_COPIERS));
* s1 = hcl_rbt_open(HCL_MMGR_GETDFL(), 0, 1, 1); // error handling skipped
* hcl_rbt_setstyle(s1, hcl_get_rbt_style(HCL_RBT_STYLE_INLINE_COPIERS));
*
* for (i = 0; i < 20; i++)
* {

View File

@ -288,52 +288,6 @@
#define HCL_HASH_MORE_UCSTR(hv, ptr) HCL_HASH_MORE_VPTR(hv, ptr, const hcl_uch_t)
/* =========================================================================
* FORMATTED OUTPUT
* ========================================================================= */
typedef struct hcl_fmtout_t hcl_fmtout_t;
typedef int (*hcl_fmtout_putbcs_t) (
hcl_fmtout_t* fmtout,
const hcl_bch_t* ptr,
hcl_oow_t len
);
typedef int (*hcl_fmtout_putucs_t) (
hcl_fmtout_t* fmtout,
const hcl_uch_t* ptr,
hcl_oow_t len
);
typedef int (*hcl_fmtout_putobj_t) (
hcl_fmtout_t* fmtout,
hcl_oop_t obj
);
enum hcl_fmtout_fmt_type_t
{
HCL_FMTOUT_FMT_TYPE_BCH = 0,
HCL_FMTOUT_FMT_TYPE_UCH
};
typedef enum hcl_fmtout_fmt_type_t hcl_fmtout_fmt_type_t;
struct hcl_fmtout_t
{
hcl_oow_t count; /* out */
hcl_fmtout_putbcs_t putbcs; /* in */
hcl_fmtout_putucs_t putucs; /* in */
hcl_fmtout_putobj_t putobj; /* in - %O is not handled if it's not set. */
hcl_bitmask_t mask; /* in */
void* ctx; /* in */
hcl_fmtout_fmt_type_t fmt_type;
const void* fmt_str;
};
#if defined(__cplusplus)
extern "C" {
#endif
@ -730,34 +684,6 @@ HCL_EXPORT int hcl_ucwidth (
hcl_uch_t uc
);
/* =========================================================================
* FORMATTED OUTPUT
* ========================================================================= */
HCL_EXPORT int hcl_bfmt_outv (
hcl_fmtout_t* fmtout,
const hcl_bch_t* fmt,
va_list ap
);
HCL_EXPORT int hcl_ufmt_outv (
hcl_fmtout_t* fmtout,
const hcl_uch_t* fmt,
va_list ap
);
HCL_EXPORT int hcl_bfmt_out (
hcl_fmtout_t* fmtout,
const hcl_bch_t* fmt,
...
);
HCL_EXPORT int hcl_ufmt_out (
hcl_fmtout_t* fmtout,
const hcl_uch_t* fmt,
...
);
/* =========================================================================
* TIME CALCULATION WITH OVERFLOW/UNDERFLOW DETECTION
* ========================================================================= */