diff --git a/include/log.h b/include/log.h new file mode 100644 index 0000000000000000000000000000000000000000..0c299b9dbf6d473a22008c9825e2859398f411b6 --- /dev/null +++ b/include/log.h @@ -0,0 +1,168 @@ +/*! + @file + @date 18.01.2019 + @author Raphael Bach + @copyright + +The MIT License (MIT) + +Copyright (c) 2019 Raphael Bach + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @brief + @details +*/ +/*============================================================================== + GUARD +==============================================================================*/ +#ifndef LOG_H_20190119152151 +#define LOG_H_20190119152151 +/*============================================================================== + INCLUDE +==============================================================================*/ +// C Standard Library +#include <stdbool.h> +#include <stdio.h> // FILE, size_t +/*============================================================================== + ENUM +==============================================================================*/ +/*------------------------------------------------------------------------------ + LogLevel +------------------------------------------------------------------------------*/ +enum LogLevel +{ + LOG_LEVEL_NONE = 0x00, // 0000 0000 + LOG_LEVEL_TRACE = 0x01, // 0000 0001 + LOG_LEVEL_DEBUG = 0x02, // 0000 0010 + LOG_LEVEL_INFO = 0x04, // 0000 0100 + LOG_LEVEL_WARNING = 0x08, // 0000 1000 + LOG_LEVEL_ERROR = 0x10, // 0001 0000 + LOG_LEVEL_FATAL = 0x20, // 0010 0000 + LOG_LEVEL_ALL = 0x3F // 0011 1111 +}; +/*------------------------------------------------------------------------------ + rtw_log_Output +------------------------------------------------------------------------------*/ +enum LogOutput +{ + LOG_OUTPUT_NONE = 0x00, // 0000 0000 + LOG_OUTPUT_STDERR = 0x01, // 0000 0001 + LOG_OUTPUT_STDOUT = 0x02, // 0000 0010 + LOG_OUTPUT_FILE = 0x04 // 0000 0100 +}; +/*============================================================================== + STRUCT +==============================================================================*/ +/*------------------------------------------------------------------------------ + Logger +------------------------------------------------------------------------------*/ +struct Logger +{ + enum LogLevel level_flag; // Levels allowed + enum LogOutput output; +}; +/*============================================================================== + MACRO +==============================================================================*/ +/*------------------------------------------------------------------------------ + Log_Trace() +------------------------------------------------------------------------------*/ +#define Log_Trace(logger, ...) \ +do { \ + if(Log_IsLevelSet(logger, LOG_LEVEL_TRACE) == true) { \ + logger_write(logger, LOG_LEVEL_TRACE, \ + __FILE__, __LINE__, __func__, __VA_ARGS__); \ + } \ +} while(0) +/*------------------------------------------------------------------------------ + Log_Debug() +------------------------------------------------------------------------------*/ +#define Log_Debug(logger, ...) \ +do { \ + if(Log_IsLevelSet(logger, LOG_LEVEL_DEBUG) == true) { \ + logger_write(logger, LOG_LEVEL_DEBUG, \ + __FILE__, __LINE__, __func__, __VA_ARGS__); \ + } \ +} while(0) +/*------------------------------------------------------------------------------ + Log_Info() +------------------------------------------------------------------------------*/ +#define Log_Info(logger, ...) \ +do { \ + if(Log_IsLevelSet(logger, LOG_LEVEL_INFO) == true) { \ + logger_write(logger, LOG_LEVEL_INFO, \ + __FILE__, __LINE__, __func__, __VA_ARGS__); \ + } \ +} while(0) +/*------------------------------------------------------------------------------ + Log_Warning() +------------------------------------------------------------------------------*/ +#define Log_Warning(logger, ...) \ +do { \ + if(Log_IsLevelSet(logger, LOG_LEVEL_WARNING) == true) { \ + logger_write(logger, LOG_LEVEL_WARNING, \ + __FILE__, __LINE__, __func__, __VA_ARGS__); \ + } \ +} while(0) +/*------------------------------------------------------------------------------ + Log_Error() +------------------------------------------------------------------------------*/ +#define Log_Error(logger, ...) \ +do { \ + if(Log_IsLevelSet(logger, LOG_LEVEL_ERROR) == true) { \ + logger_write(logger, LOG_LEVEL_ERROR, \ + __FILE__, __LINE__, __func__, __VA_ARGS__); \ + } \ +} while(0) +/*------------------------------------------------------------------------------ + Log_Fatal() +------------------------------------------------------------------------------*/ +#define Log_Fatal(logger, ...) \ +do { \ + if(Log_IsLevelSet(logger, LOG_LEVEL_FATAL) == true) { \ + logger_write(logger, LOG_LEVEL_FATAL, \ + __FILE__, __LINE__, __func__, __VA_ARGS__); \ + } \ +} while(0) +/*============================================================================== + PUBLIC FUNCTION +==============================================================================*/ +/*------------------------------------------------------------------------------ + Log_IsLevelSet() +------------------------------------------------------------------------------*/ +_Bool Log_IsLevelSet(const struct Logger * const logger, enum LogLevel level); +/*============================================================================== + PRIVATE FUNCTION +==============================================================================*/ +/*------------------------------------------------------------------------------ + logger_write() +------------------------------------------------------------------------------*/ +void logger_write +( + const struct Logger * const logger, + enum LogLevel level , + const char * const file , + size_t line , + const char * const function , + const char * const message , ... +); +/*============================================================================== + GUARD +==============================================================================*/ +#endif // LOG_H_20190119152151 diff --git a/makefile b/makefile index b0f983fb0c28b6324ccf270871215182809e163c..b26b8b615649177f97a8897a4cfc8e68790a6e87 100644 --- a/makefile +++ b/makefile @@ -199,11 +199,13 @@ LFLAGS += -o ./$@.out ################################################################################ SPARSE2IMG_DEP := \ sparse2img.o \ - sparse.o + sparse.o \ + log.o IMG2SPARSE_DEP := \ img2sparse.o \ - sparse.o + sparse.o \ + log.o SPARSE2IMG_OBJ_LIST_PATH := $(addprefix $(OBJECT_PATH)/, $(SPARSE2IMG_DEP)) IMG2SPARSE_OBJ_LIST_PATH := $(addprefix $(OBJECT_PATH)/, $(IMG2SPARSE_DEP)) @@ -213,7 +215,10 @@ S2I_DEP := \ I2S_DEP := \ $(SOURCE_FOLDER)/img2sparse.c SPARSE_DEP := \ - $(SOURCE_FOLDER)/sparse.c + $(SOURCE_FOLDER)/sparse.c \ + $(HEADER_FOLDER)/log.h +LOG_DEP := \ + $(SOURCE_FOLDER)/log.c ################################################################################ # OBJECT TARGET ################################################################################ @@ -229,6 +234,8 @@ img2sparse.o: $(I2S_DEP) $(CFLAGS) sparse.o: $(SPARSE_DEP) $(CFLAGS) +log.o: $(LOG_DEP) + $(CFLAGS) .PHONY: all all: sparse2img img2sparse diff --git a/src/log.c b/src/log.c new file mode 100644 index 0000000000000000000000000000000000000000..72be1970e5f297107e364fc99d36351a4ea81d46 --- /dev/null +++ b/src/log.c @@ -0,0 +1,119 @@ +/*! + @file + @date 18.01.2019 + @author Raphael Bach + @copyright + +The MIT License (MIT) + +Copyright (c) 2019 Raphael Bach + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @brief + @details +*/ +/*============================================================================== + INCLUDE +==============================================================================*/ +// Own header +#include "log.h" +// C Standard Library +#include <assert.h> +#include <stdarg.h> // vsprintf(), va_list, va_start(), va_end() +#include <stdbool.h> +#include <stdio.h> // sprintf(), fprintf(), NULL, FILE +#include <time.h> // time(), localtime(), time_t, struct tm +/*============================================================================== + DEFINE +==============================================================================*/ +#define LOG_MESSAGE_MAX_LENGTH 512 +#define LOG_MAX_LENGTH 1024 +/*============================================================================== + STATIC +==============================================================================*/ +static const char * const s_level_name[] = +{ + [LOG_LEVEL_TRACE] = "TRACE" , + [LOG_LEVEL_DEBUG] = "DEBUG" , + [LOG_LEVEL_INFO] = "INFO" , + [LOG_LEVEL_WARNING] = "WARNING", + [LOG_LEVEL_ERROR] = "ERROR" , + [LOG_LEVEL_FATAL] = "FATAL" , +}; +/*============================================================================== + PUBLIC FUNCTION DEFINITION +==============================================================================*/ +/*------------------------------------------------------------------------------ + Log_IsLevelSet() +------------------------------------------------------------------------------*/ +_Bool Log_IsLevelSet(const struct Logger * const logger, enum LogLevel level) +{ + assert(logger != NULL); + _Bool result = false; + if((logger->level_flag & level) == level) { + result = true; + } + return result; +} +/*============================================================================== + PRIVATE FUNCTION DEFINITION +==============================================================================*/ +/*------------------------------------------------------------------------------ + logger_write() +------------------------------------------------------------------------------*/ +void logger_write +( + const struct Logger * const logger, + enum LogLevel level , + const char * const file , + size_t line , + const char * const function , + const char * const message , ... +) +{ + assert(logger != NULL); + assert(file != NULL); + assert(function != NULL); + assert(message != NULL); + + char message_buffer[LOG_MESSAGE_MAX_LENGTH]; + + va_list args; + va_start(args, message); + vsprintf(message_buffer, message, args); + va_end(args); + + struct tm *actual_time; + time_t raw_time; + time(&raw_time); + actual_time = localtime(&raw_time); + + char log[LOG_MAX_LENGTH]; + sprintf(log, "%02d:%02d:%02d - %s:%zu:%s() - [%s] : %s", + actual_time->tm_hour, actual_time->tm_min, actual_time->tm_sec, + file, line, function, s_level_name[level], message_buffer); + + FILE * output = NULL; + if(logger->output == LOG_OUTPUT_STDERR) { + output = stderr; + } else if(logger->output == LOG_OUTPUT_STDOUT) { + output = stdout; + } + fprintf(output, "%s", log); +}