diff --git a/frontends/blif/blifparse.cc b/frontends/blif/blifparse.cc index a69cfde19..fb71cee16 100644 --- a/frontends/blif/blifparse.cc +++ b/frontends/blif/blifparse.cc @@ -21,7 +21,7 @@ YOSYS_NAMESPACE_BEGIN -static bool read_next_line(char *&buffer, size_t &buffer_size, int &line_count, FILE *f) +static bool read_next_line(char *&buffer, size_t &buffer_size, int &line_count, std::istream &f) { int buffer_len = 0; buffer[0] = 0; @@ -42,32 +42,31 @@ static bool read_next_line(char *&buffer, size_t &buffer_size, int &line_count, if (buffer_len > 0 && buffer[buffer_len-1] == '\\') buffer[--buffer_len] = 0; line_count++; - if (fgets(buffer+buffer_len, buffer_size-buffer_len, f) == NULL) + if (!f.getline(buffer+buffer_len, buffer_size-buffer_len)) return false; } else return true; } } -RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) +void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name) { - RTLIL::Design *design = new RTLIL::Design; - RTLIL::Module *module = new RTLIL::Module; - + RTLIL::Module *module = nullptr; RTLIL::Const *lutptr = NULL; RTLIL::State lut_default_state = RTLIL::State::Sx; - module->name = "\\netlist"; - design->add(module); - size_t buffer_size = 4096; char *buffer = (char*)malloc(buffer_size); int line_count = 0; while (1) { - if (!read_next_line(buffer, buffer_size, line_count, f)) - goto error; + if (!read_next_line(buffer, buffer_size, line_count, f)) { + if (module != nullptr) + goto error; + free(buffer); + return; + } continue_without_read: if (buffer[0] == '#') @@ -85,13 +84,24 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) char *cmd = strtok(buffer, " \t\r\n"); - if (!strcmp(cmd, ".model")) + if (!strcmp(cmd, ".model")) { + if (module != nullptr) + goto error; + module = new RTLIL::Module; + module->name = RTLIL::escape_id(strtok(NULL, " \t\r\n")); + if (design->module(module->name)) + log_error("Duplicate definition of module %s in line %d!\n", log_id(module->name), line_count); + design->add(module); continue; + } + + if (module == nullptr) + goto error; if (!strcmp(cmd, ".end")) { module->fixup_ports(); - free(buffer); - return design; + module = nullptr; + continue; } if (!strcmp(cmd, ".inputs") || !strcmp(cmd, ".outputs")) { @@ -256,8 +266,6 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) error: log_error("Syntax error in line %d!\n", line_count); - // delete design; - // return NULL; } YOSYS_NAMESPACE_END diff --git a/frontends/blif/blifparse.h b/frontends/blif/blifparse.h index 31f5b2e5c..1da36e00a 100644 --- a/frontends/blif/blifparse.h +++ b/frontends/blif/blifparse.h @@ -24,7 +24,7 @@ YOSYS_NAMESPACE_BEGIN -extern RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name); +extern void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name); YOSYS_NAMESPACE_END diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 2db9e259e..a180e311c 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -877,14 +877,16 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret); buffer = stringf("%s/%s", tempdir_name.c_str(), "output.blif"); - f = fopen(buffer.c_str(), "rt"); - if (f == NULL) + std::ifstream ifs; + ifs.open(buffer); + if (ifs.fail()) log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); bool builtin_lib = liberty_file.empty() && script_file.empty() && !lut_mode; - RTLIL::Design *mapped_design = abc_parse_blif(f, builtin_lib ? "\\DFF" : "\\_dff_"); + RTLIL::Design *mapped_design = new RTLIL::Design; + parse_blif(mapped_design, ifs, builtin_lib ? "\\DFF" : "\\_dff_"); - fclose(f); + ifs.close(); log_header("Re-integrating ABC results.\n"); RTLIL::Module *mapped_mod = mapped_design->modules_["\\netlist"];