X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fporting.cpp;h=4c87bddee0cf0b2a65be7a047262fa68d928af46;hb=fb4815c660d6d9cfc9df76a3ba763095b9701925;hp=240ee0af0ceff4d545d4f35cc9fc51055f2db720;hpb=67ed56be3b5cc674ee9d42ccef409952b5e0c362;p=dragonfireclient.git diff --git a/src/porting.cpp b/src/porting.cpp index 240ee0af0..4c87bddee 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -25,31 +25,49 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "porting.h" -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) #include #include + extern char **environ; #elif defined(_WIN32) #include #include #include #include + #include #endif #if !defined(_WIN32) #include #include + #if !defined(__ANDROID__) + #include + #endif #endif #if defined(__hpux) #define _PSTAT64 #include #endif +#if defined(__ANDROID__) + #include "porting_android.h" +#endif +#if defined(__APPLE__) + // For _NSGetEnviron() + // Related: https://gitlab.haskell.org/ghc/ghc/issues/2458 + #include +#endif + +#if defined(__HAIKU__) + #include +#endif #include "config.h" #include "debug.h" #include "filesys.h" #include "log.h" #include "util/string.h" -#include "settings.h" #include +#include +#include namespace porting { @@ -307,6 +325,12 @@ bool getCurrentExecPath(char *buf, size_t len) return true; } +#elif defined(__HAIKU__) + +bool getCurrentExecPath(char *buf, size_t len) +{ + return find_path(B_APP_IMAGE_SYMBOL, B_FIND_PATH_IMAGE_PATH, NULL, buf, len) == B_OK; +} //// Solaris #elif defined(__sun) || defined(sun) @@ -378,20 +402,27 @@ bool setSystemPaths() "Failed to get current executable path"); pathRemoveFile(buf, '\\'); + std::string exepath(buf); + // Use ".\bin\.." - path_share = std::string(buf) + "\\.."; + path_share = exepath + "\\.."; + if (detectMSVCBuildDir(exepath)) { + // The msvc build dir schould normaly not be present if properly installed, + // but its usefull for debugging. + path_share += DIR_DELIM ".."; + } - // Use "C:\Documents and Settings\user\Application Data\" + // Use "C:\Users\\AppData\Roaming\" DWORD len = GetEnvironmentVariable("APPDATA", buf, sizeof(buf)); FATAL_ERROR_IF(len == 0 || len > sizeof(buf), "Failed to get APPDATA"); - path_user = std::string(buf) + DIR_DELIM + PROJECT_NAME; + path_user = std::string(buf) + DIR_DELIM + PROJECT_NAME_C; return true; } //// Linux -#elif defined(__linux__) +#elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) bool setSystemPaths() { @@ -559,6 +590,10 @@ void initializePaths() if (!setSystemPaths()) errorstream << "Failed to get one or more system-wide path" << std::endl; + +# ifdef _WIN32 + path_cache = path_user + DIR_DELIM + "cache"; +# else // Initialize path_cache // First try $XDG_CACHE_HOME/PROJECT_NAME const char *cache_dir = getenv("XDG_CACHE_HOME"); @@ -575,7 +610,8 @@ void initializePaths() } // Migrate cache folder to new location if possible migrateCachePath(); -#endif +# endif // _WIN32 +#endif // RUN_IN_PLACE infostream << "Detected share path: " << path_share << std::endl; infostream << "Detected user path: " << path_user << std::endl; @@ -584,18 +620,18 @@ void initializePaths() #if USE_GETTEXT bool found_localedir = false; # ifdef STATIC_LOCALEDIR - if (STATIC_LOCALEDIR[0] && fs::PathExists(STATIC_LOCALEDIR)) { + /* STATIC_LOCALEDIR may be a generalized path such as /usr/share/locale that + * doesn't necessarily contain our locale files, so check data path first. */ + path_locale = getDataPath("locale"); + if (fs::PathExists(path_locale)) { + found_localedir = true; + infostream << "Using in-place locale directory " << path_locale + << " even though a static one was provided." << std::endl; + } else if (STATIC_LOCALEDIR[0] && fs::PathExists(STATIC_LOCALEDIR)) { found_localedir = true; path_locale = STATIC_LOCALEDIR; - infostream << "Using locale directory " << STATIC_LOCALEDIR << std::endl; - } else { - path_locale = getDataPath("locale"); - if (fs::PathExists(path_locale)) { - found_localedir = true; - infostream << "Using in-place locale directory " << path_locale - << " even though a static one was provided " - << "(RUN_IN_PLACE or CUSTOM_LOCALEDIR)." << std::endl; - } + infostream << "Using static locale directory " << STATIC_LOCALEDIR + << std::endl; } # else path_locale = getDataPath("locale"); @@ -661,6 +697,70 @@ void attachOrCreateConsole() #endif } +int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...) +{ + // https://msdn.microsoft.com/en-us/library/bt7tawza.aspx + // Many of the MSVC / Windows printf-style functions do not support positional + // arguments (eg. "%1$s"). We just forward the call to vsnprintf for sane + // platforms, but defer to _vsprintf_p on MSVC / Windows. + // https://github.com/FFmpeg/FFmpeg/blob/5ae9fa13f5ac640bec113120d540f70971aa635d/compat/msvcrt/snprintf.c#L46 + // _vsprintf_p has to be shimmed with _vscprintf_p on -1 (for an example see + // above FFmpeg link). + va_list args; + va_start(args, fmt); +#ifndef _MSC_VER + int c = vsnprintf(buf, buf_size, fmt, args); +#else // _MSC_VER + int c = _vsprintf_p(buf, buf_size, fmt, args); + if (c == -1) + c = _vscprintf_p(fmt, args); +#endif // _MSC_VER + va_end(args); + return c; +} + +static bool open_uri(const std::string &uri) +{ + if (uri.find_first_of("\r\n") != std::string::npos) { + errorstream << "Unable to open URI as it is invalid, contains new line: " << uri << std::endl; + return false; + } + +#if defined(_WIN32) + return (intptr_t)ShellExecuteA(NULL, NULL, uri.c_str(), NULL, NULL, SW_SHOWNORMAL) > 32; +#elif defined(__ANDROID__) + openURIAndroid(uri); + return true; +#elif defined(__APPLE__) + const char *argv[] = {"open", uri.c_str(), NULL}; + return posix_spawnp(NULL, "open", NULL, NULL, (char**)argv, + (*_NSGetEnviron())) == 0; +#else + const char *argv[] = {"xdg-open", uri.c_str(), NULL}; + return posix_spawnp(NULL, "xdg-open", NULL, NULL, (char**)argv, environ) == 0; +#endif +} + +bool open_url(const std::string &url) +{ + if (url.substr(0, 7) != "http://" && url.substr(0, 8) != "https://") { + errorstream << "Unable to open browser as URL is missing schema: " << url << std::endl; + return false; + } + + return open_uri(url); +} + +bool open_directory(const std::string &path) +{ + if (!fs::IsDir(path)) { + errorstream << "Unable to open directory as it does not exist: " << path << std::endl; + return false; + } + + return open_uri(path); +} + // Load performance counter frequency only once at startup #ifdef _WIN32