aboutsummaryrefslogtreecommitdiffstats
path: root/icetime/iceutil.cc
diff options
context:
space:
mode:
Diffstat (limited to 'icetime/iceutil.cc')
-rw-r--r--icetime/iceutil.cc179
1 files changed, 179 insertions, 0 deletions
diff --git a/icetime/iceutil.cc b/icetime/iceutil.cc
new file mode 100644
index 0000000..ad8d662
--- /dev/null
+++ b/icetime/iceutil.cc
@@ -0,0 +1,179 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include <errno.h>
+#include <string>
+#include <sstream>
+#include <cstring>
+
+#ifdef _WIN32
+# include <windows.h>
+# include <io.h>
+#elif defined(__APPLE__)
+# include <mach-o/dyld.h>
+# include <unistd.h>
+#else
+# include <unistd.h>
+#endif
+
+#ifdef __FreeBSD__
+# include <sys/sysctl.h>
+#endif
+
+#include <limits.h>
+
+#if defined(__linux__) || defined(__CYGWIN__)
+std::string proc_self_dirname()
+{
+ char path[PATH_MAX];
+ ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path));
+ if (buflen < 0) {
+ fprintf(stderr, "fatal error: readlink(\"/proc/self/exe\") failed: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ while (buflen > 0 && path[buflen-1] != '/')
+ buflen--;
+ return std::string(path, buflen);
+}
+#elif defined(__FreeBSD__)
+std::string proc_self_dirname()
+{
+ int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
+ size_t buflen;
+ char *buffer;
+ std::string path;
+ if (sysctl(mib, 4, NULL, &buflen, NULL, 0) != 0) {
+ fprintf(stderr, "fatal error: sysctl failed: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ buffer = (char*)malloc(buflen);
+ if (buffer == NULL) {
+ fprintf(stderr, "fatal error: malloc failed: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ if (sysctl(mib, 4, buffer, &buflen, NULL, 0) != 0) {
+ fprintf(stderr, "fatal error: sysctl failed: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ while (buflen > 0 && buffer[buflen-1] != '/')
+ buflen--;
+ path.assign(buffer, buflen);
+ free(buffer);
+ return path;
+}
+#elif defined(__APPLE__)
+std::string proc_self_dirname()
+{
+ char *path = NULL;
+ uint32_t buflen = 0;
+ while (_NSGetExecutablePath(path, &buflen) != 0)
+ path = (char *) realloc((void *) path, buflen);
+ while (buflen > 0 && path[buflen-1] != '/')
+ buflen--;
+ return std::string(path, buflen);
+}
+#elif defined(_WIN32)
+std::string proc_self_dirname()
+{
+ int i = 0;
+# ifdef __MINGW32__
+ char longpath[MAX_PATH + 1];
+ char shortpath[MAX_PATH + 1];
+# else
+ WCHAR longpath[MAX_PATH + 1];
+ TCHAR shortpath[MAX_PATH + 1];
+# endif
+ if (!GetModuleFileName(0, longpath, MAX_PATH+1)) {
+ fprintf(stderr, "fatal error: GetModuleFileName() failed.\n");
+ exit(EXIT_FAILURE);
+ }
+ if (!GetShortPathName(longpath, shortpath, MAX_PATH+1)) {
+ fprintf(stderr, "fatal error: GetShortPathName() failed.\n");
+ exit(EXIT_FAILURE);
+ }
+ while (shortpath[i] != 0)
+ i++;
+ while (i > 0 && shortpath[i-1] != '/' && shortpath[i-1] != '\\')
+ shortpath[--i] = 0;
+ std::string path;
+ for (i = 0; shortpath[i]; i++)
+ path += char(shortpath[i]);
+ return path;
+}
+#elif defined(EMSCRIPTEN)
+std::string proc_self_dirname()
+{
+ return "/";
+}
+#else
+ #error Dont know how to determine process executable base path!
+#endif
+
+bool file_test_open(std::string path)
+{
+ FILE *fdb = fopen(path.c_str(), "r");
+ if (fdb == nullptr) {
+ return false;
+ }
+ fclose(fdb);
+ return true;
+}
+
+extern bool verbose;
+
+std::string find_chipdb(std::string config_device)
+{
+ if (PREFIX[0] == '~' && PREFIX[1] == '/') {
+ std::string homepath;
+#ifdef _WIN32
+ if (getenv("USERPROFILE") != nullptr) {
+ homepath += getenv("USERPROFILE");
+ }
+ else {
+ if (getenv("HOMEDRIVE") != nullptr &&
+ getenv("HOMEPATH") != nullptr) {
+ homepath += getenv("HOMEDRIVE");
+ homepath += getenv("HOMEPATH");
+ }
+ }
+#else
+ homepath += getenv("HOME");
+#endif
+ homepath += std::string(PREFIX + 1) + "/" CHIPDB_SUBDIR "/chipdb-" + config_device + ".txt";
+ if (verbose)
+ fprintf(stderr, "Looking for chipdb '%s' at %s\n", config_device.c_str(), homepath.c_str());
+ if (file_test_open(homepath))
+ return homepath;
+ }
+
+ std::string prefixpath = PREFIX "/share/" CHIPDB_SUBDIR "/chipdb-" + config_device + ".txt";
+ if (verbose)
+ fprintf(stderr, "Looking for chipdb '%s' at %s\n", config_device.c_str(), prefixpath.c_str());
+ if (file_test_open(prefixpath))
+ return prefixpath;
+
+ std::string relbinarypath = proc_self_dirname() + "../share/" CHIPDB_SUBDIR "/chipdb-" + config_device + ".txt";
+ if (verbose)
+ fprintf(stderr, "Looking for chipdb '%s' at %s\n", config_device.c_str(), relbinarypath.c_str());
+ if (file_test_open(relbinarypath))
+ return relbinarypath;
+
+ return "";
+}
+