mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Merge pull request #5336 from rocallahan/remove-log-cstr
Remove `.c_str()` calls from `log()`/`log_error()`
This commit is contained in:
		
						commit
						dd9627ed05
					
				
					 140 changed files with 623 additions and 623 deletions
				
			
		| 
						 | 
				
			
			@ -585,7 +585,7 @@ int main(int argc, char **argv)
 | 
			
		|||
 | 
			
		||||
			FILE *scriptfp = fopen(scriptfile.c_str(), "r");
 | 
			
		||||
			if (scriptfp == nullptr) {
 | 
			
		||||
				log_error("Failed to open file '%s' for reading.\n", scriptfile.c_str());
 | 
			
		||||
				log_error("Failed to open file '%s' for reading.\n", scriptfile);
 | 
			
		||||
			}
 | 
			
		||||
			if (PyRun_SimpleFile(scriptfp, scriptfile.c_str()) != 0) {
 | 
			
		||||
				log_flush();
 | 
			
		||||
| 
						 | 
				
			
			@ -664,7 +664,7 @@ int main(int argc, char **argv)
 | 
			
		|||
			log("Warnings: %d experimental features used (not excluded with -x).\n", GetSize(log_experimentals));
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		log("End of script. Logfile hash: %s\n", hash.c_str());
 | 
			
		||||
		log("End of script. Logfile hash: %s\n", hash);
 | 
			
		||||
#else
 | 
			
		||||
		std::string meminfo;
 | 
			
		||||
		std::string stats_divider = ", ";
 | 
			
		||||
| 
						 | 
				
			
			@ -690,7 +690,7 @@ int main(int argc, char **argv)
 | 
			
		|||
		meminfo = stringf(", MEM: %.2f MB peak",
 | 
			
		||||
				ru_buffer.ru_maxrss / (1024.0 * 1024.0));
 | 
			
		||||
#endif
 | 
			
		||||
		log("End of script. Logfile hash: %s%sCPU: user %.2fs system %.2fs%s\n", hash.c_str(),
 | 
			
		||||
		log("End of script. Logfile hash: %s%sCPU: user %.2fs system %.2fs%s\n", hash,
 | 
			
		||||
				stats_divider.c_str(), ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec,
 | 
			
		||||
				ru_buffer.ru_stime.tv_sec + 1e-6 * ru_buffer.ru_stime.tv_usec, meminfo.c_str());
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -768,9 +768,9 @@ int main(int argc, char **argv)
 | 
			
		|||
		f = fopen(filename.c_str(), "a+");
 | 
			
		||||
 | 
			
		||||
		if (f == NULL)
 | 
			
		||||
			log_error("Can't create coverage file `%s'.\n", filename.c_str());
 | 
			
		||||
			log_error("Can't create coverage file `%s'.\n", filename);
 | 
			
		||||
 | 
			
		||||
		log("<writing coverage file \"%s\">\n", filename.c_str());
 | 
			
		||||
		log("<writing coverage file \"%s\">\n", filename);
 | 
			
		||||
 | 
			
		||||
		for (auto &it : get_coverage_data())
 | 
			
		||||
			fprintf(f, "%-60s %10d %s\n", it.second.first.c_str(), it.second.second, it.first.c_str());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ FstData::FstData(std::string filename) : ctx(nullptr)
 | 
			
		|||
		filename_trim.erase(filename_trim.size()-4);
 | 
			
		||||
		tmp_file = stringf("%s/converted_%s.fst", get_base_tmpdir(), filename_trim);
 | 
			
		||||
		std::string cmd = stringf("vcd2fst %s %s", filename, tmp_file);
 | 
			
		||||
		log("Exec: %s\n", cmd.c_str());
 | 
			
		||||
		log("Exec: %s\n", cmd);
 | 
			
		||||
		if (run_command(cmd) != 0)
 | 
			
		||||
			log_cmd_error("Shell command failed!\n");
 | 
			
		||||
		filename = tmp_file;
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +44,7 @@ FstData::FstData(std::string filename) : ctx(nullptr)
 | 
			
		|||
	const std::vector<std::string> g_units = { "s", "ms", "us", "ns", "ps", "fs", "as", "zs" };
 | 
			
		||||
	ctx = (fstReaderContext *)fstReaderOpen(filename.c_str());
 | 
			
		||||
	if (!ctx)
 | 
			
		||||
		log_error("Error opening '%s' as FST file\n", filename.c_str());
 | 
			
		||||
		log_error("Error opening '%s' as FST file\n", filename);
 | 
			
		||||
	int scale = (int)fstReaderGetTimescale(ctx);	
 | 
			
		||||
	timescale = pow(10.0, scale);
 | 
			
		||||
	timescale_str = "";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -395,7 +395,7 @@ public:
 | 
			
		|||
					Node y = neg_if(y_flipped, sign(b));
 | 
			
		||||
					return factory.extend(y, y_width, true);
 | 
			
		||||
				} else
 | 
			
		||||
					log_error("unhandled cell in CellSimplifier %s\n", cellType.c_str());
 | 
			
		||||
					log_error("unhandled cell in CellSimplifier %s\n", cellType);
 | 
			
		||||
			} else {
 | 
			
		||||
				if(cellType.in(ID($mod), ID($modfloor)))
 | 
			
		||||
					return factory.extend(factory.unsigned_mod(a, b), y_width, false);
 | 
			
		||||
| 
						 | 
				
			
			@ -458,9 +458,9 @@ public:
 | 
			
		|||
				return factory.value(state);
 | 
			
		||||
			}
 | 
			
		||||
		} else if(cellType == ID($check)) {
 | 
			
		||||
			log_error("The design contains a $check cell `%s'. This is not supported by the functional backend. Call `chformal -lower' to avoid this error.\n", cellName.c_str());
 | 
			
		||||
			log_error("The design contains a $check cell `%s'. This is not supported by the functional backend. Call `chformal -lower' to avoid this error.\n", cellName);
 | 
			
		||||
		} else {
 | 
			
		||||
			log_error("`%s' cells are not supported by the functional backend\n", cellType.c_str());
 | 
			
		||||
			log_error("`%s' cells are not supported by the functional backend\n", cellType);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -744,7 +744,7 @@ void IR::topological_sort() {
 | 
			
		|||
            log_warning("Combinational loop:\n");
 | 
			
		||||
            for (int *i = begin; i != end; ++i) {
 | 
			
		||||
				Node node(_graph[*i]);
 | 
			
		||||
                log("- %s = %s\n", RTLIL::unescape_id(node.name()).c_str(), node.to_string().c_str());
 | 
			
		||||
                log("- %s = %s\n", RTLIL::unescape_id(node.name()), node.to_string());
 | 
			
		||||
			}
 | 
			
		||||
            log("\n");
 | 
			
		||||
            scc = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -836,7 +836,7 @@ void Writer::print_impl(const char *fmt, vector<std::function<void()>> &fns)
 | 
			
		|||
				else
 | 
			
		||||
					p = pe;
 | 
			
		||||
				if(index >= fns.size())
 | 
			
		||||
					log_error("invalid format string: index %zu out of bounds (%zu): \"%s\"\n", index, fns.size(), quote_fmt(fmt).c_str());
 | 
			
		||||
					log_error("invalid format string: index %zu out of bounds (%zu): \"%s\"\n", index, fns.size(), quote_fmt(fmt));
 | 
			
		||||
				fns[index]();
 | 
			
		||||
				next_index = index + 1;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -844,7 +844,7 @@ void Writer::print_impl(const char *fmt, vector<std::function<void()>> &fns)
 | 
			
		|||
		case '}':
 | 
			
		||||
			p++;
 | 
			
		||||
			if(*p != '}')
 | 
			
		||||
				log_error("invalid format string: unescaped }: \"%s\"\n", quote_fmt(fmt).c_str());
 | 
			
		||||
				log_error("invalid format string: unescaped }: \"%s\"\n", quote_fmt(fmt));
 | 
			
		||||
			*os << '}';
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -552,17 +552,17 @@ namespace Functional {
 | 
			
		|||
		}
 | 
			
		||||
		IRInput &add_input(IdString name, IdString kind, Sort sort) {
 | 
			
		||||
			auto [it, inserted] = _ir._inputs.emplace({name, kind}, IRInput(_ir, name, kind, std::move(sort)));
 | 
			
		||||
			if (!inserted) log_error("input `%s` was re-defined", name.c_str());
 | 
			
		||||
			if (!inserted) log_error("input `%s` was re-defined", name);
 | 
			
		||||
			return it->second;
 | 
			
		||||
		}
 | 
			
		||||
		IROutput &add_output(IdString name, IdString kind, Sort sort) {
 | 
			
		||||
			auto [it, inserted] = _ir._outputs.emplace({name, kind}, IROutput(_ir, name, kind, std::move(sort)));
 | 
			
		||||
			if (!inserted) log_error("output `%s` was re-defined", name.c_str());
 | 
			
		||||
			if (!inserted) log_error("output `%s` was re-defined", name);
 | 
			
		||||
			return it->second;
 | 
			
		||||
		}
 | 
			
		||||
		IRState &add_state(IdString name, IdString kind, Sort sort) {
 | 
			
		||||
			auto [it, inserted] = _ir._states.emplace({name, kind}, IRState(_ir, name, kind, std::move(sort)));
 | 
			
		||||
			if (!inserted) log_error("state `%s` was re-defined", name.c_str());
 | 
			
		||||
			if (!inserted) log_error("state `%s` was re-defined", name);
 | 
			
		||||
			return it->second;
 | 
			
		||||
		}
 | 
			
		||||
		Node value(IRInput const& input) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -121,7 +121,7 @@ std::istream* uncompressed(const std::string filename, std::ios_base::openmode m
 | 
			
		|||
	}
 | 
			
		||||
	if (n == 3 && magic[0] == 0x1f && magic[1] == 0x8b) {
 | 
			
		||||
#ifdef YOSYS_ENABLE_ZLIB
 | 
			
		||||
		log("Found gzip magic in file `%s', decompressing using zlib.\n", filename.c_str());
 | 
			
		||||
		log("Found gzip magic in file `%s', decompressing using zlib.\n", filename);
 | 
			
		||||
		if (magic[2] != 8)
 | 
			
		||||
			log_cmd_error("gzip file `%s' uses unsupported compression type %02x\n",
 | 
			
		||||
				filename.c_str(), unsigned(magic[2]));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -228,7 +228,7 @@ void log_formatted_header(RTLIL::Design *design, std::string_view format, std::s
 | 
			
		|||
	for (int c : header_count)
 | 
			
		||||
		header_id += stringf("%s%d", header_id.empty() ? "" : ".", c);
 | 
			
		||||
 | 
			
		||||
	log("%s. ", header_id.c_str());
 | 
			
		||||
	log("%s. ", header_id);
 | 
			
		||||
	log_formatted_string(format, std::move(str));
 | 
			
		||||
	log_flush();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -237,7 +237,7 @@ void log_formatted_header(RTLIL::Design *design, std::string_view format, std::s
 | 
			
		|||
 | 
			
		||||
	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());
 | 
			
		||||
			log("Dumping current design to '%s'.\n", filename);
 | 
			
		||||
			if (yosys_xtrace)
 | 
			
		||||
				IdString::xtrace_db_dump();
 | 
			
		||||
			Pass::call(design, {"dump", "-o", filename});
 | 
			
		||||
| 
						 | 
				
			
			@ -635,21 +635,21 @@ void log_module(RTLIL::Module *module, std::string indent)
 | 
			
		|||
{
 | 
			
		||||
	std::stringstream buf;
 | 
			
		||||
	RTLIL_BACKEND::dump_module(buf, indent, module, module->design, false);
 | 
			
		||||
	log("%s", buf.str().c_str());
 | 
			
		||||
	log("%s", buf.str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void log_cell(RTLIL::Cell *cell, std::string indent)
 | 
			
		||||
{
 | 
			
		||||
	std::stringstream buf;
 | 
			
		||||
	RTLIL_BACKEND::dump_cell(buf, indent, cell);
 | 
			
		||||
	log("%s", buf.str().c_str());
 | 
			
		||||
	log("%s", buf.str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void log_wire(RTLIL::Wire *wire, std::string indent)
 | 
			
		||||
{
 | 
			
		||||
	std::stringstream buf;
 | 
			
		||||
	RTLIL_BACKEND::dump_wire(buf, indent, wire);
 | 
			
		||||
	log("%s", buf.str().c_str());
 | 
			
		||||
	log("%s", buf.str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void log_check_expected()
 | 
			
		||||
| 
						 | 
				
			
			@ -668,7 +668,7 @@ void log_check_expected()
 | 
			
		|||
	auto check = [&](const std::string kind, std::string pattern, LogExpectedItem item) {
 | 
			
		||||
		if (item.current_count == 0) {
 | 
			
		||||
			log_warn_regexes.clear();
 | 
			
		||||
			log_error("Expected %s pattern '%s' not found !\n", kind.c_str(), pattern.c_str());
 | 
			
		||||
			log_error("Expected %s pattern '%s' not found !\n", kind, pattern);
 | 
			
		||||
		}
 | 
			
		||||
		if (item.current_count != item.expected_count) {
 | 
			
		||||
			log_warn_regexes.clear();
 | 
			
		||||
| 
						 | 
				
			
			@ -689,7 +689,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.c_str(), pattern.c_str());
 | 
			
		||||
			log("Expected %s pattern '%s' found !!!\n", kind, pattern);
 | 
			
		||||
			yosys_shutdown();
 | 
			
		||||
			#ifdef EMSCRIPTEN
 | 
			
		||||
				throw 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -700,7 +700,7 @@ void log_check_expected()
 | 
			
		|||
			#endif
 | 
			
		||||
		} else {
 | 
			
		||||
			log_warn_regexes.clear();
 | 
			
		||||
			log_error("Expected %s pattern '%s' not found !\n", kind.c_str(), pattern.c_str());
 | 
			
		||||
			log_error("Expected %s pattern '%s' not found !\n", kind, pattern);
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
	for (auto &[pattern, item] : expect_error)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -424,7 +424,7 @@ static inline void log_dump_val_worker(bool v) { log("%s", v ? "true" : "false")
 | 
			
		|||
static inline void log_dump_val_worker(double v) { log("%f", v); }
 | 
			
		||||
static inline void log_dump_val_worker(char *v) { log("%s", v); }
 | 
			
		||||
static inline void log_dump_val_worker(const char *v) { log("%s", v); }
 | 
			
		||||
static inline void log_dump_val_worker(std::string v) { log("%s", v.c_str()); }
 | 
			
		||||
static inline void log_dump_val_worker(std::string v) { log("%s", v); }
 | 
			
		||||
static inline void log_dump_val_worker(PerformanceTimer p) { log("%f seconds", p.sec()); }
 | 
			
		||||
static inline void log_dump_args_worker(const char *p) { log_assert(*p == 0); }
 | 
			
		||||
void log_dump_val_worker(RTLIL::IdString v);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,7 +85,7 @@ void log_pass_str(const std::string &pass_str, std::string indent_str, bool lead
 | 
			
		|||
	if (leading_newline)
 | 
			
		||||
		log("\n");
 | 
			
		||||
	for (std::string line; std::getline(iss, line);) {
 | 
			
		||||
		log("%s", indent_str.c_str());
 | 
			
		||||
		log("%s", indent_str);
 | 
			
		||||
		auto curr_len = indent_str.length();
 | 
			
		||||
		std::istringstream lss(line);
 | 
			
		||||
		for (std::string word; std::getline(lss, word, ' ');) {
 | 
			
		||||
| 
						 | 
				
			
			@ -93,10 +93,10 @@ void log_pass_str(const std::string &pass_str, std::string indent_str, bool lead
 | 
			
		|||
				word = word.substr(1, word.length()-2);
 | 
			
		||||
			if (curr_len + word.length() >= MAX_LINE_LEN-1) {
 | 
			
		||||
				curr_len = 0;
 | 
			
		||||
				log("\n%s", indent_str.c_str());
 | 
			
		||||
				log("\n%s", indent_str);
 | 
			
		||||
			}
 | 
			
		||||
			if (word.length()) {
 | 
			
		||||
				log("%s ", word.c_str());
 | 
			
		||||
				log("%s ", word);
 | 
			
		||||
				curr_len += word.length() + 1;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,7 +54,7 @@ Pass::Pass(std::string name, std::string short_help, source_location location) :
 | 
			
		|||
void Pass::run_register()
 | 
			
		||||
{
 | 
			
		||||
	if (pass_register.count(pass_name) && !replace_existing_pass())
 | 
			
		||||
		log_error("Unable to register pass '%s', pass already exists!\n", pass_name.c_str());
 | 
			
		||||
		log_error("Unable to register pass '%s', pass already exists!\n", pass_name);
 | 
			
		||||
	pass_register[pass_name] = this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -123,7 +123,7 @@ void Pass::help()
 | 
			
		|||
		prettyHelp.log_help();
 | 
			
		||||
	} else {
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("No help message for command `%s'.\n", pass_name.c_str());
 | 
			
		||||
		log("No help message for command `%s'.\n", pass_name);
 | 
			
		||||
		log("\n");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -143,7 +143,7 @@ void Pass::cmd_log_args(const std::vector<std::string> &args)
 | 
			
		|||
		return;
 | 
			
		||||
	log("Full command line:");
 | 
			
		||||
	for (size_t i = 0; i < args.size(); i++)
 | 
			
		||||
		log(" %s", args[i].c_str());
 | 
			
		||||
		log(" %s", args[i]);
 | 
			
		||||
	log("\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -158,7 +158,7 @@ void Pass::cmd_error(const std::vector<std::string> &args, size_t argidx, std::s
 | 
			
		|||
		command_text = command_text + (command_text.empty() ? "" : " ") + args[i];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log("\nSyntax error in command `%s':\n", command_text.c_str());
 | 
			
		||||
	log("\nSyntax error in command `%s':\n", command_text);
 | 
			
		||||
	help();
 | 
			
		||||
 | 
			
		||||
	log_cmd_error("Command syntax error: %s\n> %s\n> %*s^\n",
 | 
			
		||||
| 
						 | 
				
			
			@ -257,7 +257,7 @@ void Pass::call(RTLIL::Design *design, std::vector<std::string> args)
 | 
			
		|||
	if (echo_mode) {
 | 
			
		||||
		log("%s", create_prompt(design, 0));
 | 
			
		||||
		for (size_t i = 0; i < args.size(); i++)
 | 
			
		||||
			log("%s%s", i ? " " : "", args[i].c_str());
 | 
			
		||||
			log("%s%s", i ? " " : "", args[i]);
 | 
			
		||||
		log("\n");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -330,9 +330,9 @@ bool ScriptPass::check_label(std::string label, std::string info)
 | 
			
		|||
	if (active_design == nullptr) {
 | 
			
		||||
		log("\n");
 | 
			
		||||
		if (info.empty())
 | 
			
		||||
			log("    %s:\n", label.c_str());
 | 
			
		||||
			log("    %s:\n", label);
 | 
			
		||||
		else
 | 
			
		||||
			log("    %s:    %s\n", label.c_str(), info.c_str());
 | 
			
		||||
			log("    %s:    %s\n", label, info);
 | 
			
		||||
		return true;
 | 
			
		||||
	} else {
 | 
			
		||||
		if (!active_run_from.empty() && active_run_from == active_run_to) {
 | 
			
		||||
| 
						 | 
				
			
			@ -351,9 +351,9 @@ void ScriptPass::run(std::string command, std::string info)
 | 
			
		|||
{
 | 
			
		||||
	if (active_design == nullptr) {
 | 
			
		||||
		if (info.empty())
 | 
			
		||||
			log("        %s\n", command.c_str());
 | 
			
		||||
			log("        %s\n", command);
 | 
			
		||||
		else
 | 
			
		||||
			log("        %s    %s\n", command.c_str(), info.c_str());
 | 
			
		||||
			log("        %s    %s\n", command, info);
 | 
			
		||||
	} else {
 | 
			
		||||
		Pass::call(active_design, command);
 | 
			
		||||
		active_design->check();
 | 
			
		||||
| 
						 | 
				
			
			@ -364,9 +364,9 @@ void ScriptPass::run_nocheck(std::string command, std::string info)
 | 
			
		|||
{
 | 
			
		||||
	if (active_design == nullptr) {
 | 
			
		||||
		if (info.empty())
 | 
			
		||||
			log("        %s\n", command.c_str());
 | 
			
		||||
			log("        %s\n", command);
 | 
			
		||||
		else
 | 
			
		||||
			log("        %s    %s\n", command.c_str(), info.c_str());
 | 
			
		||||
			log("        %s    %s\n", command, info);
 | 
			
		||||
	} else {
 | 
			
		||||
		Pass::call(active_design, command);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -402,11 +402,11 @@ Frontend::Frontend(std::string name, std::string short_help, source_location loc
 | 
			
		|||
void Frontend::run_register()
 | 
			
		||||
{
 | 
			
		||||
	if (pass_register.count(pass_name) && !replace_existing_pass())
 | 
			
		||||
		log_error("Unable to register pass '%s', pass already exists!\n", pass_name.c_str());
 | 
			
		||||
		log_error("Unable to register pass '%s', pass already exists!\n", pass_name);
 | 
			
		||||
	pass_register[pass_name] = this;
 | 
			
		||||
 | 
			
		||||
	if (frontend_register.count(frontend_name) && !replace_existing_pass())
 | 
			
		||||
		log_error("Unable to register frontend '%s', frontend already exists!\n", frontend_name.c_str());
 | 
			
		||||
		log_error("Unable to register frontend '%s', frontend already exists!\n", frontend_name);
 | 
			
		||||
	frontend_register[frontend_name] = this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -462,7 +462,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s
 | 
			
		|||
				char block[4096];
 | 
			
		||||
				while (1) {
 | 
			
		||||
					if (fgets(block, 4096, Frontend::current_script_file == nullptr? stdin : Frontend::current_script_file) == nullptr)
 | 
			
		||||
						log_error("Unexpected end of file in here document '%s'!\n", filename.c_str());
 | 
			
		||||
						log_error("Unexpected end of file in here document '%s'!\n", filename);
 | 
			
		||||
					buffer += block;
 | 
			
		||||
					if (buffer.size() > 0 && (buffer[buffer.size() - 1] == '\n' || buffer[buffer.size() - 1] == '\r'))
 | 
			
		||||
						break;
 | 
			
		||||
| 
						 | 
				
			
			@ -548,11 +548,11 @@ Backend::Backend(std::string name, std::string short_help, source_location locat
 | 
			
		|||
void Backend::run_register()
 | 
			
		||||
{
 | 
			
		||||
	if (pass_register.count(pass_name))
 | 
			
		||||
		log_error("Unable to register pass '%s', pass already exists!\n", pass_name.c_str());
 | 
			
		||||
		log_error("Unable to register pass '%s', pass already exists!\n", pass_name);
 | 
			
		||||
	pass_register[pass_name] = this;
 | 
			
		||||
 | 
			
		||||
	if (backend_register.count(backend_name))
 | 
			
		||||
		log_error("Unable to register backend '%s', backend already exists!\n", backend_name.c_str());
 | 
			
		||||
		log_error("Unable to register backend '%s', backend already exists!\n", backend_name);
 | 
			
		||||
	backend_register[backend_name] = this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -699,12 +699,12 @@ static void log_warning_flags(Pass *pass) {
 | 
			
		|||
	if (pass->experimental_flag) {
 | 
			
		||||
		if (!has_warnings) log("\n");
 | 
			
		||||
		has_warnings = true;
 | 
			
		||||
		log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", name.c_str());
 | 
			
		||||
		log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", name);
 | 
			
		||||
	}
 | 
			
		||||
	if (pass->internal_flag) {
 | 
			
		||||
		if (!has_warnings) log("\n");
 | 
			
		||||
		has_warnings = true;
 | 
			
		||||
		log("WARNING: THE '%s' COMMAND IS INTENDED FOR INTERNAL DEVELOPER USE ONLY.\n", name.c_str());
 | 
			
		||||
		log("WARNING: THE '%s' COMMAND IS INTENDED FOR INTERNAL DEVELOPER USE ONLY.\n", name);
 | 
			
		||||
	}
 | 
			
		||||
	if (has_warnings)
 | 
			
		||||
		log("\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -966,7 +966,7 @@ struct HelpPass : public Pass {
 | 
			
		|||
				auto cell_pair = pair<SimHelper, CellType>(cell_help, it.second);
 | 
			
		||||
				cells.emplace(name, cell_pair);
 | 
			
		||||
			} else {
 | 
			
		||||
				log("ERROR: Missing cell help for cell '%s'.\n", name.c_str());
 | 
			
		||||
				log("ERROR: Missing cell help for cell '%s'.\n", name);
 | 
			
		||||
				raise_error |= true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -1028,7 +1028,7 @@ struct HelpPass : public Pass {
 | 
			
		|||
		if (args.size() == 1) {
 | 
			
		||||
			log("\n");
 | 
			
		||||
			for (auto &it : pass_register)
 | 
			
		||||
				log("    %-20s %s\n", it.first.c_str(), it.second->short_help.c_str());
 | 
			
		||||
				log("    %-20s %s\n", it.first, it.second->short_help);
 | 
			
		||||
			log("\n");
 | 
			
		||||
			log("Type 'help <command>' for more information on a command.\n");
 | 
			
		||||
			log("Type 'help -cells' for a list of all cell types.\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -1040,7 +1040,7 @@ struct HelpPass : public Pass {
 | 
			
		|||
			if (args[1] == "-all") {
 | 
			
		||||
				for (auto &it : pass_register) {
 | 
			
		||||
					log("\n\n");
 | 
			
		||||
					log("%s  --  %s\n", it.first.c_str(), it.second->short_help.c_str());
 | 
			
		||||
					log("%s  --  %s\n", it.first, it.second->short_help);
 | 
			
		||||
					for (size_t i = 0; i < it.first.size() + it.second->short_help.size() + 6; i++)
 | 
			
		||||
						log("=");
 | 
			
		||||
					log("\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -1052,7 +1052,7 @@ struct HelpPass : public Pass {
 | 
			
		|||
				log("\n");
 | 
			
		||||
				for (auto &it : cell_help_messages.cell_help) {
 | 
			
		||||
					SimHelper help_cell = it.second;
 | 
			
		||||
					log("    %-15s %s\n", help_cell.name.c_str(), help_cell.ports.c_str());
 | 
			
		||||
					log("    %-15s %s\n", help_cell.name, help_cell.ports);
 | 
			
		||||
				}
 | 
			
		||||
				log("\n");
 | 
			
		||||
				log("Type 'help <cell_type>' for more information on a cell type.\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -1067,34 +1067,34 @@ struct HelpPass : public Pass {
 | 
			
		|||
				auto help_cell = cell_help_messages.get(args[1]);
 | 
			
		||||
				if (is_code_getter(args[1])) {
 | 
			
		||||
						log("\n");
 | 
			
		||||
						log("%s\n", help_cell.code.c_str());
 | 
			
		||||
						log("%s\n", help_cell.code);
 | 
			
		||||
				} else {
 | 
			
		||||
					log("\n    %s %s\n\n", help_cell.name.c_str(), help_cell.ports.c_str());
 | 
			
		||||
					log("\n    %s %s\n\n", help_cell.name, help_cell.ports);
 | 
			
		||||
					if (help_cell.ver == "2" || help_cell.ver == "2a") {
 | 
			
		||||
						if (help_cell.title != "") log("%s:\n", help_cell.title.c_str());
 | 
			
		||||
						if (help_cell.title != "") log("%s:\n", help_cell.title);
 | 
			
		||||
						std::stringstream ss;
 | 
			
		||||
						ss << help_cell.desc;
 | 
			
		||||
						for (std::string line; std::getline(ss, line, '\n');) {
 | 
			
		||||
							if (line != "::") log("%s\n", line.c_str());
 | 
			
		||||
							if (line != "::") log("%s\n", line);
 | 
			
		||||
						}
 | 
			
		||||
					} else if (help_cell.desc.length()) {
 | 
			
		||||
						log("%s\n", help_cell.desc.c_str());
 | 
			
		||||
						log("%s\n", help_cell.desc);
 | 
			
		||||
					} else {
 | 
			
		||||
						log("No help message for this cell type found.\n");
 | 
			
		||||
					}
 | 
			
		||||
					log("\nRun 'help %s+' to display the Verilog model for this cell type.\n", args[1].c_str());
 | 
			
		||||
					log("\nRun 'help %s+' to display the Verilog model for this cell type.\n", args[1]);
 | 
			
		||||
					log("\n");
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
				log("No such command or cell type: %s\n", args[1].c_str());
 | 
			
		||||
				log("No such command or cell type: %s\n", args[1]);
 | 
			
		||||
			return;
 | 
			
		||||
		} else if (args.size() == 3) {
 | 
			
		||||
			// this option is undocumented as it is for internal use only
 | 
			
		||||
			if (args[1] == "-dump-cmds-json") {
 | 
			
		||||
				PrettyJson json;
 | 
			
		||||
				if (!json.write_to_file(args[2]))
 | 
			
		||||
					log_error("Can't open file `%s' for writing: %s\n", args[2].c_str(), strerror(errno));
 | 
			
		||||
					log_error("Can't open file `%s' for writing: %s\n", args[2], strerror(errno));
 | 
			
		||||
				if (dump_cmds_json(json)) {
 | 
			
		||||
					log_abort();
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -1103,13 +1103,13 @@ struct HelpPass : public Pass {
 | 
			
		|||
			else if (args[1] == "-dump-cells-json") {
 | 
			
		||||
				PrettyJson json;
 | 
			
		||||
				if (!json.write_to_file(args[2]))
 | 
			
		||||
					log_error("Can't open file `%s' for writing: %s\n", args[2].c_str(), strerror(errno));
 | 
			
		||||
					log_error("Can't open file `%s' for writing: %s\n", args[2], strerror(errno));
 | 
			
		||||
				if (dump_cells_json(json)) {
 | 
			
		||||
					log_error("One or more cells defined in celltypes.h are missing help documentation.\n");
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
				log("Unknown help command: `%s %s'\n", args[1].c_str(), args[2].c_str());
 | 
			
		||||
				log("Unknown help command: `%s %s'\n", args[1], args[2]);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1056,7 +1056,7 @@ void RTLIL::Design::add(RTLIL::Binding *binding)
 | 
			
		|||
RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name)
 | 
			
		||||
{
 | 
			
		||||
	if (modules_.count(name) != 0)
 | 
			
		||||
		log_error("Attempted to add new module named '%s', but a module by that name already exists\n", name.c_str());
 | 
			
		||||
		log_error("Attempted to add new module named '%s', but a module by that name already exists\n", name);
 | 
			
		||||
	log_assert(refcount_modules_ == 0);
 | 
			
		||||
 | 
			
		||||
	RTLIL::Module *module = new RTLIL::Module;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -119,7 +119,7 @@ void SExprWriter::print(SExpr const &sexpr, bool close, bool indent_rest) {
 | 
			
		|||
            _pending_nl = true;
 | 
			
		||||
        }
 | 
			
		||||
    }else
 | 
			
		||||
        log_error("shouldn't happen: SExpr '%s' is neither an atom nor a list", sexpr.to_string().c_str());
 | 
			
		||||
        log_error("shouldn't happen: SExpr '%s' is neither an atom nor a list", sexpr.to_string());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SExprWriter::close(size_t n) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -87,7 +87,7 @@ static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *a
 | 
			
		|||
				tcl_command_name = "renames";
 | 
			
		||||
			Tcl_CmdInfo info;
 | 
			
		||||
			if (Tcl_GetCommandInfo(interp, tcl_command_name.c_str(), &info) != 0) {
 | 
			
		||||
				log("[TCL: yosys -import] Command name collision: found pre-existing command `%s' -> skip.\n", it.first.c_str());
 | 
			
		||||
				log("[TCL: yosys -import] Command name collision: found pre-existing command `%s' -> skip.\n", it.first);
 | 
			
		||||
			} else {
 | 
			
		||||
				std::string tcl_script = stringf("proc %s args { yosys %s {*}$args }", tcl_command_name, it.first);
 | 
			
		||||
				Tcl_Eval(interp, tcl_script.c_str());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -710,7 +710,7 @@ bool run_frontend(std::string filename, std::string command, RTLIL::Design *desi
 | 
			
		|||
	  } else if (filename == "-") {
 | 
			
		||||
	    command = "script";
 | 
			
		||||
	  } else {
 | 
			
		||||
	    log_error("Can't guess frontend for input file `%s' (missing -f option)!\n", filename.c_str());
 | 
			
		||||
	    log_error("Can't guess frontend for input file `%s' (missing -f option)!\n", filename);
 | 
			
		||||
	  }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -731,7 +731,7 @@ bool run_frontend(std::string filename, std::string command, RTLIL::Design *desi
 | 
			
		|||
			from_to_active = run_from.empty();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		log("\n-- Executing script file `%s' --\n", filename.c_str());
 | 
			
		||||
		log("\n-- Executing script file `%s' --\n", filename);
 | 
			
		||||
 | 
			
		||||
		FILE *f = stdin;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -741,7 +741,7 @@ bool run_frontend(std::string filename, std::string command, RTLIL::Design *desi
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		if (f == NULL)
 | 
			
		||||
			log_error("Can't open script file `%s' for reading: %s\n", filename.c_str(), strerror(errno));
 | 
			
		||||
			log_error("Can't open script file `%s' for reading: %s\n", filename, strerror(errno));
 | 
			
		||||
 | 
			
		||||
		FILE *backup_script_file = Frontend::current_script_file;
 | 
			
		||||
		Frontend::current_script_file = f;
 | 
			
		||||
| 
						 | 
				
			
			@ -790,9 +790,9 @@ bool run_frontend(std::string filename, std::string command, RTLIL::Design *desi
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if (filename == "-") {
 | 
			
		||||
		log("\n-- Parsing stdin using frontend `%s' --\n", command.c_str());
 | 
			
		||||
		log("\n-- Parsing stdin using frontend `%s' --\n", command);
 | 
			
		||||
	} else {
 | 
			
		||||
		log("\n-- Parsing `%s' using frontend `%s' --\n", filename.c_str(), command.c_str());
 | 
			
		||||
		log("\n-- Parsing `%s' using frontend `%s' --\n", filename, command);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (command[0] == ' ') {
 | 
			
		||||
| 
						 | 
				
			
			@ -811,7 +811,7 @@ void run_pass(std::string command, RTLIL::Design *design)
 | 
			
		|||
	if (design == nullptr)
 | 
			
		||||
		design = yosys_design;
 | 
			
		||||
 | 
			
		||||
	log("\n-- Running command `%s' --\n", command.c_str());
 | 
			
		||||
	log("\n-- Running command `%s' --\n", command);
 | 
			
		||||
 | 
			
		||||
	Pass::call(design, command);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -843,16 +843,16 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig
 | 
			
		|||
		else if (filename.empty())
 | 
			
		||||
			return;
 | 
			
		||||
		else
 | 
			
		||||
			log_error("Can't guess backend for output file `%s' (missing -b option)!\n", filename.c_str());
 | 
			
		||||
			log_error("Can't guess backend for output file `%s' (missing -b option)!\n", filename);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (filename.empty())
 | 
			
		||||
		filename = "-";
 | 
			
		||||
 | 
			
		||||
	if (filename == "-") {
 | 
			
		||||
		log("\n-- Writing to stdout using backend `%s' --\n", command.c_str());
 | 
			
		||||
		log("\n-- Writing to stdout using backend `%s' --\n", command);
 | 
			
		||||
	} else {
 | 
			
		||||
		log("\n-- Writing to `%s' using backend `%s' --\n", filename.c_str(), command.c_str());
 | 
			
		||||
		log("\n-- Writing to `%s' using backend `%s' --\n", filename, command);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Backend::backend_call(design, NULL, filename, command);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										30
									
								
								kernel/yw.cc
									
										
									
									
									
								
							
							
						
						
									
										30
									
								
								kernel/yw.cc
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -108,38 +108,38 @@ ReadWitness::ReadWitness(const std::string &filename) :
 | 
			
		|||
{
 | 
			
		||||
	std::ifstream f(filename.c_str());
 | 
			
		||||
	if (f.fail() || GetSize(filename) == 0)
 | 
			
		||||
		log_error("Cannot open file `%s`\n", filename.c_str());
 | 
			
		||||
		log_error("Cannot open file `%s`\n", filename);
 | 
			
		||||
	std::stringstream buf;
 | 
			
		||||
	buf << f.rdbuf();
 | 
			
		||||
	std::string err;
 | 
			
		||||
	json11::Json json = json11::Json::parse(buf.str(), err);
 | 
			
		||||
	if (!err.empty())
 | 
			
		||||
		log_error("Failed to parse `%s`: %s\n", filename.c_str(), err.c_str());
 | 
			
		||||
		log_error("Failed to parse `%s`: %s\n", filename, err);
 | 
			
		||||
 | 
			
		||||
	std::string format = json["format"].string_value();
 | 
			
		||||
 | 
			
		||||
	if (format.empty())
 | 
			
		||||
		log_error("Failed to parse `%s`: Unknown format\n", filename.c_str());
 | 
			
		||||
		log_error("Failed to parse `%s`: Unknown format\n", filename);
 | 
			
		||||
	if (format != "Yosys Witness Trace")
 | 
			
		||||
		log_error("Failed to parse `%s`: Unsupported format `%s`\n", filename.c_str(), format.c_str());
 | 
			
		||||
		log_error("Failed to parse `%s`: Unsupported format `%s`\n", filename, format);
 | 
			
		||||
 | 
			
		||||
	for (auto &clock_json : json["clocks"].array_items()) {
 | 
			
		||||
		Clock clock;
 | 
			
		||||
		clock.path = get_path(clock_json["path"]);
 | 
			
		||||
		if (clock.path.empty())
 | 
			
		||||
			log_error("Failed to parse `%s`: Missing path for clock `%s`\n", filename.c_str(), clock_json.dump().c_str());
 | 
			
		||||
			log_error("Failed to parse `%s`: Missing path for clock `%s`\n", filename, clock_json.dump());
 | 
			
		||||
		auto edge_str = clock_json["edge"];
 | 
			
		||||
		if (edge_str.string_value() == "posedge")
 | 
			
		||||
			clock.is_posedge = true;
 | 
			
		||||
		else if (edge_str.string_value() == "negedge")
 | 
			
		||||
			clock.is_negedge = true;
 | 
			
		||||
		else
 | 
			
		||||
			log_error("Failed to parse `%s`: Unknown edge type for clock `%s`\n", filename.c_str(), clock_json.dump().c_str());
 | 
			
		||||
			log_error("Failed to parse `%s`: Unknown edge type for clock `%s`\n", filename, clock_json.dump());
 | 
			
		||||
		if (!clock_json["offset"].is_number())
 | 
			
		||||
			log_error("Failed to parse `%s`: Unknown offset for clock `%s`\n", filename.c_str(), clock_json.dump().c_str());
 | 
			
		||||
			log_error("Failed to parse `%s`: Unknown offset for clock `%s`\n", filename, clock_json.dump());
 | 
			
		||||
		clock.offset = clock_json["offset"].int_value();
 | 
			
		||||
		if (clock.offset < 0)
 | 
			
		||||
			log_error("Failed to parse `%s`: Invalid offset for clock `%s`\n", filename.c_str(), clock_json.dump().c_str());
 | 
			
		||||
			log_error("Failed to parse `%s`: Invalid offset for clock `%s`\n", filename, clock_json.dump());
 | 
			
		||||
		clocks.push_back(clock);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -149,18 +149,18 @@ ReadWitness::ReadWitness(const std::string &filename) :
 | 
			
		|||
		signal.bits_offset = bits_offset;
 | 
			
		||||
		signal.path = get_path(signal_json["path"]);
 | 
			
		||||
		if (signal.path.empty())
 | 
			
		||||
			log_error("Failed to parse `%s`: Missing path for signal `%s`\n", filename.c_str(), signal_json.dump().c_str());
 | 
			
		||||
			log_error("Failed to parse `%s`: Missing path for signal `%s`\n", filename, signal_json.dump());
 | 
			
		||||
		if (!signal_json["width"].is_number())
 | 
			
		||||
			log_error("Failed to parse `%s`: Unknown width for signal `%s`\n", filename.c_str(), signal_json.dump().c_str());
 | 
			
		||||
			log_error("Failed to parse `%s`: Unknown width for signal `%s`\n", filename, signal_json.dump());
 | 
			
		||||
		signal.width = signal_json["width"].int_value();
 | 
			
		||||
		if (signal.width < 0)
 | 
			
		||||
			log_error("Failed to parse `%s`: Invalid width for signal `%s`\n", filename.c_str(), signal_json.dump().c_str());
 | 
			
		||||
			log_error("Failed to parse `%s`: Invalid width for signal `%s`\n", filename, signal_json.dump());
 | 
			
		||||
		bits_offset += signal.width;
 | 
			
		||||
		if (!signal_json["offset"].is_number())
 | 
			
		||||
			log_error("Failed to parse `%s`: Unknown offset for signal `%s`\n", filename.c_str(), signal_json.dump().c_str());
 | 
			
		||||
			log_error("Failed to parse `%s`: Unknown offset for signal `%s`\n", filename, signal_json.dump());
 | 
			
		||||
		signal.offset = signal_json["offset"].int_value();
 | 
			
		||||
		if (signal.offset < 0)
 | 
			
		||||
			log_error("Failed to parse `%s`: Invalid offset for signal `%s`\n", filename.c_str(), signal_json.dump().c_str());
 | 
			
		||||
			log_error("Failed to parse `%s`: Invalid offset for signal `%s`\n", filename, signal_json.dump());
 | 
			
		||||
		signal.init_only = signal_json["init_only"].bool_value();
 | 
			
		||||
		signals.push_back(signal);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -168,11 +168,11 @@ ReadWitness::ReadWitness(const std::string &filename) :
 | 
			
		|||
	for (auto &step_json : json["steps"].array_items()) {
 | 
			
		||||
		Step step;
 | 
			
		||||
		if (!step_json["bits"].is_string())
 | 
			
		||||
			log_error("Failed to parse `%s`: Expected string as bits value for step %d\n", filename.c_str(), GetSize(steps));
 | 
			
		||||
			log_error("Failed to parse `%s`: Expected string as bits value for step %d\n", filename, GetSize(steps));
 | 
			
		||||
		step.bits = step_json["bits"].string_value();
 | 
			
		||||
		for (char c : step.bits) {
 | 
			
		||||
			if (c != '0' && c != '1' && c != 'x' && c != '?')
 | 
			
		||||
				log_error("Failed to parse `%s`: Invalid bit '%c' value for step %d\n", filename.c_str(), c, GetSize(steps));
 | 
			
		||||
				log_error("Failed to parse `%s`: Invalid bit '%c' value for step %d\n", filename, c, GetSize(steps));
 | 
			
		||||
		}
 | 
			
		||||
		steps.push_back(step);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue