ice40: split out cells_map.v into ff_map.v
[yosys.git] / kernel / log.h
index 9db8efaa5eaa4cad2742e7cfa7cde7133b2d41c6..dee5d44d78969ce2545b22a3310229b0467c4b65 100644 (file)
 #define LOG_H
 
 #include <time.h>
-#include <regex>
 
-#ifndef _WIN32
+// In GCC 4.8 std::regex is not working correctlty, in order to make features
+// using regular expressions to work replacement regex library is used
+#if defined(__GNUC__) && !defined( __clang__) && ( __GNUC__ == 4 && __GNUC_MINOR__ <= 8)
+       #include <boost/xpressive/xpressive.hpp>
+       #define YS_REGEX_TYPE boost::xpressive::sregex
+       #define YS_REGEX_MATCH_TYPE boost::xpressive::smatch
+       #define YS_REGEX_NS boost::xpressive
+       #define YS_REGEX_COMPILE(param) boost::xpressive::sregex::compile(param, \
+                                       boost::xpressive::regex_constants::nosubs | \
+                                       boost::xpressive::regex_constants::optimize)
+       #define YS_REGEX_COMPILE_WITH_SUBS(param) boost::xpressive::sregex::compile(param, \
+                                       boost::xpressive::regex_constants::optimize)
+# else
+       #include <regex>
+       #define YS_REGEX_TYPE std::regex
+       #define YS_REGEX_MATCH_TYPE std::smatch
+       #define YS_REGEX_NS std
+       #define YS_REGEX_COMPILE(param) std::regex(param, \
+                                       std::regex_constants::nosubs | \
+                                       std::regex_constants::optimize | \
+                                       std::regex_constants::egrep)
+       #define YS_REGEX_COMPILE_WITH_SUBS(param) std::regex(param, \
+                                       std::regex_constants::optimize | \
+                                       std::regex_constants::egrep)
+#endif
+
+#if defined(_WIN32)
+#  include <intrin.h>
+#else
 #  include <sys/time.h>
 #  include <sys/resource.h>
+#  include <signal.h>
 #endif
 
 #if defined(_MSC_VER)
@@ -44,14 +72,51 @@ YOSYS_NAMESPACE_BEGIN
 #define S__LINE__sub1(x) S__LINE__sub2(x)
 #define S__LINE__ S__LINE__sub1(__LINE__)
 
+// YS_DEBUGTRAP is a macro that is functionally equivalent to a breakpoint
+// if the platform provides such functionality, and does nothing otherwise.
+// If no debugger is attached, it starts a just-in-time debugger if available,
+// and crashes the process otherwise.
+#if defined(_WIN32)
+# define YS_DEBUGTRAP __debugbreak()
+#else
+# ifndef __has_builtin
+// __has_builtin is a GCC/Clang extension; on a different compiler (or old enough GCC/Clang)
+// that does not have it, using __has_builtin(...) is a syntax error.
+#  define __has_builtin(x) 0
+# endif
+# if __has_builtin(__builtin_debugtrap)
+#  define YS_DEBUGTRAP __builtin_debugtrap()
+# elif defined(__unix__)
+#  define YS_DEBUGTRAP raise(SIGTRAP)
+# else
+#  define YS_DEBUGTRAP do {} while(0)
+# endif
+#endif
+
+// YS_DEBUGTRAP_IF_DEBUGGING is a macro that is functionally equivalent to a breakpoint
+// if a debugger is attached, and does nothing otherwise.
+#if defined(_WIN32)
+# define YS_DEBUGTRAP_IF_DEBUGGING do { if (IsDebuggerPresent()) DebugBreak(); } while(0)
+#elif defined(__unix__)
+// There is no reliable (or portable) *nix equivalent of IsDebuggerPresent(). However,
+// debuggers will stop when SIGTRAP is raised, even if the action is set to ignore.
+# define YS_DEBUGTRAP_IF_DEBUGGING do { \
+               sighandler_t old = signal(SIGTRAP, SIG_IGN); raise(SIGTRAP); signal(SIGTRAP, old); \
+       } while(0)
+#else
+# define YS_DEBUGTRAP_IF_DEBUGGING do {} while(0)
+#endif
+
 struct log_cmd_error_exception { };
 
 extern std::vector<FILE*> log_files;
 extern std::vector<std::ostream*> log_streams;
 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::vector<YS_REGEX_TYPE> 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 FILE *log_errfile;
 extern SHA1 *log_hasher;
@@ -135,6 +200,23 @@ void log_backtrace(const char *prefix, int levels);
 void log_reset_stack();
 void log_flush();
 
+struct LogExpectedItem
+{
+       LogExpectedItem(std::string pattern, int expected) :
+               expected_count(expected),
+               current_count(0),
+               pattern(pattern)
+       {
+       }
+
+       int expected_count;
+       int current_count;
+       std::string pattern;
+};
+
+extern std::vector<std::pair<YS_REGEX_TYPE,LogExpectedItem>> log_expect_log, log_expect_warning, log_expect_error;
+void log_check_expected();
+
 const char *log_signal(const RTLIL::SigSpec &sig, bool autoint = true);
 const char *log_const(const RTLIL::Const &value, bool autoint = true);
 const char *log_id(RTLIL::IdString id);