SOMHunter Core
static-logger.hpp
Go to the documentation of this file.
1 /* This file is part of SOMHunter.
2  *
3  * Copyright (C) 2021 Frantisek Mejzlik<frankmejzlik@protonmail.com>
4  * Mirek Kratochvil <exa.exa@gmail.com>
5  * Patrik Vesely <prtrikvesely@gmail.com>
6  *
7  * SOMHunter is free software: you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License as published by the Free
9  * Software Foundation, either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * SOMHunter is distributed in the hope that it will be useful, but WITHOUT ANY
13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * SOMHunter. If not, see <https://www.gnu.org/licenses/>.
19  */
20 
21 /* ***************************************
22  SNIPPETS
23  ---------------
24 
25 #ifdef SHLOG_D // Turn off `SHLOG_D` in this TU
26 # undef SHLOG_D
27 # define SHLOG_D(x) _dont_write_log_err
28 #endif
29 
30  ***************************************** */
31 
32 #ifndef log_h
33 #define log_h
34 
35 #include <cmath>
36 #include <exception>
37 #include <fstream>
38 #include <iostream>
39 #include <mutex>
40 #include <sstream>
41 #include <string>
42 #include <string_view>
43 // ---
44 #include "common.h"
45 
46 #define FILE_NAME_TAIL_LEN 50
47 
49 constexpr bool RUN_ASSERTS = true;
50 
51 namespace TermColor {
52 enum Code {
53  FG_RED = 31,
54  FG_GREEN = 32,
55  FG_YELLOW = 33,
56  FG_BLUE = 34,
57  FG_CYAN = 36,
58  FG_WHITE = 37,
59  FG_GREY = 90,
60  FG_DEFAULT = 39,
61 
62  BG_RED = 41,
63  BG_GREEN = 42,
64  BG_YELLOW = 43,
65  BG_BLUE = 44,
66  BG_CYAN = 46,
67  BG_WHITE = 47,
68  BG_GREY = 100,
69  BG_DEFAULT = 49
70 };
71 class Modifier {
73 
74 public:
75  Modifier(Code pCode) : code(pCode) {}
76  friend std::ostream& operator<<(std::ostream& os, const Modifier& mod) { return os << "\033[" << mod.code << "m"; }
77 };
78 
79 static Modifier red{ TermColor::Code::FG_RED };
80 static Modifier green{ TermColor::Code::FG_GREEN };
81 static Modifier yellow{ TermColor::Code::FG_YELLOW };
82 static Modifier blue{ TermColor::Code::FG_BLUE };
83 static Modifier cyan{ TermColor::Code::FG_CYAN };
84 static Modifier white{ TermColor::Code::FG_WHITE };
85 static Modifier grey{ TermColor::Code::FG_GREY };
86 static Modifier def{ TermColor::Code::FG_DEFAULT };
87 
88 static Modifier redbg{ TermColor::Code::BG_RED };
89 static Modifier greenbg{ TermColor::Code::BG_GREEN };
90 static Modifier yellowbg{ TermColor::Code::BG_YELLOW };
91 static Modifier bluebg{ TermColor::Code::BG_BLUE };
92 static Modifier cyanbg{ TermColor::Code::BG_CYAN };
93 static Modifier whitebg{ TermColor::Code::BG_WHITE };
94 static Modifier greybg{ TermColor::Code::BG_GREY };
95 static Modifier defbg{ TermColor::Code::BG_DEFAULT };
96 } // namespace TermColor
97 
101 static inline std::string_view view_tail(const std::string& str, std::size_t len) {
102  return std::string_view{ str.data() + std::max<std::size_t>(0, str.length() - len) };
103 }
104 
106 inline std::mutex logger_mtx;
107 static inline auto lock_out() {
108 #if LOCK_STDOUT
109  return std::lock_guard<std::mutex>{ logger_mtx };
110 #else
111  return 0;
112 #endif
113 }
114 
116 #define SHLOG(x) \
117  do { \
118  [[maybe_unused]] auto static_logger_lck{ lock_out() }; \
119  std::cout << x << std::endl; \
120  } while (0)
121 
122 #if LOGLEVEL > 0
123 
124 # define _dont_write_log_err \
125  do { \
126  } while (0)
127 # define _write_log_err(level, x) \
128  do { \
129  [[maybe_unused]] auto static_logger_lck{ lock_out() }; \
130  std::cerr << level << x << TermColor::grey << "\n\t" << __func__ << "() in " \
131  << view_tail(__FILE__, FILE_NAME_TAIL_LEN) << " :" << __LINE__ << "" << TermColor::def \
132  << std::endl; \
133  } while (0)
134 
135 # define _write_log_out(level, x) \
136  do { \
137  [[maybe_unused]] auto static_logger_lck{ lock_out() }; \
138  std::cout << level << x << TermColor::grey << "\n\t" << __func__ << "() in " \
139  << view_tail(__FILE__, FILE_NAME_TAIL_LEN) << " :" << __LINE__ << "" << TermColor::def \
140  << std::endl; \
141  } while (0)
142 
144 # define SHLOG_E(x) _write_log_err(TermColor::red << "E: ", x << TermColor::def)
145 
147 # define SHLOG_E_THROW(x) \
148  do { \
149  std::stringstream ss; \
150  ss << x; \
151  std::string s{ ss.str() }; \
152  _write_log_err(TermColor::red << "E: ", s << TermColor::def); \
153  throw std::runtime_error{ ss.str() }; \
154  } while (false);
155 
156 #else
157 # define SHLOG_E(x)
158 # define SHLOG_E_THROW(x)
159 # define _write_log_err(level, x)
160 #endif
161 
162 #if LOGLEVEL > 1
163 # define SHLOG_W(x) _write_log_out(TermColor::yellow << "W: ", x << TermColor::def)
164 #else
165 # define SHLOG_W(x) _dont_write_log_err
166 #endif
167 
168 #if LOGLEVEL > 2
169 # define SHLOG_I(x) _write_log_out(TermColor::white << "I: ", x << TermColor::def)
170 # define SHLOG_S(x) _write_log_out(TermColor::green << "S: ", x << TermColor::def)
171 #else
172 # define SHLOG_I(x) _dont_write_log_err
173 # define SHLOG_S(x) _dont_write_log_err
174 #endif
175 
176 #if LOGLEVEL > 3
177 # define SHLOG_D(x) _write_log_out(TermColor::grey << "D: ", x << TermColor::def)
178 #else
179 # define SHLOG_D(x) _dont_write_log_err
180 #endif
181 
182 #if LOG_API_CALLS
183 
184 # define _write_API_log_d(id, x) \
185  do { \
186  [[maybe_unused]] auto static_logger_lck{ lock_out() }; \
187  std::cout << TermColor::blue << "--> [ " << (utils::timestamp() / 1000) << id << " ] " << TermColor::cyan \
188  << x << std::endl \
189  << TermColor::def; \
190  } while (0)
191 
192 # define _write_API_unlog_d(id, x) \
193  do { \
194  [[maybe_unused]] auto static_logger_lck{ lock_out() }; \
195  std::cout << TermColor::blue << "<-- [ " << (utils::timestamp() / 1000) << id << " ] " << TermColor::cyan \
196  << x << std::endl \
197  << TermColor::def; \
198  } while (0)
199 
200 # define SHLOG_REQ(id, x) _write_API_log_d(id, x)
201 # define SHLOG_UNREQ(id, x) _write_API_unlog_d(id, x)
202 #else
203 # define SHLOG_REQ(id, x) _dont_write_log_err
204 # define SHLOG_UNREQ(id, x) _dont_write_log_err
205 #endif // LOGAPI
206 
207 namespace sh {
210 #define do_assert(assertion, msg) \
211  do { \
212  if (!(assertion)) { \
213  std::cerr << "ASSERTION FAILED: " << msg << "\n\t" \
214  << "." \
215  << "() in " << view_tail(__FILE__, FILE_NAME_TAIL_LEN) << " :" << __LINE__ << "" << std::endl; \
216  throw std::runtime_error("ASSERTION FAILED!"); \
217  } \
218  } while (0)
219 
221 #define do_assert_equals(a, b, msg) do_assert(a == b, msg);
222 
225 #define do_assert_debug(assertion, msg) \
226  do { \
227  if constexpr (RUN_ASSERTS) { \
228  do_assert(assertion, msg); \
229  } \
230  } while (0)
231 
232 }; // namespace sh
233 
234 #endif // log_h
Definition: static-logger.hpp:71
Code code
Definition: static-logger.hpp:72
friend std::ostream & operator<<(std::ostream &os, const Modifier &mod)
Definition: static-logger.hpp:76
Modifier(Code pCode)
Definition: static-logger.hpp:75
Definition: static-logger.hpp:51
Code
Definition: static-logger.hpp:52
@ FG_YELLOW
Definition: static-logger.hpp:55
@ FG_DEFAULT
Definition: static-logger.hpp:60
@ BG_GREY
Definition: static-logger.hpp:68
@ FG_GREEN
Definition: static-logger.hpp:54
@ BG_CYAN
Definition: static-logger.hpp:66
@ BG_BLUE
Definition: static-logger.hpp:65
@ FG_RED
Definition: static-logger.hpp:53
@ FG_BLUE
Definition: static-logger.hpp:56
@ BG_RED
Definition: static-logger.hpp:62
@ BG_DEFAULT
Definition: static-logger.hpp:69
@ BG_YELLOW
Definition: static-logger.hpp:64
@ BG_GREEN
Definition: static-logger.hpp:63
@ FG_WHITE
Definition: static-logger.hpp:58
@ FG_CYAN
Definition: static-logger.hpp:57
@ FG_GREY
Definition: static-logger.hpp:59
@ BG_WHITE
Definition: static-logger.hpp:67
Definition: common-types.h:33
constexpr bool RUN_ASSERTS
If true the assertions will be executed.
Definition: static-logger.hpp:49
std::mutex logger_mtx
Mutex for optional STDOUT/STDERR synchronization.
Definition: static-logger.hpp:106