From f90ee70a8de1fa6b2a248d9cc691366614df6a4f Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 12 Apr 2024 17:24:12 +0200 Subject: [PATCH 1/7] added sys/log module and setup function --- src/main.c | 13 ++++++ src/sys/log.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/sys/log.h | 81 +++++++++++++++++++++++++++++++++++++ 3 files changed, 204 insertions(+) create mode 100644 src/sys/log.c create mode 100644 src/sys/log.h diff --git a/src/main.c b/src/main.c index 6b48e00..d05ce36 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,19 @@ +#include #include +#define LOG_LEVEL LOG_LEVEL_DEBUG + +void setup(void) +{ + log_init(); + DEBUG("starting gemstone..."); + + DEBUG("finished starting up gemstone..."); +} + int main() { + setup(); + yyparse(); return 0; } \ No newline at end of file diff --git a/src/sys/log.c b/src/sys/log.c new file mode 100644 index 0000000..bbf2c37 --- /dev/null +++ b/src/sys/log.c @@ -0,0 +1,110 @@ + +#include +#include +#include +#include + +static struct Logger_t { + FILE** streams; + size_t stream_count; +} GlobalLogger; + +void log_init(void) +{ + log_register_stream(LOG_DEFAULT_STREAM); +} + +void log_register_stream(FILE* restrict stream) +{ + if (GlobalLogger.stream_count == 0) + { + GlobalLogger.streams = (FILE**) malloc(sizeof(FILE*)); + GlobalLogger.stream_count = 1; + + if (GlobalLogger.streams == NULL) + { + PANIC("failed to allocate stream buffer"); + } + } + else + { + GlobalLogger.stream_count++; + size_t bytes = GlobalLogger.stream_count * sizeof(FILE*); + GlobalLogger.streams = (FILE**) realloc(GlobalLogger.streams, bytes); + + if (GlobalLogger.streams == NULL) + { + PANIC("failed to reallocate stream buffer"); + } + } + + GlobalLogger.streams[GlobalLogger.stream_count - 1] = stream; +} + +static void vflogf( + FILE* restrict stream, + const char* restrict level, + const char* restrict file, + const unsigned long line, + const char* restrict func, + const char* restrict format, + va_list args) +{ + fprintf(stream, "%s in %s() at %s:%lu: ", level, func, file, line); + vfprintf(stream, format, args); +} + +void __logf( + const char* restrict level, + const char* restrict file, + const unsigned long line, + const char* restrict func, + const char* restrict format, + ...) +{ + va_list args; + va_start(args, format); + + for (size_t i = 0; i < GlobalLogger.stream_count; i++) + { + FILE* stream = GlobalLogger.streams[i]; + + vflogf(stream, level, file, line, func, format, args); + } + + va_end(args); +} + +void __panicf( + const char* restrict file, + const unsigned long line, + const char* restrict func, + const char* restrict format, + ...) +{ + va_list args; + va_start(args, format); + + vflogf(stderr, LOG_STRING_PANIC, file, line, func, format, args); + + va_end(args); + + exit(EXIT_FAILURE); +} + +void __fatalf( + const char* restrict file, + const unsigned long line, + const char* restrict func, + const char* restrict format, + ...) +{ + va_list args; + va_start(args, format); + + vflogf(stderr, LOG_STRING_FATAL, file, line, func, format, args); + + va_end(args); + + abort(); +} diff --git a/src/sys/log.h b/src/sys/log.h new file mode 100644 index 0000000..49e31ce --- /dev/null +++ b/src/sys/log.h @@ -0,0 +1,81 @@ +#ifndef _SYS_ERR_H_ +#define _SYS_ERR_H_ + +#include +#include + +#define LOG_DEFAULT_STREAM stderr + +#define LOG_LEVEL_ERROR 3 +#define LOG_LEVEL_WARNING 2 +#define LOG_LEVEL_INFORMATION 1 +#define LOG_LEVEL_DEBUG 0 + +#define LOG_LEVEL LOG_LEVEL_DEBUG + +#define LOG_MAX_BACKTRACE_FRAMES 64 + +#define LOG_STRING_PANIC "Critical" +#define LOG_STRING_FATAL "Fatal" +#define LOG_STRING_ERROR "Error" +#define LOG_STRING_WARNING "Warning" +#define LOG_STRING_INFORMATION "Information" +#define LOG_STRING_DEBUG "Debug" + +/** + * @brief Panic is used in cases where the process is in an unrecoverable state. + * This macro will print debug information to stderr and call abort() to + * performa a ungracefull exit. No clean up possible. + */ +#define PANIC(format, ...) __panicf(__FILE_NAME__, __LINE__, __func__, format"\n", ##__VA_ARGS__) + +/** + * @brief Panic is used in cases where the process is in an invalid or undefined state. + * This macro will print debug information to stderr and call exit() to + * initiate a gracefull exit, giving the process the opportunity to clean up. + */ +#define FATAL(format, ...) __fatalf(__FILE_NAME__, __LINE__, __func__, format"\n", ##__VA_ARGS__) + +/* +Standard log macros. These will not terminate the application. +Can be turned off by setting LOG_LEVEL. All logs which have smaller log numbers +will not print. +*/ +#define ERROR(format, ...) __LOG(LOG_STRING_ERROR, LOG_LEVEL_ERROR, format"\n", ##__VA_ARGS__) +#define WARN(format, ...) __LOG(LOG_STRING_WARNING, LOG_LEVEL_WARNING, format"\n", ##__VA_ARGS__) +#define INFO(format, ...) __LOG(LOG_STRING_INFORMATION, LOG_LEVEL_INFORMATION, format"\n", ##__VA_ARGS__) +#define DEBUG(format, ...) __LOG(LOG_STRING_DEBUG, LOG_LEVEL_DEBUG, format"\n", ##__VA_ARGS__) + +#define __LOG(level, priority, format, ...) \ + do { \ + if (LOG_LEVEL <= priority) \ + __logf(level, __FILE_NAME__, __LINE__, __func__, format, ##__VA_ARGS__); \ + } while(0) + +void __logf( + const char* restrict level, + const char* restrict file, + const unsigned long line, + const char* restrict func, + const char* restrict format, + ...); + +void __panicf( + const char* restrict file, + const unsigned long line, + const char* restrict func, + const char* restrict format, + ...); + +void __fatalf( + const char* restrict file, + const unsigned long line, + const char* restrict func, + const char* restrict format, + ...); + +void log_init(void); + +void log_register_stream(FILE* restrict stream); + +#endif /* _SYS_ERR_H_ */ From 4f30e6308d8cb271fda65ccc8ebbef95f14be2c4 Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 12 Apr 2024 17:28:20 +0200 Subject: [PATCH 2/7] added function for notifying about exit --- src/main.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main.c b/src/main.c index d05ce36..aeca14c 100644 --- a/src/main.c +++ b/src/main.c @@ -1,13 +1,23 @@ +#include #include #include #define LOG_LEVEL LOG_LEVEL_DEBUG +void notify_exit(void) +{ + DEBUG("Exiting gemstone..."); +} + void setup(void) { log_init(); DEBUG("starting gemstone..."); + #if LOG_LEVEL <= LOG_LEVEL_DEBUG + atexit(¬ify_exit); + #endif + DEBUG("finished starting up gemstone..."); } From 667f985d3069479ecd4303749d245ee317d4f295 Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 12 Apr 2024 17:29:39 +0200 Subject: [PATCH 3/7] added documentation to main.c --- src/main.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main.c b/src/main.c index aeca14c..bff54ab 100644 --- a/src/main.c +++ b/src/main.c @@ -4,13 +4,23 @@ #define LOG_LEVEL LOG_LEVEL_DEBUG +/** + * @brief Log a debug message to inform about beginning exit procedures + * + */ void notify_exit(void) { DEBUG("Exiting gemstone..."); } +/** + * @brief Run compiler setup here + * + */ void setup(void) { + // setup preample + log_init(); DEBUG("starting gemstone..."); @@ -18,6 +28,8 @@ void setup(void) atexit(¬ify_exit); #endif + // actual setup + DEBUG("finished starting up gemstone..."); } From 949bbb185ab85ed43c8287e2993a109e63d01ece Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 12 Apr 2024 17:34:38 +0200 Subject: [PATCH 4/7] added documentation to sys/log.h --- src/sys/log.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/sys/log.h b/src/sys/log.h index 49e31ce..2848e54 100644 --- a/src/sys/log.h +++ b/src/sys/log.h @@ -52,6 +52,16 @@ will not print. __logf(level, __FILE_NAME__, __LINE__, __func__, format, ##__VA_ARGS__); \ } while(0) +/** + * @brief Log a message into all registered streams + * + * @param level of the message + * @param file origin of the message cause + * @param line line in which log call was made + * @param func function the log call was done in + * @param format the format to print following args in + * @param ... + */ void __logf( const char* restrict level, const char* restrict file, @@ -60,6 +70,15 @@ void __logf( const char* restrict format, ...); +/** + * @brief Log a panic message to stderr and perform gracefull crash with exit() denoting a failure + * + * @param file origin of the message cause + * @param line line in which log call was made + * @param func function the log call was done in + * @param format the format to print following args in + * @param ... + */ void __panicf( const char* restrict file, const unsigned long line, @@ -67,6 +86,15 @@ void __panicf( const char* restrict format, ...); +/** + * @brief Log a critical message to stderr and perform ungracefull crash with abort() + * + * @param file origin of the message cause + * @param line line in which log call was made + * @param func function the log call was done in + * @param format the format to print following args in + * @param ... + */ void __fatalf( const char* restrict file, const unsigned long line, @@ -74,8 +102,17 @@ void __fatalf( const char* restrict format, ...); +/** + * @brief Initialize the logger by registering stderr as stream + * + */ void log_init(void); +/** + * @brief Register a stream as output source. Must be freed manually at exit if necessary + * + * @param stream + */ void log_register_stream(FILE* restrict stream); #endif /* _SYS_ERR_H_ */ From c1d19ed0a8d47e48584f3c09b30bac42e93203d8 Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 12 Apr 2024 17:36:13 +0200 Subject: [PATCH 5/7] added handling of registering a NULL stream for logging --- src/sys/log.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sys/log.c b/src/sys/log.c index bbf2c37..e3a7cd6 100644 --- a/src/sys/log.c +++ b/src/sys/log.c @@ -16,6 +16,9 @@ void log_init(void) void log_register_stream(FILE* restrict stream) { + if (stream == NULL) + PANIC("stream to register is NULL"); + if (GlobalLogger.stream_count == 0) { GlobalLogger.streams = (FILE**) malloc(sizeof(FILE*)); From 488acc9b1fc318a6a6863fbe36e2f82c04f2c481 Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 12 Apr 2024 17:37:48 +0200 Subject: [PATCH 6/7] removed macro for max backtrace frames --- src/sys/log.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sys/log.h b/src/sys/log.h index 2848e54..84d0440 100644 --- a/src/sys/log.h +++ b/src/sys/log.h @@ -13,8 +13,6 @@ #define LOG_LEVEL LOG_LEVEL_DEBUG -#define LOG_MAX_BACKTRACE_FRAMES 64 - #define LOG_STRING_PANIC "Critical" #define LOG_STRING_FATAL "Fatal" #define LOG_STRING_ERROR "Error" From 95f6b4ddc12f8def5c62a3a96d1850243a861647 Mon Sep 17 00:00:00 2001 From: servostar Date: Fri, 12 Apr 2024 18:20:18 +0200 Subject: [PATCH 7/7] fixed warnings in main.c regarding whiteapace and declaration of main --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index bff54ab..8bb8127 100644 --- a/src/main.c +++ b/src/main.c @@ -33,9 +33,9 @@ void setup(void) DEBUG("finished starting up gemstone..."); } -int main() { +int main(void) { setup(); yyparse(); return 0; -} \ No newline at end of file +}