3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-02-07 09:42:16 +00:00

Don't treat ABC 'Error:' output as indicating a fatal error, since these messages aren't necessarily fatal

This commit is contained in:
Robert O'Callahan 2026-01-29 18:47:12 +00:00
parent a68fee1115
commit 6af1b5b19c

View file

@ -1127,9 +1127,34 @@ void AbcModuleState::prepare_module(RTLIL::Design *design, RTLIL::Module *module
handle_loops(assign_map, module);
}
static bool is_abc_prompt(const std::string &line, std::string &rest) {
size_t pos = 0;
while (true) {
// The prompt may not start at the start of the line, because
// ABC can output progress and maybe other data that isn't
// newline-terminated.
size_t start = line.find("abc ", pos);
if (start == std::string::npos)
return false;
pos = start + 4;
size_t digits = 0;
while (pos + digits < line.size() && line[pos + digits] >= '0' && line[pos + digits] <= '9')
++digits;
if (digits < 2)
return false;
if (line.substr(pos + digits, 2) == "> ") {
rest = line.substr(pos + digits + 2);
return true;
}
}
}
bool read_until_abc_done(abc_output_filter &filt, int fd, DeferredLogs &logs) {
std::string line;
char buf[1024];
bool seen_source_cmd = false;
bool seen_yosys_abc_done = false;
while (true) {
int ret = read(fd, buf, sizeof(buf) - 1);
if (ret < 0) {
@ -1144,23 +1169,30 @@ bool read_until_abc_done(abc_output_filter &filt, int fd, DeferredLogs &logs) {
char *end = buf + ret;
while (start < end) {
char *p = static_cast<char*>(memchr(start, '\n', end - start));
if (p == nullptr) {
break;
char *upto = p == nullptr ? end : p + 1;
line.append(start, upto - start);
start = upto;
std::string rest;
bool is_prompt = is_abc_prompt(line, rest);
if (is_prompt && seen_source_cmd) {
// This is the first prompt after we sourced the script.
// We are done here.
// We won't have seen a newline yet since ABC is waiting at the prompt.
if (!seen_yosys_abc_done)
logs.log_error("ABC script did not complete successfully\n");
return seen_yosys_abc_done;
}
line.append(start, p + 1 - start);
if (line.substr(0, 14) == "YOSYS_ABC_DONE") {
// Ignore any leftover output, there should only be a prompt perhaps
return true;
}
// If ABC aborted the sourced script, it returns to the prompt and will
// never print YOSYS_ABC_DONE. Treat this as a failed run, not a hang.
if (line.substr(0, 7) == "Error: ") {
logs.log_error("ABC: %s", line.c_str());
return false;
if (line.empty() || line[line.size() - 1] != '\n') {
// No newline yet, wait for more text
continue;
}
filt.next_line(line);
if (is_prompt && rest.substr(0, 7) == "source ")
seen_source_cmd = true;
if (line.substr(0, 14) == "YOSYS_ABC_DONE")
seen_yosys_abc_done = true;
line.clear();
start = p + 1;
}
line.append(start, end - start);
}