diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp index bb446163a9f67a6eee78d90a6658b4c812407558..93a99b7a01ae422ee4fc4653dc5e95afc45fbef2 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 e76f54e8ec954267b9863dd00e5dc8f5a4b967e4..2dcda6c82a830c774231e66e28ff8ca39005ef5b 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 72f5238372c2f70202d4f5c4fef2a67f52ff03d3..6290b7652294111156c1aeaeb441e2fd7d9d9f2a 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 8378af230c7e795c4b468334425dcb5b47b5afd8..50c15ee46d600a20f6b9a34a9a78c1a49b97e430 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]