diff --git a/TODO.md b/TODO.md index 1c0be71..501cf41 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,6 @@ - [X] Improve logging (remove SDL/lws dependency) - [X] Unify memset/memcpy/free/malloc functions (remove SDL/lws dependency) +- [ ] Revisit unit tests - [ ] Implement memory pool - [ ] Fix gamepad mapping - [ ] Provide default mapping diff --git a/src/packages/compat/IZ_windows.h b/src/packages/compat/IZ_windows.h index 098c01e..ed71748 100644 --- a/src/packages/compat/IZ_windows.h +++ b/src/packages/compat/IZ_windows.h @@ -3,6 +3,9 @@ #ifndef IZ_WIN64 typedef int errno_t; +#else +#include +#include #endif #endif //IZ_WINDOWS_H diff --git a/src/packages/game/data/IZ_list.c b/src/packages/game/data/IZ_list.c index 6fd4118..3f82626 100644 --- a/src/packages/game/data/IZ_list.c +++ b/src/packages/game/data/IZ_list.c @@ -62,6 +62,7 @@ void IZ_ListDeleteFirstNode(IZ_List* list, IZ_ListFindPredicate filter) { return; } + // FIXME Teardown having problems here list->iterator = &list->root; IZ_ListNode* previous_node = NULL; u64 index = 0; diff --git a/src/packages/game/data/data.test.c b/src/packages/game/data/data.test.c index 90be2d7..b5d94a5 100644 --- a/src/packages/game/data/data.test.c +++ b/src/packages/game/data/data.test.c @@ -27,7 +27,10 @@ spec("data") { it("sets root to NULL") { IZ_ListInitialize(&list); - check(list.root == NULL, "List not properly initialized."); + check( + list.root == NULL, + "List not properly initialized. Root: %p", list.root + ); } } @@ -52,10 +55,12 @@ spec("data") { it("removes all nodes from the list") { mock_set_expected_calls(IZ_free, 3); IZ_ListTeardown(&list); + unsigned int expected_calls = mock_get_expected_calls(IZ_free); + unsigned int actual_calls = mock_get_actual_calls(IZ_free); check( - mock_get_expected_calls(IZ_free) == mock_get_actual_calls(IZ_free), - "Deallocator function call count mismatch." + expected_calls == actual_calls, + "Deallocator function call count mismatch. Expected %u, got %u.", expected_calls, actual_calls ); } } @@ -94,8 +99,9 @@ spec("data") { it("appends new node to empty list and sets it as root") { static u64 value = 69420u; IZ_ListAppendNode(&list, &value); + u64 added_value = *((u64*) list.root->value); - check(*((u64*) list.root->value) == 69420u, "Node not properly appended."); + check(added_value == 69420u, "Node not properly appended. Value: %u", added_value); check( mock_is_called(IZ_malloc), "Allocator function not called." @@ -113,7 +119,7 @@ spec("data") { mock_is_called(IZ_malloc), "Allocator function not called." ); - check(list2.length == 2, "Length mismatch."); + check(list2.length == 2, "Length mismatch. Length: %u", list2.length); } } diff --git a/src/packages/log/IZ_log.c b/src/packages/log/IZ_log.c index 6fa3711..37dafb2 100644 --- a/src/packages/log/IZ_log.c +++ b/src/packages/log/IZ_log.c @@ -1,5 +1,45 @@ #include "IZ_log.h" +bool IZ_LogIsSupportedTerminal() { + bool result; + const char *term = getenv("TERM"); + result = term && strcmp(term, "") != 0; +#ifndef _WIN32 + return result; +#else + if (result) { + return 1; + } + + // Attempt to enable virtual terminal processing on Windows. + // See: https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032(v=vs.85).aspx + HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); + if (hOut == INVALID_HANDLE_VALUE) { + return 0; + } + + DWORD dwMode = 0; + if (!GetConsoleMode(hOut, &dwMode)) { + return 0; + } + + dwMode |= 0x4; // ENABLE_VIRTUAL_TERMINAL_PROCESSING + if (!SetConsoleMode(hOut, dwMode)) { + return 0; + } + + return 1; +#endif +} + +bool IZ_LogIsSupportedColor() { +#ifdef IZ_WIN64 + return _isatty(_fileno(stdout)) && IZ_LogIsSupportedTerminal(); +#else + return isatty(fileno(stdout)) && IZ_LogIsSupportedTerminal(); +#endif +} + void IZ_LogError(const char* fmt, ...) { #ifdef IZ_LOG_LEVEL_FLAG_ERROR char buffer[4096]; @@ -7,7 +47,13 @@ void IZ_LogError(const char* fmt, ...) { va_start(args, fmt); vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); - fprintf(stderr, RED "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + + if (IZ_LogIsSupportedColor()) { + fprintf(stdout, RED "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + return; + } + + fprintf(stderr, "%12s" " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); #endif } @@ -19,18 +65,24 @@ void IZ_LogInfo(IZ_LogCategory category, const char* fmt, ...) { vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); - switch (category) { - default: - case IZ_LOG_CATEGORY_GENERIC: - fprintf(stdout, CYN "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); - break; - case IZ_LOG_CATEGORY_GLOBAL: - fprintf(stdout, MAG "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); - break; - case IZ_LOG_CATEGORY_INPUT: - fprintf(stdout, GRN "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); - break; + if (IZ_LogIsSupportedColor()) { + switch (category) { + default: + case IZ_LOG_CATEGORY_GENERIC: + fprintf(stdout, CYN "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + break; + case IZ_LOG_CATEGORY_GLOBAL: + fprintf(stdout, MAG "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + break; + case IZ_LOG_CATEGORY_INPUT: + fprintf(stdout, GRN "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + break; + } + + return; } + + fprintf(stdout, "%12s" " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); #endif } @@ -42,11 +94,16 @@ void IZ_LogWarn(bool is_critical, const char* fmt, ...) { vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); - if (is_critical) { - fprintf(stdout, WHT "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); - } else { - fprintf(stdout, YEL "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + if (IZ_LogIsSupportedColor()) { + if (is_critical) { + fprintf(stdout, WHT "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + } else { + fprintf(stdout, YEL "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + } + return; } + + fprintf(stdout, "%24s" " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); #endif } @@ -57,7 +114,11 @@ void IZ_Log(const char* fmt, ...) { va_start(args, fmt); vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); - fprintf(stdout, BLU "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + if (IZ_LogIsSupportedColor()) { + fprintf(stdout, BLU "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); + return; + } + fprintf(stdout, "%12s" " %s\n", IZ_LOG_DATE_FUNCTION(), buffer); #endif } diff --git a/src/packages/log/IZ_log.h b/src/packages/log/IZ_log.h index 02d40d0..6e879cd 100644 --- a/src/packages/log/IZ_log.h +++ b/src/packages/log/IZ_log.h @@ -1,19 +1,6 @@ #ifndef IZ_LOG_H #define IZ_LOG_H -#ifdef IZ_WIN64 - -#define RED "" -#define GRN "" -#define YEL "" -#define BLU "" -#define MAG "" -#define CYN "" -#define WHT "" -#define RESET "" - -#else - #define RED "\x1B[31m" #define GRN "\x1B[32m" #define YEL "\x1B[33m" @@ -23,13 +10,12 @@ #define WHT "\x1B[37m" #define RESET "\x1B[0m" -#endif - #define IZ_LOG_LEVEL_FLAG_DEBUG #define IZ_LOG_LEVEL_FLAG_INFO #define IZ_LOG_LEVEL_FLAG_WARN #define IZ_LOG_LEVEL_FLAG_ERROR +#include "../compat/IZ_windows.h" #include #include #include