diff --git a/v0/include.mk b/v0/include.mk index c48826a..a507fea 100644 --- a/v0/include.mk +++ b/v0/include.mk @@ -1,4 +1,4 @@ -V0_SRC := v0/main.c v0/token.c v0/parser.c +V0_SRC := v0/main.c v0/token.c v0/parser.c v0/log.c # V0_TEST must only include `v0/test.c` itself, as all other test C–source files are # included directly into `v0/test.c` using `#include "test_xyz.c"`. diff --git a/v0/log.c b/v0/log.c new file mode 100644 index 0000000..f5e4daa --- /dev/null +++ b/v0/log.c @@ -0,0 +1,16 @@ +#include "log.h" +#include + +static LogError* s_logError = NULL; + +void log_set_output(LogError* destination) { + s_logError = destination; +} + +void log_error(const char* msg) { + if (s_logError != NULL) { + s_logError(msg); + } else { + fprintf(stderr, "Error: %s\n", msg); + } +} diff --git a/v0/log.h b/v0/log.h new file mode 100644 index 0000000..cf268f7 --- /dev/null +++ b/v0/log.h @@ -0,0 +1,22 @@ +/** + * Contains the logging framework used for logging errors during compilation. + */ +#ifndef LOG_H +#define LOG_H + +/** + * A method that can log an error. + */ +typedef void LogError(const char* msg); + +/** + * Sets the destination for log errors. + */ +void log_set_output(LogError* destination); + +/** + * Logs an error to the destination. + */ +void log_error(const char* msg); + +#endif diff --git a/v0/test.c b/v0/test.c index fd60d0c..bfaad9b 100644 --- a/v0/test.c +++ b/v0/test.c @@ -30,6 +30,7 @@ typedef struct { #include "test_token.c" #include "test_parser.c" +#include "test_log.c" static int s_totalTests; static int s_greenTests; @@ -44,6 +45,7 @@ static TestCase s_tests[] = { {"tokenstream_void_function_signature", test_tokenstream_void_function_signature}, {"tokenstream_info", test_tokenstream_info}, {"parser_module_name", test_parser_module_name}, + {"log_error", test_log_error}, }; diff --git a/v0/test_log.c b/v0/test_log.c new file mode 100644 index 0000000..84203a4 --- /dev/null +++ b/v0/test_log.c @@ -0,0 +1,21 @@ +#include "test.h" +#include "log.h" +#include + +static char s_lastLoggedError[256]; + +static void mock_log(const char* msg) { + strncpy(s_lastLoggedError, msg, sizeof(s_lastLoggedError) - 1); + s_lastLoggedError[sizeof(s_lastLoggedError) - 1] = '\0'; +} + +static void test_log_error(void) { + log_set_output(mock_log); + + memset(s_lastLoggedError, 0, sizeof(s_lastLoggedError)); + log_error("test error message"); + + assert_str("test error message", s_lastLoggedError, "expected 'test error message'"); + + log_set_output(NULL); // Reset to default +}