*/
class gzip_ostream : public std::ostream {
public:
- gzip_ostream()
+ gzip_ostream() : std::ostream(nullptr)
{
rdbuf(&outbuf);
}
str("");
return 0;
}
- ~gzip_streambuf()
+ virtual ~gzip_streambuf()
{
sync();
gzclose(gzf);
void Pass::init_register()
{
+ vector<Pass*> added_passes;
while (first_queued_pass) {
+ added_passes.push_back(first_queued_pass);
first_queued_pass->run_register();
first_queued_pass = first_queued_pass->next_queued_pass;
}
+ for (auto added_pass : added_passes)
+ added_pass->on_register();
}
void Pass::done_register()
{
+ for (auto &it : pass_register)
+ it.second->on_shutdown();
+
frontend_register.clear();
pass_register.clear();
backend_register.clear();
log_assert(first_queued_pass == NULL);
}
+void Pass::on_register()
+{
+}
+
+void Pass::on_shutdown()
+{
+}
+
Pass::~Pass()
{
}
{
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)
return;
if (tok[0] == '!') {
+#if !defined(YOSYS_DISABLE_SPAWN)
cmd_buf = command.substr(command.find('!') + 1);
while (!cmd_buf.empty() && (cmd_buf.back() == ' ' || cmd_buf.back() == '\t' ||
cmd_buf.back() == '\r' || cmd_buf.back() == '\n'))
if (retCode != 0)
log_cmd_error("Shell command returned error code %d.\n", retCode);
return;
+#else
+ log_cmd_error("Shell is not available.\n");
+#endif
}
while (!tok.empty()) {
if (pass_register.count(args[0]) == 0)
log_cmd_error("No such command: %s (type 'help' for a command overview)\n", args[0].c_str());
+ if (pass_register[args[0]]->experimental_flag)
+ log_experimental("%s", args[0].c_str());
+
size_t orig_sel_stack_pos = design->selection_stack.size();
auto state = pass_register[args[0]]->pre_execute();
pass_register[args[0]]->execute(args, design);
}
}
+void ScriptPass::run_nocheck(std::string command, std::string info)
+{
+ if (active_design == nullptr) {
+ if (info.empty())
+ log(" %s\n", command.c_str());
+ else
+ log(" %s %s\n", command.c_str(), info.c_str());
+ } else {
+ Pass::call(active_design, command);
+ }
+}
+
void ScriptPass::run_script(RTLIL::Design *design, std::string run_from, std::string run_to)
{
help_mode = false;
FILE *Frontend::current_script_file = NULL;
std::string Frontend::last_here_document;
-void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<std::string> args, size_t argidx)
+void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<std::string> args, size_t argidx, bool bin_input)
{
bool called_with_fp = f != NULL;
{
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.");
filename = arg;
+ //Accommodate heredocs with EOT marker spaced out from "<<", e.g. "<< EOT" vs. "<<EOT"
if (filename == "<<" && argidx+1 < args.size())
filename += args[++argidx];
- if (filename.substr(0, 2) == "<<") {
- if (Frontend::current_script_file == NULL)
- log_error("Unexpected here document '%s' outside of script!\n", filename.c_str());
+ if (filename.compare(0, 2, "<<") == 0) {
if (filename.size() <= 2)
log_error("Missing EOT marker in here document!\n");
std::string eot_marker = filename.substr(2);
+ if (Frontend::current_script_file == nullptr)
+ filename = "<stdin>";
last_here_document.clear();
while (1) {
std::string buffer;
char block[4096];
while (1) {
- if (fgets(block, 4096, Frontend::current_script_file) == NULL)
+ if (fgets(block, 4096, Frontend::current_script_file == nullptr? stdin : Frontend::current_script_file) == nullptr)
log_error("Unexpected end of file in here document '%s'!\n", filename.c_str());
buffer += block;
if (buffer.size() > 0 && (buffer[buffer.size() - 1] == '\n' || buffer[buffer.size() - 1] == '\r'))
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;
}
next_args.insert(next_args.end(), filenames.begin()+1, filenames.end());
}
std::ifstream *ff = new std::ifstream;
- ff->open(filename.c_str());
+ ff->open(filename.c_str(), bin_input ? std::ifstream::binary : std::ifstream::in);
yosys_input_files.insert(filename);
if (ff->fail())
delete ff;
if (f != NULL) {
// Check for gzip magic
unsigned char magic[3];
- int n = readsome(*ff, reinterpret_cast<char*>(magic), 3);
+ int n = 0;
+ while (n < 3)
+ {
+ int c = ff->get();
+ if (c != EOF) {
+ magic[n] = (unsigned char) c;
+ }
+ n++;
+ }
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());
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()) {
delete f;
}
-void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<std::string> args, size_t argidx)
+void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<std::string> args, size_t argidx, bool bin_output)
{
bool called_with_fp = f != NULL;
{
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.");
filename = arg;
rewrite_filename(filename);
- if (filename.size() > 3 && filename.substr(filename.size()-3) == ".gz") {
+ 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)) {
#endif
} else {
std::ofstream *ff = new std::ofstream;
- ff->open(filename.c_str(), std::ofstream::trunc);
+ ff->open(filename.c_str(), bin_output ? (std::ofstream::trunc | std::ofstream::binary) : std::ofstream::trunc);
yosys_output_files.insert(filename);
if (ff->fail()) {
delete ff;
log("=");
log("\n");
it.second->help();
+ if (it.second->experimental_flag) {
+ log("\n");
+ log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", it.first.c_str());
+ log("\n");
+ }
}
}
else if (args[1] == "-cells") {
std::ostringstream buf;
log_streams.push_back(&buf);
it.second->help();
+ if (it.second->experimental_flag) {
+ log("\n");
+ log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", it.first.c_str());
+ log("\n");
+ }
log_streams.pop_back();
write_tex(f, it.first, it.second->short_help, buf.str());
}
std::ostringstream buf;
log_streams.push_back(&buf);
it.second->help();
+ if (it.second->experimental_flag) {
+ log("\n");
+ log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", it.first.c_str());
+ log("\n");
+ }
log_streams.pop_back();
write_html(f, it.first, it.second->short_help, buf.str());
}
}
else if (pass_register.count(args[1])) {
pass_register.at(args[1])->help();
+ if (pass_register.at(args[1])->experimental_flag) {
+ log("\n");
+ log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", args[1].c_str());
+ log("\n");
+ }
}
else if (cell_help_messages.cell_help.count(args[1])) {
log("%s", cell_help_messages.cell_help.at(args[1]).c_str());