From 21a1cc1b60f0c646dcc46c89440fc1a2cf606743 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 8 Apr 2015 12:14:34 +0200 Subject: [PATCH] Added support for "file names with blanks" --- kernel/register.cc | 7 +++---- kernel/yosys.cc | 20 +++++++++++++++++++- kernel/yosys.h | 3 ++- passes/cmds/setattr.cc | 34 ++++++++++++++-------------------- passes/memory/memory_bram.cc | 4 +--- passes/techmap/extract.cc | 2 ++ passes/techmap/techmap.cc | 6 ++---- 7 files changed, 43 insertions(+), 33 deletions(-) diff --git a/kernel/register.cc b/kernel/register.cc index af1cb77b5..d3b21c460 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -150,7 +150,7 @@ void Pass::call(RTLIL::Design *design, std::string command) std::vector args; std::string cmd_buf = command; - std::string tok = next_token(cmd_buf, " \t\r\n"); + std::string tok = next_token(cmd_buf, " \t\r\n", true); if (tok.empty()) return; @@ -201,7 +201,7 @@ void Pass::call(RTLIL::Design *design, std::string command) call(design, args); args.clear(); } - tok = next_token(cmd_buf, " \t\r\n"); + tok = next_token(cmd_buf, " \t\r\n", true); } call(design, args); @@ -359,8 +359,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vectoropen(filename.c_str()); if (ff->fail()) diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 884b2c59b..bbc142f14 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -182,13 +182,23 @@ int readsome(std::istream &f, char *s, int n) return rc; } -std::string next_token(std::string &text, const char *sep) +std::string next_token(std::string &text, const char *sep, bool long_strings) { size_t pos_begin = text.find_first_not_of(sep); if (pos_begin == std::string::npos) pos_begin = text.size(); + if (long_strings && pos_begin != text.size() && text[pos_begin] == '"') { + string sep_string = sep; + for (size_t i = pos_begin+1; i < text.size(); i++) + if (text[i] == '"' && (i+1 == text.size() || sep_string.find(text[i+1]) != std::string::npos)) { + std::string token = text.substr(pos_begin, i-pos_begin+1); + text = text.substr(i+1); + return token; + } + } + size_t pos_end = text.find_first_of(sep, pos_begin); if (pos_end == std::string::npos) @@ -505,6 +515,14 @@ const char *create_prompt(RTLIL::Design *design, int recursion_counter) return buffer; } +void rewrite_filename(std::string &filename) +{ + if (filename.substr(0, 1) == "\"" && filename.substr(GetSize(filename)-1) == "\"") + filename = filename.substr(1, GetSize(filename)-2); + if (filename.substr(0, 2) == "+/") + filename = proc_share_dirname() + filename.substr(2); +} + #ifdef YOSYS_ENABLE_TCL static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *argv[]) { diff --git a/kernel/yosys.h b/kernel/yosys.h index 231dd4de6..e442c3e2e 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -204,7 +204,7 @@ void yosys_banner(); std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2)); std::string vstringf(const char *fmt, va_list ap); int readsome(std::istream &f, char *s, int n); -std::string next_token(std::string &text, const char *sep = " \t\r\n"); +std::string next_token(std::string &text, const char *sep = " \t\r\n", bool long_strings = false); bool patmatch(const char *pattern, const char *string); int run_command(const std::string &command, std::function process_line = std::function()); std::string make_temp_file(std::string template_str = "/tmp/yosys_XXXXXX"); @@ -254,6 +254,7 @@ RTLIL::Design *yosys_get_design(); std::string proc_self_dirname(); std::string proc_share_dirname(); const char *create_prompt(RTLIL::Design *design, int recursion_counter); +void rewrite_filename(std::string &filename); void run_pass(std::string command, RTLIL::Design *design = nullptr); void run_frontend(std::string filename, std::string command, std::string *backend_command, std::string *from_to_label = nullptr, RTLIL::Design *design = nullptr); diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index e4ad1f37d..a82625696 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -32,19 +32,14 @@ struct setunset_t setunset_t(std::string unset_name) : name(RTLIL::escape_id(unset_name)), value(), unset(true) { } - setunset_t(std::string set_name, std::vector args, size_t &argidx) : name(RTLIL::escape_id(set_name)), value(), unset(false) + setunset_t(std::string set_name, std::string set_value) : name(RTLIL::escape_id(set_name)), value(), unset(false) { - if (!args[argidx].empty() && args[argidx][0] == '"') { - std::string str = args[argidx++].substr(1); - while (str.size() != 0 && str[str.size()-1] != '"' && argidx < args.size()) - str += args[argidx++]; - if (str.size() != 0 && str[str.size()-1] == '"') - str = str.substr(0, str.size()-1); - value = RTLIL::Const(str); + if (set_value.substr(0, 1) == "\"" && set_value.substr(GetSize(set_value)-1) == "\"") { + value = RTLIL::Const(set_value.substr(1, GetSize(set_value)-2)); } else { RTLIL::SigSpec sig_value; - if (!RTLIL::SigSpec::parse(sig_value, NULL, args[argidx++])) - log_cmd_error("Can't decode value '%s'!\n", args[argidx-1].c_str()); + if (!RTLIL::SigSpec::parse(sig_value, NULL, set_value)) + log_cmd_error("Can't decode value '%s'!\n", set_value.c_str()); value = sig_value.as_const(); } } @@ -84,9 +79,9 @@ struct SetattrPass : public Pass { { std::string arg = args[argidx]; if (arg == "-set" && argidx+2 < args.size()) { - argidx += 2; - setunset_list.push_back(setunset_t(args[argidx-1], args, argidx)); - argidx--; + string set_key = args[++argidx]; + string set_val = args[++argidx]; + setunset_list.push_back(setunset_t(set_key, set_val)); continue; } if (arg == "-unset" && argidx+1 < args.size()) { @@ -154,9 +149,9 @@ struct SetparamPass : public Pass { { std::string arg = args[argidx]; if (arg == "-set" && argidx+2 < args.size()) { - argidx += 2; - setunset_list.push_back(setunset_t(args[argidx-1], args, argidx)); - argidx--; + string set_key = args[++argidx]; + string set_val = args[++argidx]; + setunset_list.push_back(setunset_t(set_key, set_val)); continue; } if (arg == "-unset" && argidx+1 < args.size()) { @@ -209,10 +204,9 @@ struct ChparamPass : public Pass { { std::string arg = args[argidx]; if (arg == "-set" && argidx+2 < args.size()) { - argidx += 2; - setunset_t new_param(args[argidx-1], args, argidx); - new_parameters[new_param.name] = new_param.value; - argidx--; + string set_key = args[++argidx]; + string set_val = args[++argidx]; + setunset_list.push_back(setunset_t(set_key, set_val)); continue; } if (arg == "-list") { diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index e651a977b..d6c74ee6e 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -320,9 +320,7 @@ struct rules_t void parse(string filename) { - if (filename.substr(0, 2) == "+/") - filename = proc_share_dirname() + filename.substr(1); - + rewrite_filename(filename); infile.open(filename); linecount = 0; diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index ff99040e1..27689663e 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -607,6 +607,7 @@ struct ExtractPass : public Pass { else { std::ifstream f; + rewrite_filename(filename); f.open(filename.c_str()); if (f.fail()) { delete map; @@ -746,6 +747,7 @@ struct ExtractPass : public Pass { } std::ofstream f; + rewrite_filename(mine_outfile); f.open(mine_outfile.c_str(), std::ofstream::trunc); if (f.fail()) log_error("Can't open output file `%s'.\n", mine_outfile.c_str()); diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index bc86571b8..aea7ef1be 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -951,10 +951,7 @@ struct TechmapPass : public Pass { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-map" && argidx+1 < args.size()) { - if (args[argidx+1].substr(0, 2) == "+/") - map_files.push_back(proc_share_dirname() + args[++argidx].substr(2)); - else - map_files.push_back(args[++argidx]); + map_files.push_back(args[++argidx]); continue; } if (args[argidx] == "-max_iter" && argidx+1 < args.size()) { @@ -1005,6 +1002,7 @@ struct TechmapPass : public Pass { map->add(mod->clone()); } else { std::ifstream f; + rewrite_filename(fn); f.open(fn.c_str()); if (f.fail()) log_cmd_error("Can't open map file `%s'\n", fn.c_str()); -- 2.30.2