From 10458ef654d81983e17309dd151e55a6bde7b884 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Tue, 17 Mar 2015 16:00:51 +0000 Subject: [PATCH] first try at implementing GetExecutableName() --- Common/GmshMessage.cpp | 8 ++-- Common/OS.cpp | 101 +++++++++++++++++++++++++++++++++++++++++ Common/OS.h | 1 + Common/StringUtils.cpp | 3 +- 4 files changed, 108 insertions(+), 5 deletions(-) diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp index bb446163a9..93a99b7a01 100644 --- a/Common/GmshMessage.cpp +++ b/Common/GmshMessage.cpp @@ -99,19 +99,19 @@ static int vsnprintf(char *str, size_t size, const char *fmt, va_list ap) static void addGmshPathToEnvironmentVar(const std::string &name) { - std::vector<std::string> split = SplitFileName(CTX::instance()->argv0); + std::string gmshPath = SplitFileName(GetExecutableName(CTX::instance()->argv0))[0]; std::string path; char *tmp = getenv(name.c_str()); if(tmp){ path = tmp; #if defined(WIN32) - path += ";" + split[0]; + path += ";" + gmshPath; #else - path += ":" + split[0]; + path += ":" + gmshPath; #endif } else - path = split[0]; + path = gmshPath; SetEnvironmentVar(name.c_str(), path.c_str()); } diff --git a/Common/OS.cpp b/Common/OS.cpp index e76f54e8ec..2dcda6c82a 100644 --- a/Common/OS.cpp +++ b/Common/OS.cpp @@ -20,6 +20,7 @@ #if defined(__APPLE__) #include <sys/sysctl.h> +#include <mach-o/dyld.h> #endif #if defined(__linux__) && !defined(BUILD_ANDROID) @@ -143,6 +144,68 @@ static unsigned utf8toUtf16(const char* src, unsigned srclen, return count; } +static unsigned utf8FromUtf16(char* dst, unsigned dstlen, + const wchar_t* src, unsigned srclen) +{ + unsigned i = 0; + unsigned count = 0; + if (dstlen) { + for (;;) { + unsigned ucs; + if (i >= srclen) {dst[count] = 0; return count;} + ucs = src[i++]; + if (ucs < 0x80U) { + dst[count++] = ucs; + if (count >= dstlen) {dst[count-1] = 0; break;} + } + else if (ucs < 0x800U) { /* 2 bytes */ + if (count+2 >= dstlen) {dst[count] = 0; count += 2; break;} + dst[count++] = 0xc0 | (ucs >> 6); + dst[count++] = 0x80 | (ucs & 0x3F); + } + else if (ucs >= 0xd800 && ucs <= 0xdbff && i < srclen && + src[i] >= 0xdc00 && src[i] <= 0xdfff) { + /* surrogate pair */ + unsigned ucs2 = src[i++]; + ucs = 0x10000U + ((ucs&0x3ff)<<10) + (ucs2&0x3ff); + /* all surrogate pairs turn into 4-byte utf8 */ + if (count+4 >= dstlen) {dst[count] = 0; count += 4; break;} + dst[count++] = 0xf0 | (ucs >> 18); + dst[count++] = 0x80 | ((ucs >> 12) & 0x3F); + dst[count++] = 0x80 | ((ucs >> 6) & 0x3F); + dst[count++] = 0x80 | (ucs & 0x3F); + } + else { + /* all others are 3 bytes: */ + if (count+3 >= dstlen) {dst[count] = 0; count += 3; break;} + dst[count++] = 0xe0 | (ucs >> 12); + dst[count++] = 0x80 | ((ucs >> 6) & 0x3F); + dst[count++] = 0x80 | (ucs & 0x3F); + } + } + } + /* we filled dst, measure the rest: */ + while (i < srclen) { + unsigned ucs = src[i++]; + if (ucs < 0x80U) { + count++; + } + else if (ucs < 0x800U) { /* 2 bytes */ + count += 2; + } + else if (ucs >= 0xd800 && ucs <= 0xdbff && i < srclen-1 && + src[i+1] >= 0xdc00 && src[i+1] <= 0xdfff) { + /* surrogate pair */ + ++i; + count += 4; + } + else { + count += 3; + } + } + return count; +} + static wchar_t *wbuf[3] = {NULL, NULL, NULL}; static void setwbuf(int i, const char *f) @@ -312,6 +375,44 @@ int GetProcessId() #endif } +std::string GetExecutableName(const std::string &argv0) +{ + std::string name = ""; +#if defined(WIN32) && !defined(__CYGWIN__) + WCHAR src[MAX_PATH]; + DWARD size = GetModuleFileNameW(NULL, src, MAX_PATH); + if(size){ + char dst[MAX_PATH]; + utf8FromUtf16(dst, MAX_PATH, src, size); + name = std::string(dst); + } +#elif defined(__APPLE__) + char path[PATH_MAX]; + uint32_t size = sizeof(path); + if (_NSGetExecutablePath(path, &size) == 0){ + char real[PATH_MAX]; + if(realpath(path, real)){ + name = std::string(real); + } + } +#elif defined(__linux__) + char path[PATH_MAX]; + int s = readlink("/proc/self/exe", path, sizeof(path)); + if(s > 0){ + path[s - 1] = '\0'; + name = std::string(path); + } +#endif + if(name.empty()){ + name = argv0; + printf("Found executable name through argv0 = '%s'\n", name.c_str()); + } + else + printf("Found executable name = '%s'\n", name.c_str()); + + return name; +} + std::string GetHostName() { char host[256]; diff --git a/Common/OS.h b/Common/OS.h index 72f5238372..6290b76522 100644 --- a/Common/OS.h +++ b/Common/OS.h @@ -18,6 +18,7 @@ double Cpu(); double TotalRam(); long GetMemoryUsage(); int GetProcessId(); +std::string GetExecutableName(const std::string &argv0); std::string GetHostName(); int UnlinkFile(const std::string &fileName); int StatFile(const std::string &fileName); diff --git a/Common/StringUtils.cpp b/Common/StringUtils.cpp index 8378af230c..50c15ee46d 100644 --- a/Common/StringUtils.cpp +++ b/Common/StringUtils.cpp @@ -91,7 +91,8 @@ std::string FixRelativePath(const std::string &reference, const std::string &in) std::vector<std::string> SplitFileName(const std::string &fileName) { - // JFR DO NOT CHANGE TO std::vector<std::string> s(3), it segfaults while destructor si called + // JFR DO NOT CHANGE TO std::vector<std::string> s(3), it segfaults while + // destructor si called std::vector<std::string> s; s.resize(3); if(fileName.size()){ // returns [path, baseName, extension] -- GitLab