From b1596bc0e7e5269fd610508f608f65f3aa696bd9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 12 Oct 2014 10:57:15 +0200 Subject: Added run_command() api to replace system() and popen() --- kernel/register.cc | 2 +- kernel/yosys.cc | 25 +++++++++++++++++++++++++ kernel/yosys.h | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/register.cc b/kernel/register.cc index 9452eb355..33c129d83 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -159,7 +159,7 @@ void Pass::call(RTLIL::Design *design, std::string command) cmd_buf.back() == '\r' || cmd_buf.back() == '\n')) cmd_buf.resize(cmd_buf.size()-1); log_header("Shell command: %s\n", cmd_buf.c_str()); - int retCode = system(cmd_buf.c_str()); + int retCode = run_command(cmd_buf); if (retCode != 0) log_cmd_error("Shell command returned error code %d.\n", retCode); return; diff --git a/kernel/yosys.cc b/kernel/yosys.cc index a40ad4372..50da13ae7 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -182,6 +182,31 @@ int readsome(std::istream &f, char *s, int n) return rc; } +int run_command(const std::string &command, std::function process_line) +{ + if (!process_line) + return system(command.c_str()); + + FILE *f = popen(command.c_str(), "r"); + if (f == nullptr) + return -1; + + std::string line; + char logbuf[128]; + while (fgets(logbuf, 128, f) != NULL) { + line += logbuf; + if (!line.empty() && line.back() == '\n') + process_line(line), line.clear(); + } + if (!line.empty()) + process_line(line); + + int ret = pclose(f); + if (ret < 0) + return -1; + return WEXITSTATUS(ret); +} + int GetSize(RTLIL::Wire *wire) { return wire->width; diff --git a/kernel/yosys.h b/kernel/yosys.h index d38e60ceb..fcf60f9f1 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -87,6 +87,7 @@ std::string vstringf(const char *fmt, va_list ap); std::string next_token(std::string &text, const char *sep); bool patmatch(const char *pattern, const char *string); int readsome(std::istream &f, char *s, int n); +int run_command(const std::string &command, std::function process_line = std::function()); template int GetSize(const T &obj) { return obj.size(); } int GetSize(RTLIL::Wire *wire); -- cgit v1.2.3