added qse_fmtintmaxtombs()/qse_fmtintmaxtowcs() and related functions.
changed qse_awk_t to use these new formatting functions. redefined some primitive types
This commit is contained in:
@ -1108,25 +1108,6 @@ void qse_awk_rtx_freemem (qse_awk_rtx_t* rtx, void* ptr)
|
||||
qse_awk_freemem (rtx->awk, ptr);
|
||||
}
|
||||
|
||||
int qse_awk_sprintlong (
|
||||
qse_awk_t* awk, qse_char_t* buf, qse_size_t len, qse_long_t num)
|
||||
{
|
||||
return awk->prm.sprintf (
|
||||
awk, buf, len,
|
||||
#if QSE_SIZEOF_LONG_LONG > 0
|
||||
QSE_T("%lld"), (long long)num
|
||||
#elif QSE_SIZEOF___INT64 > 0
|
||||
QSE_T("%I64d"), (__int64)num
|
||||
#elif QSE_SIZEOF_LONG > 0
|
||||
QSE_T("%ld"), (long)num
|
||||
#elif QSE_SIZEOF_INT > 0
|
||||
QSE_T("%d"), (int)num
|
||||
#else
|
||||
#error unsupported size
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
int qse_awk_sprintreal (
|
||||
qse_awk_t* awk, qse_char_t* buf, qse_size_t len, qse_real_t num)
|
||||
{
|
||||
|
@ -76,14 +76,6 @@ int qse_awk_matchrex (
|
||||
qse_cstr_t* match, qse_awk_errnum_t* errnum
|
||||
);
|
||||
|
||||
int qse_awk_sprintlong (
|
||||
qse_awk_t* awk,
|
||||
qse_char_t* buf,
|
||||
qse_size_t len,
|
||||
qse_long_t num
|
||||
);
|
||||
|
||||
|
||||
int qse_awk_sprintreal (
|
||||
qse_awk_t* awk,
|
||||
qse_char_t* buf,
|
||||
|
@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "awk.h"
|
||||
#include <qse/cmn/fmt.h>
|
||||
|
||||
#ifdef DEBUG_RUN
|
||||
#include <qse/cmn/stdio.h>
|
||||
@ -6777,14 +6778,19 @@ qse_char_t* qse_awk_rtx_format (
|
||||
|
||||
do
|
||||
{
|
||||
n = qse_awk_sprintlong (
|
||||
rtx->awk,
|
||||
n = qse_fmtintmax (
|
||||
rtx->format.tmp.ptr,
|
||||
rtx->format.tmp.len,
|
||||
width
|
||||
);
|
||||
if (n == -1)
|
||||
width,
|
||||
10 | QSE_FMTINTMAX_NOTRUNC,
|
||||
QSE_T('\0')
|
||||
);
|
||||
if (n <= -1)
|
||||
{
|
||||
/* TODO: utilize n in GROW.
|
||||
* since -n is the number of characters required
|
||||
* including terminating null, it can be used there
|
||||
* this doesn't have to be in the loop any more */
|
||||
GROW (&rtx->format.tmp);
|
||||
if (rtx->format.tmp.ptr == QSE_NULL)
|
||||
{
|
||||
@ -6799,6 +6805,8 @@ qse_char_t* qse_awk_rtx_format (
|
||||
}
|
||||
while (1);
|
||||
|
||||
/* TODO: we know that n is the length.
|
||||
* the contents can be added without scanning the whole string again */
|
||||
p = rtx->format.tmp.ptr;
|
||||
while (*p != QSE_T('\0'))
|
||||
{
|
||||
@ -6870,14 +6878,19 @@ qse_char_t* qse_awk_rtx_format (
|
||||
|
||||
do
|
||||
{
|
||||
n = qse_awk_sprintlong (
|
||||
rtx->awk,
|
||||
n = qse_fmtintmax (
|
||||
rtx->format.tmp.ptr,
|
||||
rtx->format.tmp.len,
|
||||
prec
|
||||
);
|
||||
if (n == -1)
|
||||
prec,
|
||||
10 | QSE_FMTINTMAX_NOTRUNC,
|
||||
QSE_T('\0')
|
||||
);
|
||||
if (n <= -1)
|
||||
{
|
||||
/* TODO: utilize n in GROW.
|
||||
* since -n is the number of characters required
|
||||
* including terminating null, it can be used there.
|
||||
* this doesn't have to be in the loop any more */
|
||||
GROW (&rtx->format.tmp);
|
||||
if (rtx->format.tmp.ptr == QSE_NULL)
|
||||
{
|
||||
@ -6891,6 +6904,8 @@ qse_char_t* qse_awk_rtx_format (
|
||||
}
|
||||
while (1);
|
||||
|
||||
/* TODO: we know that n is the length.
|
||||
* the contents can be added without scanning the whole string again */
|
||||
p = rtx->format.tmp.ptr;
|
||||
while (*p != QSE_T('\0'))
|
||||
{
|
||||
|
@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "awk.h"
|
||||
#include <qse/cmn/fmt.h>
|
||||
|
||||
static const qse_char_t* assop_str[] =
|
||||
{
|
||||
@ -268,10 +269,24 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde)
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_char_t buf[64];
|
||||
qse_awk_sprintlong (
|
||||
awk, buf, QSE_COUNTOF(buf),
|
||||
((qse_awk_nde_int_t*)nde)->val);
|
||||
/* Note that the array sizing fomula is not accurate
|
||||
* but should be good enoug consiering the followings.
|
||||
*
|
||||
* size minval digits sign
|
||||
* 1 -128 3 1
|
||||
* 2 -32768 5 1
|
||||
* 4 -2147483648 10 1
|
||||
* 8 -9223372036854775808 19 1
|
||||
* 16 -170141183460469231731687303715884105728 39 1
|
||||
*/
|
||||
qse_char_t buf[QSE_SIZEOF(qse_long_t) * 3 + 2];
|
||||
|
||||
qse_fmtintmax (
|
||||
buf, QSE_COUNTOF(buf),
|
||||
((qse_awk_nde_int_t*)nde)->val,
|
||||
10,
|
||||
QSE_T('\0')
|
||||
);
|
||||
PUT_SRCSTR (awk, buf);
|
||||
}
|
||||
break;
|
||||
|
@ -21,25 +21,23 @@
|
||||
#include <qse/cmn/fmt.h>
|
||||
|
||||
/* ==================== multibyte ===================================== */
|
||||
qse_size_t qse_fmtulongtombs (
|
||||
qse_mchar_t* buf, qse_size_t size,
|
||||
qse_long_t value, int base_and_flags, qse_mchar_t fillchar)
|
||||
static int fmt_unsigned_to_mbs (
|
||||
qse_mchar_t* buf, int size,
|
||||
qse_uintmax_t value, int base_and_flags,
|
||||
qse_mchar_t fillchar, qse_mchar_t signchar)
|
||||
{
|
||||
qse_mchar_t tmp[(QSE_SIZEOF(qse_ulong_t) * 8)];
|
||||
qse_mchar_t tmp[(QSE_SIZEOF(qse_uintmax_t) * 8)];
|
||||
int reslen, base, xsize, reqlen;
|
||||
qse_mchar_t* p, * bp, * be;
|
||||
int base;
|
||||
qse_mchar_t xbasechar;
|
||||
|
||||
base = base_and_flags & 0xFF;
|
||||
if (base < 2 || base > 36 || size <= 0) return 0;
|
||||
if (base < 2 || base > 36) return -1;
|
||||
|
||||
p = tmp;
|
||||
bp = buf;
|
||||
be = buf + size - 1;
|
||||
|
||||
xbasechar = (base_and_flags & QSE_FMTULONGTOMBS_UPPERCASE)? QSE_MT('A'): QSE_MT('a');
|
||||
xbasechar = (base_and_flags & QSE_FMTINTMAXTOMBS_UPPERCASE)? QSE_MT('A'): QSE_MT('a');
|
||||
|
||||
/* store the resulting numeric string into 'tmp' first */
|
||||
p = tmp;
|
||||
do
|
||||
{
|
||||
int digit = value % base;
|
||||
@ -49,66 +47,152 @@ qse_size_t qse_fmtulongtombs (
|
||||
}
|
||||
while (value > 0);
|
||||
|
||||
/* reslen is the length of the resulting string without padding. */
|
||||
reslen = (int)(p - tmp);
|
||||
if (signchar) reslen++; /* increment reslen for the sign character */
|
||||
|
||||
/* get the required buffer size for lossless formatting */
|
||||
reqlen = (base_and_flags & QSE_FMTINTMAXTOMBS_NONULL)? reslen: (reslen + 1);
|
||||
|
||||
if (size <= 0 ||
|
||||
((base_and_flags & QSE_FMTINTMAXTOMBS_NOTRUNC) && size < reqlen))
|
||||
{
|
||||
return -reqlen;
|
||||
}
|
||||
|
||||
xsize = (base_and_flags & QSE_FMTINTMAXTOMBS_NONULL)? size: (size - 1);
|
||||
bp = buf;
|
||||
be = buf + xsize;
|
||||
|
||||
/* fill space */
|
||||
if (fillchar != QSE_MT('\0'))
|
||||
{
|
||||
qse_size_t tmplen = p - tmp;
|
||||
|
||||
if (base_and_flags & QSE_FMTULONGTOMBS_FILLRIGHT)
|
||||
if (base_and_flags & QSE_FMTINTMAXTOMBS_FILLRIGHT)
|
||||
{
|
||||
/* emit sign */
|
||||
if (signchar && bp < be) *bp++ = signchar;
|
||||
|
||||
/* copy the numeric string to the destination buffer */
|
||||
while (p > tmp && bp < be) *bp++ = *--p;
|
||||
|
||||
/* fill the right side */
|
||||
while (size - 1 > tmplen)
|
||||
while (xsize > reslen)
|
||||
{
|
||||
*bp++ = fillchar;
|
||||
size--;
|
||||
xsize--;
|
||||
}
|
||||
}
|
||||
else if (base_and_flags & QSE_FMTINTMAXTOMBS_FILLCENTER)
|
||||
{
|
||||
/* emit sign */
|
||||
if (signchar && bp < be) *bp++ = signchar;
|
||||
|
||||
/* fill the left side */
|
||||
while (xsize > reslen)
|
||||
{
|
||||
*bp++ = fillchar;
|
||||
xsize--;
|
||||
}
|
||||
|
||||
/* copy the numeric string to the destination buffer */
|
||||
while (p > tmp && bp < be) *bp++ = *--p;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fill the left side */
|
||||
while (size - 1 > tmplen)
|
||||
while (xsize > reslen)
|
||||
{
|
||||
*bp++ = fillchar;
|
||||
size--;
|
||||
xsize--;
|
||||
}
|
||||
|
||||
/* emit sign */
|
||||
if (signchar && bp < be) *bp++ = signchar;
|
||||
|
||||
/* 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 the numeric string to the destination buffer */
|
||||
while (p > tmp && bp < be) *bp++ = *--p;
|
||||
}
|
||||
|
||||
*bp = QSE_MT('\0');
|
||||
if (!(base_and_flags & QSE_FMTINTMAXTOMBS_NONULL)) *bp = QSE_MT('\0');
|
||||
return bp - buf;
|
||||
}
|
||||
|
||||
/* ==================== wide-char ===================================== */
|
||||
qse_size_t qse_fmtulongtowcs (
|
||||
qse_wchar_t* buf, qse_size_t size,
|
||||
qse_long_t value, int base_and_flags, qse_wchar_t fillchar)
|
||||
int qse_fmtintmaxtombs (
|
||||
qse_mchar_t* buf, int size,
|
||||
qse_intmax_t value, int base_and_flags, qse_mchar_t fillchar)
|
||||
{
|
||||
qse_wchar_t tmp[(QSE_SIZEOF(qse_ulong_t) * 8)];
|
||||
qse_mchar_t signchar;
|
||||
qse_uintmax_t absvalue;
|
||||
|
||||
if (value < 0)
|
||||
{
|
||||
signchar = QSE_MT('-');
|
||||
absvalue = -value;
|
||||
}
|
||||
else if (base_and_flags & QSE_FMTINTMAXTOMBS_PLUSSIGN)
|
||||
{
|
||||
signchar = QSE_MT('+');
|
||||
absvalue = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
signchar = QSE_MT('\0');
|
||||
absvalue = value;
|
||||
}
|
||||
|
||||
return fmt_unsigned_to_mbs (buf, size, absvalue, base_and_flags, fillchar, signchar);
|
||||
}
|
||||
|
||||
int qse_fmtuintmaxtombs (
|
||||
qse_mchar_t* buf, int size,
|
||||
qse_uintmax_t value, int base_and_flags, qse_mchar_t fillchar)
|
||||
{
|
||||
qse_mchar_t signchar;
|
||||
|
||||
/* determine if a sign character is needed */
|
||||
if (base_and_flags & QSE_FMTINTMAXTOMBS_PLUSSIGN)
|
||||
{
|
||||
signchar = QSE_MT('+');
|
||||
}
|
||||
else
|
||||
{
|
||||
signchar = QSE_MT('\0');
|
||||
}
|
||||
|
||||
return fmt_unsigned_to_mbs (buf, size, value, base_and_flags, fillchar, signchar);
|
||||
}
|
||||
|
||||
|
||||
/* ==================== wide-char ===================================== */
|
||||
|
||||
#if 0
|
||||
static int fmt_unsigned_to_wcs (
|
||||
qse_wchar_t* buf, int size,
|
||||
qse_uintmax_t value, int base_and_flags,
|
||||
qse_wchar_t fillchar, qse_wchar_t signchar)
|
||||
{
|
||||
qse_wchar_t tmp[(QSE_SIZEOF(qse_uintmax_t) * 8)];
|
||||
int reslen, base;
|
||||
qse_wchar_t* p, * bp, * be;
|
||||
int base;
|
||||
qse_wchar_t xbasechar;
|
||||
|
||||
base = base_and_flags & 0xFF;
|
||||
if (base < 2 || base > 36 || size <= 0) return 0;
|
||||
if (base < 2 || base > 36) return -1;
|
||||
|
||||
p = tmp;
|
||||
bp = buf;
|
||||
be = buf + size - 1;
|
||||
|
||||
xbasechar = (base_and_flags & QSE_FMTULONGTOWCS_UPPERCASE)? QSE_WT('A'): QSE_WT('a');
|
||||
xbasechar = (base_and_flags & QSE_FMTINTMAXTOWCS_UPPERCASE)? QSE_WT('A'): QSE_WT('a');
|
||||
|
||||
/* store the resulting numeric string into 'tmp' first */
|
||||
p = tmp;
|
||||
do
|
||||
{
|
||||
int digit = value % base;
|
||||
@ -118,38 +202,75 @@ qse_size_t qse_fmtulongtowcs (
|
||||
}
|
||||
while (value > 0);
|
||||
|
||||
/* reslen is the length of the resulting string without padding. */
|
||||
reslen = (int)(p - tmp);
|
||||
if (signchar) reslen++; /* increment reslen for the sign character */
|
||||
|
||||
if (size <= 0 ||
|
||||
((base_and_flags & QSE_FMTINTMAXTOWCS_NOTRUNC) && size <= reslen))
|
||||
{
|
||||
/* conversion without loss requires at least 'reslen + 1'. */
|
||||
return -(reslen + 1);
|
||||
}
|
||||
|
||||
bp = buf;
|
||||
be = buf + size - 1;
|
||||
|
||||
/* fill space */
|
||||
if (fillchar != QSE_WT('\0'))
|
||||
{
|
||||
qse_size_t tmplen = p - tmp;
|
||||
|
||||
if (base_and_flags & QSE_FMTULONGTOWCS_FILLRIGHT)
|
||||
if (base_and_flags & QSE_FMTINTMAXTOWCS_FILLRIGHT)
|
||||
{
|
||||
/* emit sign */
|
||||
if (signchar && bp < be) *bp++ = signchar;
|
||||
|
||||
/* copy the numeric string to the destination buffer */
|
||||
while (p > tmp && bp < be) *bp++ = *--p;
|
||||
|
||||
/* fill the right side */
|
||||
while (size - 1 > tmplen)
|
||||
while (size - 1 > reslen)
|
||||
{
|
||||
*bp++ = fillchar;
|
||||
size--;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (base_and_flags & QSE_FMTINTMAXTOWCS_FILLCENTER)
|
||||
{
|
||||
/* emit sign */
|
||||
if (signchar && bp < be) *bp++ = signchar;
|
||||
|
||||
/* fill the left side */
|
||||
while (size - 1 > tmplen)
|
||||
while (size - 1 > reslen)
|
||||
{
|
||||
*bp++ = fillchar;
|
||||
size--;
|
||||
}
|
||||
|
||||
/* copy the numeric string to the destination buffer */
|
||||
while (p > tmp && bp < be) *bp++ = *--p;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fill the left side */
|
||||
while (size - 1 > reslen)
|
||||
{
|
||||
*bp++ = fillchar;
|
||||
size--;
|
||||
}
|
||||
|
||||
/* emit sign */
|
||||
if (signchar && bp < be) *bp++ = signchar;
|
||||
|
||||
/* 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 the numeric string to the destination buffer */
|
||||
while (p > tmp && bp < be) *bp++ = *--p;
|
||||
}
|
||||
@ -157,5 +278,156 @@ qse_size_t qse_fmtulongtowcs (
|
||||
*bp = QSE_WT('\0');
|
||||
return bp - buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int fmt_unsigned_to_wcs (
|
||||
qse_wchar_t* buf, int size,
|
||||
qse_uintmax_t value, int base_and_flags,
|
||||
qse_wchar_t fillchar, qse_wchar_t signchar)
|
||||
{
|
||||
qse_wchar_t tmp[(QSE_SIZEOF(qse_uintmax_t) * 8)];
|
||||
int reslen, base, xsize, reqlen;
|
||||
qse_wchar_t* p, * bp, * be;
|
||||
qse_wchar_t xbasechar;
|
||||
|
||||
base = base_and_flags & 0xFF;
|
||||
if (base < 2 || base > 36) return -1;
|
||||
|
||||
xbasechar = (base_and_flags & QSE_FMTINTMAXTOWCS_UPPERCASE)? QSE_WT('A'): QSE_WT('a');
|
||||
|
||||
/* store the resulting numeric string into 'tmp' first */
|
||||
p = tmp;
|
||||
do
|
||||
{
|
||||
int digit = value % base;
|
||||
if (digit < 10) *p++ = digit + QSE_WT('0');
|
||||
else *p++ = digit + xbasechar - 10;
|
||||
value /= base;
|
||||
}
|
||||
while (value > 0);
|
||||
|
||||
/* reslen is the length of the resulting string without padding. */
|
||||
reslen = (int)(p - tmp);
|
||||
if (signchar) reslen++; /* increment reslen for the sign character */
|
||||
|
||||
/* get the required buffer size for lossless formatting */
|
||||
reqlen = (base_and_flags & QSE_FMTINTMAXTOWCS_NONULL)? reslen: (reslen + 1);
|
||||
|
||||
if (size <= 0 ||
|
||||
((base_and_flags & QSE_FMTINTMAXTOWCS_NOTRUNC) && size < reqlen))
|
||||
{
|
||||
return -reqlen;
|
||||
}
|
||||
|
||||
xsize = (base_and_flags & QSE_FMTINTMAXTOWCS_NONULL)? size: (size - 1);
|
||||
bp = buf;
|
||||
be = buf + xsize;
|
||||
|
||||
/* fill space */
|
||||
if (fillchar != QSE_WT('\0'))
|
||||
{
|
||||
|
||||
if (base_and_flags & QSE_FMTINTMAXTOWCS_FILLRIGHT)
|
||||
{
|
||||
/* emit sign */
|
||||
if (signchar && bp < be) *bp++ = signchar;
|
||||
|
||||
/* copy the numeric string to the destination buffer */
|
||||
while (p > tmp && bp < be) *bp++ = *--p;
|
||||
|
||||
/* fill the right side */
|
||||
while (xsize > reslen)
|
||||
{
|
||||
*bp++ = fillchar;
|
||||
xsize--;
|
||||
}
|
||||
}
|
||||
else if (base_and_flags & QSE_FMTINTMAXTOWCS_FILLCENTER)
|
||||
{
|
||||
/* emit sign */
|
||||
if (signchar && bp < be) *bp++ = signchar;
|
||||
|
||||
/* fill the left side */
|
||||
while (xsize > reslen)
|
||||
{
|
||||
*bp++ = fillchar;
|
||||
xsize--;
|
||||
}
|
||||
|
||||
/* copy the numeric string to the destination buffer */
|
||||
while (p > tmp && bp < be) *bp++ = *--p;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fill the left side */
|
||||
while (xsize > reslen)
|
||||
{
|
||||
*bp++ = fillchar;
|
||||
xsize--;
|
||||
}
|
||||
|
||||
/* emit sign */
|
||||
if (signchar && bp < be) *bp++ = signchar;
|
||||
|
||||
/* 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 the numeric string to the destination buffer */
|
||||
while (p > tmp && bp < be) *bp++ = *--p;
|
||||
}
|
||||
|
||||
if (!(base_and_flags & QSE_FMTINTMAXTOWCS_NONULL)) *bp = QSE_WT('\0');
|
||||
return bp - buf;
|
||||
}
|
||||
|
||||
int qse_fmtintmaxtowcs (
|
||||
qse_wchar_t* buf, int size,
|
||||
qse_intmax_t value, int base_and_flags, qse_wchar_t fillchar)
|
||||
{
|
||||
qse_wchar_t signchar;
|
||||
qse_uintmax_t absvalue;
|
||||
|
||||
if (value < 0)
|
||||
{
|
||||
signchar = QSE_WT('-');
|
||||
absvalue = -value;
|
||||
}
|
||||
else if (base_and_flags & QSE_FMTINTMAXTOWCS_PLUSSIGN)
|
||||
{
|
||||
signchar = QSE_WT('+');
|
||||
absvalue = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
signchar = QSE_WT('\0');
|
||||
absvalue = value;
|
||||
}
|
||||
|
||||
return fmt_unsigned_to_wcs (buf, size, absvalue, base_and_flags, fillchar, signchar);
|
||||
}
|
||||
|
||||
int qse_fmtuintmaxtowcs (
|
||||
qse_wchar_t* buf, int size,
|
||||
qse_uintmax_t value, int base_and_flags, qse_wchar_t fillchar)
|
||||
{
|
||||
qse_wchar_t signchar;
|
||||
|
||||
/* determine if a sign character is needed */
|
||||
if (base_and_flags & QSE_FMTINTMAXTOWCS_PLUSSIGN)
|
||||
{
|
||||
signchar = QSE_WT('+');
|
||||
}
|
||||
else
|
||||
{
|
||||
signchar = QSE_WT('\0');
|
||||
}
|
||||
|
||||
return fmt_unsigned_to_wcs (buf, size, value, base_and_flags, fillchar, signchar);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user