7624036b1e73db17015715f81a017a66c11a8e96
[sim/o1-interface.git] / ntsimulator / ntsim-ng / utils / log_utils.c
1 /*************************************************************************
2 *
3 * Copyright 2020 highstreet technologies GmbH and others
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 ***************************************************************************/
17
18 #define _GNU_SOURCE
19
20 #include "log_utils.h"
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <stdbool.h>
25 #include <time.h>
26 #include <assert.h>
27
28 #include <core/framework.h>
29
30 static int instances = 0;
31 static int errors = 0;
32 static FILE* logfile = 0;
33
34 static char *extract_format(const char *format);
35
36 void log_init(const char *logfilename) {
37     assert(instances == 0);
38     instances++;
39
40     logfile = fopen(logfilename, "w");
41
42     assert(logfile);
43
44     time_t t = time(NULL);
45     struct tm tm = *localtime(&t);
46     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);
47     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);
48 }
49
50 void log__message(char const * const filename, uint32_t location, const int verbose_level, const char *format, ...) {
51     va_list arg;
52
53     char *format2 = 0;
54     asprintf(&format2, "[%s:%u] %s", filename, location, format);
55     if(format2 == 0) {
56         fprintf(stderr, LOG_COLOR_BOLD_RED"bad malloc in log system\n"LOG_COLOR_RESET);
57         format2 = (char *)format;
58     }
59
60     va_start(arg, format);
61     char *new_format = extract_format(format2);
62     vfprintf(logfile, new_format, arg);
63
64     if(new_format != format2) {
65         free(new_format);
66     }
67
68     if(format2 != format) {
69         free(format2);
70     }
71     fflush(logfile);
72     va_end(arg);
73
74     if(verbose_level <= framework_arguments.verbosity_level) {
75         va_start(arg, format);
76         vfprintf(stdout, format, arg);
77         va_end(arg);
78     }
79 }
80
81 void log__error(char const * const function, uint32_t location, const char *format, ...) {
82     va_list arg;
83     bool has_newline = false;
84     if(format[strlen(format) - 1] == '\n') {
85         has_newline = true;
86     }
87
88     errors++;
89     char *new_format = extract_format(format);
90     fprintf(logfile, "[error in %s():%d] ", function, location);
91     va_start(arg, format);
92     vfprintf(logfile, new_format, arg);
93     if(new_format != format) {
94         free(new_format);
95     }
96     if(!has_newline) {
97         fprintf(logfile, "\n");
98     }
99     fflush(logfile);
100     va_end(arg);
101
102     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);
103     va_start(arg, format);
104     vfprintf(stderr, format, arg);
105     if(!has_newline) {
106         fprintf(stderr, "\n");
107     }
108     va_end(arg);
109 }
110
111 void log_close(void) {
112     time_t t = time(NULL);
113     struct tm tm = *localtime(&t);
114     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);
115     fclose(logfile);
116
117     if(errors) {
118         fprintf(stderr, "-------- !!!!!! ERRORS WERE PRESENT, CHECK ERROR FILE !!!!!! ------------\n\n\n\n");
119     }
120 }
121
122 static char *extract_format(const char *format) {
123     assert(format);
124
125     int l = strlen(format);
126     char *ret = (char *)malloc(sizeof(char) * (l + 1));
127     if(ret == 0) {
128         fprintf(stderr, LOG_COLOR_BOLD_RED"bad malloc in log system\n"LOG_COLOR_RESET);
129         return (char *)format;
130     }
131
132     int s = 0;
133     int d = 0;
134     bool in_escape = false;
135
136     while(s < l) {
137         if(!in_escape) {
138             //escape char
139             if(format[s] == 27) {
140                 in_escape = true;
141                 s++;
142             }
143         }
144         else {
145             if(format[s] == 'm') {
146                 in_escape = false;
147                 s++;
148             }
149         }
150
151
152         if(!in_escape) {
153             ret[d++] = format[s];
154         }
155
156         s++;
157     }
158
159     ret[d] = 0;
160   
161     return ret;
162 }