diff options
author | Supercip971 <supercyp971@gmail.com> | 2022-02-25 19:16:31 +0400 |
---|---|---|
committer | Supercip971 <supercyp971@gmail.com> | 2022-03-23 00:14:15 +0000 |
commit | 86605ad5fded0e3b855740a3ef51c8f443318b4e (patch) | |
tree | 53908cc387641342e68cfabf003f12334ce2de79 | |
parent | 373265e18b3ad559825383d52a6db4880ea0b3fe (diff) |
io: added color to fmtrgb-log
- added color to test for showing off beautifull colors
-rw-r--r-- | sources/libs/brutal/io/fmt.c | 203 | ||||
-rw-r--r-- | sources/libs/brutal/io/fmt.h | 31 | ||||
-rw-r--r-- | sources/utils/test/main.c | 4 |
3 files changed, 226 insertions, 12 deletions
diff --git a/sources/libs/brutal/io/fmt.c b/sources/libs/brutal/io/fmt.c index 64f6fba4..bd62b782 100644 --- a/sources/libs/brutal/io/fmt.c +++ b/sources/libs/brutal/io/fmt.c @@ -50,7 +50,66 @@ static char fmt_prefix(Fmt self) } } -static void fmt_pase_case(Fmt *fmt, Scan *scan) +const char *color_table[] = { + [FMT_COL_NONE] = "none", + [FMT_BLACK] = "black", + [FMT_RED] = "red", + [FMT_WHITE] = "white", + [FMT_GREEN] = "green", + [FMT_BLUE] = "blue", + [FMT_YELLOW] = "yellow", + [FMT_MAGENTA] = "magenta", + [FMT_CYAN] = "cyan", + [FMT_GRAY] = "gray", + [FMT_BLACK_GRAY] = "dark-gray", +}; + +static FmtColor fmt_parse_color(Scan *scan) +{ + FmtColor col = {}; + if (scan_skip_word(scan, str$("light-"))) + { + col.bright = true; + } + + for (size_t i = 0; i < sizeof(color_table) / sizeof(color_table[0]); i++) + { + if (scan_skip_word(scan, str$(color_table[i]))) + { + col.type = (FmtColorTypes)i; + break; + } + } + + return col; +} + +static bool fmt_parse_style(Fmt *fmt, Scan *scan) +{ + if (scan_skip_word(scan, str$("underline"))) + { + fmt->style.underline = true; + return true; + } + else if (scan_skip_word(scan, str$("bold"))) + { + fmt->style.bold = true; + return true; + } + else if (scan_skip_word(scan, str$("bg-"))) + { + fmt->style.bg_color = fmt_parse_color(scan); + return true; + } + else if (scan_skip_word(scan, str$("fg-"))) + { + fmt->style.fg_color = fmt_parse_color(scan); + return true; + } + return false; +} + +static void fmt_parse_case(Fmt *fmt, Scan *scan) { if (scan_skip_word(scan, str$("default"))) { @@ -197,13 +256,17 @@ Fmt fmt_parse(Scan *scan) scan_next(scan); fmt.prefix = true; } + else if (fmt_parse_style(&fmt, scan)) + { + fmt.style.has_style = true; + } else if (scan_curr(scan) >= '0' && scan_curr(scan) <= '9') { fmt_parse_min_width(&fmt, scan); } else if (scan_skip_word(scan, str$("case:"))) { - fmt_pase_case(&fmt, scan); + fmt_parse_case(&fmt, scan); } else { @@ -391,34 +454,154 @@ IoResult fmt_string(Fmt self, IoWriter writer, Str value) } } +// FIXME: maybe put it in a specific header later. +#define ANSI_ESC_BRIGHT 60 +#define ANSI_ESC_FG 30 +#define ANSI_ESC_BG 40 + +static int fmt_color_id(FmtColor color) +{ + int offset = 0; + + if(color.bright) + { + offset += ANSI_ESC_BRIGHT; + } + + switch (color.type) + { + case FMT_BLACK: + return 0 + offset; + case FMT_RED: + return 1 + offset; + case FMT_GREEN: + return 2 + offset; + case FMT_YELLOW: + return 3 + offset; + case FMT_BLUE: + return 4 + offset; + case FMT_MAGENTA: + return 5 + offset; + case FMT_CYAN: + return 6 + offset; + case FMT_WHITE: + return 7 + ANSI_ESC_BRIGHT; // always bright + case FMT_GRAY: + return 7 + offset; + case FMT_BLACK_GRAY: + return 0 + ANSI_ESC_BRIGHT; // always bright + case FMT_COL_NONE: + default: + return -1; + } +} + +static IoResult fmt_start_style(IoWriter writer, FmtStyle style) +{ + size_t written = 0; + if (style.bold) + { + written += TRY(IoResult, io_write_str(writer, str$("\033[1m"))); + } + if (style.underline) + { + written += TRY(IoResult, io_write_str(writer, str$("\033[4m"))); + } + + int fg_id = fmt_color_id(style.fg_color); + if (fg_id != -1) + { + written += TRY(IoResult, io_write_str(writer, str$("\033["))); + written += TRY(IoResult, fmt_signed((Fmt){}, writer, fg_id + ANSI_ESC_FG)); + written += TRY(IoResult, io_write_str(writer, str$("m"))); + } + + int bg_id = fmt_color_id(style.bg_color); + if (bg_id != -1) + { + written += TRY(IoResult, io_write_str(writer, str$("\033["))); + written += TRY(IoResult, fmt_signed((Fmt){}, writer, bg_id + ANSI_ESC_BG)); + written += TRY(IoResult, io_write_str(writer, str$("m"))); + } + + return OK(IoResult, written); +} + +static IoResult fmt_end_style(IoWriter writer) +{ + return io_write_str(writer, str$("\033[0m")); +} + IoResult fmt_any(Fmt self, IoWriter writer, Any value) { + size_t res = 0; + + if (self.style.has_style) + { + res = TRY(IoResult, fmt_start_style(writer, self.style)); + } + switch (value.type) { case ANY_INT: + { if (self.type == FMT_CHAR) - return fmt_char(self, writer, value.int_); + { + res += TRY(IoResult, fmt_char(self, writer, value.int_)); + break; + } else - return fmt_signed(self, writer, value.int_); + { + res += TRY(IoResult, fmt_signed(self, writer, value.int_)); + break; + } + } case ANY_UINT: + { if (self.type == FMT_CHAR) - return fmt_char(self, writer, value.uint_); + { + res += TRY(IoResult, fmt_char(self, writer, value.uint_)); + break; + } else - return fmt_unsigned(self, writer, value.uint_); + { + res += TRY(IoResult, fmt_unsigned(self, writer, value.uint_)); + break; + } + } #ifndef __freestanding__ case ANY_FLOAT: - return fmt_float(self, writer, value.float_); + { + res += TRY(IoResult, fmt_float(self, writer, value.float_)); + break; + } #endif case ANY_STR: - return fmt_string(self, writer, value.str_); + { + res += TRY(IoResult, fmt_string(self, writer, value.str_)); + break; + } case ANY_PTR: - return fmt_unsigned(self, writer, (uintptr_t)value.ptr_); + { + res += TRY(IoResult, fmt_unsigned(self, writer, (uintptr_t)value.ptr_)); + break; + } default: - return io_write_str(writer, str$("<unknown>")); + { + res += TRY(IoResult, io_write_str(writer, str$("<unknown>"))); + break; } + } + + if (self.style.has_style) + { + res += TRY(IoResult, fmt_end_style(writer)); + } + + return OK(IoResult, res); } diff --git a/sources/libs/brutal/io/fmt.h b/sources/libs/brutal/io/fmt.h index 60b305d7..792fd5f0 100644 --- a/sources/libs/brutal/io/fmt.h +++ b/sources/libs/brutal/io/fmt.h @@ -19,9 +19,40 @@ typedef enum FMT_POINTER, } FmtType; +typedef enum +{ + FMT_COL_NONE, + FMT_BLACK, + FMT_WHITE, + FMT_RED, + FMT_GREEN, + FMT_BLUE, + FMT_YELLOW, + FMT_MAGENTA, + FMT_CYAN, + FMT_GRAY, + FMT_BLACK_GRAY, +} FmtColorTypes; + +typedef struct +{ + FmtColorTypes type; + bool bright; +} FmtColor; + +typedef struct +{ + bool has_style; + bool bold; + bool underline; + FmtColor fg_color; + FmtColor bg_color; +} FmtStyle; + typedef struct { FmtType type; + FmtStyle style; Case casing; long precison; diff --git a/sources/utils/test/main.c b/sources/utils/test/main.c index 7a954a6a..3d638c0f 100644 --- a/sources/utils/test/main.c +++ b/sources/utils/test/main.c @@ -38,11 +38,11 @@ bool test_run(Test test) if (pass) { - log$("[ PASS ] {}", test.name); + log$("[ {fg-green} ] {}", "PASS", test.name); } else { - log$("[ FAIL ] {}", test.name); + log$("[ {fg-red} ] {}", "FAIL", test.name); } return pass; |