scc 2025.09
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 <mutex>
26#include <sstream>
27#include <stdexcept>
28#include <sysc/kernel/sc_time.h>
29#include <sysc/utils/sc_report.h>
30#include <unordered_map>
31#include <util/ities.h>
32
33#if defined(_MSC_VER) && defined(ERROR)
34#undef ERROR
35#endif
36
78#define SCC_LOG_LEVEL_PARAM_NAME "log_level"
84namespace scc {
86enum class log { NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE, TRACEALL, DBGTRACE = TRACEALL };
87namespace {
89static std::array<const char* const, 8> log_level_names = {{"NONE", "FATAL", "ERROR", "WARNING", "INFO", "DEBUG", "TRACE", "TRACEALL"}};
90static const std::unordered_map<std::string, scc::log> log_level_lut = {
91 {"NONE", scc::log::NONE}, {"FATAL", scc::log::FATAL}, {"ERROR", scc::log::ERROR}, {"WARNING", scc::log::WARNING},
92 {"INFO", scc::log::INFO}, {"DEBUG", scc::log::DEBUG}, {"TRACE", scc::log::TRACE}, {"TRACEALL", scc::log::TRACEALL}};
93} // namespace
101inline log as_log(int logLevel) {
102 assert(logLevel >= static_cast<int>(log::NONE) && logLevel <= static_cast<int>(log::TRACEALL));
103 std::array<const log, 8> m = {{log::NONE, log::FATAL, log::ERROR, log::WARNING, log::INFO, log::DEBUG, log::TRACE, log::TRACEALL}};
104 return m[logLevel];
105}
106
114inline std::istream& operator>>(std::istream& is, log& val) {
115 std::string buf;
116 is >> buf;
117 auto it = scc::log_level_lut.find(buf);
118 if(it == std::end(scc::log_level_lut))
119 throw std::out_of_range(std::string("Illegal log level value: ") + buf);
120 val = it->second;
121 return is;
122}
123
131inline std::ostream& operator<<(std::ostream& os, log const& val) {
132 os << log_level_names[static_cast<unsigned>(val)];
133 return os;
134}
135
143void init_logging(log level = log::WARNING, unsigned type_field_width = 24, bool print_time = false);
149void reinit_logging();
156void reinit_logging(log level);
163struct LogConfig {
164 log level{log::WARNING};
165 unsigned msg_type_field_width{24};
166 bool print_sys_time{false};
167 bool print_sim_time{true};
168 bool print_delta{false};
169 bool print_severity{true};
170 bool colored_output{true};
171 std::string log_file_name{""};
172 std::string log_filter_regex{""};
173 bool log_async{true};
174 bool dont_create_broker{false};
175 bool report_only_first_error{false};
176 bool instance_based_log_levels{true};
177 bool install_handler{true};
178
190 LogConfig& msgTypeFieldWidth(unsigned);
196 LogConfig& printSysTime(bool = true);
202 LogConfig& printSimTime(bool = true);
208 LogConfig& printDelta(bool = true);
214 LogConfig& printSeverity(bool = true);
220 LogConfig& coloredOutput(bool = true);
226 LogConfig& logFileName(std::string&&);
232 LogConfig& logFileName(const std::string&);
238 LogConfig& logFilterRegex(std::string&&);
244 LogConfig& logFilterRegex(const std::string&);
250 LogConfig& logAsync(bool = true);
256 LogConfig& dontCreateBroker(bool = true);
262 LogConfig& reportOnlyFirstError(bool = true);
268 LogConfig& instanceBasedLogLevels(bool = true);
274 LogConfig& installHandler(bool = true);
275};
276
282void init_logging(const LogConfig& log_config);
296void set_logging_level(log level);
312void set_cycle_base(sc_core::sc_time period);
317extern std::mutex verbosity_mtx;
324inline sc_core::sc_verbosity get_log_verbosity() {
325 return static_cast<sc_core::sc_verbosity>(::sc_core::sc_report_handler::get_verbosity_level());
326}
327
337sc_core::sc_verbosity get_log_verbosity(char const* t);
348inline sc_core::sc_verbosity get_log_verbosity(std::string const& t) { return get_log_verbosity(t.c_str()); }
357template <sc_core::sc_severity SEVERITY> struct ScLogger {
366 ScLogger(const char* file, int line, int verbosity = sc_core::SC_MEDIUM)
367 : t(nullptr)
368 , file(file)
369 , line(line)
370 , level(verbosity){};
371
372 ScLogger() = delete;
373
374 ScLogger(const ScLogger&) = delete;
375
376 ScLogger(ScLogger&&) = delete;
377
378 ScLogger& operator=(const ScLogger&) = delete;
379
380 ScLogger& operator=(ScLogger&&) = delete;
386 virtual ~ScLogger() noexcept(false) {
387 std::lock_guard<std::mutex> lock(verbosity_mtx);
388 auto verb = ::sc_core::sc_report_handler::set_verbosity_level(1000);
389 ::sc_core::sc_report_handler::report(SEVERITY, t ? t : "SystemC", os.str().c_str(), level, file, line);
390 ::sc_core::sc_report_handler::set_verbosity_level(verb);
391 }
392
398 inline ScLogger& type() {
399 this->t = nullptr;
400 return *this;
401 }
402
409 inline ScLogger& type(char const* t) {
410 this->t = const_cast<char*>(t);
411 return *this;
412 }
413
420 inline ScLogger& type(std::string const& t) {
421 this->t = const_cast<char*>(t.c_str());
422 return *this;
423 }
424
430 inline std::ostream& get() { return os; };
431
432protected:
433 std::ostringstream os{};
434 char* t{nullptr};
435 const char* file;
436 const int line;
437 const int level;
438};
439
444#define SCCLOG(lvl, ...) ::scc::ScLogger<::sc_core::SC_INFO>(__FILE__, __LINE__, lvl).type(__VA_ARGS__).get()
446#define SCCTRACEALL(...) \
447 if(::scc::get_log_verbosity(__VA_ARGS__) >= sc_core::SC_DEBUG) \
448 SCCLOG(sc_core::SC_DEBUG, __VA_ARGS__)
450#define SCCTRACE(...) \
451 if(::scc::get_log_verbosity(__VA_ARGS__) >= sc_core::SC_FULL) \
452 SCCLOG(sc_core::SC_FULL, __VA_ARGS__)
454#define SCCDEBUG(...) \
455 if(::scc::get_log_verbosity(__VA_ARGS__) >= sc_core::SC_HIGH) \
456 SCCLOG(sc_core::SC_HIGH, __VA_ARGS__)
458#define SCCINFO(...) \
459 if(::scc::get_log_verbosity(__VA_ARGS__) >= sc_core::SC_MEDIUM) \
460 SCCLOG(sc_core::SC_MEDIUM, __VA_ARGS__)
462#define SCCWARN(...) \
463 if(::scc::get_log_verbosity(__VA_ARGS__) >= sc_core::SC_LOW) \
464 ::scc::ScLogger<::sc_core::SC_WARNING>(__FILE__, __LINE__, sc_core::SC_MEDIUM).type(__VA_ARGS__).get()
466#define SCCERR(...) ::scc::ScLogger<::sc_core::SC_ERROR>(__FILE__, __LINE__, sc_core::SC_MEDIUM).type(__VA_ARGS__).get()
468#define SCCFATAL(...) ::scc::ScLogger<::sc_core::SC_FATAL>(__FILE__, __LINE__, sc_core::SC_MEDIUM).type(__VA_ARGS__).get()
469
470#ifdef NDEBUG
471#define SCC_ASSERT(expr) ((void)0)
472#else
473#define SCC_ASSERT(expr) ((void)((expr) ? 0 : (SC_REPORT_FATAL(::sc_core::SC_ID_ASSERTION_FAILED_, #expr), 0)))
474#endif
476#ifndef SCMOD
477#define SCMOD this->name()
478#endif
479#ifndef SCOBJ
480#define SCOBJ this->name()
481#endif
489class stream_redirection : public std::stringbuf {
490public:
498 stream_redirection(std::ostream& os, log level);
499
500 stream_redirection(stream_redirection const&) = delete;
501
502 stream_redirection& operator=(stream_redirection const&) = delete;
503
505
506 stream_redirection& operator=(stream_redirection&&) = delete;
518 void reset();
519
520protected:
521 std::streamsize xsputn(const char_type* s, std::streamsize n) override;
522 int sync() override;
523 std::ostream& os;
524 log level;
525 std::streambuf* old_buf{nullptr};
526};
527
528} // namespace scc // end of scc-sysc
530namespace cci {
531template <> inline bool cci_value_converter<scc::log>::pack(cci_value::reference dst, scc::log const& src) {
532 dst.set_string(scc::log_level_names[static_cast<unsigned>(src)]);
533 return true;
534}
535template <> inline bool cci_value_converter<scc::log>::unpack(scc::log& dst, cci_value::const_reference src) {
536 // Highly defensive unpacker; probably could check less
537 if(!src.is_string())
538 return false;
539 auto it = scc::log_level_lut.find(src.get_string());
540 if(it != std::end(scc::log_level_lut)) {
541 dst = it->second;
542 return true;
543 }
544 return false;
545}
546} // namespace cci
547#endif /* _SCC_REPORT_H_ */
~stream_redirection()
destructor restoring the output stream buffer
Definition report.cpp:334
void reset()
reset the stream redirection and restore output buffer of the stream
Definition report.cpp:338
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:114
void set_logging_level(log level)
sets the SystemC logging level
Definition report.cpp:516
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:502
log as_log(int logLevel)
safely convert an integer into a log level
Definition report.h:101
bool is_logging_initialized()
get the state of the SCC logging system
Definition report.cpp:500
void set_cycle_base(sc_core::sc_time period)
sets the cycle base for cycle based logging
log get_logging_level()
get the SystemC logging level
Definition report.cpp:524
sc_core::sc_verbosity get_log_verbosity()
get the global verbosity level
Definition report.h:324
std::ostream & operator<<(std::ostream &os, log const &val)
output the textual representation of the log level
Definition report.h:131
log
enum defining the log levels
Definition report.h:86
std::mutex verbosity_mtx
a mutex needed to syncronize verbosity manipulations
Definition report.cpp:326
the configuration class for the logging setup
Definition report.h:163
LogConfig & printSeverity(bool=true)
Definition report.cpp:553
LogConfig & printSysTime(bool=true)
Definition report.cpp:538
LogConfig & reportOnlyFirstError(bool=true)
Definition report.cpp:593
LogConfig & coloredOutput(bool=true)
Definition report.cpp:568
LogConfig & logFileName(std::string &&)
LogConfig & dontCreateBroker(bool=true)
Definition report.cpp:588
LogConfig & logFilterRegex(const std::string &)
LogConfig & logFileName(const std::string &)
LogConfig & logLevel(log)
Definition report.cpp:528
LogConfig & msgTypeFieldWidth(unsigned)
Definition report.cpp:533
LogConfig & printSimTime(bool=true)
Definition report.cpp:543
LogConfig & logAsync(bool=true)
Definition report.cpp:583
LogConfig & printDelta(bool=true)
Definition report.cpp:548
LogConfig & instanceBasedLogLevels(bool=true)
Definition report.cpp:597
LogConfig & installHandler(bool=true)
Definition report.cpp:601
LogConfig & logFilterRegex(std::string &&)
the logger class
Definition report.h:357
ScLogger & type(char const *t)
set the category of the log entry
Definition report.h:409
virtual ~ScLogger() noexcept(false)
the destructor generating the SystemC report
Definition report.h:386
ScLogger & type(std::string const &t)
set the category of the log entry
Definition report.h:420
std::ostream & get()
get the underlying ostringstream
Definition report.h:430
ScLogger & type()
reset the category of the log entry
Definition report.h:398
ScLogger(const char *file, int line, int verbosity=sc_core::SC_MEDIUM)
Definition report.h:366