/************************************************************************* * * Copyright 2020 highstreet technologies GmbH and others * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ #define _GNU_SOURCE #include "log_utils.h" #include #include #include #include #include #include #include static int instances = 0; static int errors = 0; static FILE* logfile = 0; static char *extract_format(const char *format); void log_init(const char *logfilename) { assert(instances == 0); instances++; logfile = fopen(logfilename, "w"); assert(logfile); time_t t = time(NULL); struct tm tm = *localtime(&t); fprintf(logfile, "started at: %d-%02d-%02d %02d:%02d:%02d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); fprintf(stdout, LOG_COLOR_BOLD_RED"started at: %d-%02d-%02d %02d:%02d:%02d\n"LOG_COLOR_RESET, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); } void log__message(char const * const filename, uint32_t location, const int verbose_level, const char *format, ...) { va_list arg; char *format2 = 0; asprintf(&format2, "[%s:%u] %s", filename, location, format); if(format2 == 0) { fprintf(stderr, LOG_COLOR_BOLD_RED"bad malloc in log system\n"LOG_COLOR_RESET); format2 = (char *)format; } va_start(arg, format); char *new_format = extract_format(format2); vfprintf(logfile, new_format, arg); if(new_format != format2) { free(new_format); } if(format2 != format) { free(format2); } fflush(logfile); va_end(arg); if(verbose_level <= framework_arguments.verbosity_level) { va_start(arg, format); vfprintf(stdout, format, arg); va_end(arg); } } void log__error(char const * const function, uint32_t location, const char *format, ...) { va_list arg; bool has_newline = false; if(format[strlen(format) - 1] == '\n') { has_newline = true; } errors++; char *new_format = extract_format(format); fprintf(logfile, "[error in %s():%d] ", function, location); va_start(arg, format); vfprintf(logfile, new_format, arg); if(new_format != format) { free(new_format); } if(!has_newline) { fprintf(logfile, "\n"); } fflush(logfile); va_end(arg); fprintf(stderr, "["LOG_COLOR_RED"error in "LOG_COLOR_BOLD_RED"%s()"LOG_COLOR_RED":"LOG_COLOR_BOLD_CYAN"%d"LOG_COLOR_RESET"] ", function, location); va_start(arg, format); vfprintf(stderr, format, arg); if(!has_newline) { fprintf(stderr, "\n"); } va_end(arg); } void log_close(void) { time_t t = time(NULL); struct tm tm = *localtime(&t); fprintf(logfile, "finished at: %d-%02d-%02d %02d:%02d:%02d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); fclose(logfile); if(errors) { fprintf(stderr, "-------- !!!!!! ERRORS WERE PRESENT, CHECK ERROR FILE !!!!!! ------------\n\n\n\n"); } } static char *extract_format(const char *format) { assert(format); int l = strlen(format); char *ret = (char *)malloc(sizeof(char) * (l + 1)); if(ret == 0) { fprintf(stderr, LOG_COLOR_BOLD_RED"bad malloc in log system\n"LOG_COLOR_RESET); return (char *)format; } int s = 0; int d = 0; bool in_escape = false; while(s < l) { if(!in_escape) { //escape char if(format[s] == 27) { in_escape = true; s++; } } else { if(format[s] == 'm') { in_escape = false; s++; } } if(!in_escape) { ret[d++] = format[s]; } s++; } ret[d] = 0; return ret; }