aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/register.cc
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/register.cc')
-rw-r--r--kernel/register.cc131
1 files changed, 111 insertions, 20 deletions
diff --git a/kernel/register.cc b/kernel/register.cc
index 26da96b95..1fd1bad1d 100644
--- a/kernel/register.cc
+++ b/kernel/register.cc
@@ -25,6 +25,65 @@
#include <stdio.h>
#include <errno.h>
+#ifdef YOSYS_ENABLE_ZLIB
+#include <zlib.h>
+
+PRIVATE_NAMESPACE_BEGIN
+#define GZ_BUFFER_SIZE 8192
+void decompress_gzip(const std::string &filename, std::stringstream &out)
+{
+ char buffer[GZ_BUFFER_SIZE];
+ int bytes_read;
+ gzFile gzf = gzopen(filename.c_str(), "rb");
+ while(!gzeof(gzf)) {
+ bytes_read = gzread(gzf, reinterpret_cast<void *>(buffer), GZ_BUFFER_SIZE);
+ out.write(buffer, bytes_read);
+ }
+ gzclose(gzf);
+}
+
+/*
+An output stream that uses a stringbuf to buffer data internally,
+using zlib to write gzip-compressed data every time the stream is flushed.
+*/
+class gzip_ostream : public std::ostream {
+public:
+ gzip_ostream()
+ {
+ rdbuf(&outbuf);
+ }
+ bool open(const std::string &filename)
+ {
+ return outbuf.open(filename);
+ }
+private:
+ class gzip_streambuf : public std::stringbuf {
+ public:
+ gzip_streambuf() { };
+ bool open(const std::string &filename)
+ {
+ gzf = gzopen(filename.c_str(), "wb");
+ return gzf != nullptr;
+ }
+ virtual int sync() override
+ {
+ gzwrite(gzf, reinterpret_cast<const void *>(str().c_str()), unsigned(str().size()));
+ str("");
+ return 0;
+ }
+ ~gzip_streambuf()
+ {
+ sync();
+ gzclose(gzf);
+ }
+ private:
+ gzFile gzf = nullptr;
+ } outbuf;
+};
+PRIVATE_NAMESPACE_END
+
+#endif
+
YOSYS_NAMESPACE_BEGIN
#define MAX_REG_COUNT 1000
@@ -141,7 +200,7 @@ void Pass::extra_args(std::vector<std::string> args, size_t argidx, RTLIL::Desig
{
std::string arg = args[argidx];
- if (arg.substr(0, 1) == "-")
+ if (arg.compare(0, 1, "-") == 0)
cmd_error(args, argidx, "Unknown option or option in arguments.");
if (!select)
@@ -236,8 +295,6 @@ void Pass::call(RTLIL::Design *design, std::vector<std::string> args)
pass_register[args[0]]->post_execute(state);
while (design->selection_stack.size() > orig_sel_stack_pos)
design->selection_stack.pop_back();
-
- design->check();
}
void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::string command)
@@ -319,8 +376,10 @@ void ScriptPass::run(std::string command, std::string info)
log(" %s\n", command.c_str());
else
log(" %s %s\n", command.c_str(), info.c_str());
- } else
+ } else {
Pass::call(active_design, command);
+ active_design->check();
+ }
}
void ScriptPass::run_script(RTLIL::Design *design, std::string run_from, std::string run_to)
@@ -390,7 +449,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s
{
std::string arg = args[argidx];
- if (arg.substr(0, 1) == "-")
+ if (arg.compare(0, 1, "-") == 0)
cmd_error(args, argidx, "Unknown option or option in arguments.");
if (f != NULL)
cmd_error(args, argidx, "Extra filename argument in direct file mode.");
@@ -398,7 +457,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s
filename = arg;
if (filename == "<<" && argidx+1 < args.size())
filename += args[++argidx];
- if (filename.substr(0, 2) == "<<") {
+ if (filename.compare(0, 2, "<<") == 0) {
if (Frontend::current_script_file == NULL)
log_error("Unexpected here document '%s' outside of script!\n", filename.c_str());
if (filename.size() <= 2)
@@ -416,7 +475,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s
break;
}
size_t indent = buffer.find_first_not_of(" \t\r\n");
- if (indent != std::string::npos && buffer.substr(indent, eot_marker.size()) == eot_marker)
+ if (indent != std::string::npos && buffer.compare(indent, eot_marker.size(), eot_marker) == 0)
break;
last_here_document += buffer;
}
@@ -436,12 +495,34 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s
delete ff;
else
f = ff;
+ if (f != NULL) {
+ // Check for gzip magic
+ unsigned char magic[3];
+ int n = readsome(*ff, reinterpret_cast<char*>(magic), 3);
+ 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());
+ if (magic[2] != 8)
+ log_cmd_error("gzip file `%s' uses unsupported compression type %02x\n",
+ filename.c_str(), unsigned(magic[2]));
+ delete ff;
+ std::stringstream *df = new std::stringstream();
+ decompress_gzip(filename, *df);
+ f = df;
+ #else
+ log_cmd_error("File `%s' is a gzip file, but Yosys is compiled without zlib.\n", filename.c_str());
+ #endif
+ } else {
+ ff->clear();
+ ff->seekg(0, std::ios::beg);
+ }
+ }
}
if (f == NULL)
log_cmd_error("Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno));
for (size_t i = argidx+1; i < args.size(); i++)
- if (args[i].substr(0, 1) == "-")
+ if (args[i].compare(0, 1, "-") == 0)
cmd_error(args, i, "Found option, expected arguments.");
if (argidx+1 < args.size()) {
@@ -492,8 +573,6 @@ void Frontend::frontend_call(RTLIL::Design *design, std::istream *f, std::string
args.push_back(filename);
frontend_register[args[0]]->execute(args, design);
}
-
- design->check();
}
Backend::Backend(std::string name, std::string short_help) :
@@ -533,7 +612,7 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<st
{
std::string arg = args[argidx];
- if (arg.substr(0, 1) == "-" && arg != "-")
+ if (arg.compare(0, 1, "-") == 0 && arg != "-")
cmd_error(args, argidx, "Unknown option or option in arguments.");
if (f != NULL)
cmd_error(args, argidx, "Extra filename argument in direct file mode.");
@@ -546,14 +625,28 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<st
filename = arg;
rewrite_filename(filename);
- std::ofstream *ff = new std::ofstream;
- ff->open(filename.c_str(), std::ofstream::trunc);
- yosys_output_files.insert(filename);
- if (ff->fail()) {
- delete ff;
- log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
+ if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".gz") == 0) {
+#ifdef YOSYS_ENABLE_ZLIB
+ gzip_ostream *gf = new gzip_ostream;
+ if (!gf->open(filename)) {
+ delete gf;
+ log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
+ }
+ yosys_output_files.insert(filename);
+ f = gf;
+#else
+ log_cmd_error("Yosys is compiled without zlib support, unable to write gzip output.\n");
+#endif
+ } else {
+ std::ofstream *ff = new std::ofstream;
+ ff->open(filename.c_str(), std::ofstream::trunc);
+ yosys_output_files.insert(filename);
+ if (ff->fail()) {
+ delete ff;
+ log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
+ }
+ f = ff;
}
- f = ff;
}
if (called_with_fp)
@@ -603,8 +696,6 @@ void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string f
while (design->selection_stack.size() > orig_sel_stack_pos)
design->selection_stack.pop_back();
-
- design->check();
}
static struct CellHelpMessages {