From 0ba2a2b1fa898e48feffa23b8958255d9ed0834c Mon Sep 17 00:00:00 2001
From: Miodrag Milanovic <mmicko@gmail.com>
Date: Thu, 13 Feb 2020 13:35:29 +0100
Subject: [PATCH] Add new logger pass

---
 passes/cmds/Makefile.inc |   1 +
 passes/cmds/logger.cc    | 141 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 142 insertions(+)
 create mode 100644 passes/cmds/logger.cc

diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc
index 07a5d3ddc..20b38bf8e 100644
--- a/passes/cmds/Makefile.inc
+++ b/passes/cmds/Makefile.inc
@@ -33,3 +33,4 @@ OBJS += passes/cmds/blackbox.o
 OBJS += passes/cmds/ltp.o
 OBJS += passes/cmds/bugpoint.o
 OBJS += passes/cmds/scratchpad.o
+OBJS += passes/cmds/logger.o
diff --git a/passes/cmds/logger.cc b/passes/cmds/logger.cc
new file mode 100644
index 000000000..3feef7dc5
--- /dev/null
+++ b/passes/cmds/logger.cc
@@ -0,0 +1,141 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2020  Miodrag Milanovic <clifford@clifford.at>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/register.h"
+#include "kernel/log.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct LoggerPass : public Pass {
+	LoggerPass() : Pass("logger", "set logger properties") { }
+	void help() YS_OVERRIDE
+	{
+		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+		log("\n");
+		log("    logger [options]\n");
+		log("\n");
+		log("This command sets global logger properties, also available using command line\n");
+		log("options.\n");
+		log("\n");
+		log("    -[no]time\n");
+		log("        enable/disable display of timestamp in log output.\n");
+		log("\n");
+		log("    -[no]stderr\n");
+		log("        enable/disable logging errors to stderr.\n");
+		log("\n");
+		log("    -warn regex\n");
+		log("        print a warning for all log messages matching the regex.\n");
+		log("\n");
+		log("    -nowarn regex\n");
+		log("        if a warning message matches the regex, it is printed as regular\n");
+		log("        message instead.\n");
+		log("\n");
+		log("    -werror regex\n");
+		log("        if a warning message matches the regex, it is printed as error\n");
+		log("        message instead and the tool terminates with a nonzero return code.\n");
+		log("\n");
+		log("    -[no]debug\n");
+		log("        globally enable/disable debug log messages.\n");
+		log("\n");
+		log("    -experimental <feature>\n");
+		log("        do not print warnings for the specified experimental feature\n");
+		log("\n");
+	}
+
+	void execute(std::vector<std::string> args, RTLIL::Design * design) YS_OVERRIDE
+	{
+		size_t argidx;
+		for (argidx = 1; argidx < args.size(); argidx++)
+		{
+
+			if (args[argidx] == "-time") {
+				log_time = true;
+				log("Enabled timestamp in logs.");
+				continue;
+			}
+			if (args[argidx] == "-notime") {
+				log_time = false;
+				log("Disabled timestamp in logs.");
+				continue;
+			}
+			if (args[argidx] == "-stderr") {
+				log_error_stderr = true;
+				log("Enabled loggint errors to stderr.");
+				continue;
+			}
+			if (args[argidx] == "-nostderr") {
+				log_error_stderr = false;
+				log("Disabled loggint errors to stderr.");
+				continue;
+			}
+			if (args[argidx] == "-warn" && argidx+1 < args.size()) {
+				std::string pattern = args[++argidx];
+				if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);		
+				log("Added regex '%s' for warnings to warn list.", pattern.c_str());
+				log_warn_regexes.push_back(std::regex(pattern,
+					std::regex_constants::nosubs |
+					std::regex_constants::optimize |
+					std::regex_constants::egrep));
+				continue;
+			}
+			if (args[argidx] == "-nowarn" && argidx+1 < args.size()) {
+				std::string pattern = args[++argidx];
+				if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);	
+				log("Added regex '%s' for warnings to nowarn list.", pattern.c_str());
+				log_nowarn_regexes.push_back(std::regex(pattern,
+					std::regex_constants::nosubs |
+					std::regex_constants::optimize |
+					std::regex_constants::egrep));
+				continue;
+			}
+			if (args[argidx] == "-werror" && argidx+1 < args.size()) {
+				std::string pattern = args[++argidx];
+				if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);	
+				log("Added regex '%s' for warnings to werror list.", pattern.c_str());
+				log_werror_regexes.push_back(std::regex(pattern,
+					std::regex_constants::nosubs |
+					std::regex_constants::optimize |
+					std::regex_constants::egrep));
+				continue;
+			}
+			if (args[argidx] == "-debug") {
+				log_force_debug = 1;
+				log("Enabled debug log messages.");
+				continue;
+			}
+			if (args[argidx] == "-nodebug") {
+				log_force_debug = 0;
+				log("Disabled debug log messages.");
+				continue;
+			}
+			break;
+			if (args[argidx] == "-experimental" && argidx+1 < args.size()) {
+				std::string value = args[++argidx];
+				log("Added '%s' experimental ignore list.", value.c_str());
+				log_experimentals_ignored.insert(value);
+				continue;
+			}
+			break;
+		}
+		extra_args(args, argidx, design, false);
+	}
+} LoggerPass;
+
+PRIVATE_NAMESPACE_END