scc  2024.06
SystemC components library
report.h
1 /*******************************************************************************
2  * Copyright 2016, 2018 MINRES Technologies GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *******************************************************************************/
16 
17 #ifndef _SCC_REPORT_H_
18 #define _SCC_REPORT_H_
19 
20 #include "utilities.h"
21 #include <cci_configuration>
22 #include <cstring>
23 #include <iomanip>
24 #include <iostream>
25 #include <sstream>
26 #include <stdexcept>
27 #include <sysc/kernel/sc_time.h>
28 #include <sysc/utils/sc_report.h>
29 #include <unordered_map>
30 #include <util/ities.h>
31 
32 #if defined(_MSC_VER) && defined(ERROR)
33 #undef ERROR
34 #endif
35 
77 #define SCC_LOG_LEVEL_PARAM_NAME "log_level"
83 namespace scc {
85 enum class log { NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE, TRACEALL, DBGTRACE = TRACEALL };
86 namespace {
88 static std::array<const char* const, 8> log_level_names = {{"NONE", "FATAL", "ERROR", "WARNING", "INFO", "DEBUG", "TRACE", "TRACEALL"}};
89 static const std::unordered_map<std::string, scc::log> log_level_lut = {
90  {"NONE", scc::log::NONE}, {"FATAL", scc::log::FATAL}, {"ERROR", scc::log::ERROR}, {"WARNING", scc::log::WARNING},
91  {"INFO", scc::log::INFO}, {"DEBUG", scc::log::DEBUG}, {"TRACE", scc::log::TRACE}, {"TRACEALL", scc::log::TRACEALL}};
92 } // namespace
100 inline log as_log(int logLevel) {
101  assert(logLevel >= static_cast<int>(log::NONE) && logLevel <= static_cast<int>(log::TRACEALL));
102  std::array<const log, 8> m = {{log::NONE, log::FATAL, log::ERROR, log::WARNING, log::INFO, log::DEBUG, log::TRACE, log::TRACEALL}};
103  return m[logLevel];
104 }
113 inline std::istream& operator>>(std::istream& is, log& val) {
114  std::string buf;
115  is >> buf;
116  auto it = scc::log_level_lut.find(buf);
117  if(it == std::end(scc::log_level_lut))
118  throw std::out_of_range(std::string("Illegal log level value: ") + buf);
119  val = it->second;
120  return is;
121 }
130 inline std::ostream& operator<<(std::ostream& os, log const& val) {
131  os << log_level_names[static_cast<unsigned>(val)];
132  return os;
133 }
142 void init_logging(log level = log::WARNING, unsigned type_field_width = 24, bool print_time = false);
148 void reinit_logging();
155 void reinit_logging(log level);
162 struct LogConfig {
163  log level{log::WARNING};
164  unsigned msg_type_field_width{24};
165  bool print_sys_time{false};
166  bool print_sim_time{true};
167  bool print_delta{false};
168  bool print_severity{true};
169  bool colored_output{true};
170  std::string log_file_name{""};
171  std::string log_filter_regex{""};
172  bool log_async{true};
173  bool dont_create_broker{false};
174  bool report_only_first_error{false};
175  bool instance_based_log_levels{true};
176  bool install_handler{true};
177 
189  LogConfig& msgTypeFieldWidth(unsigned);
195  LogConfig& printSysTime(bool = true);
201  LogConfig& printSimTime(bool = true);
207  LogConfig& printDelta(bool = true);
213  LogConfig& printSeverity(bool = true);
219  LogConfig& coloredOutput(bool = true);
225  LogConfig& logFileName(std::string&&);
231  LogConfig& logFileName(const std::string&);
237  LogConfig& logFilterRegex(std::string&&);
243  LogConfig& logFilterRegex(const std::string&);
249  LogConfig& logAsync(bool = true);
255  LogConfig& dontCreateBroker(bool = true);
261  LogConfig& reportOnlyFirstError(bool = true);
267  LogConfig& instanceBasedLogLevels(bool = true);
273  LogConfig& installHandler(bool = true);
274 };
281 void init_logging(const LogConfig& log_config);
295 void set_logging_level(log level);
311 void set_cycle_base(sc_core::sc_time period);
318 inline sc_core::sc_verbosity get_log_verbosity() {
319  return static_cast<sc_core::sc_verbosity>(::sc_core::sc_report_handler::get_verbosity_level());
320 }
331 sc_core::sc_verbosity get_log_verbosity(char const* t);
342 inline sc_core::sc_verbosity get_log_verbosity(std::string const& t) { return get_log_verbosity(t.c_str()); }
351 template <sc_core::sc_severity SEVERITY> struct ScLogger {
360  ScLogger(const char* file, int line, int verbosity = sc_core::SC_MEDIUM)
361  : t(nullptr)
362  , file(file)
363  , line(line)
364  , level(verbosity){};
365 
366  ScLogger() = delete;
367 
368  ScLogger(const ScLogger&) = delete;
369 
370  ScLogger(ScLogger&&) = delete;
371 
372  ScLogger& operator=(const ScLogger&) = delete;
373 
374  ScLogger& operator=(ScLogger&&) = delete;
380  virtual ~ScLogger() { ::sc_core::sc_report_handler::report(SEVERITY, t ? t : "SystemC", os.str().c_str(), level, file, line); }
387  inline ScLogger& type() {
388  this->t = nullptr;
389  return *this;
390  }
398  inline ScLogger& type(char const* t) {
399  this->t = const_cast<char*>(t);
400  return *this;
401  }
409  inline ScLogger& type(std::string const& t) {
410  this->t = const_cast<char*>(t.c_str());
411  return *this;
412  }
419  inline std::ostream& get() { return os; };
420 
421 protected:
422  std::ostringstream os{};
423  char* t{nullptr};
424  const char* file;
425  const int line;
426  const int level;
427 };
428 
433 #define SCCLOG(lvl, ...) ::scc::ScLogger<::sc_core::SC_INFO>(__FILE__, __LINE__, lvl).type(__VA_ARGS__).get()
435 #define SCCTRACEALL(...) \
436  if(::scc::get_log_verbosity(__VA_ARGS__) >= sc_core::SC_DEBUG) \
437  SCCLOG(sc_core::SC_DEBUG, __VA_ARGS__)
439 #define SCCTRACE(...) \
440  if(::scc::get_log_verbosity(__VA_ARGS__) >= sc_core::SC_FULL) \
441  SCCLOG(sc_core::SC_FULL, __VA_ARGS__)
443 #define SCCDEBUG(...) \
444  if(::scc::get_log_verbosity(__VA_ARGS__) >= sc_core::SC_HIGH) \
445  SCCLOG(sc_core::SC_HIGH, __VA_ARGS__)
447 #define SCCINFO(...) \
448  if(::scc::get_log_verbosity(__VA_ARGS__) >= sc_core::SC_MEDIUM) \
449  SCCLOG(sc_core::SC_MEDIUM, __VA_ARGS__)
451 #define SCCWARN(...) \
452  if(::scc::get_log_verbosity(__VA_ARGS__) >= sc_core::SC_LOW) \
453  ::scc::ScLogger<::sc_core::SC_WARNING>(__FILE__, __LINE__, sc_core::SC_MEDIUM).type(__VA_ARGS__).get()
455 #define SCCERR(...) ::scc::ScLogger<::sc_core::SC_ERROR>(__FILE__, __LINE__, sc_core::SC_MEDIUM).type(__VA_ARGS__).get()
457 #define SCCFATAL(...) ::scc::ScLogger<::sc_core::SC_FATAL>(__FILE__, __LINE__, sc_core::SC_MEDIUM).type(__VA_ARGS__).get()
458 
459 #ifdef NDEBUG
460 #define SCC_ASSERT(expr) ((void)0)
461 #else
462 #define SCC_ASSERT(expr) ((void)((expr) ? 0 : (SC_REPORT_FATAL(::sc_core::SC_ID_ASSERTION_FAILED_, #expr), 0)))
463 #endif
465 #define SCMOD this->name()
473 class stream_redirection : public std::stringbuf {
474 public:
482  stream_redirection(std::ostream& os, log level);
483 
484  stream_redirection(stream_redirection const&) = delete;
485 
486  stream_redirection& operator=(stream_redirection const&) = delete;
487 
489 
490  stream_redirection& operator=(stream_redirection&&) = delete;
502  void reset();
503 
504 protected:
505  std::streamsize xsputn(const char_type* s, std::streamsize n) override;
506  int sync() override;
507  std::ostream& os;
508  log level;
509  std::streambuf* old_buf{nullptr};
510 };
511 
512 } // namespace scc // end of scc-sysc
514 namespace cci {
515 template <> inline bool cci_value_converter<scc::log>::pack(cci_value::reference dst, scc::log const& src) {
516  dst.set_string(scc::log_level_names[static_cast<unsigned>(src)]);
517  return true;
518 }
519 template <> inline bool cci_value_converter<scc::log>::unpack(scc::log& dst, cci_value::const_reference src) {
520  // Highly defensive unpacker; probably could check less
521  if(!src.is_string())
522  return false;
523  auto it = scc::log_level_lut.find(src.get_string());
524  if(it != std::end(scc::log_level_lut)) {
525  dst = it->second;
526  return true;
527  }
528  return false;
529 }
530 } // namespace cci
531 #endif /* _SCC_REPORT_H_ */
stream redirector
Definition: report.h:473
~stream_redirection()
destructor restoring the output stream buffer
Definition: report.cpp:321
void reset()
reset the stream redirection and restore output buffer of the stream
Definition: report.cpp:325
stream_redirection(std::ostream &os, log level)
constructor redirecting the given stream to a SystemC log message of given llog level
SCC TLM utilities.
std::istream & operator>>(std::istream &is, log &val)
read a log level from input stream e.g. used by boost::lexical_cast
Definition: report.h:113
bool is_logging_initialized()
get the state of the SCC logging system
Definition: report.cpp:437
void set_logging_level(log level)
sets the SystemC logging level
Definition: report.cpp:453
void init_logging(log level=log::WARNING, unsigned type_field_width=24, bool print_time=false)
initializes the SystemC logging system with a particular logging level
Definition: report.cpp:439
log as_log(int logLevel)
safely convert an integer into a log level
Definition: report.h:100
log get_logging_level()
get the SystemC logging level
Definition: report.cpp:461
void set_cycle_base(sc_core::sc_time period)
sets the cycle base for cycle based logging
sc_core::sc_verbosity get_log_verbosity()
get the global verbosity level
Definition: report.h:318
std::ostream & operator<<(std::ostream &os, log const &val)
output the textual representation of the log level
Definition: report.h:130
log
enum defining the log levels
Definition: report.h:85
the configuration class for the logging setup
Definition: report.h:162
LogConfig & printSeverity(bool=true)
Definition: report.cpp:490
LogConfig & printSysTime(bool=true)
Definition: report.cpp:475
LogConfig & logFilterRegex(std::string &&)
LogConfig & reportOnlyFirstError(bool=true)
Definition: report.cpp:530
LogConfig & coloredOutput(bool=true)
Definition: report.cpp:505
LogConfig & dontCreateBroker(bool=true)
Definition: report.cpp:525
LogConfig & logLevel(log)
Definition: report.cpp:465
LogConfig & msgTypeFieldWidth(unsigned)
Definition: report.cpp:470
LogConfig & logFileName(const std::string &)
LogConfig & printSimTime(bool=true)
Definition: report.cpp:480
LogConfig & logAsync(bool=true)
Definition: report.cpp:520
LogConfig & printDelta(bool=true)
Definition: report.cpp:485
LogConfig & instanceBasedLogLevels(bool=true)
Definition: report.cpp:534
LogConfig & installHandler(bool=true)
Definition: report.cpp:538
LogConfig & logFilterRegex(const std::string &)
LogConfig & logFileName(std::string &&)
the logger class
Definition: report.h:351
ScLogger & type(char const *t)
set the category of the log entry
Definition: report.h:398
virtual ~ScLogger()
the destructor generating the SystemC report
Definition: report.h:380
ScLogger & type(std::string const &t)
set the category of the log entry
Definition: report.h:409
std::ostream & get()
get the underlying ostringstream
Definition: report.h:419
ScLogger & type()
reset the category of the log entry
Definition: report.h:387
ScLogger(const char *file, int line, int verbosity=sc_core::SC_MEDIUM)
Definition: report.h:360