diff options
Diffstat (limited to 'kernel/log.cc')
-rw-r--r-- | kernel/log.cc | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/kernel/log.cc b/kernel/log.cc index f5d6c488e..997c39c64 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -42,6 +42,7 @@ std::vector<FILE*> log_files; std::vector<std::ostream*> log_streams; std::map<std::string, std::set<std::string>> log_hdump; std::vector<std::regex> log_warn_regexes, log_nowarn_regexes, log_werror_regexes; +std::vector<std::pair<std::regex,LogExpectedItem>> log_expect_log, log_expect_warning, log_expect_error; std::set<std::string> log_warnings, log_experimentals, log_experimentals_ignored; int log_warnings_count = 0; bool log_hdump_all = false; @@ -68,6 +69,7 @@ int string_buf_index = -1; static struct timeval initial_tv = { 0, 0 }; static bool next_print_log = false; static int log_newline_count = 0; +static bool check_expected_logs = true; static void log_id_cache_clear() { @@ -162,7 +164,7 @@ void logv(const char *format, va_list ap) { log_warn_regex_recusion_guard = true; - if (log_warn_regexes.empty()) + if (log_warn_regexes.empty() && log_expect_log.empty()) { linebuffer.clear(); } @@ -174,6 +176,11 @@ void logv(const char *format, va_list ap) for (auto &re : log_warn_regexes) if (std::regex_search(linebuffer, re)) log_warning("Found log message matching -W regex:\n%s", str.c_str()); + + for (auto &item : log_expect_log) + if (std::regex_search(linebuffer, item.first)) + item.second.current_count++; + linebuffer.clear(); } } @@ -244,6 +251,10 @@ static void logv_warning_with_prefix(const char *prefix, if (std::regex_search(message, re)) log_error("%s", message.c_str()); + for (auto &item : log_expect_warning) + if (std::regex_search(message, item.first)) + item.second.current_count++; + if (log_warnings.count(message)) { log("%s%s", prefix, message.c_str()); @@ -328,6 +339,12 @@ static void logv_error_with_prefix(const char *prefix, if (log_error_atexit) log_error_atexit(); + for (auto &item : log_expect_error) + if (std::regex_search(log_last_error, item.first)) + item.second.current_count++; + + if (check_expected_logs) + log_check_expected(); #ifdef EMSCRIPTEN log_files = backup_log_files; throw 0; @@ -636,6 +653,46 @@ void log_wire(RTLIL::Wire *wire, std::string indent) log("%s", buf.str().c_str()); } +void log_check_expected() +{ + check_expected_logs = false; + + for (auto &item : log_expect_warning) { + if (item.second.current_count != item.second.expected_count) { + log_error("Expected warning pattern '%s' not found !\n", item.second.pattern.c_str()); + } + if (item.second.current_count != item.second.expected_count) { + log_error("Expected warning pattern '%s' found %d time(s), instead of %d time(s) !\n", + item.second.pattern.c_str(), item.second.current_count, item.second.expected_count); + } + } + + for (auto &item : log_expect_log) { + if (item.second.current_count == 0) { + log_error("Expected log pattern '%s' not found !\n", item.second.pattern.c_str()); + } + if (item.second.current_count != item.second.expected_count) { + log_error("Expected log pattern '%s' found %d time(s), instead of %d time(s) !\n", + item.second.pattern.c_str(), item.second.current_count, item.second.expected_count); + } + } + + for (auto &item : log_expect_error) + if (item.second.current_count == item.second.expected_count) { + log("Expected error pattern '%s' found !!!\n", item.second.pattern.c_str()); + #ifdef EMSCRIPTEN + log_files = backup_log_files; + throw 0; + #elif defined(_MSC_VER) + _exit(0); + #else + _Exit(0); + #endif + } else { + log_error("Expected error pattern '%s' not found !\n", item.second.pattern.c_str()); + } +} + // --------------------------------------------------- // This is the magic behind the code coverage counters // --------------------------------------------------- |