+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);
+}
+