added hcl_byte_to_bcstr().

implemented k/K/w/W in the formatted output function
This commit is contained in:
hyung-hwan 2019-03-18 15:37:07 +00:00
parent 258567dca9
commit 1a6aaf1831
3 changed files with 222 additions and 1 deletions

View File

@ -429,8 +429,16 @@ HCL_EXPORT hcl_oow_t hcl_count_bcstr (
# define hcl_count_oocstr(str) hcl_count_bcstr(str)
#endif
#define HCL_BYTE_TO_BCSTR_RADIXMASK (0xFF)
#define HCL_BYTE_TO_BCSTR_LOWERCASE (1 << 8)
hcl_oow_t hcl_byte_to_bcstr (
hcl_uint8_t byte,
hcl_bch_t* buf,
hcl_oow_t size,
int flagged_radix,
hcl_bch_t fill
);
HCL_EXPORT int hcl_conv_bcs_to_ucs_with_cmgr (

View File

@ -88,6 +88,16 @@
} \
} while (0)
#define PUT_BYTE_IN_HEX(byte) do { \
hcl_bch_t __xbuf[3]; \
hcl_byte_to_bcstr (byte, __xbuf, HCL_COUNTOF(__xbuf), (16 | (ch == 'w'? HCL_BYTE_TO_BCSTR_LOWERCASE: 0)), '0'); \
PUT_OOCH(__xbuf[0], 1); \
PUT_OOCH(__xbuf[1], 1); \
} while (0)
/* TODO: redefine this */
#define BYTE_PRINTABLE(x) ((x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z') || (x == ' '))
static int logfmtv (hcl_t* hcl, const fmtchar_t* fmt, hcl_fmtout_t* data, va_list ap, hcl_outbfmt_t outbfmt)
{
const fmtchar_t* percent;
@ -604,6 +614,173 @@ static int logfmtv (hcl_t* hcl, const fmtchar_t* fmt, hcl_fmtout_t* data, va_lis
break;
}
case 'k':
case 'K':
{
/* byte or multibyte character string in escape sequence */
const hcl_uint8_t* bsp;
hcl_oow_t k_hex_width;
/* zeropad must not take effect for 'k' and 'K'
*
* 'h' & 'l' is not used to differentiate qse_mchar_t and qse_wchar_t
* because 'k' means qse_byte_t.
* 'l', results in uppercase hexadecimal letters.
* 'h' drops the leading \x in the output
* --------------------------------------------------------
* hk -> \x + non-printable in lowercase hex
* k -> all in lowercase hex
* lk -> \x + all in lowercase hex
* --------------------------------------------------------
* hK -> \x + non-printable in uppercase hex
* K -> all in uppercase hex
* lK -> \x + all in uppercase hex
* --------------------------------------------------------
* with 'k' or 'K', i don't substitute "(null)" for the NULL pointer
*/
if (flagc & FLAGC_ZEROPAD) padc = ' ';
bsp = va_arg(ap, hcl_uint8_t*);
k_hex_width = (lm_flag & (LF_H | LF_L))? 4: 2;
if (lm_flag& LF_H)
{
if (flagc & FLAGC_DOT)
{
/* if precision is specifed, it doesn't stop at the value of zero unlike 's' or 'S' */
for (n = 0; n < precision; n++) width -= BYTE_PRINTABLE(bsp[n])? 1: k_hex_width;
}
else
{
for (n = 0; bsp[n]; n++) width -= BYTE_PRINTABLE(bsp[n])? 1: k_hex_width;
}
}
else
{
if (flagc & FLAGC_DOT)
{
/* if precision is specifed, it doesn't stop at the value of zero unlike 's' or 'S' */
for (n = 0; n < precision; n++) /* nothing */;
}
else
{
for (n = 0; bsp[n]; n++) /* nothing */;
}
width -= (n * k_hex_width);
}
if (!(flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
while (n--)
{
if ((lm_flag & LF_H) && BYTE_PRINTABLE(*bsp))
{
PUT_OOCH(*bsp, 1);
}
else
{
hcl_bch_t xbuf[3];
hcl_byte_to_bcstr (*bsp, xbuf, HCL_COUNTOF(xbuf), (16 | (ch == 'k'? HCL_BYTE_TO_BCSTR_LOWERCASE: 0)), '0');
if (lm_flag & (LF_H | LF_L))
{
PUT_OOCH('\\', 1);
PUT_OOCH('x', 1);
}
PUT_OOCH(xbuf[0], 1);
PUT_OOCH(xbuf[1], 1);
}
bsp++;
}
if ((flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
break;
}
case 'w':
case 'W':
{
/* unicode string in unicode escape sequence.
*
* hw -> \uXXXX, \UXXXXXXXX, printable-byte(only in ascii range)
* w -> \uXXXX, \UXXXXXXXX
* lw -> all in \UXXXXXXXX
*/
const hcl_uch_t* usp;
hcl_oow_t uwid;
if (flagc & FLAGC_ZEROPAD) padc = ' ';
usp = va_arg(ap, hcl_uch_t*);
if (flagc & FLAGC_DOT)
{
/* if precision is specifed, it doesn't stop at the value of zero unlike 's' or 'S' */
for (n = 0; n < precision; n++)
{
if ((lm_flag & LF_H) && BYTE_PRINTABLE(usp[n])) uwid = 1;
else if (!(lm_flag & LF_L) && usp[n] <= 0xFFFF) uwid = 6;
else uwid = 10;
width -= uwid;
}
}
else
{
for (n = 0; usp[n]; n++)
{
if ((lm_flag & LF_H) && BYTE_PRINTABLE(usp[n])) uwid = 1;
else if (!(lm_flag & LF_L) && usp[n] <= 0xFFFF) uwid = 6;
else uwid = 10;
width -= uwid;
}
}
if (!(flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
while (n--)
{
if ((lm_flag & LF_H) && BYTE_PRINTABLE(*usp))
{
PUT_OOCH(*usp, 1);
}
else if (!(lm_flag & LF_L) && *usp <= 0xFFFF)
{
hcl_uint16_t u16 = *usp;
hcl_uint8_t* bsp = (hcl_uint8_t*)&u16;
PUT_OOCH('\\', 1);
PUT_OOCH('u', 1);
#if defined(HCL_ENDIAN_BIG)
PUT_BYTE_IN_HEX(bsp[0]);
PUT_BYTE_IN_HEX(bsp[1]);
#else
PUT_BYTE_IN_HEX(bsp[1]);
PUT_BYTE_IN_HEX(bsp[0]);
#endif
}
else
{
hcl_uint32_t u32 = *usp;
hcl_uint8_t* bsp = (hcl_uint8_t*)&u32;
PUT_OOCH('\\', 1);
PUT_OOCH('U', 1);
#if defined(HCL_ENDIAN_BIG)
PUT_BYTE_IN_HEX(bsp[0]);
PUT_BYTE_IN_HEX(bsp[1]);
PUT_BYTE_IN_HEX(bsp[2]);
PUT_BYTE_IN_HEX(bsp[3]);
#else
PUT_BYTE_IN_HEX(bsp[3]);
PUT_BYTE_IN_HEX(bsp[2]);
PUT_BYTE_IN_HEX(bsp[1]);
PUT_BYTE_IN_HEX(bsp[0]);
#endif
}
usp++;
}
if ((flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
break;
}
case 'O': /* object - ignore precision, width, adjustment */
if (hcl_outfmtobj(hcl, (data->mask & ~HCL_LOG_PREFER_JSON), va_arg(ap, hcl_oop_t), outbfmt) <= -1) goto oops;
break;

View File

@ -359,6 +359,42 @@ hcl_bch_t* hcl_find_bchar_in_bcstr (const hcl_bch_t* ptr, hcl_bch_t c)
/* ----------------------------------------------------------------------- */
hcl_oow_t hcl_byte_to_bcstr (hcl_uint8_t byte, hcl_bch_t* buf, hcl_oow_t size, int flagged_radix, hcl_bch_t fill)
{
hcl_bch_t tmp[(HCL_SIZEOF(hcl_uint8_t) * 8)];
hcl_bch_t* p = tmp, * bp = buf, * be = buf + size - 1;
int radix;
hcl_bch_t radix_char;
radix = (flagged_radix & HCL_BYTE_TO_BCSTR_RADIXMASK);
radix_char = (flagged_radix & HCL_BYTE_TO_BCSTR_LOWERCASE)? 'a': 'A';
if (radix < 2 || radix > 36 || size <= 0) return 0;
do
{
hcl_uint8_t digit = byte % radix;
if (digit < 10) *p++ = digit + '0';
else *p++ = digit + radix_char - 10;
byte /= radix;
}
while (byte > 0);
if (fill != '\0')
{
while (size - 1 > p - tmp)
{
*bp++ = fill;
size--;
}
}
while (p > tmp && bp < be) *bp++ = *--p;
*bp = '\0';
return bp - buf;
}
/* ----------------------------------------------------------------------- */
HCL_INLINE int hcl_conv_bchars_to_uchars_with_cmgr (
const hcl_bch_t* bcs, hcl_oow_t* bcslen,
hcl_uch_t* ucs, hcl_oow_t* ucslen, hcl_cmgr_t* cmgr, int all)