Compare commits

...

1 Commits

Author SHA1 Message Date
Lephenixnoir 89c6c39405
stdio: support for UTF-8 %lc in printf() 2022-08-01 11:27:24 +01:00
3 changed files with 29 additions and 9 deletions

View File

@ -85,12 +85,8 @@ struct __printf_format {
int16_t precision;
/*
** Size specifier for integers (%o, %x, %i, %d, %u), may be one of:
** (0) char (8-bit)
** (1) short (16-bit)
** (2) int (32-bit)
** (3) long (32-bit)
** (4) long long (64-bit)
** Size specifier for integers (%o, %x, %i, %d, %u), is equal to the
** sizeof() of the targeted type. Also used for %lc.
*/
uint8_t size;

View File

@ -19,7 +19,27 @@ void __printf_format_c(
__printf_compute_geometry(opt, &g);
__printf_outn(out, ' ', g.left_spaces);
__printf_out(out, c);
/* When using %lc, output as UTF-8 */
if(opt->size != 4 || c <= 0x7f) {
__printf_out(out, c);
}
else if(c <= 0x7ff) {
__printf_out(out, 0xc0 | (c >> 6));
__printf_out(out, 0x80 | (c & 0x3f));
}
else if(c <= 0xffff) {
__printf_out(out, 0xe0 | (c >> 12));
__printf_out(out, 0x80 | ((c >> 6) & 0x3f));
__printf_out(out, 0x80 | (c & 0x3f));
}
else {
__printf_out(out, 0xf0 | (c >> 18));
__printf_out(out, 0x80 | ((c >> 12) & 0x3f));
__printf_out(out, 0x80 | ((c >> 6) & 0x3f));
__printf_out(out, 0x80 | (c & 0x3f));
}
__printf_outn(out, ' ', g.right_spaces);
}

View File

@ -125,8 +125,8 @@ void __printf_flush(struct __printf_output *out)
/* Parse format strings. */
static struct __printf_format parse_fmt(char const * restrict *options_ptr)
{
/* No options enabled by default, set the size to int */
struct __printf_format opt = { .size = sizeof(int), .precision = -1 };
/* No options enabled by default; default size is set at the end */
struct __printf_format opt = { .size = 0, .precision = -1 };
/* This function acts as a deterministic finite automaton */
enum {
@ -252,6 +252,10 @@ int __printf(
opt = parse_fmt(&format);
opt.spec = *format++;
/* Set default size to 1 for %c, 4 otherwise */
if(opt.size == 0)
opt.size = (opt.spec == 'c') ? 1 : 4;
int id;
if(isupper(opt.spec))
id = opt.spec - 'A';