From d8c7b3162f2497496ce24017fc5ec143a6abee96 Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sat, 5 Oct 2024 18:46:14 +0100 Subject: [PATCH] Split termcolour implementations by platform and simplify the API --- .../shell/termcolour/posix/termcolour_posix.c | 34 ++++++ .../shell/termcolour/posix/termcolour_posix.h | 22 ++++ src/common/shell/termcolour/termcolour.c | 100 ++---------------- src/common/shell/termcolour/termcolour.h | 53 +--------- .../shell/termcolour/terminal_colours.h | 34 ++++++ .../shell/termcolour/win/termcolour_win.c | 72 +++++++++++++ .../shell/termcolour/win/termcolour_win.h | 26 +++++ src/tester/tester.c | 17 ++- src/tester/tester.h | 3 +- 9 files changed, 209 insertions(+), 152 deletions(-) create mode 100644 src/common/shell/termcolour/posix/termcolour_posix.c create mode 100644 src/common/shell/termcolour/posix/termcolour_posix.h create mode 100644 src/common/shell/termcolour/terminal_colours.h create mode 100644 src/common/shell/termcolour/win/termcolour_win.c create mode 100644 src/common/shell/termcolour/win/termcolour_win.h diff --git a/src/common/shell/termcolour/posix/termcolour_posix.c b/src/common/shell/termcolour/posix/termcolour_posix.c new file mode 100644 index 0000000..039bc18 --- /dev/null +++ b/src/common/shell/termcolour/posix/termcolour_posix.c @@ -0,0 +1,34 @@ +#include "aliases.h" +#include "platform.h" + +#ifdef WAPP_PLATFORM_POSIX + +#include "terminal_colours.h" +#include "termcolour_posix.h" +#include + +internal const char *colours[COUNT_TERM_COLOUR] = { + [WAPP_TERM_COLOUR_FG_BLACK] = "\033[30m", + [WAPP_TERM_COLOUR_FG_RED] = "\033[31m", + [WAPP_TERM_COLOUR_FG_GREEN] = "\033[32m", + [WAPP_TERM_COLOUR_FG_BLUE] = "\033[34m", + [WAPP_TERM_COLOUR_FG_CYAN] = "\033[36m", + [WAPP_TERM_COLOUR_FG_MAGENTA] = "\033[35m", + [WAPP_TERM_COLOUR_FG_YELLOW] = "\033[33m", + [WAPP_TERM_COLOUR_FG_WHITE] = "\033[37m", + [WAPP_TERM_COLOUR_FG_BR_BLACK] = "\033[90m", + [WAPP_TERM_COLOUR_FG_BR_RED] = "\033[91m", + [WAPP_TERM_COLOUR_FG_BR_GREEN] = "\033[92m", + [WAPP_TERM_COLOUR_FG_BR_BLUE] = "\033[94m", + [WAPP_TERM_COLOUR_FG_BR_CYAN] = "\033[96m", + [WAPP_TERM_COLOUR_FG_BR_MAGENTA] = "\033[95m", + [WAPP_TERM_COLOUR_FG_BR_YELLOW] = "\033[93m", + [WAPP_TERM_COLOUR_FG_BR_WHITE] = "\033[97m", + [WAPP_TERM_COLOUR_CLEAR] = "\033[0m", +}; + +void print_coloured_text(const char *text, TerminalColour colour) { + printf("%s%s", colours[colour], text); +} + +#endif // !WAPP_PLATFORM_POSIX diff --git a/src/common/shell/termcolour/posix/termcolour_posix.h b/src/common/shell/termcolour/posix/termcolour_posix.h new file mode 100644 index 0000000..6866f48 --- /dev/null +++ b/src/common/shell/termcolour/posix/termcolour_posix.h @@ -0,0 +1,22 @@ +#ifndef TERM_COLOUR_POSIX_H +#define TERM_COLOUR_POSIX_H + +#include "platform.h" + +#ifdef WAPP_PLATFORM_POSIX + +#include "terminal_colours.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void print_coloured_text(const char *text, TerminalColour colour); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // !WAPP_PLATFORM_POSIX + +#endif // !TERM_COLOUR_POSIX_H diff --git a/src/common/shell/termcolour/termcolour.c b/src/common/shell/termcolour/termcolour.c index 9c5cdb1..980b17d 100644 --- a/src/common/shell/termcolour/termcolour.c +++ b/src/common/shell/termcolour/termcolour.c @@ -1,101 +1,23 @@ #include "termcolour.h" -#include "aliases.h" +#include "terminal_colours.h" #include "platform.h" -#include - -internal void print_coloured_text(const TerminalColourist *colourist, - const char *text); #ifdef WAPP_PLATFORM_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include - -internal WORD colours[COUNT_TERM_COLOUR] = { - [WAPP_TERM_COLOUR_FG_BLACK] = 0, - [WAPP_TERM_COLOUR_FG_RED] = FOREGROUND_RED, - [WAPP_TERM_COLOUR_FG_GREEN] = FOREGROUND_GREEN, - [WAPP_TERM_COLOUR_FG_BLUE] = FOREGROUND_BLUE, - [WAPP_TERM_COLOUR_FG_CYAN] = FOREGROUND_GREEN | FOREGROUND_BLUE, - [WAPP_TERM_COLOUR_FG_MAGENTA] = FOREGROUND_RED | FOREGROUND_BLUE, - [WAPP_TERM_COLOUR_FG_YELLOW] = FOREGROUND_RED | FOREGROUND_GREEN, - [WAPP_TERM_COLOUR_FG_WHITE] = - FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, - [WAPP_TERM_COLOUR_FG_BR_BLACK] = FOREGROUND_INTENSITY, - [WAPP_TERM_COLOUR_FG_BR_RED] = FOREGROUND_RED | FOREGROUND_INTENSITY, - [WAPP_TERM_COLOUR_FG_BR_GREEN] = FOREGROUND_GREEN | FOREGROUND_INTENSITY, - [WAPP_TERM_COLOUR_FG_BR_BLUE] = FOREGROUND_BLUE | FOREGROUND_INTENSITY, - [WAPP_TERM_COLOUR_FG_BR_CYAN] = - FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY, - [WAPP_TERM_COLOUR_FG_BR_MAGENTA] = - FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY, - [WAPP_TERM_COLOUR_FG_BR_YELLOW] = - FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY, - [WAPP_TERM_COLOUR_FG_BR_WHITE] = FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE | FOREGROUND_INTENSITY, -}; + #include "termcolour_win.h" +#elif defined(WAPP_PLATFORM_POSIX) + #include "termcolour_posix.h" #else -internal const char *colours[COUNT_TERM_COLOUR] = { - [WAPP_TERM_COLOUR_FG_BLACK] = "\033[30m", - [WAPP_TERM_COLOUR_FG_RED] = "\033[31m", - [WAPP_TERM_COLOUR_FG_GREEN] = "\033[32m", - [WAPP_TERM_COLOUR_FG_BLUE] = "\033[34m", - [WAPP_TERM_COLOUR_FG_CYAN] = "\033[36m", - [WAPP_TERM_COLOUR_FG_MAGENTA] = "\033[35m", - [WAPP_TERM_COLOUR_FG_YELLOW] = "\033[33m", - [WAPP_TERM_COLOUR_FG_WHITE] = "\033[37m", - [WAPP_TERM_COLOUR_FG_BR_BLACK] = "\033[90m", - [WAPP_TERM_COLOUR_FG_BR_RED] = "\033[91m", - [WAPP_TERM_COLOUR_FG_BR_GREEN] = "\033[92m", - [WAPP_TERM_COLOUR_FG_BR_BLUE] = "\033[94m", - [WAPP_TERM_COLOUR_FG_BR_CYAN] = "\033[96m", - [WAPP_TERM_COLOUR_FG_BR_MAGENTA] = "\033[95m", - [WAPP_TERM_COLOUR_FG_BR_YELLOW] = "\033[93m", - [WAPP_TERM_COLOUR_FG_BR_WHITE] = "\033[97m", -}; -#endif /* ifdef WAPP_PLATFORM_WINDOWS */ + #error "Unrecognised platform" +#endif -TerminalColourist wapp_shell_termcolour_get_colourist(void) { - TerminalColourist colourist; - -#ifdef WAPP_PLATFORM_WINDOWS - // create handle - colourist.handle = GetStdHandle(STD_OUTPUT_HANDLE); - - // get console colour information - CONSOLE_SCREEN_BUFFER_INFO csbi; - GetConsoleScreenBufferInfo(colourist.handle, &csbi); - colourist.default_colour = csbi.wAttributes; -#else - colourist.default_colour = "\033[0m"; -#endif // ifdef WAPP_PLATFORM_WINDOWS - - colourist.current_colour = colourist.default_colour; - - return colourist; -} - -void wapp_shell_termcolour_print_text(TerminalColourist *colourist, - const char *text, TerminalColour colour) { - if (colour < WAPP_TERM_COLOUR_FG_BLACK || - colour > WAPP_TERM_COLOUR_FG_BR_WHITE) { +void wapp_shell_termcolour_print_text(const char *text, TerminalColour colour) { + if (colour < WAPP_TERM_COLOUR_FG_BLACK || colour > WAPP_TERM_COLOUR_FG_BR_WHITE) { return; } - colourist->current_colour = colours[colour]; - print_coloured_text(colourist, text); + print_coloured_text(text, colour); } -void wapp_shell_termcolour_clear_colour(TerminalColourist *colourist) { - colourist->current_colour = colourist->default_colour; - print_coloured_text(colourist, ""); -} - -internal void print_coloured_text(const TerminalColourist *colourist, - const char *text) { -#ifdef WAPP_PLATFORM_WINDOWS - SetConsoleTextAttribute(colourist->handle, colourist->current_colour); - printf("%s", text); -#else - printf("%s%s", colourist->current_colour, text); -#endif // ifdef WAPP_PLATFORM_WINDOWS +void wapp_shell_termcolour_clear_colour(void) { + print_coloured_text("", WAPP_TERM_COLOUR_CLEAR); } diff --git a/src/common/shell/termcolour/termcolour.h b/src/common/shell/termcolour/termcolour.h index 6e4c52e..52830b4 100644 --- a/src/common/shell/termcolour/termcolour.h +++ b/src/common/shell/termcolour/termcolour.h @@ -1,61 +1,14 @@ #ifndef TERM_COLOUR_H #define TERM_COLOUR_H -#include "aliases.h" -#include "misc_utils.h" -#include "platform.h" +#include "terminal_colours.h" #ifdef __cplusplus extern "C" { #endif // __cplusplus -typedef enum { - WAPP_TERM_COLOUR_FG_BLACK, - WAPP_TERM_COLOUR_FG_RED, - WAPP_TERM_COLOUR_FG_GREEN, - WAPP_TERM_COLOUR_FG_BLUE, - WAPP_TERM_COLOUR_FG_CYAN, - WAPP_TERM_COLOUR_FG_MAGENTA, - WAPP_TERM_COLOUR_FG_YELLOW, - WAPP_TERM_COLOUR_FG_WHITE, - WAPP_TERM_COLOUR_FG_BR_BLACK, - WAPP_TERM_COLOUR_FG_BR_RED, - WAPP_TERM_COLOUR_FG_BR_GREEN, - WAPP_TERM_COLOUR_FG_BR_BLUE, - WAPP_TERM_COLOUR_FG_BR_CYAN, - WAPP_TERM_COLOUR_FG_BR_MAGENTA, - WAPP_TERM_COLOUR_FG_BR_YELLOW, - WAPP_TERM_COLOUR_FG_BR_WHITE, - - COUNT_TERM_COLOUR, -} TerminalColour; - -typedef struct terminal_colourist TerminalColourist; - -// clang-format off -#ifdef WAPP_PLATFORM_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include -#include - -struct terminal_colourist { - HANDLE handle; - WORD default_colour; - WORD current_colour; - wapp_misc_utils_padding_size(sizeof(HANDLE) + sizeof(WORD) + sizeof(WORD)); -}; -#else -struct terminal_colourist { - const char *default_colour; - const char *current_colour; -}; -#endif // WAPP_PLATFORM_WINDOWS -// clang-format on - -TerminalColourist wapp_shell_termcolour_get_colourist(void); -void wapp_shell_termcolour_print_text(TerminalColourist *colourist, - const char *text, TerminalColour colour); -void wapp_shell_termcolour_clear_colour(TerminalColourist *colourist); +void wapp_shell_termcolour_print_text(const char *text, TerminalColour colour); +void wapp_shell_termcolour_clear_colour(void); #ifdef __cplusplus } diff --git a/src/common/shell/termcolour/terminal_colours.h b/src/common/shell/termcolour/terminal_colours.h new file mode 100644 index 0000000..420863b --- /dev/null +++ b/src/common/shell/termcolour/terminal_colours.h @@ -0,0 +1,34 @@ +#ifndef TERMINAL_COLOURS_H +#define TERMINAL_COLOURS_H + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef enum { + WAPP_TERM_COLOUR_FG_BLACK, + WAPP_TERM_COLOUR_FG_RED, + WAPP_TERM_COLOUR_FG_GREEN, + WAPP_TERM_COLOUR_FG_BLUE, + WAPP_TERM_COLOUR_FG_CYAN, + WAPP_TERM_COLOUR_FG_MAGENTA, + WAPP_TERM_COLOUR_FG_YELLOW, + WAPP_TERM_COLOUR_FG_WHITE, + WAPP_TERM_COLOUR_FG_BR_BLACK, + WAPP_TERM_COLOUR_FG_BR_RED, + WAPP_TERM_COLOUR_FG_BR_GREEN, + WAPP_TERM_COLOUR_FG_BR_BLUE, + WAPP_TERM_COLOUR_FG_BR_CYAN, + WAPP_TERM_COLOUR_FG_BR_MAGENTA, + WAPP_TERM_COLOUR_FG_BR_YELLOW, + WAPP_TERM_COLOUR_FG_BR_WHITE, + WAPP_TERM_COLOUR_CLEAR, + + COUNT_TERM_COLOUR, +} TerminalColour; + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // !TERMINAL_COLOURS_H diff --git a/src/common/shell/termcolour/win/termcolour_win.c b/src/common/shell/termcolour/win/termcolour_win.c new file mode 100644 index 0000000..8506e93 --- /dev/null +++ b/src/common/shell/termcolour/win/termcolour_win.c @@ -0,0 +1,72 @@ +#include "aliases.h" +#include "platform.h" + +#ifdef WAPP_PLATFORM_WINDOWS + +#include "misc_utils.h" +#include "termcolour_win.h" +#include "terminal_colours.h" +#include + +#define WIN32_LEAN_AND_MEAN +#include + +typedef struct termcolour_data TermcolourData; +struct termcolour_data { + HANDLE handle; + WORD default_colour; + WORD current_colour; + + wapp_misc_utils_padding_size(sizeof(HANDLE) + sizeof(WORD) + sizeof(WORD)); +}; + +internal TermcolourData init_data(void); + +internal WORD colours[COUNT_TERM_COLOUR] = { + [WAPP_TERM_COLOUR_FG_BLACK] = 0, + [WAPP_TERM_COLOUR_FG_RED] = FOREGROUND_RED, + [WAPP_TERM_COLOUR_FG_GREEN] = FOREGROUND_GREEN, + [WAPP_TERM_COLOUR_FG_BLUE] = FOREGROUND_BLUE, + [WAPP_TERM_COLOUR_FG_CYAN] = FOREGROUND_GREEN | FOREGROUND_BLUE, + [WAPP_TERM_COLOUR_FG_MAGENTA] = FOREGROUND_RED | FOREGROUND_BLUE, + [WAPP_TERM_COLOUR_FG_YELLOW] = FOREGROUND_RED | FOREGROUND_GREEN, + [WAPP_TERM_COLOUR_FG_WHITE] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, + [WAPP_TERM_COLOUR_FG_BR_BLACK] = FOREGROUND_INTENSITY, + [WAPP_TERM_COLOUR_FG_BR_RED] = FOREGROUND_RED | FOREGROUND_INTENSITY, + [WAPP_TERM_COLOUR_FG_BR_GREEN] = FOREGROUND_GREEN | FOREGROUND_INTENSITY, + [WAPP_TERM_COLOUR_FG_BR_BLUE] = FOREGROUND_BLUE | FOREGROUND_INTENSITY, + [WAPP_TERM_COLOUR_FG_BR_CYAN] = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY, + [WAPP_TERM_COLOUR_FG_BR_MAGENTA] = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY, + [WAPP_TERM_COLOUR_FG_BR_YELLOW] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY, + [WAPP_TERM_COLOUR_FG_BR_WHITE] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY, +}; + +void print_coloured_text(const char *text, TerminalColour colour) { + persistent TermcolourData data = init_data(); + + if (color == WAPP_TERM_COLOUR_CLEAR) { + data->current_colour = data->default_colour; + } else { + data->current_colour = colours[colour]; + } + + SetConsoleTextAttribute(data->handle, data->current_colour); + printf("%s", text); +} + +internal TermcolourData init_data(void) { + TermcolourData data = {0}; + + // create handle + data.handle = GetStdHandle(STD_OUTPUT_HANDLE); + + // get console colour information + CONSOLE_SCREEN_BUFFER_INFO csbi; + GetConsoleScreenBufferInfo(data.handle, &csbi); + data.default_colour = csbi.wAttributes; + data.current_colour = data.default_colour; + + return data; +} + +#endif // !WAPP_PLATFORM_WINDOWS diff --git a/src/common/shell/termcolour/win/termcolour_win.h b/src/common/shell/termcolour/win/termcolour_win.h new file mode 100644 index 0000000..78d1e10 --- /dev/null +++ b/src/common/shell/termcolour/win/termcolour_win.h @@ -0,0 +1,26 @@ +#ifndef TERM_COLOUR_WIN_H +#define TERM_COLOUR_WIN_H + +#include "platform.h" + +#ifdef WAPP_PLATFORM_WINDOWS + +#include "terminal_colours.h" + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void print_coloured_text(const char *text, TerminalColour colour); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // !WAPP_PLATFORM_WINDOWS + +#endif // !TERM_COLOUR_WIN_H diff --git a/src/tester/tester.c b/src/tester/tester.c index ee69c8c..ab90205 100644 --- a/src/tester/tester.c +++ b/src/tester/tester.c @@ -1,20 +1,16 @@ #include "tester.h" #include "aliases.h" -#include "platform.h" #include "termcolour.h" #include #include #include -internal void handle_test_result(TerminalColourist *colourist, - TestFuncResult result); +internal void handle_test_result(TestFuncResult result); void run_tests(TestFunc *func1, ...) { - TerminalColourist colourist = wapp_shell_termcolour_get_colourist(); - printf("\n"); - handle_test_result(&colourist, func1()); + handle_test_result(func1()); va_list args; va_start(args, func1); @@ -23,7 +19,7 @@ void run_tests(TestFunc *func1, ...) { while (func) { TestFuncResult result = func(); - handle_test_result(&colourist, result); + handle_test_result(result); func = va_arg(args, TestFunc *); } @@ -33,8 +29,7 @@ void run_tests(TestFunc *func1, ...) { printf("\n"); } -internal void handle_test_result(TerminalColourist *colourist, - TestFuncResult result) { +internal void handle_test_result(TestFuncResult result) { TerminalColour colour; const char *result_text; @@ -47,8 +42,8 @@ internal void handle_test_result(TerminalColourist *colourist, } printf("["); - wapp_shell_termcolour_print_text(colourist, result_text, colour); - wapp_shell_termcolour_clear_colour(colourist); + wapp_shell_termcolour_print_text(result_text, colour); + wapp_shell_termcolour_clear_colour(); printf("] %s\n", result.name); if (!result.passed) { diff --git a/src/tester/tester.h b/src/tester/tester.h index 1e182f8..d4b397e 100644 --- a/src/tester/tester.h +++ b/src/tester/tester.h @@ -9,8 +9,7 @@ extern "C" { #endif // __cplusplus -#define wapp_tester_result(PASSED) \ - ((TestFuncResult){.name = __func__, .passed = PASSED}) +#define wapp_tester_result(PASSED) ((TestFuncResult){.name = __func__, .passed = PASSED}) #define wapp_tester_run_tests(...) run_tests(__VA_ARGS__, NULL) typedef struct test_func_result TestFuncResult;