summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSupercip971 <supercyp971@gmail.com>2022-02-25 19:16:31 +0400
committerSupercip971 <supercyp971@gmail.com>2022-03-23 00:14:15 +0000
commit86605ad5fded0e3b855740a3ef51c8f443318b4e (patch)
tree53908cc387641342e68cfabf003f12334ce2de79
parent373265e18b3ad559825383d52a6db4880ea0b3fe (diff)
io: added color to fmtrgb-log
- added color to test for showing off beautifull colors
-rw-r--r--sources/libs/brutal/io/fmt.c203
-rw-r--r--sources/libs/brutal/io/fmt.h31
-rw-r--r--sources/utils/test/main.c4
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;