cleaned up code and build files
This commit is contained in:
parent
0823ddc2d0
commit
656e0150a9
@ -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 \
|
||||
|
@ -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 \
|
||||
|
16
lib/err.c
16
lib/err.c
@ -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;
|
||||
|
||||
|
@ -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
228
lib/fmt-imp.h
Normal 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
360
lib/fmt.c
@ -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. */
|
||||
|
@ -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
389
lib/hcl-fmt.h
Normal 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
|
@ -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
|
||||
|
@ -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++)
|
||||
* {
|
||||
|
@ -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
|
||||
* ========================================================================= */
|
||||
|
Loading…
Reference in New Issue
Block a user