mirror of https://github.com/YosysHQ/yosys.git
log: create LogManager singleton and move implementation
This commit is contained in:
parent
b17b5a19e0
commit
2e113f5eff
|
|
@ -321,11 +321,11 @@ AstNode::~AstNode()
|
|||
void AstNode::dumpAst(FILE *f, std::string indent) const
|
||||
{
|
||||
if (f == NULL) {
|
||||
for (auto &s : log_sinks) {
|
||||
f = s->file_handle();
|
||||
logger().for_each_sink([&](LogSink &sink) {
|
||||
FILE *f = sink.file_handle();
|
||||
if (f)
|
||||
dumpAst(f, indent);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -428,11 +428,11 @@ void AstNode::dumpVlog(FILE *f, std::string indent) const
|
|||
std::vector<AstNode*> rem_children1, rem_children2;
|
||||
|
||||
if (f == NULL) {
|
||||
for (auto &s : log_sinks) {
|
||||
f = s->file_handle();
|
||||
logger().for_each_sink([&](LogSink &sink) {
|
||||
FILE *f = sink.file_handle();
|
||||
if (f)
|
||||
dumpVlog(f, indent);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1944,7 +1944,7 @@ void AstModule::loadconfig() const
|
|||
|
||||
void AstNode::formatted_input_error(std::string str) const
|
||||
{
|
||||
log_formatted_file_error(*location.begin.filename, location.begin.line, std::move(str));
|
||||
log_file_error(*location.begin.filename, location.begin.line, "%s", std::move(str));
|
||||
}
|
||||
|
||||
YOSYS_NAMESPACE_END
|
||||
|
|
|
|||
|
|
@ -1386,11 +1386,11 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
|||
// everything should have been handled above -> print error if not.
|
||||
default:
|
||||
AstNode *current_scope_ast = current_ast_mod == nullptr ? current_ast : current_ast_mod;
|
||||
for (auto &s : log_sinks) {
|
||||
auto f = s->file_handle();
|
||||
logger().for_each_sink([&](LogSink &sink) {
|
||||
FILE *f = sink.file_handle();
|
||||
if (f)
|
||||
current_scope_ast->dumpAst(f, "verilog-ast> ");
|
||||
}
|
||||
});
|
||||
input_error("Don't know how to detect sign and width for %s node!\n", type2str(type));
|
||||
|
||||
}
|
||||
|
|
@ -2365,11 +2365,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
|
||||
// everything should have been handled above -> print error if not.
|
||||
default:
|
||||
for (auto &s : log_sinks) {
|
||||
auto f = s->file_handle();
|
||||
logger().for_each_sink([&](LogSink &sink) {
|
||||
FILE *f = sink.file_handle();
|
||||
if (f)
|
||||
current_ast_mod->dumpAst(f, "verilog-ast> ");
|
||||
}
|
||||
});
|
||||
input_error("Don't know how to generate RTLIL code for %s node!\n", type2str(type));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2791,10 +2791,11 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
|
|||
auto buf = children[0]->clone();
|
||||
while (buf->simplify(true, stage, width_hint, sign_hint)) { }
|
||||
if (buf->type != AST_CONSTANT) {
|
||||
// for (auto &s : log_sinks) {
|
||||
// auto f = s->file_handle();
|
||||
// if (f)
|
||||
// dumpAst(f, "verilog-ast> ");
|
||||
//logger().for_each_sink([&](LogSink &sink) {
|
||||
// FILE *f = sink.file_handle();
|
||||
// if (f)
|
||||
// dumpAst(f, "verilog-ast> ");
|
||||
//});
|
||||
input_error("Condition for generate if is not constant!\n");
|
||||
}
|
||||
if (buf->asBool() != 0) {
|
||||
|
|
@ -2830,10 +2831,11 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
|
|||
auto buf = children[0]->clone();
|
||||
while (buf->simplify(true, stage, width_hint, sign_hint)) { }
|
||||
if (buf->type != AST_CONSTANT) {
|
||||
// for (auto &s : log_sinks) {
|
||||
// auto f = s->file_handle();
|
||||
// if (f)
|
||||
// dumpAst(f, "verilog-ast> ");
|
||||
//logger().for_each_sink([&](LogSink &sink) {
|
||||
// FILE *f = sink.file_handle();
|
||||
// if (f)
|
||||
// dumpAst(f, "verilog-ast> ");
|
||||
//});
|
||||
input_error("Condition for generate case is not constant!\n");
|
||||
}
|
||||
|
||||
|
|
@ -2866,10 +2868,11 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
|
|||
buf->set_in_param_flag(true);
|
||||
while (buf->simplify(true, stage, width_hint, sign_hint)) { }
|
||||
if (buf->type != AST_CONSTANT) {
|
||||
// for (auto &s : log_sinks) {
|
||||
// auto f = s->file_handle();
|
||||
// if (f)
|
||||
// dumpAst(f, "verilog-ast> ");
|
||||
//logger().for_each_sink([&](LogSink &sink) {
|
||||
// FILE *f = sink.file_handle();
|
||||
// if (f)
|
||||
// dumpAst(f, "verilog-ast> ");
|
||||
//});
|
||||
input_error("Expression in generate case is not constant!\n");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include "kernel/yosys.h"
|
||||
#include "kernel/hashlib.h"
|
||||
#include "libs/sha1/sha1.h"
|
||||
#define CXXOPTS_VECTOR_DELIMITER '\0'
|
||||
#include "libs/cxxopts/include/cxxopts.hpp"
|
||||
#include <iostream>
|
||||
|
|
@ -287,7 +286,7 @@ int main(int argc, char **argv)
|
|||
run_shell = false;
|
||||
}
|
||||
if (result.count("C")) run_tcl_shell = true;
|
||||
if (result.count("g")) log_force_debug++;
|
||||
if (result.count("g")) logger().force_debug_on();
|
||||
if (result.count("m")) plugin_filenames = result["m"].as<std::vector<std::string>>();
|
||||
if (result.count("f")) frontend_command = result["f"].as<std::string>();
|
||||
if (result.count("H")) {
|
||||
|
|
@ -316,7 +315,7 @@ int main(int argc, char **argv)
|
|||
if (result.count(key)) {
|
||||
for (const auto& filename : result[key].as<std::vector<std::string>>()) {
|
||||
try {
|
||||
log_sinks.push_back(std::make_unique<FileLogSink>(filename, key[0] == 'L', false));
|
||||
logger().add_sink<FileLogSink>(filename, key[0] == 'L', false);
|
||||
} catch (const std::runtime_error &e) {
|
||||
std::cerr << e.what();
|
||||
exit(1);
|
||||
|
|
@ -326,15 +325,15 @@ int main(int argc, char **argv)
|
|||
}
|
||||
if (result.count("q")) {
|
||||
mode_q = true;
|
||||
if (log_errfile == stderr) log_quiet_warnings = true;
|
||||
if (log_errfile == stderr) logger().set_quiet_warnings(true);
|
||||
log_errfile = stderr;
|
||||
}
|
||||
if (result.count("v")) {
|
||||
mode_v = true;
|
||||
log_errfile = stderr;
|
||||
log_verbose_level = result["v"].as<int>();
|
||||
logger().set_verbose_level(result["v"].as<int>());
|
||||
}
|
||||
if (result.count("t")) log_time = true;
|
||||
if (result.count("t")) logger().set_log_time(true);
|
||||
if (result.count("d")) timing_details = true;
|
||||
for (const auto& key : {"s", "c"}) {
|
||||
if (result.count(key)) {
|
||||
|
|
@ -353,11 +352,11 @@ int main(int argc, char **argv)
|
|||
auto regexes = result[key].as<std::vector<std::string>>();
|
||||
for (const auto& regex : regexes) {
|
||||
if (std::string(key) == "W")
|
||||
log_warn_regexes.push_back(std::regex(regex));
|
||||
logger().add_warn(regex);
|
||||
if (std::string(key) == "w")
|
||||
log_nowarn_regexes.push_back(std::regex(regex));
|
||||
logger().add_nowarn(regex);
|
||||
if (std::string(key) == "e")
|
||||
log_werror_regexes.push_back(std::regex(regex));
|
||||
logger().add_werror(regex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -372,7 +371,7 @@ int main(int argc, char **argv)
|
|||
std::cerr << "Invalid number of tokens in -P ALL." << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
log_hdump_all = true;
|
||||
logger().set_hdump_all(true);
|
||||
} else {
|
||||
if (!tokens.empty() && !tokens[0].empty() && tokens[0].back() == '.')
|
||||
tokens[0].pop_back();
|
||||
|
|
@ -382,14 +381,14 @@ int main(int argc, char **argv)
|
|||
std::cerr << "Invalid number of tokens in -P." << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
log_hdump[tokens[0]].insert(tokens[1]);
|
||||
logger().add_hdump(tokens[0],tokens[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result.count("E")) depsfile = result["E"].as<std::string>();
|
||||
if (result.count("x")) {
|
||||
auto ignores = result["x"].as<std::vector<std::string>>();
|
||||
log_experimentals_ignored.insert(ignores.begin(), ignores.end());
|
||||
for (const auto &ignore : result["x"].as<std::vector<std::string>>())
|
||||
logger().add_experimental_ignore(ignore);
|
||||
}
|
||||
if (result.count("perffile")) perffile = result["perffile"].as<std::string>();
|
||||
if (result.count("infile")) {
|
||||
|
|
@ -405,10 +404,10 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
if (log_errfile == NULL) {
|
||||
log_sinks.push_back(std::make_unique<ConsoleLogSink>());
|
||||
log_error_stderr = true;
|
||||
logger().add_sink<ConsoleLogSink>();
|
||||
logger().set_error_stderr(true);
|
||||
} else {
|
||||
log_sinks.push_back(std::make_unique<StderrLogSink>());
|
||||
logger().add_sink<StderrLogSink>();
|
||||
}
|
||||
|
||||
if (print_banner)
|
||||
|
|
@ -452,7 +451,7 @@ int main(int argc, char **argv)
|
|||
#endif
|
||||
|
||||
if (print_stats)
|
||||
log_hasher = new SHA1;
|
||||
logger().start_hasher();
|
||||
|
||||
#if defined(__OpenBSD__)
|
||||
// save the executable origin for proc_self_dirname()
|
||||
|
|
@ -596,28 +595,19 @@ int main(int argc, char **argv)
|
|||
fprintf(f, "\n");
|
||||
}
|
||||
|
||||
if (log_expect_no_warnings && log_warnings_count_noexpect)
|
||||
log_error("Unexpected warnings found: %d unique messages, %d total, %d expected\n", GetSize(log_warnings),
|
||||
log_warnings_count, log_warnings_count - log_warnings_count_noexpect);
|
||||
logger().report_unexpected_error();
|
||||
|
||||
if (print_stats)
|
||||
{
|
||||
std::string hash = log_hasher->final().substr(0, 10);
|
||||
delete log_hasher;
|
||||
log_hasher = nullptr;
|
||||
|
||||
log_time = false;
|
||||
std::string hash = logger().finish_hasher();
|
||||
logger().set_log_time(false);
|
||||
yosys_xtrace = 0;
|
||||
log_spacer();
|
||||
|
||||
if (mode_v && !mode_q)
|
||||
log_stderr_force = true;
|
||||
logger().set_stderr_force(true);
|
||||
|
||||
if (log_warnings_count)
|
||||
log("Warnings: %d unique messages, %d total\n", GetSize(log_warnings), log_warnings_count);
|
||||
|
||||
if (!log_experimentals.empty())
|
||||
log("Warnings: %d experimental features used (not excluded with -x).\n", GetSize(log_experimentals));
|
||||
logger().report_warning_stats();
|
||||
|
||||
#ifdef _WIN32
|
||||
log("End of script. Logfile hash: %s\n", hash);
|
||||
|
|
@ -719,7 +709,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
log_check_expected();
|
||||
logger().check_expected();
|
||||
|
||||
yosys_atexit();
|
||||
|
||||
|
|
|
|||
184
kernel/log.cc
184
kernel/log.cc
|
|
@ -38,40 +38,19 @@
|
|||
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
|
||||
std::vector<std::unique_ptr<LogSink>> log_sinks;
|
||||
|
||||
std::map<std::string, std::set<std::string>> log_hdump;
|
||||
std::vector<std::regex> log_warn_regexes, log_nowarn_regexes, log_werror_regexes;
|
||||
dict<std::string, LogExpectedItem> log_expect_log, log_expect_warning, log_expect_error;
|
||||
dict<std::string, LogExpectedItem> log_expect_prefix_log, log_expect_prefix_warning, log_expect_prefix_error;
|
||||
std::set<std::string> log_warnings, log_experimentals, log_experimentals_ignored;
|
||||
int log_warnings_count = 0;
|
||||
int log_warnings_count_noexpect = 0;
|
||||
bool log_expect_no_warnings = false;
|
||||
bool log_hdump_all = false;
|
||||
SHA1 *log_hasher = NULL;
|
||||
|
||||
bool log_time = false;
|
||||
bool log_error_stderr = false;
|
||||
bool log_cmd_error_throw = false;
|
||||
bool log_quiet_warnings = false;
|
||||
int log_verbose_level;
|
||||
LogManager &logger()
|
||||
{
|
||||
static LogManager instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void (*log_error_atexit)() = NULL;
|
||||
void (*log_verific_callback)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg) = NULL;
|
||||
|
||||
int log_make_debug = 0;
|
||||
int log_force_debug = 0;
|
||||
int log_debug_suppressed = 0;
|
||||
|
||||
bool log_stderr_force = false;
|
||||
|
||||
vector<int> header_count;
|
||||
// TODO: remove when log_id is removed
|
||||
vector<char*> log_id_cache;
|
||||
|
||||
static std::optional<std::chrono::steady_clock::time_point> initial_time;
|
||||
static bool next_print_log = false;
|
||||
static int log_newline_count = 0;
|
||||
|
||||
FileLogSink::FileLogSink(const std::string &filename, bool line_buffered, bool append)
|
||||
: file(fopen(filename.c_str(), append ? "at" : "wt"))
|
||||
|
|
@ -92,7 +71,7 @@ FileLogSink::~FileLogSink()
|
|||
|
||||
void FileLogSink::log(const LogMessage &msg)
|
||||
{
|
||||
fputs(msg.legacy_msg.c_str(), file);
|
||||
fputs(msg.cached_msg.c_str(), file);
|
||||
}
|
||||
|
||||
void FileLogSink::flush()
|
||||
|
|
@ -102,8 +81,8 @@ void FileLogSink::flush()
|
|||
|
||||
void ConsoleLogSink::log(const LogMessage &msg)
|
||||
{
|
||||
FILE *file = (msg.severity == LogSeverity::LOG_ERROR && log_error_stderr) ? stderr : stdout;
|
||||
fputs(msg.legacy_msg.c_str(), file);
|
||||
FILE *file = (msg.severity == LogSeverity::LOG_ERROR && logger().get_error_stderr()) ? stderr : stdout;
|
||||
fputs(msg.cached_msg.c_str(), file);
|
||||
}
|
||||
|
||||
void ConsoleLogSink::flush()
|
||||
|
|
@ -115,14 +94,13 @@ void ConsoleLogSink::flush()
|
|||
bool StderrLogSink::should_log(const LogMessage &msg) const
|
||||
{
|
||||
return msg.severity == LogSeverity::LOG_ERROR ||
|
||||
(msg.severity == LogSeverity::LOG_WARNING && !log_quiet_warnings) ||
|
||||
/* (msg.severity == LogSeverity::LOG_HEADER && int(header_count.size()) <= log_verbose_level) || */
|
||||
log_stderr_force;
|
||||
(msg.severity == LogSeverity::LOG_WARNING && !logger().get_quiet_warnings()) ||
|
||||
logger().get_stderr_force();
|
||||
}
|
||||
|
||||
void StderrLogSink::log(const LogMessage &msg)
|
||||
{
|
||||
fputs(msg.legacy_msg.c_str(), stderr);
|
||||
fputs(msg.cached_msg.c_str(), stderr);
|
||||
}
|
||||
|
||||
void StderrLogSink::flush()
|
||||
|
|
@ -131,7 +109,7 @@ void StderrLogSink::flush()
|
|||
}
|
||||
|
||||
ScratchPadLogSink::ScratchPadLogSink(std::string scratchpad)
|
||||
: scratchpad(std::move(scratchpad))
|
||||
: scratchpad(std::move(scratchpad))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -141,7 +119,7 @@ void ScratchPadLogSink::log(const LogMessage &msg)
|
|||
if (!design)
|
||||
return;
|
||||
|
||||
design->scratchpad[scratchpad].append(msg.legacy_msg);
|
||||
design->scratchpad[scratchpad].append(msg.cached_msg);
|
||||
}
|
||||
|
||||
LogMessage::LogMessage(LogSeverity severity, std::string_view prefix, std::string_view format, std::string_view message) :
|
||||
|
|
@ -152,13 +130,11 @@ LogMessage::LogMessage(LogSeverity severity, std::string_view prefix, std::strin
|
|||
timestamp(std::chrono::steady_clock::now())
|
||||
{
|
||||
std::string time_str;
|
||||
if (log_time)
|
||||
if (logger().get_log_time())
|
||||
{
|
||||
if (next_print_log || !initial_time) {
|
||||
if (next_print_log) {
|
||||
next_print_log = false;
|
||||
if (!initial_time)
|
||||
initial_time = std::chrono::steady_clock::now();
|
||||
auto elapsed = std::chrono::steady_clock::now() - *initial_time;
|
||||
auto elapsed = std::chrono::steady_clock::now() - logger().get_initial_time();
|
||||
auto us = std::chrono::duration_cast<std::chrono::microseconds>(elapsed);
|
||||
time_str += stringf("[%05d.%06d] ", int(us.count() / 1'000'000),int(us.count() % 1'000'000));
|
||||
}
|
||||
|
|
@ -172,7 +148,7 @@ LogMessage::LogMessage(LogSeverity severity, std::string_view prefix, std::strin
|
|||
if (format == "%s" && message.back() == '\n')
|
||||
next_print_log = true;
|
||||
}
|
||||
legacy_msg = stringf("%s%s%s", time_str, prefix, message);
|
||||
cached_msg = stringf("%s%s%s", time_str, prefix, message);
|
||||
}
|
||||
|
||||
static void log_id_cache_clear()
|
||||
|
|
@ -182,7 +158,7 @@ static void log_id_cache_clear()
|
|||
log_id_cache.clear();
|
||||
}
|
||||
|
||||
static void logv_string(std::string_view prefix, std::string_view format, std::string str_in, LogSeverity severity) {
|
||||
void LogManager::logv_string(std::string_view prefix, std::string_view format, std::string str_in, LogSeverity severity) {
|
||||
size_t remove_leading = 0;
|
||||
while (format.size() > 1 && format[0] == '\n') {
|
||||
logv_string(prefix, "\n", "\n", severity);
|
||||
|
|
@ -208,10 +184,7 @@ static void logv_string(std::string_view prefix, std::string_view format, std::s
|
|||
log_hasher->update(str);
|
||||
|
||||
auto msg = LogMessage(severity, prefix, format, str_in);
|
||||
for (auto &sink : log_sinks) {
|
||||
if (sink->should_log(msg))
|
||||
sink->log(msg);
|
||||
}
|
||||
log(msg);
|
||||
|
||||
static std::string linebuffer;
|
||||
static bool log_warn_regex_recusion_guard = false;
|
||||
|
|
@ -245,16 +218,16 @@ static void logv_string(std::string_view prefix, std::string_view format, std::s
|
|||
}
|
||||
}
|
||||
|
||||
void log_formatted_string(std::string_view prefix, std::string_view format, std::string str, LogSeverity severity)
|
||||
void LogManager::log_formatted_string(std::string_view prefix, std::string_view format, std::string str, LogSeverity severity)
|
||||
{
|
||||
log_assert(!Multithreading::active());
|
||||
|
||||
if (log_make_debug && !ys_debug(1))
|
||||
if (log_make_debug && !is_debug(1))
|
||||
return;
|
||||
logv_string(prefix, format, std::move(str), severity);
|
||||
}
|
||||
|
||||
void log_formatted_header(RTLIL::Design *design, std::string_view format, std::string str)
|
||||
void LogManager::log_formatted_header(RTLIL::Design *design, std::string_view format, std::string str)
|
||||
{
|
||||
log_assert(!Multithreading::active());
|
||||
|
||||
|
|
@ -273,24 +246,24 @@ void log_formatted_header(RTLIL::Design *design, std::string_view format, std::s
|
|||
|
||||
log_formatted_string(stringf("%s. ", header_id), {}, {}, LogSeverity::LOG_HEADER);
|
||||
log_formatted_string({}, format, std::move(str), LogSeverity::LOG_HEADER);
|
||||
log_flush();
|
||||
flush();
|
||||
|
||||
if (log_hdump_all)
|
||||
log_hdump[header_id].insert("yosys_dump_" + header_id + ".il");
|
||||
|
||||
if (log_hdump.count(header_id) && design != nullptr)
|
||||
for (auto &filename : log_hdump.at(header_id)) {
|
||||
log("Dumping current design to '%s'.\n", filename);
|
||||
YOSYS_NAMESPACE_PREFIX log("Dumping current design to '%s'.\n", filename);
|
||||
if (yosys_xtrace)
|
||||
IdString::xtrace_db_dump();
|
||||
Pass::call(design, {"dump", "-o", filename});
|
||||
if (yosys_xtrace)
|
||||
log("#X# -- end of dump --\n");
|
||||
YOSYS_NAMESPACE_PREFIX log("#X# -- end of dump --\n");
|
||||
}
|
||||
log_stderr_force = false;
|
||||
}
|
||||
|
||||
void log_formatted_warning(std::string_view prefix, std::string message)
|
||||
void LogManager::log_formatted_warning(std::string_view prefix, std::string message)
|
||||
{
|
||||
log_assert(!Multithreading::active());
|
||||
|
||||
|
|
@ -302,7 +275,7 @@ void log_formatted_warning(std::string_view prefix, std::string message)
|
|||
|
||||
if (suppressed)
|
||||
{
|
||||
log("Suppressed %s%s", prefix, message);
|
||||
YOSYS_NAMESPACE_PREFIX log("Suppressed %s%s", prefix, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -329,12 +302,12 @@ void log_formatted_warning(std::string_view prefix, std::string message)
|
|||
if (log_warnings.count(message))
|
||||
{
|
||||
log_formatted_string(prefix, "%s", message, LogSeverity::LOG_INFO);
|
||||
log_flush();
|
||||
flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
log_formatted_string(prefix, "%s", message, LogSeverity::LOG_WARNING);
|
||||
log_flush();
|
||||
flush();
|
||||
log_warnings.insert(message);
|
||||
}
|
||||
|
||||
|
|
@ -345,18 +318,18 @@ void log_formatted_warning(std::string_view prefix, std::string message)
|
|||
}
|
||||
}
|
||||
|
||||
void log_formatted_file_warning(std::string_view filename, int lineno, std::string str)
|
||||
void LogManager::log_formatted_file_warning(std::string_view filename, int lineno, std::string str)
|
||||
{
|
||||
std::string prefix = stringf("%s:%d: Warning: ", filename, lineno);
|
||||
log_formatted_warning(prefix, std::move(str));
|
||||
}
|
||||
|
||||
void log_formatted_file_info(std::string_view filename, int lineno, std::string str)
|
||||
void LogManager::log_formatted_file_info(std::string_view filename, int lineno, std::string str)
|
||||
{
|
||||
log("%s:%d: Info: %s", filename, lineno, str);
|
||||
YOSYS_NAMESPACE_PREFIX log("%s:%d: Info: %s", filename, lineno, str);
|
||||
}
|
||||
|
||||
void log_suppressed() {
|
||||
void LogManager::log_suppressed() {
|
||||
if (log_debug_suppressed && !log_make_debug) {
|
||||
constexpr const char* format = "<suppressed ~%d debug messages>\n";
|
||||
logv_string({}, format, stringf(format, log_debug_suppressed),LogSeverity::LOG_INFO);
|
||||
|
|
@ -365,14 +338,14 @@ void log_suppressed() {
|
|||
}
|
||||
|
||||
[[noreturn]]
|
||||
static void log_error_with_prefix(std::string_view prefix, std::string message)
|
||||
void LogManager::log_error_with_prefix(std::string_view prefix, std::string message)
|
||||
{
|
||||
int bak_log_make_debug = log_make_debug;
|
||||
log_make_debug = 0;
|
||||
log_suppressed();
|
||||
|
||||
log_formatted_string(prefix, "%s", message, LogSeverity::LOG_ERROR);
|
||||
log_flush();
|
||||
flush();
|
||||
|
||||
log_make_debug = bak_log_make_debug;
|
||||
|
||||
|
|
@ -384,7 +357,7 @@ static void log_error_with_prefix(std::string_view prefix, std::string message)
|
|||
if (std::regex_search(string(prefix) + message, item.pattern))
|
||||
item.current_count++;
|
||||
|
||||
log_check_expected();
|
||||
check_expected();
|
||||
|
||||
if (log_error_atexit)
|
||||
log_error_atexit();
|
||||
|
|
@ -401,13 +374,13 @@ static void log_error_with_prefix(std::string_view prefix, std::string message)
|
|||
#endif
|
||||
}
|
||||
|
||||
void log_formatted_file_error(std::string_view filename, int lineno, std::string str)
|
||||
void LogManager::log_formatted_file_error(std::string_view filename, int lineno, std::string str)
|
||||
{
|
||||
std::string prefix = stringf("%s:%d: ERROR: ", filename, lineno);
|
||||
log_error_with_prefix(prefix, str);
|
||||
}
|
||||
|
||||
void log_experimental(const std::string &str)
|
||||
void LogManager::log_experimental(const std::string &str)
|
||||
{
|
||||
if (log_experimentals_ignored.count(str) == 0 && log_experimentals.count(str) == 0) {
|
||||
log_warning("Feature '%s' is experimental.\n", str);
|
||||
|
|
@ -415,7 +388,7 @@ void log_experimental(const std::string &str)
|
|||
}
|
||||
}
|
||||
|
||||
void log_formatted_error(std::string str)
|
||||
void LogManager::log_formatted_error(std::string str)
|
||||
{
|
||||
log_error_with_prefix("ERROR: ", std::move(str));
|
||||
}
|
||||
|
|
@ -435,11 +408,11 @@ void log_yosys_abort_message(std::string_view file, int line, std::string_view f
|
|||
log_error("Abort in %s:%d (%s): %s\n", file, line, func, message);
|
||||
}
|
||||
|
||||
void log_formatted_cmd_error(std::string message)
|
||||
void LogManager::log_formatted_cmd_error(std::string message)
|
||||
{
|
||||
if (log_cmd_error_throw) {
|
||||
log_formatted_string("ERROR: ", "%s", message, LogSeverity::LOG_ERROR);
|
||||
log_flush();
|
||||
flush();
|
||||
|
||||
throw log_cmd_error_exception();
|
||||
}
|
||||
|
|
@ -447,22 +420,22 @@ void log_formatted_cmd_error(std::string message)
|
|||
log_formatted_error(message);
|
||||
}
|
||||
|
||||
void log_spacer()
|
||||
void LogManager::log_spacer()
|
||||
{
|
||||
if (log_newline_count < 2) log("\n");
|
||||
if (log_newline_count < 2) log("\n");
|
||||
if (log_newline_count < 2) YOSYS_NAMESPACE_PREFIX log("\n");
|
||||
if (log_newline_count < 2) YOSYS_NAMESPACE_PREFIX log("\n");
|
||||
}
|
||||
|
||||
void log_push()
|
||||
void LogManager::log_push()
|
||||
{
|
||||
header_count.push_back(0);
|
||||
}
|
||||
|
||||
void log_pop()
|
||||
void LogManager::log_pop()
|
||||
{
|
||||
header_count.pop_back();
|
||||
log_id_cache_clear();
|
||||
log_flush();
|
||||
flush();
|
||||
}
|
||||
|
||||
#if defined(YOSYS_ENABLE_DLOPEN)
|
||||
|
|
@ -562,18 +535,12 @@ void log_backtrace(const char *prefix, int levels)
|
|||
void log_backtrace(const char*, int) { }
|
||||
#endif
|
||||
|
||||
void log_reset_stack()
|
||||
void LogManager::log_reset_stack()
|
||||
{
|
||||
while (header_count.size() > 1)
|
||||
header_count.pop_back();
|
||||
log_id_cache_clear();
|
||||
log_flush();
|
||||
}
|
||||
|
||||
void log_flush()
|
||||
{
|
||||
for (auto &sink : log_sinks)
|
||||
sink->flush();
|
||||
flush();
|
||||
}
|
||||
|
||||
void log_dump_val_worker(RTLIL::IdString v) {
|
||||
|
|
@ -631,7 +598,7 @@ void log_wire(RTLIL::Wire *wire, std::string indent)
|
|||
log("%s", buf.str());
|
||||
}
|
||||
|
||||
void log_check_expected()
|
||||
void LogManager::check_expected()
|
||||
{
|
||||
// copy out all of the expected logs so that they cannot be re-checked
|
||||
// or match against themselves
|
||||
|
|
@ -668,7 +635,7 @@ void log_check_expected()
|
|||
auto check_err = [&](const std::string kind, std::string pattern, LogExpectedItem item) {
|
||||
if (item.current_count == item.expected_count) {
|
||||
log_warn_regexes.clear();
|
||||
log("Expected %s pattern '%s' found !!!\n", kind, pattern);
|
||||
YOSYS_NAMESPACE_PREFIX log("Expected %s pattern '%s' found !!!\n", kind, pattern);
|
||||
yosys_shutdown();
|
||||
#if defined(_MSC_VER)
|
||||
_exit(0);
|
||||
|
|
@ -686,4 +653,51 @@ void log_check_expected()
|
|||
check_err("prefixed error", pattern, item);
|
||||
}
|
||||
|
||||
void LogManager::report_unexpected_error()
|
||||
{
|
||||
if (log_expect_no_warnings && log_warnings_count_noexpect)
|
||||
log_error("Unexpected warnings found: %d unique messages, %d total, %d expected\n", GetSize(log_warnings),
|
||||
log_warnings_count, log_warnings_count - log_warnings_count_noexpect);
|
||||
}
|
||||
|
||||
|
||||
void LogManager::report_warning_stats()
|
||||
{
|
||||
if (log_warnings_count)
|
||||
YOSYS_NAMESPACE_PREFIX log("Warnings: %d unique messages, %d total\n", GetSize(log_warnings), log_warnings_count);
|
||||
|
||||
if (!log_experimentals.empty())
|
||||
YOSYS_NAMESPACE_PREFIX log("Warnings: %d experimental features used (not excluded with -x).\n", GetSize(log_experimentals));
|
||||
}
|
||||
|
||||
void LogManager::add_expect(std::string type, std::string pattern, int count)
|
||||
{
|
||||
if (type == "error")
|
||||
log_expect_error[pattern] = LogExpectedItem(YS_REGEX_COMPILE(pattern), count);
|
||||
else if (type == "prefix-error")
|
||||
log_expect_prefix_error[pattern] = LogExpectedItem(YS_REGEX_COMPILE(pattern), count);
|
||||
else if (type == "warning")
|
||||
log_expect_warning[pattern] = LogExpectedItem(YS_REGEX_COMPILE(pattern), count);
|
||||
else if (type == "prefix-warning")
|
||||
log_expect_prefix_warning[pattern] = LogExpectedItem(YS_REGEX_COMPILE(pattern), count);
|
||||
else if (type == "log")
|
||||
log_expect_log[pattern] = LogExpectedItem(YS_REGEX_COMPILE(pattern), count);
|
||||
else if (type == "prefix-log")
|
||||
log_expect_prefix_log[pattern] = LogExpectedItem(YS_REGEX_COMPILE(pattern), count);
|
||||
else log_abort();
|
||||
}
|
||||
void LogManager::start_hasher()
|
||||
{
|
||||
log_hasher = std::make_unique<SHA1>();
|
||||
}
|
||||
|
||||
std::string LogManager::finish_hasher()
|
||||
{
|
||||
if (!log_hasher)
|
||||
return {};
|
||||
|
||||
std::string hash = log_hasher->final().substr(0, 10);
|
||||
log_hasher.reset();
|
||||
return hash;
|
||||
}
|
||||
YOSYS_NAMESPACE_END
|
||||
|
|
|
|||
459
kernel/log.h
459
kernel/log.h
|
|
@ -102,237 +102,470 @@ struct LogMessage {
|
|||
std::string format;
|
||||
std::string message;
|
||||
std::chrono::steady_clock::time_point timestamp;
|
||||
//TODO: remove
|
||||
std::string legacy_msg;
|
||||
|
||||
std::string cached_msg;
|
||||
};
|
||||
|
||||
class LogSink
|
||||
{
|
||||
public:
|
||||
virtual ~LogSink() = default;
|
||||
virtual ~LogSink() = default;
|
||||
|
||||
virtual bool should_log(const LogMessage &) const { return true; }
|
||||
virtual void log(const LogMessage &msg) = 0;
|
||||
virtual bool should_log(const LogMessage &) const { return true; }
|
||||
virtual void log(const LogMessage &msg) = 0;
|
||||
virtual void flush() {}
|
||||
// TODO: Remove when AST/read_verilog removed
|
||||
virtual FILE *file_handle() { return nullptr; }
|
||||
};
|
||||
|
||||
extern std::vector<std::unique_ptr<LogSink>> log_sinks;
|
||||
|
||||
class LogSinkRef : public LogSink
|
||||
{
|
||||
public:
|
||||
explicit LogSinkRef(LogSink *sink) : sink(sink) {}
|
||||
bool should_log(const LogMessage &msg) const override { return sink->should_log(msg); }
|
||||
void log(const LogMessage &msg) override { sink->log(msg); }
|
||||
void flush() override { sink->flush(); }
|
||||
explicit LogSinkRef(LogSink *sink) : sink(sink) {}
|
||||
bool should_log(const LogMessage &msg) const override { return sink->should_log(msg); }
|
||||
void log(const LogMessage &msg) override { sink->log(msg); }
|
||||
void flush() override { sink->flush(); }
|
||||
FILE *file_handle() override { return sink->file_handle(); }
|
||||
private:
|
||||
LogSink *sink;
|
||||
LogSink *sink;
|
||||
};
|
||||
|
||||
class FileLogSink : public LogSink
|
||||
{
|
||||
public:
|
||||
explicit FileLogSink(const std::string &filename, bool line_buffered, bool append);
|
||||
~FileLogSink() override;
|
||||
void log(const LogMessage &msg) override;
|
||||
explicit FileLogSink(const std::string &filename, bool line_buffered, bool append);
|
||||
~FileLogSink() override;
|
||||
void log(const LogMessage &msg) override;
|
||||
void flush() override;
|
||||
FILE *file_handle() override { return file; }
|
||||
|
||||
private:
|
||||
FILE *file;
|
||||
FILE *file;
|
||||
};
|
||||
|
||||
class ConsoleLogSink : public LogSink
|
||||
{
|
||||
public:
|
||||
void log(const LogMessage &msg) override;
|
||||
void flush() override;
|
||||
void log(const LogMessage &msg) override;
|
||||
void flush() override;
|
||||
FILE *file_handle() override { return stdout; };
|
||||
};
|
||||
|
||||
class StderrLogSink : public LogSink
|
||||
{
|
||||
public:
|
||||
bool should_log(const LogMessage &msg) const override;
|
||||
void log(const LogMessage &msg) override;
|
||||
void flush() override;
|
||||
bool should_log(const LogMessage &msg) const override;
|
||||
void log(const LogMessage &msg) override;
|
||||
void flush() override;
|
||||
};
|
||||
|
||||
class StreamLogSink : public LogSink
|
||||
{
|
||||
public:
|
||||
explicit StreamLogSink(std::ostream &stream) : stream(stream) {}
|
||||
void log(const LogMessage &msg) override { stream << msg.message; }
|
||||
void flush() override { stream.flush(); }
|
||||
|
||||
private:
|
||||
std::ostream &stream;
|
||||
};
|
||||
|
||||
class ScratchPadLogSink : public LogSink
|
||||
{
|
||||
public:
|
||||
explicit ScratchPadLogSink(std::string scratchpad);
|
||||
void log(const LogMessage &msg) override;
|
||||
explicit ScratchPadLogSink(std::string scratchpad);
|
||||
void log(const LogMessage &msg) override;
|
||||
|
||||
private:
|
||||
std::string scratchpad;
|
||||
private:
|
||||
std::string scratchpad;
|
||||
};
|
||||
|
||||
extern bool log_stderr_force;
|
||||
class LogManager
|
||||
{
|
||||
private:
|
||||
struct LogExpectedItem
|
||||
{
|
||||
LogExpectedItem(const std::regex &pat, int expected) :
|
||||
pattern(pat), expected_count(expected), current_count(0) {}
|
||||
LogExpectedItem() : expected_count(0), current_count(0) {}
|
||||
|
||||
extern std::map<std::string, std::set<std::string>> log_hdump;
|
||||
extern std::vector<std::regex> log_warn_regexes, log_nowarn_regexes, log_werror_regexes;
|
||||
extern std::set<std::string> log_warnings, log_experimentals, log_experimentals_ignored;
|
||||
extern int log_warnings_count;
|
||||
extern int log_warnings_count_noexpect;
|
||||
extern bool log_expect_no_warnings;
|
||||
extern bool log_hdump_all;
|
||||
extern SHA1 *log_hasher;
|
||||
std::regex pattern;
|
||||
int expected_count;
|
||||
int current_count;
|
||||
};
|
||||
|
||||
public:
|
||||
LogManager() = default;
|
||||
|
||||
LogManager(const LogManager &) = delete;
|
||||
LogManager &operator=(const LogManager &) = delete;
|
||||
|
||||
LogManager(LogManager &&) = default;
|
||||
LogManager &operator=(LogManager &&) = default;
|
||||
|
||||
template<typename T, typename... Args>
|
||||
T &add_sink(Args&&... args)
|
||||
{
|
||||
auto sink = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
T &ref = *sink;
|
||||
log_sinks.push_back(std::move(sink));
|
||||
return ref;
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void for_each_sink(F &&func)
|
||||
{
|
||||
for (auto &sink : log_sinks)
|
||||
func(*sink);
|
||||
}
|
||||
|
||||
void log(const LogMessage &msg)
|
||||
{
|
||||
for (auto &sink : log_sinks) {
|
||||
if (sink->should_log(msg))
|
||||
sink->log(msg);
|
||||
}
|
||||
}
|
||||
|
||||
bool empty() { return log_sinks.empty(); }
|
||||
void clear() { log_sinks.clear(); }
|
||||
void flush() { for (auto &sink : log_sinks) sink->flush(); }
|
||||
|
||||
class Scoped
|
||||
{
|
||||
public:
|
||||
explicit Scoped(LogManager &manager) :
|
||||
manager(manager),
|
||||
backup_log_sinks(std::move(manager.log_sinks)),
|
||||
backup_log_verbose_level(manager.log_verbose_level)
|
||||
{
|
||||
manager.log_sinks.reserve(backup_log_sinks.size());
|
||||
|
||||
for (const auto &sink : backup_log_sinks)
|
||||
manager.log_sinks.push_back(std::make_unique<LogSinkRef>(sink.get()));
|
||||
}
|
||||
|
||||
~Scoped()
|
||||
{
|
||||
manager.log_sinks.clear();
|
||||
manager.log_sinks = std::move(backup_log_sinks);
|
||||
manager.log_verbose_level = backup_log_verbose_level;
|
||||
}
|
||||
|
||||
Scoped(const Scoped &) = delete;
|
||||
Scoped &operator=(const Scoped &) = delete;
|
||||
|
||||
private:
|
||||
LogManager &manager;
|
||||
std::vector<std::unique_ptr<LogSink>> backup_log_sinks;
|
||||
int backup_log_verbose_level;
|
||||
};
|
||||
|
||||
Scoped scoped()
|
||||
{
|
||||
return Scoped(*this);
|
||||
}
|
||||
|
||||
class ScopedCmdErrorThrow
|
||||
{
|
||||
public:
|
||||
explicit ScopedCmdErrorThrow(LogManager &manager)
|
||||
: manager(manager), previous(manager.log_cmd_error_throw)
|
||||
{
|
||||
manager.log_cmd_error_throw = true;
|
||||
}
|
||||
|
||||
~ScopedCmdErrorThrow()
|
||||
{
|
||||
manager.log_cmd_error_throw = previous;
|
||||
}
|
||||
|
||||
private:
|
||||
LogManager &manager;
|
||||
bool previous;
|
||||
};
|
||||
|
||||
ScopedCmdErrorThrow scoped_cmd_error_throw()
|
||||
{
|
||||
return ScopedCmdErrorThrow(*this);
|
||||
}
|
||||
|
||||
class LogMakeDebugHdl
|
||||
{
|
||||
public:
|
||||
explicit LogMakeDebugHdl(LogManager &manager, bool start_on = false)
|
||||
: manager(manager)
|
||||
{
|
||||
if (start_on)
|
||||
on();
|
||||
}
|
||||
|
||||
~LogMakeDebugHdl()
|
||||
{
|
||||
off();
|
||||
}
|
||||
|
||||
void on()
|
||||
{
|
||||
if (status)
|
||||
return;
|
||||
status = true;
|
||||
manager.log_make_debug++;
|
||||
}
|
||||
|
||||
void off_silent()
|
||||
{
|
||||
if (!status)
|
||||
return;
|
||||
status = false;
|
||||
manager.log_make_debug--;
|
||||
}
|
||||
|
||||
void off()
|
||||
{
|
||||
off_silent();
|
||||
}
|
||||
private:
|
||||
LogManager &manager;
|
||||
bool status = false;
|
||||
};
|
||||
|
||||
LogMakeDebugHdl make_debug(bool start_on = false)
|
||||
{
|
||||
return LogMakeDebugHdl(*this, start_on);
|
||||
}
|
||||
|
||||
class ForceDebug
|
||||
{
|
||||
public:
|
||||
explicit ForceDebug(LogManager &manager, bool start_on = false)
|
||||
: manager(manager)
|
||||
{
|
||||
if (start_on)
|
||||
on();
|
||||
}
|
||||
|
||||
~ForceDebug()
|
||||
{
|
||||
off();
|
||||
}
|
||||
|
||||
void on()
|
||||
{
|
||||
if (active)
|
||||
return;
|
||||
|
||||
active = true;
|
||||
manager.log_force_debug++;
|
||||
}
|
||||
|
||||
void off()
|
||||
{
|
||||
if (!active)
|
||||
return;
|
||||
|
||||
active = false;
|
||||
manager.log_force_debug--;
|
||||
}
|
||||
private:
|
||||
LogManager &manager;
|
||||
bool active = false;
|
||||
};
|
||||
|
||||
ForceDebug force_debug(bool start_on = false)
|
||||
{
|
||||
return ForceDebug(*this, start_on);
|
||||
}
|
||||
|
||||
void force_debug_on() { log_force_debug++; }
|
||||
void force_debug_off() { if (log_force_debug > 0) log_force_debug--; }
|
||||
void set_force_debug(bool enabled) { log_force_debug = enabled ? 1 : 0; }
|
||||
|
||||
void report_unexpected_error();
|
||||
void report_warning_stats();
|
||||
|
||||
void add_experimental_ignore(std::string name) { log_experimentals_ignored.insert(name); }
|
||||
void add_warn(std::string pattern) { log_warn_regexes.push_back(YS_REGEX_COMPILE(pattern)); }
|
||||
void add_nowarn(std::string pattern) { log_nowarn_regexes.push_back(YS_REGEX_COMPILE(pattern)); }
|
||||
void add_werror(std::string pattern) { log_werror_regexes.push_back(YS_REGEX_COMPILE(pattern)); }
|
||||
void add_expect(std::string type, std::string pattern, int count);
|
||||
|
||||
void set_verbose_level(int level) { log_verbose_level = level; }
|
||||
void add_verbose_level(int level) { log_verbose_level += level; }
|
||||
void set_expect_no_warnings(bool value) { log_expect_no_warnings = value; }
|
||||
void set_log_time(bool value) { log_time = value; }
|
||||
void set_error_stderr(bool value) { log_error_stderr = value; }
|
||||
void set_cmd_error_throw(bool value) { log_cmd_error_throw = value; }
|
||||
void set_quiet_warnings(bool value) { log_quiet_warnings = value; }
|
||||
void set_stderr_force(bool value) { log_stderr_force = value; }
|
||||
void set_hdump_all(bool value) { log_hdump_all = value; }
|
||||
int get_verbose_level() const { return log_verbose_level; }
|
||||
bool get_log_time() const { return log_time; }
|
||||
bool get_error_stderr() const { return log_error_stderr; }
|
||||
bool get_quiet_warnings() const { return log_quiet_warnings; }
|
||||
bool get_stderr_force() const { return log_stderr_force; }
|
||||
std::chrono::steady_clock::time_point get_initial_time() const { return initial_time; }
|
||||
|
||||
void add_hdump(std::string name, std::string value) { log_hdump[name].insert(value); }
|
||||
|
||||
void log_formatted_string(std::string_view prefix, std::string_view format, std::string str, LogSeverity severity);
|
||||
void log_formatted_header(RTLIL::Design *design, std::string_view format, std::string str);
|
||||
void log_formatted_warning(std::string_view prefix, std::string message);
|
||||
void log_formatted_file_warning(std::string_view filename, int lineno, std::string str);
|
||||
void log_formatted_file_info(std::string_view filename, int lineno, std::string str);
|
||||
void log_suppressed();
|
||||
[[noreturn]] void log_formatted_file_error(std::string_view filename, int lineno, std::string str);
|
||||
void log_experimental(const std::string &str);
|
||||
[[noreturn]] void log_formatted_error(std::string str);
|
||||
[[noreturn]] void log_formatted_cmd_error(std::string message);
|
||||
void log_spacer();
|
||||
void log_push();
|
||||
void log_pop();
|
||||
|
||||
void log_reset_stack();
|
||||
|
||||
void check_expected();
|
||||
bool expects_error() { return (log_expect_error.size() + log_expect_prefix_error.size())>0; }
|
||||
#ifndef NDEBUG
|
||||
bool is_debug(int n = 0) { if (log_force_debug) return true; log_debug_suppressed += n; return false; }
|
||||
#else
|
||||
bool is_debug(int = 0) { return false; }
|
||||
#endif
|
||||
void start_hasher();
|
||||
std::string finish_hasher();
|
||||
|
||||
private:
|
||||
void logv_string(std::string_view prefix, std::string_view format, std::string str_in, LogSeverity severity);
|
||||
[[noreturn]] void log_error_with_prefix(std::string_view prefix, std::string message);
|
||||
|
||||
std::chrono::steady_clock::time_point initial_time = std::chrono::steady_clock::now();
|
||||
std::vector<std::unique_ptr<LogSink>> log_sinks;
|
||||
int log_verbose_level = 0;
|
||||
int log_newline_count = 0;
|
||||
vector<int> header_count;
|
||||
int log_warnings_count = 0;
|
||||
int log_warnings_count_noexpect = 0;
|
||||
std::set<std::string> log_warnings, log_experimentals, log_experimentals_ignored;
|
||||
|
||||
std::vector<std::regex> log_warn_regexes, log_nowarn_regexes, log_werror_regexes;
|
||||
dict<std::string, LogExpectedItem> log_expect_log, log_expect_warning, log_expect_error;
|
||||
dict<std::string, LogExpectedItem> log_expect_prefix_log, log_expect_prefix_warning, log_expect_prefix_error;
|
||||
bool log_expect_no_warnings = false;
|
||||
bool log_time = false;
|
||||
bool log_error_stderr = false;
|
||||
bool log_cmd_error_throw = false;
|
||||
bool log_quiet_warnings = false;
|
||||
bool log_stderr_force = false;
|
||||
std::map<std::string, std::set<std::string>> log_hdump;
|
||||
bool log_hdump_all = false;
|
||||
|
||||
int log_debug_suppressed = 0;
|
||||
int log_make_debug = 0;
|
||||
int log_force_debug = 0;
|
||||
std::unique_ptr<SHA1> log_hasher;
|
||||
};
|
||||
|
||||
LogManager &logger();
|
||||
|
||||
extern bool log_time;
|
||||
extern bool log_error_stderr;
|
||||
extern bool log_cmd_error_throw;
|
||||
extern bool log_quiet_warnings;
|
||||
extern int log_verbose_level;
|
||||
extern void (*log_error_atexit)();
|
||||
|
||||
extern int log_make_debug;
|
||||
extern int log_force_debug;
|
||||
extern int log_debug_suppressed;
|
||||
|
||||
void set_verific_logging(void (*cb)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg));
|
||||
extern void (*log_verific_callback)(int msg_type, const char *message_id, const char* file_path, unsigned int left_line, unsigned int left_col, unsigned int right_line, unsigned int right_col, const char *msg);
|
||||
|
||||
#ifndef NDEBUG
|
||||
static inline bool ys_debug(int n = 0) { if (log_force_debug) return true; log_debug_suppressed += n; return false; }
|
||||
static inline bool ys_debug(int n = 0) { return logger().is_debug(n); }
|
||||
#else
|
||||
static inline bool ys_debug(int = 0) { return false; }
|
||||
#endif
|
||||
|
||||
void log_formatted_string(std::string_view prefix, std::string_view format, std::string str, LogSeverity severity);
|
||||
template <typename... Args>
|
||||
inline void log(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
|
||||
{
|
||||
log_formatted_string({}, fmt.format_string(), fmt.format(args...), LogSeverity::LOG_INFO);
|
||||
logger().log_formatted_string({}, fmt.format_string(), fmt.format(args...), LogSeverity::LOG_INFO);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void log_comment(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
|
||||
{
|
||||
log_formatted_string({}, fmt.format_string(), fmt.format(args...), LogSeverity::LOG_COMMENT);
|
||||
logger().log_formatted_string({}, fmt.format_string(), fmt.format(args...), LogSeverity::LOG_COMMENT);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void log_debug(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
|
||||
{
|
||||
if (!ys_debug(1))
|
||||
return;
|
||||
log_formatted_string({}, fmt.format_string(), fmt.format(args...), LogSeverity::LOG_DEBUG);
|
||||
if (!ys_debug(1))
|
||||
return;
|
||||
logger().log_formatted_string({}, fmt.format_string(), fmt.format(args...), LogSeverity::LOG_DEBUG);
|
||||
}
|
||||
|
||||
void log_formatted_header(RTLIL::Design *design, std::string_view format, std::string str);
|
||||
template <typename... Args>
|
||||
inline void log_header(RTLIL::Design *design, FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
|
||||
{
|
||||
log_formatted_header(design, fmt.format_string(), fmt.format(args...));
|
||||
logger().log_formatted_header(design, fmt.format_string(), fmt.format(args...));
|
||||
}
|
||||
|
||||
void log_formatted_warning(std::string_view prefix, std::string str);
|
||||
template <typename... Args>
|
||||
inline void log_warning(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
|
||||
{
|
||||
log_formatted_warning("Warning: ", fmt.format(args...));
|
||||
logger().log_formatted_warning("Warning: ", fmt.format(args...));
|
||||
}
|
||||
|
||||
inline void log_formatted_warning_noprefix(std::string str)
|
||||
{
|
||||
log_formatted_warning({}, str);
|
||||
}
|
||||
template <typename... Args>
|
||||
inline void log_warning_noprefix(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
|
||||
{
|
||||
log_formatted_warning({}, fmt.format(args...));
|
||||
logger().log_formatted_warning({}, fmt.format(args...));
|
||||
}
|
||||
|
||||
void log_experimental(const std::string &str);
|
||||
inline void log_experimental(const std::string &str)
|
||||
{
|
||||
logger().log_experimental(str);
|
||||
}
|
||||
|
||||
// Log with filename to report a problem in a source file.
|
||||
void log_formatted_file_warning(std::string_view filename, int lineno, std::string str);
|
||||
template <typename... Args>
|
||||
void log_file_warning(std::string_view filename, int lineno, FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
|
||||
{
|
||||
log_formatted_file_warning(filename, lineno, fmt.format(args...));
|
||||
logger().log_formatted_file_warning(filename, lineno, fmt.format(args...));
|
||||
}
|
||||
|
||||
void log_formatted_file_info(std::string_view filename, int lineno, std::string str);
|
||||
template <typename... Args>
|
||||
void log_file_info(std::string_view filename, int lineno, FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
|
||||
{
|
||||
log_formatted_file_info(filename, lineno, fmt.format(args...));
|
||||
logger().log_formatted_file_info(filename, lineno, fmt.format(args...));
|
||||
}
|
||||
|
||||
[[noreturn]] void log_formatted_error(std::string str);
|
||||
template <typename... Args>
|
||||
[[noreturn]] void log_error(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
|
||||
{
|
||||
log_formatted_error(fmt.format(args...));
|
||||
logger().log_formatted_error(fmt.format(args...));
|
||||
}
|
||||
|
||||
[[noreturn]] void log_formatted_file_error(std::string_view filename, int lineno, std::string str);
|
||||
template <typename... Args>
|
||||
[[noreturn]] void log_file_error(std::string_view filename, int lineno, FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
|
||||
{
|
||||
log_formatted_file_error(filename, lineno, fmt.format(args...));
|
||||
logger().log_formatted_file_error(filename, lineno, fmt.format(args...));
|
||||
}
|
||||
|
||||
[[noreturn]] void log_formatted_cmd_error(std::string str);
|
||||
template <typename... Args>
|
||||
[[noreturn]] void log_cmd_error(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
|
||||
{
|
||||
log_formatted_cmd_error(fmt.format(args...));
|
||||
logger().log_formatted_cmd_error(fmt.format(args...));
|
||||
}
|
||||
|
||||
void log_suppressed();
|
||||
inline void log_suppressed()
|
||||
{
|
||||
logger().log_suppressed();
|
||||
}
|
||||
|
||||
struct LogMakeDebugHdl {
|
||||
bool status = false;
|
||||
LogMakeDebugHdl(bool start_on = false) {
|
||||
if (start_on)
|
||||
on();
|
||||
}
|
||||
~LogMakeDebugHdl() {
|
||||
off();
|
||||
}
|
||||
void on() {
|
||||
if (status) return;
|
||||
status=true;
|
||||
log_make_debug++;
|
||||
}
|
||||
void off_silent() {
|
||||
if (!status) return;
|
||||
status=false;
|
||||
log_make_debug--;
|
||||
}
|
||||
void off() {
|
||||
off_silent();
|
||||
}
|
||||
};
|
||||
inline void log_spacer() { logger().log_spacer(); }
|
||||
inline void log_push() { logger().log_push(); }
|
||||
inline void log_pop() { logger().log_pop(); }
|
||||
|
||||
void log_spacer();
|
||||
void log_push();
|
||||
void log_pop();
|
||||
inline void log_reset_stack() { logger().log_reset_stack(); }
|
||||
inline void log_flush() { logger().flush(); }
|
||||
|
||||
void log_backtrace(const char *prefix, int levels);
|
||||
void log_reset_stack();
|
||||
void log_flush();
|
||||
|
||||
struct LogExpectedItem
|
||||
{
|
||||
LogExpectedItem(const std::regex &pat, int expected) :
|
||||
pattern(pat), expected_count(expected), current_count(0) {}
|
||||
LogExpectedItem() : expected_count(0), current_count(0) {}
|
||||
|
||||
std::regex pattern;
|
||||
int expected_count;
|
||||
int current_count;
|
||||
};
|
||||
|
||||
extern dict<std::string, LogExpectedItem> log_expect_log, log_expect_warning, log_expect_error;
|
||||
extern dict<std::string, LogExpectedItem> log_expect_prefix_log, log_expect_prefix_warning, log_expect_prefix_error;
|
||||
void log_check_expected();
|
||||
|
||||
std::string log_signal(const RTLIL::SigSpec &sig, bool autoint = true);
|
||||
std::string log_const(const RTLIL::Const &value, bool autoint = true);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ void log_cmd_error(const char *format, ...)
|
|||
va_start(ap, format);
|
||||
std::string formatted = vstringf(format, ap);
|
||||
va_end(ap);
|
||||
log_formatted_cmd_error(formatted);
|
||||
logger().log_formatted_cmd_error(formatted);
|
||||
}
|
||||
|
||||
void log_warning(const char *format, ...)
|
||||
|
|
@ -46,7 +46,7 @@ void log_warning(const char *format, ...)
|
|||
va_start(ap, format);
|
||||
std::string formatted = vstringf(format, ap);
|
||||
va_end(ap);
|
||||
log_formatted_warning("Warning: ", formatted);
|
||||
logger().log_formatted_warning("Warning: ", formatted);
|
||||
}
|
||||
|
||||
void log_warning_noprefix(const char *format, ...)
|
||||
|
|
@ -55,7 +55,7 @@ void log_warning_noprefix(const char *format, ...)
|
|||
va_start(ap, format);
|
||||
std::string formatted = vstringf(format, ap);
|
||||
va_end(ap);
|
||||
log_formatted_warning("", formatted);
|
||||
logger().log_formatted_warning("", formatted);
|
||||
}
|
||||
|
||||
void log_error(const char *format, ...)
|
||||
|
|
@ -64,7 +64,7 @@ void log_error(const char *format, ...)
|
|||
va_start(ap, format);
|
||||
std::string formatted = vstringf(format, ap);
|
||||
va_end(ap);
|
||||
log_formatted_error(formatted);
|
||||
logger().log_formatted_error(formatted);
|
||||
}
|
||||
|
||||
static inline void log_formatted(std::string const &str)
|
||||
|
|
|
|||
|
|
@ -753,16 +753,6 @@ static struct CellHelpMessages {
|
|||
SimHelper get(string name) { return cell_help[get_cell_name(name)]; }
|
||||
} cell_help_messages;
|
||||
|
||||
class HelpMsgLogSink : public LogSink
|
||||
{
|
||||
public:
|
||||
explicit HelpMsgLogSink(std::ostream *buf) : buf(buf) {}
|
||||
void log(const LogMessage &msg) override { *buf << msg.message; }
|
||||
void flush() override { buf->flush(); }
|
||||
private:
|
||||
std::ostream *buf;
|
||||
};
|
||||
|
||||
struct HelpPass : public Pass {
|
||||
HelpPass() : Pass("help", "display help messages") { }
|
||||
void help() override
|
||||
|
|
@ -815,9 +805,11 @@ struct HelpPass : public Pass {
|
|||
|
||||
// dump command help
|
||||
std::ostringstream buf;
|
||||
log_sinks.push_back(std::make_unique<HelpMsgLogSink>(&buf));
|
||||
pass->help();
|
||||
log_sinks.pop_back();
|
||||
{
|
||||
auto log_scope = logger().scoped();
|
||||
logger().add_sink<StreamLogSink>(buf);
|
||||
pass->help();
|
||||
}
|
||||
std::stringstream ss;
|
||||
ss << buf.str();
|
||||
|
||||
|
|
|
|||
|
|
@ -1400,9 +1400,9 @@ void report_missing_model(bool warn_only, RTLIL::Cell* cell)
|
|||
s = stringf("No SAT model available for cell %s (%s).\n", cell, cell->type.unescape());
|
||||
|
||||
if (warn_only) {
|
||||
log_formatted_warning_noprefix(s);
|
||||
log_warning_noprefix("%s", s);
|
||||
} else {
|
||||
log_formatted_error(s);
|
||||
log_error("%s", s);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,10 +100,7 @@ static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *a
|
|||
yosys_get_design()->scratchpad_unset("result.string");
|
||||
|
||||
bool in_repl = yosys_tcl_repl_active;
|
||||
bool restore_log_cmd_error_throw = log_cmd_error_throw;
|
||||
|
||||
log_cmd_error_throw = true;
|
||||
|
||||
auto guard = logger().scoped_cmd_error_throw();
|
||||
try {
|
||||
if (args.size() == 1) {
|
||||
Pass::call(yosys_get_design(), args[0]);
|
||||
|
|
@ -120,14 +117,12 @@ static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *a
|
|||
Tcl_SetResult(interp, (char *)"Yosys command produced an error", TCL_STATIC);
|
||||
|
||||
yosys_tcl_repl_active = in_repl;
|
||||
log_cmd_error_throw = restore_log_cmd_error_throw;
|
||||
return TCL_ERROR;
|
||||
} catch (...) {
|
||||
log_error("uncaught exception during Yosys command invoked from TCL\n");
|
||||
}
|
||||
|
||||
yosys_tcl_repl_active = in_repl;
|
||||
log_cmd_error_throw = restore_log_cmd_error_throw;
|
||||
|
||||
auto &scratchpad = yosys_get_design()->scratchpad;
|
||||
auto result = scratchpad.find("result.json");
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ void yosys_shutdown()
|
|||
yosys_design = NULL;
|
||||
RTLIL::OwningIdString::collect_garbage();
|
||||
|
||||
log_sinks.clear();
|
||||
logger().clear();
|
||||
|
||||
#ifdef YOSYS_ENABLE_TCL
|
||||
if (yosys_tcl_interp != NULL) {
|
||||
|
|
@ -995,7 +995,7 @@ void shell(RTLIL::Design *design)
|
|||
static int recursion_counter = 0;
|
||||
|
||||
recursion_counter++;
|
||||
log_cmd_error_throw = true;
|
||||
auto guard = logger().scoped_cmd_error_throw();
|
||||
|
||||
#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
|
||||
rl_readline_name = (char*)"yosys";
|
||||
|
|
@ -1055,7 +1055,6 @@ void shell(RTLIL::Design *design)
|
|||
free(command);
|
||||
#endif
|
||||
recursion_counter--;
|
||||
log_cmd_error_throw = false;
|
||||
}
|
||||
|
||||
struct ShellPass : public Pass {
|
||||
|
|
|
|||
|
|
@ -85,22 +85,22 @@ struct LoggerPass : public Pass {
|
|||
{
|
||||
|
||||
if (args[argidx] == "-time") {
|
||||
log_time = true;
|
||||
logger().set_log_time(true);
|
||||
log("Enabled timestamp in logs.\n");
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-notime") {
|
||||
log_time = false;
|
||||
logger().set_log_time(false);
|
||||
log("Disabled timestamp in logs.\n");
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-stderr") {
|
||||
log_error_stderr = true;
|
||||
logger().set_error_stderr(true);
|
||||
log("Enabled loggint errors to stderr.\n");
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nostderr") {
|
||||
log_error_stderr = false;
|
||||
logger().set_error_stderr(false);
|
||||
log("Disabled loggint errors to stderr.\n");
|
||||
continue;
|
||||
}
|
||||
|
|
@ -109,7 +109,7 @@ struct LoggerPass : public Pass {
|
|||
if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);
|
||||
try {
|
||||
log("Added regex '%s' for warnings to warn list.\n", pattern);
|
||||
log_warn_regexes.push_back(YS_REGEX_COMPILE(pattern));
|
||||
logger().add_warn(pattern);
|
||||
}
|
||||
catch (const std::regex_error& e) {
|
||||
log_cmd_error("Error in regex expression '%s' !\n", pattern);
|
||||
|
|
@ -121,7 +121,7 @@ struct LoggerPass : public Pass {
|
|||
if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);
|
||||
try {
|
||||
log("Added regex '%s' for warnings to nowarn list.\n", pattern);
|
||||
log_nowarn_regexes.push_back(YS_REGEX_COMPILE(pattern));
|
||||
logger().add_nowarn(pattern);
|
||||
}
|
||||
catch (const std::regex_error& e) {
|
||||
log_cmd_error("Error in regex expression '%s' !\n", pattern);
|
||||
|
|
@ -133,7 +133,7 @@ struct LoggerPass : public Pass {
|
|||
if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);
|
||||
try {
|
||||
log("Added regex '%s' for warnings to werror list.\n", pattern);
|
||||
log_werror_regexes.push_back(YS_REGEX_COMPILE(pattern));
|
||||
logger().add_werror(pattern);
|
||||
}
|
||||
catch (const std::regex_error& e) {
|
||||
log_cmd_error("Error in regex expression '%s' !\n", pattern);
|
||||
|
|
@ -141,19 +141,19 @@ struct LoggerPass : public Pass {
|
|||
continue;
|
||||
}
|
||||
if (args[argidx] == "-debug") {
|
||||
log_force_debug = 1;
|
||||
logger().set_force_debug(true);
|
||||
log("Enabled debug log messages.\n");
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nodebug") {
|
||||
log_force_debug = 0;
|
||||
logger().set_force_debug(false);
|
||||
log("Disabled debug log messages.\n");
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-experimental" && argidx+1 < args.size()) {
|
||||
std::string value = args[++argidx];
|
||||
log("Added '%s' experimental ignore list.\n", value);
|
||||
log_experimentals_ignored.insert(value);
|
||||
logger().add_experimental_ignore(value);
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-expect" && argidx+3 < args.size()) {
|
||||
|
|
@ -161,7 +161,7 @@ struct LoggerPass : public Pass {
|
|||
if (type!="error" && type!="warning" && type!="log"
|
||||
&& type!="prefix-error" && type!="prefix-warning" && type!="prefix-log")
|
||||
log_cmd_error("Expect command require type to be 'log', 'warning' or 'error' !\n");
|
||||
if ((type=="error" || type=="prefix-error") && log_expect_error.size()>0)
|
||||
if ((type=="error" || type=="prefix-error") && logger().expects_error())
|
||||
log_cmd_error("Only single error message can be expected !\n");
|
||||
std::string pattern = args[++argidx];
|
||||
if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);
|
||||
|
|
@ -173,19 +173,7 @@ struct LoggerPass : public Pass {
|
|||
log("Added regex '%s' to expected %s messages list.\n",
|
||||
pattern.c_str(), type.c_str());
|
||||
try {
|
||||
if (type == "error")
|
||||
log_expect_error[pattern] = LogExpectedItem(YS_REGEX_COMPILE(pattern), count);
|
||||
else if (type == "prefix-error")
|
||||
log_expect_prefix_error[pattern] = LogExpectedItem(YS_REGEX_COMPILE(pattern), count);
|
||||
else if (type == "warning")
|
||||
log_expect_warning[pattern] = LogExpectedItem(YS_REGEX_COMPILE(pattern), count);
|
||||
else if (type == "prefix-warning")
|
||||
log_expect_prefix_warning[pattern] = LogExpectedItem(YS_REGEX_COMPILE(pattern), count);
|
||||
else if (type == "log")
|
||||
log_expect_log[pattern] = LogExpectedItem(YS_REGEX_COMPILE(pattern), count);
|
||||
else if (type == "prefix-log")
|
||||
log_expect_prefix_log[pattern] = LogExpectedItem(YS_REGEX_COMPILE(pattern), count);
|
||||
else log_abort();
|
||||
logger().add_expect(type, pattern, count);
|
||||
}
|
||||
catch (const std::regex_error& e) {
|
||||
log_cmd_error("Error in regex expression '%s' !\n", pattern);
|
||||
|
|
@ -193,11 +181,11 @@ struct LoggerPass : public Pass {
|
|||
continue;
|
||||
}
|
||||
if (args[argidx] == "-expect-no-warnings") {
|
||||
log_expect_no_warnings = true;
|
||||
logger().set_expect_no_warnings(true);
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-check-expected") {
|
||||
log_check_expected();
|
||||
logger().check_expected();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -58,17 +58,13 @@ struct TeePass : public Pass {
|
|||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
int backup_log_verbose_level = log_verbose_level;
|
||||
auto backup_log_sinks = std::move(log_sinks);
|
||||
log_sinks.reserve(backup_log_sinks.size());
|
||||
for (const auto &sink : backup_log_sinks)
|
||||
log_sinks.push_back(std::make_unique<LogSinkRef>(sink.get()));
|
||||
auto log_scope = logger().scoped();
|
||||
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
if (args[argidx] == "-q") {
|
||||
log_sinks.clear();
|
||||
logger().clear();
|
||||
continue;
|
||||
}
|
||||
if ((args[argidx] == "-o" || args[argidx] == "-a") && argidx+1 < args.size()) {
|
||||
|
|
@ -76,7 +72,7 @@ struct TeePass : public Pass {
|
|||
auto path = args[++argidx];
|
||||
rewrite_filename(path);
|
||||
try {
|
||||
log_sinks.push_back(std::make_unique<FileLogSink>(path.c_str(), false, is_append));
|
||||
logger().add_sink<FileLogSink>(path.c_str(), false, is_append);
|
||||
} catch (const std::runtime_error &e) {
|
||||
std::cerr << e.what();
|
||||
exit(1);
|
||||
|
|
@ -86,28 +82,18 @@ struct TeePass : public Pass {
|
|||
if (args[argidx] == "-s" && argidx+1 < args.size()) {
|
||||
auto name = args[++argidx];
|
||||
design->scratchpad[name] = "";
|
||||
log_sinks.push_back(std::make_unique<ScratchPadLogSink>(name));
|
||||
logger().add_sink<ScratchPadLogSink>(name);
|
||||
continue;
|
||||
}
|
||||
if (GetSize(args[argidx]) >= 2 && (args[argidx][0] == '-' || args[argidx][0] == '+') && args[argidx][1] >= '0' && args[argidx][1] <= '9') {
|
||||
log_verbose_level += atoi(args[argidx].c_str());
|
||||
logger().add_verbose_level(atoi(args[argidx].c_str()));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
std::vector<std::string> new_args(args.begin() + argidx, args.end());
|
||||
Pass::call(design, new_args);
|
||||
} catch (...) {
|
||||
log_sinks.clear();
|
||||
log_sinks = std::move(backup_log_sinks);
|
||||
throw;
|
||||
}
|
||||
|
||||
log_verbose_level = backup_log_verbose_level;
|
||||
log_sinks.clear();
|
||||
log_sinks = std::move(backup_log_sinks);
|
||||
std::vector<std::string> new_args(args.begin() + argidx, args.end());
|
||||
Pass::call(design, new_args);
|
||||
}
|
||||
} TeePass;
|
||||
|
||||
|
|
|
|||
|
|
@ -144,27 +144,19 @@ struct DebugPass : public Pass {
|
|||
log_cmd_error("Cannot specify both -on and -off\n");
|
||||
|
||||
if (mode_on) {
|
||||
log_force_debug++;
|
||||
logger().force_debug_on();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode_off) {
|
||||
if (log_force_debug > 0)
|
||||
log_force_debug--;
|
||||
logger().force_debug_off();
|
||||
return;
|
||||
}
|
||||
|
||||
log_force_debug++;
|
||||
auto force_debug = logger().force_debug(true);
|
||||
|
||||
try {
|
||||
std::vector<std::string> new_args(args.begin() + argidx, args.end());
|
||||
Pass::call(design, new_args);
|
||||
} catch (...) {
|
||||
log_force_debug--;
|
||||
throw;
|
||||
}
|
||||
|
||||
log_force_debug--;
|
||||
std::vector<std::string> new_args(args.begin() + argidx, args.end());
|
||||
Pass::call(design, new_args);
|
||||
}
|
||||
} DebugPass;
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ void warn(std::string str) {
|
|||
#else
|
||||
#include "kernel/log.h"
|
||||
void warn(std::string str) {
|
||||
Yosys::log_formatted_warning("", str);
|
||||
Yosys::log_warning_noprefix("%s", str);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -419,7 +419,7 @@ struct TechmapWorker
|
|||
|
||||
bool log_continue = false;
|
||||
bool did_something = false;
|
||||
LogMakeDebugHdl mkdebug;
|
||||
auto mkdebug = logger().make_debug();
|
||||
|
||||
SigMap sigmap(module);
|
||||
FfInitVals initvals(&sigmap, module);
|
||||
|
|
|
|||
|
|
@ -119,21 +119,15 @@ global_denylist = frozenset(
|
|||
{
|
||||
# deprecated
|
||||
"builtin_ff_cell_types",
|
||||
"logv_file_error",
|
||||
# no implementation
|
||||
"set_verific_logging",
|
||||
# can't bridge to python cleanly
|
||||
## std::regex
|
||||
"log_warn_regexes",
|
||||
"log_nowarn_regexes",
|
||||
"log_werror_regexes",
|
||||
## function pointers
|
||||
"log_error_atexit",
|
||||
"log_verific_callback",
|
||||
# incomplete type
|
||||
"yosys_get_tcl_interp",
|
||||
# unique ptr vector
|
||||
"log_sinks",
|
||||
# manually added later
|
||||
"logger",
|
||||
}
|
||||
)
|
||||
pyosys_headers = [
|
||||
|
|
|
|||
|
|
@ -168,8 +168,8 @@ namespace pyosys {
|
|||
m.doc() = "python access to libyosys";
|
||||
|
||||
if (!yosys_already_setup()) {
|
||||
log_sinks.push_back(std::make_unique<ConsoleLogSink>());
|
||||
log_error_stderr = true;
|
||||
logger().add_sink<ConsoleLogSink>();
|
||||
logger().set_error_stderr(true);
|
||||
yosys_setup();
|
||||
|
||||
// Cleanup
|
||||
|
|
@ -179,17 +179,24 @@ namespace pyosys {
|
|||
}
|
||||
|
||||
// Logging Methods
|
||||
m.def("log_header", [](Design *d, std::string s) { log_formatted_header(d, "%s", s); });
|
||||
m.def("log", [](std::string s) { log_formatted_string({}, "%s", s, LogSeverity::LOG_INFO); });
|
||||
m.def("log_file_info", [](std::string_view file, int line, std::string s) { log_formatted_file_info(file, line, s); });
|
||||
m.def("log_warning", [](std::string s) { log_formatted_warning("Warning: ", s); });
|
||||
m.def("log_warning_noprefix", [](std::string s) { log_formatted_warning("", s); });
|
||||
m.def("log_file_warning", [](std::string_view file, int line, std::string s) { log_formatted_file_warning(file, line, s); });
|
||||
m.def("log_error", [](std::string s) { log_formatted_error(s); });
|
||||
m.def("log_file_error", [](std::string_view file, int line, std::string s) { log_formatted_file_error(file, line, s); });
|
||||
m.def("log_header", [](Design *d, std::string s) { logger().log_formatted_header(d, "%s", s); });
|
||||
m.def("log", [](std::string s) { logger().log_formatted_string({}, "%s", s, LogSeverity::LOG_INFO); });
|
||||
m.def("log_file_info", [](std::string_view file, int line, std::string s) { logger().log_formatted_file_info(file, line, s); });
|
||||
m.def("log_warning", [](std::string s) { logger().log_formatted_warning("Warning: ", s); });
|
||||
m.def("log_warning_noprefix", [](std::string s) { logger().log_formatted_warning("", s); });
|
||||
m.def("log_file_warning", [](std::string_view file, int line, std::string s) { logger().log_formatted_file_warning(file, line, s); });
|
||||
m.def("log_error", [](std::string s) { logger().log_formatted_error(s); });
|
||||
m.def("log_file_error", [](std::string_view file, int line, std::string s) { logger().log_formatted_file_error(file, line, s); });
|
||||
|
||||
// Namespace to host global objects
|
||||
auto global_variables = py::class_<Globals>(m, "Globals");
|
||||
global_variables.def_property_readonly_static(
|
||||
"logger",
|
||||
[](const pyosys::Globals &) -> Yosys::LogManager & {
|
||||
return logger();
|
||||
},
|
||||
pybind11::return_value_policy::reference
|
||||
);
|
||||
|
||||
// Trampoline Classes
|
||||
py::class_<Pass, pyosys::PassTrampoline, std::unique_ptr<Pass, py::nodelete>>(m, "Pass")
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ YOSYS_NAMESPACE_BEGIN
|
|||
TEST(CellTypesTest, basic)
|
||||
{
|
||||
yosys_setup();
|
||||
if (log_sinks.empty()) log_sinks.push_back(std::make_unique<ConsoleLogSink>());
|
||||
if (logger().empty()) logger().add_sink<ConsoleLogSink>();
|
||||
CellTypes older;
|
||||
NewCellTypes newer;
|
||||
older.setup(nullptr);
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ TEST(ModIndexSwapTest, has)
|
|||
|
||||
TEST(ModIndexDeleteTest, has)
|
||||
{
|
||||
if (log_sinks.empty()) log_sinks.push_back(std::make_unique<ConsoleLogSink>());
|
||||
if (logger().empty()) logger().add_sink<ConsoleLogSink>();
|
||||
Design* d = new Design;
|
||||
Module* m = d->addModule("$m");
|
||||
Wire* w = m->addWire("$w");
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace RTLIL {
|
|||
class KernelRtlilTest : public testing::Test {
|
||||
protected:
|
||||
KernelRtlilTest() {
|
||||
if (log_sinks.empty()) log_sinks.push_back(std::make_unique<ConsoleLogSink>());
|
||||
if (logger().empty()) logger().add_sink<ConsoleLogSink>();
|
||||
}
|
||||
virtual void SetUp() override {
|
||||
IdString::ensure_prepopulated();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ YOSYS_NAMESPACE_BEGIN
|
|||
class ThreadingTest : public testing::Test {
|
||||
protected:
|
||||
ThreadingTest() {
|
||||
if (log_sinks.empty()) log_sinks.push_back(std::make_unique<ConsoleLogSink>());
|
||||
if (logger().empty()) logger().add_sink<ConsoleLogSink>();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ namespace RTLIL {
|
|||
class TechmapLibparseTest : public testing::Test {
|
||||
protected:
|
||||
TechmapLibparseTest() {
|
||||
if (log_sinks.empty()) log_sinks.push_back(std::make_unique<ConsoleLogSink>());
|
||||
if (logger().empty()) logger().add_sink<ConsoleLogSink>();
|
||||
}
|
||||
void checkAll(std::initializer_list<std::string> expressions, std::string expected) {
|
||||
for (const auto& e : expressions) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue