summaryrefslogtreecommitdiff
path: root/backends/ilang/ilang_backend.cc
diff options
context:
space:
mode:
Diffstat (limited to 'backends/ilang/ilang_backend.cc')
-rw-r--r--backends/ilang/ilang_backend.cc329
1 files changed, 185 insertions, 144 deletions
diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc
index c585d40c..48d818d7 100644
--- a/backends/ilang/ilang_backend.cc
+++ b/backends/ilang/ilang_backend.cc
@@ -23,16 +23,12 @@
*/
#include "ilang_backend.h"
-#include "kernel/register.h"
-#include "kernel/log.h"
-#include <string>
-#include <assert.h>
-#include <string.h>
+#include "kernel/yosys.h"
#include <errno.h>
using namespace ILANG_BACKEND;
-void ILANG_BACKEND::dump_const(FILE *f, const RTLIL::Const &data, int width, int offset, bool autoint)
+void ILANG_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int width, int offset, bool autoint)
{
if (width < 0)
width = data.bits.size() - offset;
@@ -40,7 +36,7 @@ void ILANG_BACKEND::dump_const(FILE *f, const RTLIL::Const &data, int width, int
if (width == 32 && autoint) {
int32_t val = 0;
for (int i = 0; i < width; i++) {
- assert(offset+i < (int)data.bits.size());
+ log_assert(offset+i < (int)data.bits.size());
switch (data.bits[offset+i]) {
case RTLIL::S0: break;
case RTLIL::S1: val |= 1 << i; break;
@@ -48,220 +44,230 @@ void ILANG_BACKEND::dump_const(FILE *f, const RTLIL::Const &data, int width, int
}
}
if (val >= 0) {
- fprintf(f, "%d", val);
+ f << stringf("%d", val);
return;
}
}
- fprintf(f, "%d'", width);
+ f << stringf("%d'", width);
for (int i = offset+width-1; i >= offset; i--) {
- assert(i < (int)data.bits.size());
+ log_assert(i < (int)data.bits.size());
switch (data.bits[i]) {
- case RTLIL::S0: fprintf(f, "0"); break;
- case RTLIL::S1: fprintf(f, "1"); break;
- case RTLIL::Sx: fprintf(f, "x"); break;
- case RTLIL::Sz: fprintf(f, "z"); break;
- case RTLIL::Sa: fprintf(f, "-"); break;
- case RTLIL::Sm: fprintf(f, "m"); break;
+ case RTLIL::S0: f << stringf("0"); break;
+ case RTLIL::S1: f << stringf("1"); break;
+ case RTLIL::Sx: f << stringf("x"); break;
+ case RTLIL::Sz: f << stringf("z"); break;
+ case RTLIL::Sa: f << stringf("-"); break;
+ case RTLIL::Sm: f << stringf("m"); break;
}
}
} else {
- fprintf(f, "\"");
+ f << stringf("\"");
std::string str = data.decode_string();
for (size_t i = 0; i < str.size(); i++) {
if (str[i] == '\n')
- fprintf(f, "\\n");
+ f << stringf("\\n");
else if (str[i] == '\t')
- fprintf(f, "\\t");
+ f << stringf("\\t");
else if (str[i] < 32)
- fprintf(f, "\\%03o", str[i]);
+ f << stringf("\\%03o", str[i]);
else if (str[i] == '"')
- fprintf(f, "\\\"");
+ f << stringf("\\\"");
else if (str[i] == '\\')
- fprintf(f, "\\\\");
+ f << stringf("\\\\");
else
- fputc(str[i], f);
+ f << str[i];
}
- fprintf(f, "\"");
+ f << stringf("\"");
}
}
-void ILANG_BACKEND::dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool autoint)
+void ILANG_BACKEND::dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool autoint)
{
if (chunk.wire == NULL) {
dump_const(f, chunk.data, chunk.width, chunk.offset, autoint);
} else {
if (chunk.width == chunk.wire->width && chunk.offset == 0)
- fprintf(f, "%s", chunk.wire->name.c_str());
+ f << stringf("%s", chunk.wire->name.c_str());
else if (chunk.width == 1)
- fprintf(f, "%s [%d]", chunk.wire->name.c_str(), chunk.offset);
+ f << stringf("%s [%d]", chunk.wire->name.c_str(), chunk.offset);
else
- fprintf(f, "%s [%d:%d]", chunk.wire->name.c_str(), chunk.offset+chunk.width-1, chunk.offset);
+ f << stringf("%s [%d:%d]", chunk.wire->name.c_str(), chunk.offset+chunk.width-1, chunk.offset);
}
}
-void ILANG_BACKEND::dump_sigspec(FILE *f, const RTLIL::SigSpec &sig, bool autoint)
+void ILANG_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, bool autoint)
{
- if (sig.chunks.size() == 1) {
- dump_sigchunk(f, sig.chunks[0], autoint);
+ if (sig.is_chunk()) {
+ dump_sigchunk(f, sig.as_chunk(), autoint);
} else {
- fprintf(f, "{ ");
- for (auto it = sig.chunks.rbegin(); it != sig.chunks.rend(); it++) {
+ f << stringf("{ ");
+ for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); it++) {
dump_sigchunk(f, *it, false);
- fprintf(f, " ");
+ f << stringf(" ");
}
- fprintf(f, "}");
+ f << stringf("}");
}
}
-void ILANG_BACKEND::dump_wire(FILE *f, std::string indent, const RTLIL::Wire *wire)
+void ILANG_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire)
{
- for (auto it = wire->attributes.begin(); it != wire->attributes.end(); it++) {
- fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str());
+ std::map<RTLIL::IdString, RTLIL::Const, RTLIL::sort_by_id_str> sorted_attributes(wire->attributes.begin(), wire->attributes.end());
+
+ for (auto it = sorted_attributes.begin(); it != sorted_attributes.end(); it++) {
+ f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
dump_const(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- fprintf(f, "%s" "wire ", indent.c_str());
+ f << stringf("%s" "wire ", indent.c_str());
if (wire->width != 1)
- fprintf(f, "width %d ", wire->width);
+ f << stringf("width %d ", wire->width);
+ if (wire->upto)
+ f << stringf("upto ");
if (wire->start_offset != 0)
- fprintf(f, "offset %d ", wire->start_offset);
+ f << stringf("offset %d ", wire->start_offset);
if (wire->port_input && !wire->port_output)
- fprintf(f, "input %d ", wire->port_id);
+ f << stringf("input %d ", wire->port_id);
if (!wire->port_input && wire->port_output)
- fprintf(f, "output %d ", wire->port_id);
+ f << stringf("output %d ", wire->port_id);
if (wire->port_input && wire->port_output)
- fprintf(f, "inout %d ", wire->port_id);
- fprintf(f, "%s\n", wire->name.c_str());
+ f << stringf("inout %d ", wire->port_id);
+ f << stringf("%s\n", wire->name.c_str());
}
-void ILANG_BACKEND::dump_memory(FILE *f, std::string indent, const RTLIL::Memory *memory)
+void ILANG_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory)
{
- for (auto it = memory->attributes.begin(); it != memory->attributes.end(); it++) {
- fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str());
+ std::map<RTLIL::IdString, RTLIL::Const, RTLIL::sort_by_id_str> sorted_attributes(memory->attributes.begin(), memory->attributes.end());
+
+ for (auto it = sorted_attributes.begin(); it != sorted_attributes.end(); it++) {
+ f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
dump_const(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- fprintf(f, "%s" "memory ", indent.c_str());
+ f << stringf("%s" "memory ", indent.c_str());
if (memory->width != 1)
- fprintf(f, "width %d ", memory->width);
+ f << stringf("width %d ", memory->width);
if (memory->size != 0)
- fprintf(f, "size %d ", memory->size);
- fprintf(f, "%s\n", memory->name.c_str());
+ f << stringf("size %d ", memory->size);
+ f << stringf("%s\n", memory->name.c_str());
}
-void ILANG_BACKEND::dump_cell(FILE *f, std::string indent, const RTLIL::Cell *cell)
+void ILANG_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell)
{
- for (auto it = cell->attributes.begin(); it != cell->attributes.end(); it++) {
- fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str());
+ std::map<RTLIL::IdString, RTLIL::Const, RTLIL::sort_by_id_str> sorted_attributes(cell->attributes.begin(), cell->attributes.end());
+ std::map<RTLIL::IdString, RTLIL::Const, RTLIL::sort_by_id_str> sorted_parameters(cell->parameters.begin(), cell->parameters.end());
+ std::map<RTLIL::IdString, RTLIL::SigSpec, RTLIL::sort_by_id_str> sorted_connections(cell->connections().begin(), cell->connections().end());
+
+ for (auto it = sorted_attributes.begin(); it != sorted_attributes.end(); it++) {
+ f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
dump_const(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- fprintf(f, "%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str());
- for (auto it = cell->parameters.begin(); it != cell->parameters.end(); it++) {
- fprintf(f, "%s parameter%s %s ", indent.c_str(), (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "", it->first.c_str());
+ f << stringf("%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str());
+ for (auto it = sorted_parameters.begin(); it != sorted_parameters.end(); it++) {
+ f << stringf("%s parameter%s %s ", indent.c_str(), (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "", it->first.c_str());
dump_const(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- for (auto it = cell->connections.begin(); it != cell->connections.end(); it++) {
- fprintf(f, "%s connect %s ", indent.c_str(), it->first.c_str());
+ for (auto it = sorted_connections.begin(); it != sorted_connections.end(); it++) {
+ f << stringf("%s connect %s ", indent.c_str(), it->first.c_str());
dump_sigspec(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- fprintf(f, "%s" "end\n", indent.c_str());
+ f << stringf("%s" "end\n", indent.c_str());
}
-void ILANG_BACKEND::dump_proc_case_body(FILE *f, std::string indent, const RTLIL::CaseRule *cs)
+void ILANG_BACKEND::dump_proc_case_body(std::ostream &f, std::string indent, const RTLIL::CaseRule *cs)
{
for (auto it = cs->actions.begin(); it != cs->actions.end(); it++)
{
- fprintf(f, "%s" "assign ", indent.c_str());
+ f << stringf("%s" "assign ", indent.c_str());
dump_sigspec(f, it->first);
- fprintf(f, " ");
+ f << stringf(" ");
dump_sigspec(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
for (auto it = cs->switches.begin(); it != cs->switches.end(); it++)
dump_proc_switch(f, indent, *it);
}
-void ILANG_BACKEND::dump_proc_switch(FILE *f, std::string indent, const RTLIL::SwitchRule *sw)
+void ILANG_BACKEND::dump_proc_switch(std::ostream &f, std::string indent, const RTLIL::SwitchRule *sw)
{
for (auto it = sw->attributes.begin(); it != sw->attributes.end(); it++) {
- fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str());
+ f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
dump_const(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- fprintf(f, "%s" "switch ", indent.c_str());
+ f << stringf("%s" "switch ", indent.c_str());
dump_sigspec(f, sw->signal);
- fprintf(f, "\n");
+ f << stringf("\n");
for (auto it = sw->cases.begin(); it != sw->cases.end(); it++)
{
- fprintf(f, "%s case ", indent.c_str());
+ f << stringf("%s case ", indent.c_str());
for (size_t i = 0; i < (*it)->compare.size(); i++) {
if (i > 0)
- fprintf(f, ", ");
+ f << stringf(", ");
dump_sigspec(f, (*it)->compare[i]);
}
- fprintf(f, "\n");
+ f << stringf("\n");
dump_proc_case_body(f, indent + " ", *it);
}
- fprintf(f, "%s" "end\n", indent.c_str());
+ f << stringf("%s" "end\n", indent.c_str());
}
-void ILANG_BACKEND::dump_proc_sync(FILE *f, std::string indent, const RTLIL::SyncRule *sy)
+void ILANG_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RTLIL::SyncRule *sy)
{
- fprintf(f, "%s" "sync ", indent.c_str());
+ f << stringf("%s" "sync ", indent.c_str());
switch (sy->type) {
- if (0) case RTLIL::ST0: fprintf(f, "low ");
- if (0) case RTLIL::ST1: fprintf(f, "high ");
- if (0) case RTLIL::STp: fprintf(f, "posedge ");
- if (0) case RTLIL::STn: fprintf(f, "negedge ");
- if (0) case RTLIL::STe: fprintf(f, "edge ");
+ if (0) case RTLIL::ST0: f << stringf("low ");
+ if (0) case RTLIL::ST1: f << stringf("high ");
+ if (0) case RTLIL::STp: f << stringf("posedge ");
+ if (0) case RTLIL::STn: f << stringf("negedge ");
+ if (0) case RTLIL::STe: f << stringf("edge ");
dump_sigspec(f, sy->signal);
- fprintf(f, "\n");
+ f << stringf("\n");
break;
- case RTLIL::STa: fprintf(f, "always\n"); break;
- case RTLIL::STi: fprintf(f, "init\n"); break;
+ case RTLIL::STa: f << stringf("always\n"); break;
+ case RTLIL::STi: f << stringf("init\n"); break;
}
for (auto it = sy->actions.begin(); it != sy->actions.end(); it++) {
- fprintf(f, "%s update ", indent.c_str());
+ f << stringf("%s update ", indent.c_str());
dump_sigspec(f, it->first);
- fprintf(f, " ");
+ f << stringf(" ");
dump_sigspec(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
}
-void ILANG_BACKEND::dump_proc(FILE *f, std::string indent, const RTLIL::Process *proc)
+void ILANG_BACKEND::dump_proc(std::ostream &f, std::string indent, const RTLIL::Process *proc)
{
for (auto it = proc->attributes.begin(); it != proc->attributes.end(); it++) {
- fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str());
+ f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
dump_const(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- fprintf(f, "%s" "process %s\n", indent.c_str(), proc->name.c_str());
+ f << stringf("%s" "process %s\n", indent.c_str(), proc->name.c_str());
dump_proc_case_body(f, indent + " ", &proc->root_case);
for (auto it = proc->syncs.begin(); it != proc->syncs.end(); it++)
dump_proc_sync(f, indent + " ", *it);
- fprintf(f, "%s" "end\n", indent.c_str());
+ f << stringf("%s" "end\n", indent.c_str());
}
-void ILANG_BACKEND::dump_conn(FILE *f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
+void ILANG_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
{
- fprintf(f, "%s" "connect ", indent.c_str());
+ f << stringf("%s" "connect ", indent.c_str());
dump_sigspec(f, left);
- fprintf(f, " ");
+ f << stringf(" ");
dump_sigspec(f, right);
- fprintf(f, "\n");
+ f << stringf("\n");
}
-void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module *module, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n)
+void ILANG_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Module *module, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n)
{
bool print_header = flag_m || design->selected_whole_module(module->name);
bool print_body = !flag_n || !design->selected_whole_module(module->name);
@@ -269,51 +275,71 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module
if (print_header)
{
for (auto it = module->attributes.begin(); it != module->attributes.end(); it++) {
- fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str());
+ f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
dump_const(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- fprintf(f, "%s" "module %s\n", indent.c_str(), module->name.c_str());
+ f << stringf("%s" "module %s\n", indent.c_str(), module->name.c_str());
}
if (print_body)
{
- for (auto it = module->wires.begin(); it != module->wires.end(); it++)
- if (!only_selected || design->selected(module, it->second)) {
+ std::vector<RTLIL::Wire*> sorted_wires;
+ for (auto it : module->wires())
+ sorted_wires.push_back(it);
+ std::sort(sorted_wires.begin(), sorted_wires.end(), RTLIL::sort_by_name_str<RTLIL::Wire>());
+
+ std::vector<RTLIL::Memory*> sorted_memories;
+ for (auto it : module->memories)
+ sorted_memories.push_back(it.second);
+ std::sort(sorted_memories.begin(), sorted_memories.end(), RTLIL::sort_by_name_str<RTLIL::Memory>());
+
+ std::vector<RTLIL::Cell*> sorted_cells;
+ for (auto it : module->cells())
+ sorted_cells.push_back(it);
+ std::sort(sorted_cells.begin(), sorted_cells.end(), RTLIL::sort_by_name_str<RTLIL::Cell>());
+
+ std::vector<RTLIL::Process*> sorted_processes;
+ for (auto it : module->processes)
+ sorted_processes.push_back(it.second);
+ std::sort(sorted_processes.begin(), sorted_processes.end(), RTLIL::sort_by_name_str<RTLIL::Process>());
+
+ for (auto it : sorted_wires)
+ if (!only_selected || design->selected(module, it)) {
if (only_selected)
- fprintf(f, "\n");
- dump_wire(f, indent + " ", it->second);
+ f << stringf("\n");
+ dump_wire(f, indent + " ", it);
}
- for (auto it = module->memories.begin(); it != module->memories.end(); it++)
- if (!only_selected || design->selected(module, it->second)) {
+ for (auto it : sorted_memories)
+ if (!only_selected || design->selected(module, it)) {
if (only_selected)
- fprintf(f, "\n");
- dump_memory(f, indent + " ", it->second);
+ f << stringf("\n");
+ dump_memory(f, indent + " ", it);
}
- for (auto it = module->cells.begin(); it != module->cells.end(); it++)
- if (!only_selected || design->selected(module, it->second)) {
+ for (auto it : sorted_cells)
+ if (!only_selected || design->selected(module, it)) {
if (only_selected)
- fprintf(f, "\n");
- dump_cell(f, indent + " ", it->second);
+ f << stringf("\n");
+ dump_cell(f, indent + " ", it);
}
- for (auto it = module->processes.begin(); it != module->processes.end(); it++)
- if (!only_selected || design->selected(module, it->second)) {
+ for (auto it : sorted_processes)
+ if (!only_selected || design->selected(module, it)) {
if (only_selected)
- fprintf(f, "\n");
- dump_proc(f, indent + " ", it->second);
+ f << stringf("\n");
+ dump_proc(f, indent + " ", it);
}
bool first_conn_line = true;
- for (auto it = module->connections.begin(); it != module->connections.end(); it++) {
+ for (auto it = module->connections().begin(); it != module->connections().end(); it++) {
bool show_conn = !only_selected;
if (only_selected) {
RTLIL::SigSpec sigs = it->first;
sigs.append(it->second);
- for (auto &c : sigs.chunks) {
+ for (auto &c : sigs.chunks()) {
if (c.wire == NULL || !design->selected(module, c.wire))
continue;
show_conn = true;
@@ -321,7 +347,7 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module
}
if (show_conn) {
if (only_selected && first_conn_line)
- fprintf(f, "\n");
+ f << stringf("\n");
dump_conn(f, indent + " ", it->first, it->second);
first_conn_line = false;
}
@@ -329,27 +355,40 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module
}
if (print_header)
- fprintf(f, "%s" "end\n", indent.c_str());
+ f << stringf("%s" "end\n", indent.c_str());
}
-void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n)
+void ILANG_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n)
{
+ int init_autoidx = autoidx;
+
if (!flag_m) {
int count_selected_mods = 0;
- for (auto it = design->modules.begin(); it != design->modules.end(); it++)
+ for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) {
+ if (design->selected_whole_module(it->first))
+ flag_m = true;
if (design->selected(it->second))
count_selected_mods++;
+ }
if (count_selected_mods > 1)
flag_m = true;
}
- for (auto it = design->modules.begin(); it != design->modules.end(); it++) {
+ if (!only_selected || flag_m) {
+ if (only_selected)
+ f << stringf("\n");
+ f << stringf("autoidx %d\n", autoidx);
+ }
+
+ for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) {
if (!only_selected || design->selected(it->second)) {
if (only_selected)
- fprintf(f, "\n");
+ f << stringf("\n");
dump_module(f, "", it->second, design, only_selected, flag_m, flag_n);
}
}
+
+ log_assert(init_autoidx == autoidx);
}
struct IlangBackend : public Backend {
@@ -367,7 +406,7 @@ struct IlangBackend : public Backend {
log(" only write selected parts of the design.\n");
log("\n");
}
- virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
+ virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
{
bool selected = false;
@@ -385,8 +424,8 @@ struct IlangBackend : public Backend {
extra_args(f, filename, args, argidx);
log("Output filename: %s\n", filename.c_str());
- fprintf(f, "# Generated by %s\n", yosys_version_str);
- ILANG_BACKEND::dump_design(f, design, selected, true, false);
+ *f << stringf("# Generated by %s\n", yosys_version_str);
+ ILANG_BACKEND::dump_design(*f, design, selected, true, false);
}
} IlangBackend;
@@ -446,25 +485,27 @@ struct DumpPass : public Pass {
}
extra_args(args, argidx, design);
- FILE *f = NULL;
- char *buf_ptr;
- size_t buf_size;
+ std::ostream *f;
+ std::stringstream buf;
if (!filename.empty()) {
- f = fopen(filename.c_str(), append ? "a" : "w");
- if (f == NULL)
+ std::ofstream *ff = new std::ofstream;
+ ff->open(filename.c_str(), append ? std::ofstream::app : std::ofstream::trunc);
+ if (ff->fail()) {
+ delete ff;
log_error("Can't open file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
+ }
+ f = ff;
} else {
- f = open_memstream(&buf_ptr, &buf_size);
+ f = &buf;
}
- ILANG_BACKEND::dump_design(f, design, true, flag_m, flag_n);
+ ILANG_BACKEND::dump_design(*f, design, true, flag_m, flag_n);
- fclose(f);
-
- if (filename.empty()) {
- log("%s", buf_ptr);
- free(buf_ptr);
+ if (!filename.empty()) {
+ delete f;
+ } else {
+ log("%s", buf.str().c_str());
}
}
} DumpPass;