added mio_byte_to_bcstr().
implemented k/K/w/W in the formatted output function
This commit is contained in:
		| @ -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) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user