#include #include #include "tty.h" #include "printf.h" #define MOD_HASH_BLACK 0x4b5dd0abbc6fc1e4 #define MOD_HASH_RED 0x89e9be1960f4c21c #define MOD_HASH_GREEN 0x0f40f029637fecbc #define MOD_HASH_YELLOW 0x8346a574925e75a9 #define MOD_HASH_BLUE 0xc5ccd29bc2dda64d #define MOD_HASH_MAGENTA 0x6c90e772edbc8708 #define MOD_HASH_CYAN 0x70ae2e90c1bce27a #define MOD_HASH_WHITE 0xced973885856e206 #define MOD_HASH_DARK_GREY 0x55a19de854654d99 #define MOD_HASH_BRIGHT_RED 0xbad8e3fe841b9385 #define MOD_HASH_BRIGHT_GREEN 0x11cc5e579bdd2fb9 #define MOD_HASH_BRIGHT_YELLOW 0xfd579007fe8579f6 #define MOD_HASH_BRIGHT_BLUE 0x57c76bf18badb6d6 #define MOD_HASH_BRIGHT_MAGENTA 0xf6ecc6d3fdfec129 #define MOD_HASH_BRIGHT_CYAN 0x03df73fd4e12ec6d #define MOD_HASH_BRIGHT_WHITE 0xb5ebc3323f57d7fb #define MOD_HASH_BG_BLACK 0xd87a8f2d9d394432 #define MOD_HASH_BG_RED 0x145b1e4366c7d7aa #define MOD_HASH_BG_GREEN 0xa00b8541d3b1e55a #define MOD_HASH_BG_YELLOW 0x98b030fd86e3b3cf #define MOD_HASH_BG_BLUE 0xa15529109506b5df #define MOD_HASH_BG_MAGENTA 0x86dbda99bcc86222 #define MOD_HASH_BG_CYAN 0xf16a3104cf61a098 #define MOD_HASH_BG_WHITE 0x3408c46ab5836674 #define MOD_HASH_BG_DARK_GREY 0x820d2e77568eec47 #define MOD_HASH_BRIGHT_BG_RED 0x144f5dc138087701 #define MOD_HASH_BRIGHT_BG_GREEN 0xc4d88c6426ffe355 #define MOD_HASH_BRIGHT_BG_YELLOW 0xf7bb000a4a792602 #define MOD_HASH_BRIGHT_BG_BLUE 0x9b5c16d6807a1002 #define MOD_HASH_BRIGHT_BG_MAGENTA 0xc59fb2196cdba3fd #define MOD_HASH_BRIGHT_BG_CYAN 0x46feb6dc999a6f09 #define MOD_HASH_BRIGHT_BG_WHITE 0xa3e7d1da08826f5f #define MOD_HASH_BOLD 0xcd32ea9bc6b26ff6 #define MOD_HASH_ULINE 0x141fe741e9f8c22a #define MOD_HASH_ITALIC 0x69d5e5f057d8992d #define MOD_HASH_INVERT 0xab4ab85ddd6232e1 #define MOD_HASH_RESET 0x0f136ff2c086b760 #define COMPARE_MOD_NAME(ss, sd, hs, hd) ((hs) == (hd) && !strcmp(ss, sd)) static void apply_code_to_vmode(struct tty_format_buf *fmt) { const char *modifier = fmt->buf; uint64_t mod_hash = b_hash_string(modifier); if (COMPARE_MOD_NAME(modifier, "black", mod_hash, MOD_HASH_BLACK)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BLACK; } if (COMPARE_MOD_NAME(modifier, "red", mod_hash, MOD_HASH_RED)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_RED; } if (COMPARE_MOD_NAME(modifier, "green", mod_hash, MOD_HASH_GREEN)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_GREEN; } if (COMPARE_MOD_NAME(modifier, "yellow", mod_hash, MOD_HASH_YELLOW)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_YELLOW; } if (COMPARE_MOD_NAME(modifier, "blue", mod_hash, MOD_HASH_BLUE)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BLUE; } if (COMPARE_MOD_NAME(modifier, "magenta", mod_hash, MOD_HASH_MAGENTA)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_MAGENTA; } if (COMPARE_MOD_NAME(modifier, "cyan", mod_hash, MOD_HASH_CYAN)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_CYAN; } if (COMPARE_MOD_NAME(modifier, "white", mod_hash, MOD_HASH_WHITE)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_WHITE; } if (COMPARE_MOD_NAME(modifier, "dark_grey", mod_hash, MOD_HASH_DARK_GREY)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_BLACK; } if (COMPARE_MOD_NAME(modifier, "bright_red", mod_hash, MOD_HASH_BRIGHT_RED)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_RED; } if (COMPARE_MOD_NAME(modifier, "bright_green", mod_hash, MOD_HASH_BRIGHT_GREEN)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_GREEN; } if (COMPARE_MOD_NAME(modifier, "bright_yellow", mod_hash, MOD_HASH_BRIGHT_YELLOW)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_YELLOW; } if (COMPARE_MOD_NAME(modifier, "bright_blue", mod_hash, MOD_HASH_BRIGHT_BLUE)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_BLUE; } if (COMPARE_MOD_NAME(modifier, "bright_magenta", mod_hash, MOD_HASH_BRIGHT_MAGENTA)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_MAGENTA; } if (COMPARE_MOD_NAME(modifier, "bright_cyan", mod_hash, MOD_HASH_BRIGHT_CYAN)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_CYAN; } if (COMPARE_MOD_NAME(modifier, "bright_white", mod_hash, MOD_HASH_BRIGHT_WHITE)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_BRIGHT_WHITE; } if (COMPARE_MOD_NAME(modifier, "bg_black", mod_hash, MOD_HASH_BG_BLACK)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BLACK; } if (COMPARE_MOD_NAME(modifier, "bg_red", mod_hash, MOD_HASH_BG_RED)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_RED; } if (COMPARE_MOD_NAME(modifier, "bg_green", mod_hash, MOD_HASH_BG_GREEN)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_GREEN; } if (COMPARE_MOD_NAME(modifier, "bg_yellow", mod_hash, MOD_HASH_BG_YELLOW)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_YELLOW; } if (COMPARE_MOD_NAME(modifier, "bg_blue", mod_hash, MOD_HASH_BG_BLUE)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BLUE; } if (COMPARE_MOD_NAME(modifier, "bg_magenta", mod_hash, MOD_HASH_BG_MAGENTA)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_MAGENTA; } if (COMPARE_MOD_NAME(modifier, "bg_cyan", mod_hash, MOD_HASH_BG_CYAN)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_CYAN; } if (COMPARE_MOD_NAME(modifier, "bg_white", mod_hash, MOD_HASH_BG_WHITE)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_WHITE; } if (COMPARE_MOD_NAME(modifier, "bg_dark_grey", mod_hash, MOD_HASH_BG_DARK_GREY)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_BLACK; } if (COMPARE_MOD_NAME(modifier, "bright_bg_red", mod_hash, MOD_HASH_BRIGHT_BG_RED)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_RED; } if (COMPARE_MOD_NAME(modifier, "bright_bg_green", mod_hash, MOD_HASH_BRIGHT_BG_GREEN)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_GREEN; } if (COMPARE_MOD_NAME(modifier, "bright_bg_yellow", mod_hash, MOD_HASH_BRIGHT_BG_YELLOW)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_YELLOW; } if (COMPARE_MOD_NAME(modifier, "bright_bg_blue", mod_hash, MOD_HASH_BRIGHT_BG_BLUE)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_BLUE; } if (COMPARE_MOD_NAME(modifier, "bright_bg_magenta", mod_hash, MOD_HASH_BRIGHT_BG_MAGENTA)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_MAGENTA; } if (COMPARE_MOD_NAME(modifier, "bright_bg_cyan", mod_hash, MOD_HASH_BRIGHT_BG_CYAN)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_CYAN; } if (COMPARE_MOD_NAME(modifier, "bright_bg_white", mod_hash, MOD_HASH_BRIGHT_BG_WHITE)) { fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BRIGHT_WHITE; } if (COMPARE_MOD_NAME(modifier, "bold", mod_hash, MOD_HASH_BOLD)) { fmt->vmode.v_attrib |= B_TTY_ATTRIB_BOLD; } if (COMPARE_MOD_NAME(modifier, "uline", mod_hash, MOD_HASH_ULINE)) { fmt->vmode.v_attrib |= B_TTY_ATTRIB_UNDERLINE; } if (COMPARE_MOD_NAME(modifier, "italic", mod_hash, MOD_HASH_ITALIC)) { fmt->vmode.v_attrib |= B_TTY_ATTRIB_ITALIC; } if (COMPARE_MOD_NAME(modifier, "invert", mod_hash, MOD_HASH_INVERT)) { fmt->vmode.v_attrib |= B_TTY_ATTRIB_INVERT; } if (COMPARE_MOD_NAME(modifier, "reset", mod_hash, MOD_HASH_RESET)) { fmt->vmode.v_fg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_bg.c_mode = B_TTY_COLOUR_16; fmt->vmode.v_fg.c_16.value = B_TTY_COLOUR16_WHITE; fmt->vmode.v_bg.c_16.value = B_TTY_COLOUR16_BLACK; fmt->vmode.v_attrib = 0; } } static void format_buffer_putc(struct tty_format_buf* fmt, int c) { if (fmt->ptr < TTY_TMPBUF_SIZE - 1) { fmt->buf[fmt->ptr++] = c; fmt->buf[fmt->ptr] = '\0'; } } static void format_buffer_clear(struct tty_format_buf* fmt) { fmt->ptr = 0; fmt->buf[fmt->ptr] = '\0'; } static void flush_vmode(struct b_tty* tty, struct tty_format_buf* fmt) { b_tty_set_vmode(tty, &fmt->vmode); } int b_tty_putc(struct b_tty *tty, enum b_tty_print_flags flags, char c) { if (flags & B_TTY_DISABLE_FORMATTING) { z__b_tty_putc(tty, c); return c; } struct tty_format_buf *fmt = z__b_tty_get_format_buf(tty); if (c == '[') { if (!fmt->in_format) { fmt->in_format = true; return c; } if (fmt->ptr == 0) { fmt->in_format = false; z__b_tty_putc(tty, '['); return c; } format_buffer_putc(fmt, c); return c; } if (fmt->in_format && c == ']') { apply_code_to_vmode(fmt); format_buffer_clear(fmt); flush_vmode(tty, fmt); fmt->in_format = false; return c; } if (fmt->in_format && c == ',') { apply_code_to_vmode(fmt); format_buffer_clear(fmt); return c; } if (fmt->in_format) { format_buffer_putc(fmt, c); } else { z__b_tty_putc(tty, c); } return c; } int b_tty_puts( struct b_tty* tty, enum b_tty_print_flags flags, const char* s) { int r = 0; while (s[r]) { b_tty_putc(tty, flags, s[r]); r++; } return r; } int b_tty_printf( struct b_tty* tty, enum b_tty_print_flags flags, const char* s, ...) { va_list arg; va_start(arg, s); int r = b_tty_vprintf(tty, flags, s, arg); va_end(arg); return r; }