added mio_byte_to_bcstr().
implemented k/K/w/W in the formatted output function
This commit is contained in:
parent
1bc418b99e
commit
7e0ee486a5
@ -89,6 +89,16 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PUT_BYTE_IN_HEX(byte) do { \
|
||||
mio_bch_t __xbuf[3]; \
|
||||
mio_byte_to_bcstr (byte, __xbuf, MIO_COUNTOF(__xbuf), (16 | (ch == 'w'? MIO_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 fmtoutv (mio_t* mio, const fmtchar_t* fmt, mio_fmtout_data_t* data, va_list ap)
|
||||
{
|
||||
const fmtchar_t* percent;
|
||||
@ -598,6 +608,172 @@ static int fmtoutv (mio_t* mio, const fmtchar_t* fmt, mio_fmtout_data_t* data, v
|
||||
break;
|
||||
}
|
||||
|
||||
case 'k':
|
||||
case 'K':
|
||||
{
|
||||
/* byte or multibyte character string in escape sequence */
|
||||
|
||||
const mio_uint8_t* bsp;
|
||||
mio_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, mio_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
|
||||
{
|
||||
mio_bch_t xbuf[3];
|
||||
mio_byte_to_bcstr (*bsp, xbuf, MIO_COUNTOF(xbuf), (16 | (ch == 'k'? MIO_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 mio_uch_t* usp;
|
||||
mio_oow_t uwid;
|
||||
|
||||
if (flagc & FLAGC_ZEROPAD) padc = ' ';
|
||||
usp = va_arg(ap, mio_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)
|
||||
{
|
||||
mio_uint16_t u16 = *usp;
|
||||
mio_uint8_t* bsp = (mio_uint8_t*)&u16;
|
||||
PUT_OOCH('\\', 1);
|
||||
PUT_OOCH('u', 1);
|
||||
#if defined(MIO_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
|
||||
{
|
||||
mio_uint32_t u32 = *usp;
|
||||
mio_uint8_t* bsp = (mio_uint8_t*)&u32;
|
||||
PUT_OOCH('\\', 1);
|
||||
PUT_OOCH('U', 1);
|
||||
#if defined(MIO_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;
|
||||
}
|
||||
#if 0
|
||||
case 'e':
|
||||
case 'E':
|
||||
|
@ -243,8 +243,18 @@ MIO_EXPORT mio_oow_t mio_count_bcstr (
|
||||
# define mio_find_oochar_in_oocstr(ptr,c) mio_find_bchar_in_bcstr(ptr,c)
|
||||
# define mio_count_oocstr(str) mio_count_bcstr(str)
|
||||
#endif
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#define MIO_BYTE_TO_BCSTR_RADIXMASK (0xFF)
|
||||
#define MIO_BYTE_TO_BCSTR_LOWERCASE (1 << 8)
|
||||
|
||||
mio_oow_t mio_byte_to_bcstr (
|
||||
mio_uint8_t byte,
|
||||
mio_bch_t* buf,
|
||||
mio_oow_t size,
|
||||
int flagged_radix,
|
||||
mio_bch_t fill
|
||||
);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
@ -656,6 +656,42 @@ mio_bch_t* mio_find_bchar_in_bcstr (const mio_bch_t* ptr, mio_bch_t c)
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
mio_oow_t mio_byte_to_bcstr (mio_uint8_t byte, mio_bch_t* buf, mio_oow_t size, int flagged_radix, mio_bch_t fill)
|
||||
{
|
||||
mio_bch_t tmp[(MIO_SIZEOF(mio_uint8_t) * 8)];
|
||||
mio_bch_t* p = tmp, * bp = buf, * be = buf + size - 1;
|
||||
int radix;
|
||||
mio_bch_t radix_char;
|
||||
|
||||
radix = (flagged_radix & MIO_BYTE_TO_BCSTR_RADIXMASK);
|
||||
radix_char = (flagged_radix & MIO_BYTE_TO_BCSTR_LOWERCASE)? 'a': 'A';
|
||||
if (radix < 2 || radix > 36 || size <= 0) return 0;
|
||||
|
||||
do
|
||||
{
|
||||
mio_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;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
MIO_INLINE int mio_conv_bchars_to_uchars_with_cmgr (
|
||||
const mio_bch_t* bcs, mio_oow_t* bcslen,
|
||||
mio_uch_t* ucs, mio_oow_t* ucslen, mio_cmgr_t* cmgr, int all)
|
||||
|
Loading…
x
Reference in New Issue
Block a user