|
|
@@ -45,10 +45,11 @@
|
|
|
#elif defined RMLUI_PLATFORM_UNIX
|
|
|
|
|
|
#include <X11/Xlib.h>
|
|
|
- #include <unistd.h>
|
|
|
- #include <sys/stat.h>
|
|
|
#include <dirent.h>
|
|
|
+ #include <stdlib.h>
|
|
|
#include <string.h>
|
|
|
+ #include <sys/stat.h>
|
|
|
+ #include <unistd.h>
|
|
|
|
|
|
#endif
|
|
|
|
|
|
@@ -57,7 +58,8 @@ Rml::String PlatformExtensions::FindSamplesRoot()
|
|
|
#ifdef RMLUI_PLATFORM_WIN32
|
|
|
// Test various relative paths to the "Samples" directory, based on common build and install locations.
|
|
|
const char* candidate_paths[] = {
|
|
|
- "",
|
|
|
+ ".\\",
|
|
|
+ "Samples\\",
|
|
|
"..\\Samples\\",
|
|
|
"..\\share\\Samples\\",
|
|
|
"..\\..\\Samples\\",
|
|
|
@@ -65,30 +67,44 @@ Rml::String PlatformExtensions::FindSamplesRoot()
|
|
|
"..\\..\\..\\..\\Samples\\",
|
|
|
};
|
|
|
|
|
|
- // Fetch the path of the executable, test the candidate paths appended to that.
|
|
|
- char executable_file_name[MAX_PATH];
|
|
|
- if (GetModuleFileNameA(NULL, executable_file_name, MAX_PATH) >= MAX_PATH && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
|
|
- {
|
|
|
- executable_file_name[0] = 0;
|
|
|
- }
|
|
|
+ char path_buffer[MAX_PATH];
|
|
|
|
|
|
- Rml::String executable_path(executable_file_name);
|
|
|
- executable_path = executable_path.substr(0, executable_path.rfind('\\') + 1);
|
|
|
+ // Fetch the path of the executable.
|
|
|
+ if (GetModuleFileNameA(NULL, path_buffer, MAX_PATH) >= MAX_PATH && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
|
|
+ return {};
|
|
|
+ Rml::String executable_directory_path = Rml::String(path_buffer);
|
|
|
+ executable_directory_path = executable_directory_path.substr(0, executable_directory_path.rfind('\\') + 1);
|
|
|
|
|
|
- // We assume we have found the correct path if we can find the lookup file from it
|
|
|
+ // We assume we have found the correct path if we can find the lookup file from it.
|
|
|
const char* lookup_file = "assets\\rml.rcss";
|
|
|
|
|
|
- for (const char* relative_path : candidate_paths)
|
|
|
+ // Test the candidate paths relative to the executable folder, and the current working directory, respectively.
|
|
|
+ for (const Rml::String relative_target_path : candidate_paths)
|
|
|
{
|
|
|
- Rml::String absolute_path = executable_path + relative_path;
|
|
|
+ const Rml::String absolute_target_path = executable_directory_path + relative_target_path;
|
|
|
+ const Rml::String absolute_lookup_path = absolute_target_path + lookup_file;
|
|
|
+ if (PathFileExistsA(absolute_lookup_path.c_str()))
|
|
|
+ {
|
|
|
+ if (!PathCanonicalizeA(path_buffer, absolute_target_path.c_str()))
|
|
|
+ {
|
|
|
+ Rml::Log::Message(Rml::Log::LT_ERROR, "Failed to canonicalize the path to the samples root: %s", absolute_target_path.c_str());
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+
|
|
|
+ return Rml::String(path_buffer);
|
|
|
+ }
|
|
|
|
|
|
- if (PathFileExistsA(Rml::String(absolute_path + lookup_file).c_str()))
|
|
|
+ const Rml::String relative_lookup_path = relative_target_path + lookup_file;
|
|
|
+ if (PathFileExistsA(relative_lookup_path.c_str()))
|
|
|
{
|
|
|
- char canonical_path[MAX_PATH];
|
|
|
- if (!PathCanonicalizeA(canonical_path, absolute_path.c_str()))
|
|
|
- canonical_path[0] = 0;
|
|
|
+ const DWORD working_directory_length = GetFullPathNameA(relative_target_path.c_str(), MAX_PATH, path_buffer, nullptr);
|
|
|
+ if (working_directory_length <= 0 || working_directory_length >= MAX_PATH)
|
|
|
+ {
|
|
|
+ Rml::Log::Message(Rml::Log::LT_ERROR, "Failed to get the full path to the samples root: %s", relative_target_path.c_str());
|
|
|
+ return {};
|
|
|
+ }
|
|
|
|
|
|
- return Rml::String(canonical_path);
|
|
|
+ return Rml::String(path_buffer);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -124,27 +140,28 @@ Rml::String PlatformExtensions::FindSamplesRoot()
|
|
|
|
|
|
#elif defined RMLUI_PLATFORM_UNIX
|
|
|
|
|
|
- char executable_file_name[PATH_MAX];
|
|
|
- ssize_t len = readlink("/proc/self/exe", executable_file_name, PATH_MAX);
|
|
|
+ char path_buffer[PATH_MAX + 1];
|
|
|
+ ssize_t len = readlink("/proc/self/exe", path_buffer, PATH_MAX);
|
|
|
if (len == -1)
|
|
|
{
|
|
|
Rml::Log::Message(Rml::Log::LT_ERROR, "Failed to determine the executable path");
|
|
|
- executable_file_name[0] = 0;
|
|
|
+ path_buffer[0] = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// readlink() does not append a null byte to buf.
|
|
|
- executable_file_name[len] = 0;
|
|
|
+ path_buffer[len] = 0;
|
|
|
}
|
|
|
- Rml::String executable_path = Rml::String(executable_file_name);
|
|
|
- executable_path = executable_path.substr(0, executable_path.rfind("/") + 1);
|
|
|
+ Rml::String executable_directory_path = Rml::String(path_buffer);
|
|
|
+ executable_directory_path = executable_directory_path.substr(0, executable_directory_path.rfind("/") + 1);
|
|
|
|
|
|
// We assume we have found the correct path if we can find the lookup file from it.
|
|
|
const char* lookup_file = "assets/rml.rcss";
|
|
|
|
|
|
// Test various relative paths to the "Samples" directory, based on common build and install locations.
|
|
|
const char* candidate_paths[] = {
|
|
|
- "",
|
|
|
+ "./",
|
|
|
+ "Samples/",
|
|
|
"../",
|
|
|
"../Samples/",
|
|
|
"../share/Samples/",
|
|
|
@@ -157,16 +174,26 @@ Rml::String PlatformExtensions::FindSamplesRoot()
|
|
|
struct stat sb;
|
|
|
return stat(path.c_str(), &sb) == 0 && S_ISREG(sb.st_mode);
|
|
|
};
|
|
|
-
|
|
|
- for (const char* relative_path : candidate_paths)
|
|
|
- {
|
|
|
- Rml::String absolute_path = executable_path + relative_path;
|
|
|
- Rml::String absolute_lookup_file = absolute_path + lookup_file;
|
|
|
-
|
|
|
- if (isRegularFile(absolute_lookup_file))
|
|
|
+ auto GetAbsoluteFilePath = [&](const Rml::String& path) -> Rml::String {
|
|
|
+ const char* absolute_path = realpath(path.c_str(), path_buffer);
|
|
|
+ if (!absolute_path)
|
|
|
{
|
|
|
- return absolute_path;
|
|
|
+ Rml::Log::Message(Rml::Log::LT_ERROR, "Failed to canonicalize the path to the samples root: %s", path.c_str());
|
|
|
+ return {};
|
|
|
}
|
|
|
+ return Rml::String(absolute_path) + '/';
|
|
|
+ };
|
|
|
+
|
|
|
+ for (const Rml::String relative_target_path : candidate_paths)
|
|
|
+ {
|
|
|
+ const Rml::String absolute_target_path = executable_directory_path + relative_target_path;
|
|
|
+ const Rml::String absolute_lookup_path = absolute_target_path + lookup_file;
|
|
|
+ if (isRegularFile(absolute_lookup_path))
|
|
|
+ return GetAbsoluteFilePath(absolute_target_path);
|
|
|
+
|
|
|
+ const Rml::String relative_lookup_path = relative_target_path + lookup_file;
|
|
|
+ if (isRegularFile(relative_lookup_path))
|
|
|
+ return GetAbsoluteFilePath(relative_target_path);
|
|
|
}
|
|
|
|
|
|
Rml::Log::Message(Rml::Log::LT_ERROR, "Failed to find the path to the samples root");
|