Revert "Merge remote-tracking branch 'origin/eddie/shregmap_improve' into xc7mux"
[yosys.git] / kernel / log.cc
index de564cb362dac18caf6ec8ce14a458933e43a5bb..a7820950c9dcdc3f4ea45b240931af5c3d7b02b6 100644 (file)
@@ -25,7 +25,7 @@
 #  include <sys/time.h>
 #endif
 
-#ifdef __linux__
+#if defined(__linux__) || defined(__FreeBSD__)
 #  include <dlfcn.h>
 #endif
 
@@ -41,7 +41,7 @@ YOSYS_NAMESPACE_BEGIN
 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;
+std::vector<std::regex> log_warn_regexes, log_nowarn_regexes, log_werror_regexes;
 std::set<std::string> log_warnings;
 int log_warnings_count = 0;
 bool log_hdump_all = false;
@@ -56,6 +56,10 @@ int log_verbose_level;
 string log_last_error;
 void (*log_error_atexit)() = NULL;
 
+int log_make_debug = 0;
+int log_force_debug = 0;
+int log_debug_suppressed = 0;
+
 vector<int> header_count;
 pool<RTLIL::IdString> log_id_cache;
 vector<shared_str> string_buf;
@@ -92,6 +96,9 @@ void logv(const char *format, va_list ap)
                format++;
        }
 
+       if (log_make_debug && !ys_debug(1))
+               return;
+
        std::string str = vstringf(format, ap);
 
        if (str.empty())
@@ -196,14 +203,19 @@ void logv_header(RTLIL::Design *design, const char *format, va_list ap)
        if (log_hdump.count(header_id) && design != nullptr)
                for (auto &filename : log_hdump.at(header_id)) {
                        log("Dumping current design to '%s'.\n", filename.c_str());
+                       if (yosys_xtrace)
+                               IdString::xtrace_db_dump();
                        Pass::call(design, {"dump", "-o", filename});
+                       if (yosys_xtrace)
+                               log("#X# -- end of dump --\n");
                }
 
        if (pop_errfile)
                log_files.pop_back();
 }
 
-void logv_warning(const char *format, va_list ap)
+static void logv_warning_with_prefix(const char *prefix,
+                                     const char *format, va_list ap)
 {
        std::string message = vstringf(format, ap);
        bool suppressed = false;
@@ -214,13 +226,20 @@ void logv_warning(const char *format, va_list ap)
 
        if (suppressed)
        {
-               log("Suppressed warning: %s", message.c_str());
+               log("Suppressed %s%s", prefix, message.c_str());
        }
        else
        {
+               int bak_log_make_debug = log_make_debug;
+               log_make_debug = 0;
+
+               for (auto &re : log_werror_regexes)
+                       if (std::regex_search(message, re))
+                               log_error("%s",  message.c_str());
+
                if (log_warnings.count(message))
                {
-                       log("Warning: %s", message.c_str());
+                       log("%s%s", prefix, message.c_str());
                        log_flush();
                }
                else
@@ -228,7 +247,7 @@ void logv_warning(const char *format, va_list ap)
                        if (log_errfile != NULL && !log_quiet_warnings)
                                log_files.push_back(log_errfile);
 
-                       log("Warning: %s", message.c_str());
+                       log("%s%s", prefix, message.c_str());
                        log_flush();
 
                        if (log_errfile != NULL && !log_quiet_warnings)
@@ -238,52 +257,52 @@ void logv_warning(const char *format, va_list ap)
                }
 
                log_warnings_count++;
+               log_make_debug = bak_log_make_debug;
        }
 }
 
-void logv_warning_noprefix(const char *format, va_list ap)
+void logv_warning(const char *format, va_list ap)
 {
-       std::string message = vstringf(format, ap);
-       bool suppressed = false;
-
-       for (auto &re : log_nowarn_regexes)
-               if (std::regex_search(message, re))
-                       suppressed = true;
-
-       if (suppressed)
-       {
-               log("%s", message.c_str());
-       }
-       else
-       {
-               if (log_warnings.count(message))
-               {
-                       log("%s", message.c_str());
-                       log_flush();
-               }
-               else
-               {
-                       if (log_errfile != NULL && !log_quiet_warnings)
-                               log_files.push_back(log_errfile);
-
-                       log("%s", message.c_str());
-                       log_flush();
+       logv_warning_with_prefix("Warning: ", format, ap);
+}
 
-                       if (log_errfile != NULL && !log_quiet_warnings)
-                               log_files.pop_back();
+void logv_warning_noprefix(const char *format, va_list ap)
+{
+       logv_warning_with_prefix("", format, ap);
+}
 
-                       log_warnings.insert(message);
-               }
+void log_file_warning(const std::string &filename, int lineno,
+                      const char *format, ...)
+{
+       va_list ap;
+       va_start(ap, format);
+       std::string prefix = stringf("%s:%d: Warning: ",
+                       filename.c_str(), lineno);
+       logv_warning_with_prefix(prefix.c_str(), format, ap);
+       va_end(ap);
+}
 
-               log_warnings_count++;
-       }
+void log_file_info(const std::string &filename, int lineno,
+                      const char *format, ...)
+{
+       va_list ap;
+       va_start(ap, format);
+       std::string fmt = stringf("%s:%d: Info: %s",
+                       filename.c_str(), lineno, format);
+       logv(fmt.c_str(), ap);
+       va_end(ap);
 }
 
-void logv_error(const char *format, va_list ap)
+YS_ATTRIBUTE(noreturn)
+static void logv_error_with_prefix(const char *prefix,
+                                   const char *format, va_list ap)
 {
 #ifdef EMSCRIPTEN
        auto backup_log_files = log_files;
 #endif
+       int bak_log_make_debug = log_make_debug;
+       log_make_debug = 0;
+       log_suppressed();
 
        if (log_errfile != NULL)
                log_files.push_back(log_errfile);
@@ -294,9 +313,11 @@ void logv_error(const char *format, va_list ap)
                                f = stderr;
 
        log_last_error = vstringf(format, ap);
-       log("ERROR: %s", log_last_error.c_str());
+       log("%s%s", prefix, log_last_error.c_str());
        log_flush();
 
+       log_make_debug = bak_log_make_debug;
+
        if (log_error_atexit)
                log_error_atexit();
 
@@ -310,6 +331,21 @@ void logv_error(const char *format, va_list ap)
 #endif
 }
 
+void logv_error(const char *format, va_list ap)
+{
+       logv_error_with_prefix("ERROR: ", format, ap);
+}
+
+void log_file_error(const string &filename, int lineno,
+                    const char *format, ...)
+{
+       va_list ap;
+       va_start(ap, format);
+       std::string prefix = stringf("%s:%d: ERROR: ",
+                                    filename.c_str(), lineno);
+       logv_error_with_prefix(prefix.c_str(), format, ap);
+}
+
 void log(const char *format, ...)
 {
        va_list ap;
@@ -384,7 +420,7 @@ void log_pop()
        log_flush();
 }
 
-#if defined(__linux__) && defined(YOSYS_ENABLE_PLUGINS)
+#if (defined(__linux__) || defined(__FreeBSD__)) && defined(YOSYS_ENABLE_PLUGINS)
 void log_backtrace(const char *prefix, int levels)
 {
        if (levels <= 0) return;
@@ -579,7 +615,7 @@ void log_wire(RTLIL::Wire *wire, std::string indent)
 // ---------------------------------------------------
 // This is the magic behind the code coverage counters
 // ---------------------------------------------------
-#if defined(YOSYS_ENABLE_COVER) && defined(__linux__)
+#if defined(YOSYS_ENABLE_COVER) && (defined(__linux__) || defined(__FreeBSD__))
 
 dict<std::string, std::pair<std::string, int>> extra_coverage_data;
 
@@ -628,4 +664,3 @@ dict<std::string, std::pair<std::string, int>> get_coverage_data()
 #endif
 
 YOSYS_NAMESPACE_END
-