From c52d70f2dabf4944e92819e0191137e839902ed4 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Mon, 18 Mar 2019 15:16:15 +0000 Subject: [PATCH] implemented w/W for formatted output --- moo/lib/fmtoutv.h | 99 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 2 deletions(-) diff --git a/moo/lib/fmtoutv.h b/moo/lib/fmtoutv.h index cd84060..aaa27fa 100644 --- a/moo/lib/fmtoutv.h +++ b/moo/lib/fmtoutv.h @@ -89,8 +89,15 @@ } \ } while (0) +#define PUT_BYTE_IN_HEX(byte) do { \ + moo_bch_t __xbuf[3]; \ + moo_byte_to_bcstr (byte, __xbuf, MOO_COUNTOF(__xbuf), (16 | (ch == 'w'? MOO_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')) +#define BYTE_PRINTABLE(x) ((x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z') || (x == ' ')) static int fmtoutv (moo_t* moo, const fmtchar_t* fmt, moo_fmtout_data_t* data, va_list ap, moo_outbfmt_t outbfmt) { @@ -604,8 +611,10 @@ static int fmtoutv (moo_t* moo, const fmtchar_t* fmt, moo_fmtout_data_t* data, v case 'k': case 'K': { + /* byte or multibyte character string in escape sequence */ + const moo_uint8_t* bsp; - moo_oow_t bslen, slen, k_hex_width; + moo_oow_t k_hex_width; /* zeropad must not take effect for 'k' and 'K' * @@ -682,6 +691,92 @@ static int fmtoutv (moo_t* moo, const fmtchar_t* fmt, moo_fmtout_data_t* data, v 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 moo_uch_t* usp; + moo_oow_t uwid; + + if (flagc & FLAGC_ZEROPAD) padc = ' '; + usp = va_arg(ap, moo_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) + { + moo_bch_t xbuf[3]; + moo_uint16_t u16 = *usp; + moo_uint8_t* bsp = (moo_uint8_t*)&u16; + PUT_OOCH('\\', 1); + PUT_OOCH('u', 1); + #if defined(MOO_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 + { + moo_bch_t xbuf[3]; + moo_uint32_t u32 = *usp; + moo_uint8_t* bsp = (moo_uint8_t*)&u32; + PUT_OOCH('\\', 1); + PUT_OOCH('U', 1); + #if defined(MOO_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 (print_object(moo, data->mask, va_arg(ap, moo_oop_t), outbfmt) <= -1) goto oops; break;