From f50e8a3c1baaff8cb3c6055a2b18caab8ce904e3 Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Thu, 21 Dec 2023 21:44:02 +0300 Subject: [PATCH 1/9] Follow the XDG Base Directory Specification --- kernel/driver.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index c779611e097..c1995e7f7fc 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -244,7 +244,11 @@ int main(int argc, char **argv) bool mode_q = false; #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) - if (getenv("HOME") != NULL) { + if (getenv("XDG_DATA_HOME") != NULL && getenv("XDG_DATA_HOME")[0] != '\0') { + yosys_history_file = stringf("%s/yosys/.yosys_history", getenv("XDG_DATA_HOME")); + read_history(yosys_history_file.c_str()); + yosys_history_offset = where_history(); + } else if (getenv("HOME") != NULL) { yosys_history_file = stringf("%s/.yosys_history", getenv("HOME")); read_history(yosys_history_file.c_str()); yosys_history_offset = where_history(); From 31b45c9555752070c7a8909ade46a95093979188 Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Sun, 7 Jan 2024 14:17:48 +0300 Subject: [PATCH 2/9] fix: xdg spec for hist --- kernel/driver.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index c1995e7f7fc..eda90745a21 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -244,15 +244,13 @@ int main(int argc, char **argv) bool mode_q = false; #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) - if (getenv("XDG_DATA_HOME") != NULL && getenv("XDG_DATA_HOME")[0] != '\0') { - yosys_history_file = stringf("%s/yosys/.yosys_history", getenv("XDG_DATA_HOME")); - read_history(yosys_history_file.c_str()); - yosys_history_offset = where_history(); - } else if (getenv("HOME") != NULL) { - yosys_history_file = stringf("%s/.yosys_history", getenv("HOME")); - read_history(yosys_history_file.c_str()); - yosys_history_offset = where_history(); + if (getenv("XDG_STATE_HOME") != NULL && getenv("XDG_STATE_HOME")[0] != '\0') { + yosys_history_file = stringf("%s/.local/state/.yosys_history", getenv("HOME")); + } else { + yosys_history_file = stringf("%s/.yosys_history", getenv("XDG_STATE_HOME")); } + read_history(yosys_history_file.c_str()); + yosys_history_offset = where_history(); #endif if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-help") || !strcmp(argv[1], "--help"))) From 54c3b63d241d9da6acfdcb4bcd1a1bb2387090eb Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Sun, 7 Jan 2024 14:34:27 +0300 Subject: [PATCH 3/9] fix: third time is the charm --- kernel/driver.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index eda90745a21..503899d302d 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -244,8 +244,10 @@ int main(int argc, char **argv) bool mode_q = false; #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) - if (getenv("XDG_STATE_HOME") != NULL && getenv("XDG_STATE_HOME")[0] != '\0') { - yosys_history_file = stringf("%s/.local/state/.yosys_history", getenv("HOME")); + if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { + if (getenv("HOME") != NULL) { + yosys_history_file = stringf("%s/.local/state/.yosys_history", getenv("HOME")); + } } else { yosys_history_file = stringf("%s/.yosys_history", getenv("XDG_STATE_HOME")); } From e093f57c1075104df8135df1c04f4d134d5a7db6 Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Mon, 8 Jan 2024 08:49:04 +0300 Subject: [PATCH 4/9] fix: fail if neither HOME nor XDG_STATE_HOME are set --- kernel/driver.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 503899d302d..3a5e49cb451 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -247,12 +247,14 @@ int main(int argc, char **argv) if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { if (getenv("HOME") != NULL) { yosys_history_file = stringf("%s/.local/state/.yosys_history", getenv("HOME")); + read_history(yosys_history_file.c_str()); + yosys_history_offset = where_history(); } } else { yosys_history_file = stringf("%s/.yosys_history", getenv("XDG_STATE_HOME")); + read_history(yosys_history_file.c_str()); + yosys_history_offset = where_history(); } - read_history(yosys_history_file.c_str()); - yosys_history_offset = where_history(); #endif if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-help") || !strcmp(argv[1], "--help"))) From 039634d9737dd7198d21e534b386203aebf0750a Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Wed, 31 Jan 2024 01:03:01 +0300 Subject: [PATCH 5/9] feat: mkdir with tree --- kernel/driver.cc | 101 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 9 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 3a5e49cb451..ee30c2b27f3 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -53,6 +53,78 @@ # include #endif +#include // _stat +#include // errno, ENOENT, EEXIST +#if defined(_WIN32) +# include +# define mkdir(path, mode) _mkdir(path) +# define PATH_DELIMETER "\\" +#else +# define PATH_DELIMETER "/" +#endif + + + +bool isDirExist(const std::string& path) +{ +#if defined(_WIN32) + struct _stat info; + if (_stat(path.c_str(), &info) != 0) + { + return false; + } + return (info.st_mode & _S_IFDIR) != 0; +#else + struct stat info; + if (stat(path.c_str(), &info) != 0) + { + return false; + } + return (info.st_mode & S_IFDIR) != 0; +#endif +} +bool makePath(const std::string& path) +{ +#if defined(_WIN32) + int ret = _mkdir(path.c_str()); +#else + mode_t mode = 0755; + int ret = mkdir(path.c_str(), mode); +#endif + if (ret == 0) + return true; + + switch (errno) + { + case ENOENT: + // parent didn't exist, try to create it + { + int pos = path.find_last_of('/'); + if (pos == std::string::npos) +#if defined(_WIN32) + pos = path.find_last_of('\\'); + if (pos == std::string::npos) +#endif + return false; + if (!makePath( path.substr(0, pos) )) + return false; + } + // now, try to create again +#if defined(_WIN32) + return 0 == _mkdir(path.c_str()); +#else + return 0 == mkdir(path.c_str(), mode); +#endif + + case EEXIST: + // done! + return isDirExist(path); + + default: + return false; + } +} + USING_YOSYS_NAMESPACE char *optarg; @@ -244,16 +316,27 @@ int main(int argc, char **argv) bool mode_q = false; #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) - if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { - if (getenv("HOME") != NULL) { - yosys_history_file = stringf("%s/.local/state/.yosys_history", getenv("HOME")); - read_history(yosys_history_file.c_str()); - yosys_history_offset = where_history(); + std::string state_dir; + if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { + if (getenv("HOME") != NULL) { + state_dir = stringf("%s/.local/state", getenv("HOME")); + }else { + log("$HOME is empty. No history file will be created."); } - } else { - yosys_history_file = stringf("%s/.yosys_history", getenv("XDG_STATE_HOME")); - read_history(yosys_history_file.c_str()); - yosys_history_offset = where_history(); + } else { + state_dir = stringf("%s", getenv("XDG_STATE_HOME")); + } + + if (!state_dir.empty()) { + std::string yosys_dir = state_dir + "/yosys"; + // mkdir(yosys_dir.c_str(), 0777); + makePath(yosys_dir); + + yosys_history_file = yosys_dir + "/history"; + read_history(yosys_history_file.c_str()); + yosys_history_offset = where_history(); + }else { + log("state_dir is empty. No history file will be created."); } #endif From 820232eacaa88e81be044a90dcc3b96e411dea8c Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Wed, 31 Jan 2024 19:50:31 +0300 Subject: [PATCH 6/9] fix: function naming and locations --- kernel/driver.cc | 75 +----------------------------------------------- kernel/yosys.cc | 65 +++++++++++++++++++++++++++++++++++++++-- kernel/yosys.h | 4 +++ 3 files changed, 68 insertions(+), 76 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index ee30c2b27f3..5f105ea0328 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -53,78 +53,6 @@ # include #endif -#include // _stat -#include // errno, ENOENT, EEXIST -#if defined(_WIN32) -# include -# define mkdir(path, mode) _mkdir(path) -# define PATH_DELIMETER "\\" -#else -# define PATH_DELIMETER "/" -#endif - - - -bool isDirExist(const std::string& path) -{ -#if defined(_WIN32) - struct _stat info; - if (_stat(path.c_str(), &info) != 0) - { - return false; - } - return (info.st_mode & _S_IFDIR) != 0; -#else - struct stat info; - if (stat(path.c_str(), &info) != 0) - { - return false; - } - return (info.st_mode & S_IFDIR) != 0; -#endif -} -bool makePath(const std::string& path) -{ -#if defined(_WIN32) - int ret = _mkdir(path.c_str()); -#else - mode_t mode = 0755; - int ret = mkdir(path.c_str(), mode); -#endif - if (ret == 0) - return true; - - switch (errno) - { - case ENOENT: - // parent didn't exist, try to create it - { - int pos = path.find_last_of('/'); - if (pos == std::string::npos) -#if defined(_WIN32) - pos = path.find_last_of('\\'); - if (pos == std::string::npos) -#endif - return false; - if (!makePath( path.substr(0, pos) )) - return false; - } - // now, try to create again -#if defined(_WIN32) - return 0 == _mkdir(path.c_str()); -#else - return 0 == mkdir(path.c_str(), mode); -#endif - - case EEXIST: - // done! - return isDirExist(path); - - default: - return false; - } -} - USING_YOSYS_NAMESPACE char *optarg; @@ -329,8 +257,7 @@ int main(int argc, char **argv) if (!state_dir.empty()) { std::string yosys_dir = state_dir + "/yosys"; - // mkdir(yosys_dir.c_str(), 0777); - makePath(yosys_dir); + create_directory(yosys_dir); yosys_history_file = yosys_dir + "/history"; read_history(yosys_history_file.c_str()); diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 4409dc91ddd..0362bc1eb87 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -436,6 +436,25 @@ std::string make_temp_dir(std::string template_str) #endif } +bool check_dir_exists(const std::string& path) +{ +#if defined(_WIN32) + struct _stat info; + if (_stat(path.c_str(), &info) != 0) + { + return false; + } + return (info.st_mode & _S_IFDIR) != 0; +#else + struct stat info; + if (stat(path.c_str(), &info) != 0) + { + return false; + } + return (info.st_mode & S_IFDIR) != 0; +#endif +} + #ifdef _WIN32 bool check_file_exists(std::string filename, bool) { @@ -481,6 +500,48 @@ void remove_directory(std::string dirname) #endif } +bool create_directory(const std::string& path) +{ +#if defined(_WIN32) + int ret = _mkdir(path.c_str()); +#else + mode_t mode = 0755; + int ret = mkdir(path.c_str(), mode); +#endif + if (ret == 0) + return true; + + switch (errno) + { + case ENOENT: + // parent didn't exist, try to create it + { + std::string::size_type pos = path.find_last_of('/'); + if (pos == std::string::npos) +#if defined(_WIN32) + pos = path.find_last_of('\\'); + if (pos == std::string::npos) +#endif + return false; + if (!create_directory( path.substr(0, pos) )) + return false; + } + // now, try to create again +#if defined(_WIN32) + return 0 == _mkdir(path.c_str()); +#else + return 0 == mkdir(path.c_str(), mode); +#endif + + case EEXIST: + // done! + return check_dir_exists(path); + + default: + return false; + } +} + std::string escape_filename_spaces(const std::string& filename) { std::string out; @@ -781,10 +842,10 @@ static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *a int yosys_tcl_iterp_init(Tcl_Interp *interp) { - if (Tcl_Init(interp)!=TCL_OK) + if (Tcl_Init(interp)!=TCL_OK) log_warning("Tcl_Init() call failed - %s\n",Tcl_ErrnoMsg(Tcl_GetErrno())); Tcl_CreateCommand(interp, "yosys", tcl_yosys_cmd, NULL, NULL); - return TCL_OK ; + return TCL_OK ; } void yosys_tcl_activate_repl() diff --git a/kernel/yosys.h b/kernel/yosys.h index 97a79861e15..76ad01aa985 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -66,6 +66,8 @@ #include #include #include +#include +#include #ifdef WITH_PYTHON #include @@ -341,8 +343,10 @@ std::string get_base_tmpdir(); std::string make_temp_file(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); std::string make_temp_dir(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); bool check_file_exists(std::string filename, bool is_exec = false); +bool check_dir_exists(const std::string& path); bool is_absolute_path(std::string filename); void remove_directory(std::string dirname); +bool create_directory(const std::string& path); std::string escape_filename_spaces(const std::string& filename); template int GetSize(const T &obj) { return obj.size(); } From dd5dc06863d0e9fe76ff0d2f4cffbe9869bfa92f Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Wed, 31 Jan 2024 20:14:32 +0300 Subject: [PATCH 7/9] fix: save history file on windows --- kernel/driver.cc | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 5f105ea0328..a5201464d48 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -245,26 +245,34 @@ int main(int argc, char **argv) #if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE) std::string state_dir; - if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { - if (getenv("HOME") != NULL) { - state_dir = stringf("%s/.local/state", getenv("HOME")); - }else { - log("$HOME is empty. No history file will be created."); - } - } else { - state_dir = stringf("%s", getenv("XDG_STATE_HOME")); - } + #if defined(_WIN32) + if (getenv("HOMEDRIVE") != NULL && getenv("HOMEPATH") != NULL) { + state_dir = stringf("%s%s/.local/state", getenv("HOMEDRIVE"), getenv("HOMEPATH")); + } else { + log("$HOMEDRIVE and/or $HOMEPATH is empty. No history file will be created."); + } + #else + if (getenv("XDG_STATE_HOME") == NULL || getenv("XDG_STATE_HOME")[0] == '\0') { + if (getenv("HOME") != NULL) { + state_dir = stringf("%s/.local/state", getenv("HOME")); + } else { + log("$HOME is empty. No history file will be created."); + } + } else { + state_dir = stringf("%s", getenv("XDG_STATE_HOME")); + } + #endif if (!state_dir.empty()) { std::string yosys_dir = state_dir + "/yosys"; - create_directory(yosys_dir); + create_directory(yosys_dir); yosys_history_file = yosys_dir + "/history"; read_history(yosys_history_file.c_str()); yosys_history_offset = where_history(); - }else { - log("state_dir is empty. No history file will be created."); - } + } else { + log("state_dir is empty. No history file will be created."); + } #endif if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-help") || !strcmp(argv[1], "--help"))) From c1d32886540bd22bd78646b0694a67c49f1550a5 Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Fri, 2 Feb 2024 01:25:58 +0300 Subject: [PATCH 8/9] chore: use similar variable/function names --- kernel/yosys.cc | 24 ++++++++++++------------ kernel/yosys.h | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 0362bc1eb87..c7f5bebdab7 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -436,18 +436,18 @@ std::string make_temp_dir(std::string template_str) #endif } -bool check_dir_exists(const std::string& path) +bool check_directory_exists(const std::string& dirname) { #if defined(_WIN32) struct _stat info; - if (_stat(path.c_str(), &info) != 0) + if (_stat(dirname.c_str(), &info) != 0) { return false; } return (info.st_mode & _S_IFDIR) != 0; #else struct stat info; - if (stat(path.c_str(), &info) != 0) + if (stat(dirname.c_str(), &info) != 0) { return false; } @@ -500,13 +500,13 @@ void remove_directory(std::string dirname) #endif } -bool create_directory(const std::string& path) +bool create_directory(const std::string& dirname) { #if defined(_WIN32) - int ret = _mkdir(path.c_str()); + int ret = _mkdir(dirname.c_str()); #else mode_t mode = 0755; - int ret = mkdir(path.c_str(), mode); + int ret = mkdir(dirname.c_str(), mode); #endif if (ret == 0) return true; @@ -516,26 +516,26 @@ bool create_directory(const std::string& path) case ENOENT: // parent didn't exist, try to create it { - std::string::size_type pos = path.find_last_of('/'); + std::string::size_type pos = dirname.find_last_of('/'); if (pos == std::string::npos) #if defined(_WIN32) - pos = path.find_last_of('\\'); + pos = dirname.find_last_of('\\'); if (pos == std::string::npos) #endif return false; - if (!create_directory( path.substr(0, pos) )) + if (!create_directory( dirname.substr(0, pos) )) return false; } // now, try to create again #if defined(_WIN32) - return 0 == _mkdir(path.c_str()); + return 0 == _mkdir(dirname.c_str()); #else - return 0 == mkdir(path.c_str(), mode); + return 0 == mkdir(dirname.c_str(), mode); #endif case EEXIST: // done! - return check_dir_exists(path); + return check_directory_exists(dirname); default: return false; diff --git a/kernel/yosys.h b/kernel/yosys.h index 76ad01aa985..0a4641d1819 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -343,10 +343,10 @@ std::string get_base_tmpdir(); std::string make_temp_file(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); std::string make_temp_dir(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); bool check_file_exists(std::string filename, bool is_exec = false); -bool check_dir_exists(const std::string& path); +bool check_directory_exists(const std::string& dirname); bool is_absolute_path(std::string filename); void remove_directory(std::string dirname); -bool create_directory(const std::string& path); +bool create_directory(const std::string& dirname); std::string escape_filename_spaces(const std::string& filename); template int GetSize(const T &obj) { return obj.size(); } From 7dbe288d6fafb821976f51967b6c65abd53891f7 Mon Sep 17 00:00:00 2001 From: hakan-demirli Date: Fri, 2 Feb 2024 02:39:04 +0300 Subject: [PATCH 9/9] fix: descriptive logs --- kernel/driver.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index a5201464d48..373295b1de3 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -271,7 +271,7 @@ int main(int argc, char **argv) read_history(yosys_history_file.c_str()); yosys_history_offset = where_history(); } else { - log("state_dir is empty. No history file will be created."); + log("Directory to put history file does not exist. If you are on Windows either $HOMEDRIVE or $HOMEPATH is empty."); } #endif