From: Clifford Wolf Date: Sun, 12 Oct 2014 10:11:57 +0000 (+0200) Subject: Added make_temp_{file,dir}() and remove_directory() APIs X-Git-Tag: yosys-0.4~59 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0b9282a779867459fe5babfff300795c343c46ea;p=yosys.git Added make_temp_{file,dir}() and remove_directory() APIs --- diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 3895ecfd2..39b4f1496 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -120,15 +120,8 @@ struct Vhdl2verilogPass : public Pass { if (top_entity.empty()) log_cmd_error("Missing -top option.\n"); -#ifdef _WIN32 - #warning Fixme: The vhdl2veriog command has not been ported to win32. - log_cmd_error("The vhdl2veriog command has not been ported to win32.\n"); -#else - char tempdir_name[] = "/tmp/yosys-vhdl2verilog-XXXXXX"; - char *p = mkdtemp(tempdir_name); - log("Using temp directory %s.\n", tempdir_name); - if (p == NULL) - log_error("For some reason mkdtemp() failed!\n"); + std::string tempdir_name = make_temp_dir("/tmp/yosys-vhdl2verilog-XXXXXX"); + log("Using temp directory %s.\n", tempdir_name.c_str()); if (!out_file.empty() && out_file[0] != '/') { char pwd[PATH_MAX]; @@ -139,7 +132,7 @@ struct Vhdl2verilogPass : public Pass { out_file = pwd + ("/" + out_file); } - FILE *f = fopen(stringf("%s/files.list", tempdir_name).c_str(), "wt"); + FILE *f = fopen(stringf("%s/files.list", tempdir_name.c_str()).c_str(), "wt"); while (argidx < args.size()) { std::string file = args[argidx++]; if (file.empty()) @@ -160,7 +153,7 @@ struct Vhdl2verilogPass : public Pass { std::string command = "exec 2>&1; "; if (!vhdl2verilog_dir.empty()) command += stringf("cd '%s'; . ./setup_env.sh; ", vhdl2verilog_dir.c_str()); - command += stringf("cd '%s'; vhdl2verilog -out '%s' -filelist files.list -top '%s'%s", tempdir_name, + command += stringf("cd '%s'; vhdl2verilog -out '%s' -filelist files.list -top '%s'%s", tempdir_name.c_str(), out_file.empty() ? "vhdl2verilog_output.v" : out_file.c_str(), top_entity.c_str(), extra_opts.c_str()); log("Running '%s'..\n", command.c_str()); @@ -171,18 +164,15 @@ struct Vhdl2verilogPass : public Pass { if (out_file.empty()) { std::ifstream ff; - ff.open(stringf("%s/vhdl2verilog_output.v", tempdir_name).c_str()); + ff.open(stringf("%s/vhdl2verilog_output.v", tempdir_name.c_str()).c_str()); if (ff.fail()) log_error("Can't open vhdl2verilog output file `vhdl2verilog_output.v'.\n"); - Frontend::frontend_call(design, &ff, stringf("%s/vhdl2verilog_output.v", tempdir_name), "verilog"); + Frontend::frontend_call(design, &ff, stringf("%s/vhdl2verilog_output.v", tempdir_name.c_str()), "verilog"); } - log_header("Removing temp directory `%s':\n", tempdir_name); - if (run_command(stringf("rm -rf '%s'", tempdir_name).c_str()) != 0) - log_error("Execution of \"rm -rf '%s'\" failed!\n", tempdir_name); - + log_header("Removing temp directory `%s':\n", tempdir_name.c_str()); + remove_directory(tempdir_name); log_pop(); -#endif } } Vhdl2verilogPass; diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 50da13ae7..4af3ff9c0 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -34,6 +34,7 @@ #include #include +#include #include YOSYS_NAMESPACE_BEGIN @@ -204,7 +205,96 @@ int run_command(const std::string &command, std::function> 17, x ^= x << 5; + template_str[pos+i] = y[x % y.size()]; + } + if (access(template_str.c_str(), F_OK) != 0) + break; + } +#else + size_t pos = template_str.rfind("XXXXXX"); + log_assert(pos != std::string::npos); + + int suffixlen = GetSize(template_str) - pos - 6; + + char *p = strdup(template_str.c_str()); + close(mkstemps(p, suffixlen)); + template_str = p; + free(p); +#endif + + return template_str; +} + +std::string make_temp_dir(std::string template_str) +{ +#ifdef _WIN32 + template_str = make_temp_file(template_str); + mkdir(template_str.c_str()); + return template_str; +#else + size_t pos = template_str.rfind("XXXXXX"); + log_assert(pos != std::string::npos); + + int suffixlen = GetSize(template_str) - pos - 6; + log_assert(suffixlen == 0); + + char *p = strdup(template_str.c_str()); + mkdtemp(p, suffixlen); + template_str = p; + free(p); + + return template_str; +#endif +} + +void remove_directory(std::string dirname) +{ +#ifdef _WIN32 + run_command(stringf("rmdir /s /q \"%s\"", dirname.c_str())); +#else + struct stat stbuf; + struct dirent **namelist; + int n = scandir(dirname.c_str(), &namelist, nullptr, alphasort); + log_assert(n >= 0); + for (int i = 0; i < n; i++) { + if (strcmp(namelist[i]->d_name, ".") && strcmp(namelist[i]->d_name, "..")) { + buffer = stringf("%s/%s", dirname.c_str(), namelist[i]->d_name); + if (!stat(buffer.c_str(), &stbuf) && S_ISREG(stbuf.st_mode)) { + log("Removing `%s'.\n", buffer.c_str()); + remove(buffer.c_str()); + } else + remove_directory(buffer); + } + free(namelist[i]); + } + free(namelist); + log("Removing `%s'.\n", dirname.c_str()); + rmdir(dirname.c_str()); +#endif } int GetSize(RTLIL::Wire *wire) diff --git a/kernel/yosys.h b/kernel/yosys.h index fcf60f9f1..e579e90d9 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -88,6 +88,9 @@ std::string next_token(std::string &text, const char *sep); bool patmatch(const char *pattern, const char *string); int readsome(std::istream &f, char *s, int n); 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"); +std::string make_temp_dir(std::string template_str = "/tmp/yosys_XXXXXX"); +void remove_directory(std::string dirname); template int GetSize(const T &obj) { return obj.size(); } int GetSize(RTLIL::Wire *wire); diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 82ebead71..c63867068 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -553,13 +553,11 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin clk_polarity = true; clk_sig = RTLIL::SigSpec(); - char tempdir_name[] = "/tmp/yosys-abc-XXXXXX"; + std::string tempdir_name = "/tmp/yosys-abc-XXXXXX"; if (!cleanup) tempdir_name[0] = tempdir_name[4] = '_'; - char *p = mkdtemp(tempdir_name); - log_header("Extracting gate netlist of module `%s' to `%s/input.blif'..\n", module->name.c_str(), tempdir_name); - if (p == NULL) - log_error("For some reason mkdtemp() failed!\n"); + tempdir_name = make_temp_dir(tempdir_name); + log_header("Extracting gate netlist of module `%s' to `%s/input.blif'..\n", module->name.c_str(), tempdir_name.c_str()); std::string abc_command; if (!script_file.empty()) { @@ -589,10 +587,10 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin for (size_t i = 0; i+1 < abc_command.size(); i++) if (abc_command[i] == ';' && abc_command[i+1] == ' ') abc_command[i+1] = '\n'; - FILE *f = fopen(stringf("%s/abc.script", tempdir_name).c_str(), "wt"); + FILE *f = fopen(stringf("%s/abc.script", tempdir_name.c_str()).c_str(), "wt"); fprintf(f, "%s\n", abc_command.c_str()); fclose(f); - abc_command = stringf("source %s/abc.script", tempdir_name); + abc_command = stringf("source %s/abc.script", tempdir_name.c_str()); } if (clk_str.empty()) { @@ -653,7 +651,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin handle_loops(); - std::string buffer = stringf("%s/input.blif", tempdir_name); + std::string buffer = stringf("%s/input.blif", tempdir_name.c_str()); FILE *f = fopen(buffer.c_str(), "wt"); if (f == NULL) log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); @@ -764,7 +762,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin { log_header("Executing ABC.\n"); - buffer = stringf("%s/stdcells.genlib", tempdir_name); + buffer = stringf("%s/stdcells.genlib", tempdir_name.c_str()); f = fopen(buffer.c_str(), "wt"); if (f == NULL) log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); @@ -786,7 +784,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin fclose(f); if (lut_mode) { - buffer = stringf("%s/lutdefs.txt", tempdir_name); + buffer = stringf("%s/lutdefs.txt", tempdir_name.c_str()); f = fopen(buffer.c_str(), "wt"); if (f == NULL) log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); @@ -798,18 +796,18 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin buffer = stringf("%s -s -c '", exe_file.c_str()); if (!liberty_file.empty()) { buffer += stringf("read_blif %s/input.blif; read_lib -w %s; ", - tempdir_name, liberty_file.c_str()); + tempdir_name.c_str(), liberty_file.c_str()); if (!constr_file.empty()) buffer += stringf("read_constr -v %s; ", constr_file.c_str()); buffer += abc_command + "; "; } else if (lut_mode) buffer += stringf("read_blif %s/input.blif; read_lut %s/lutdefs.txt; %s; ", - tempdir_name, tempdir_name, abc_command.c_str()); + tempdir_name.c_str(), tempdir_name.c_str(), abc_command.c_str()); else buffer += stringf("read_blif %s/input.blif; read_library %s/stdcells.genlib; %s; ", - tempdir_name, tempdir_name, abc_command.c_str()); - buffer += stringf("write_blif %s/output.blif' 2>&1", tempdir_name); + tempdir_name.c_str(), tempdir_name.c_str(), abc_command.c_str()); + buffer += stringf("write_blif %s/output.blif' 2>&1", tempdir_name.c_str()); log("%s\n", buffer.c_str()); @@ -818,7 +816,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin if (ret != 0) log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret); - buffer = stringf("%s/%s", tempdir_name, "output.blif"); + buffer = stringf("%s/%s", tempdir_name.c_str(), "output.blif"); f = fopen(buffer.c_str(), "rt"); if (f == NULL) log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); @@ -991,22 +989,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin if (cleanup) { - log_header("Removing temp directory `%s':\n", tempdir_name); - - struct dirent **namelist; - int n = scandir(tempdir_name, &namelist, 0, alphasort); - log_assert(n >= 0); - for (int i = 0; i < n; i++) { - if (strcmp(namelist[i]->d_name, ".") && strcmp(namelist[i]->d_name, "..")) { - buffer = stringf("%s/%s", tempdir_name, namelist[i]->d_name); - log("Removing `%s'.\n", buffer.c_str()); - remove(buffer.c_str()); - } - free(namelist[i]); - } - free(namelist); - log("Removing `%s'.\n", tempdir_name); - rmdir(tempdir_name); + log_header("Removing temp directory `%s':\n", tempdir_name.c_str()); + remove_directory(tempdir_name); } log_pop();