80 lines
2.4 KiB
C++
80 lines
2.4 KiB
C++
#include "editor/SpineEditorLocator.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <cstdlib>
|
|
#include <system_error>
|
|
|
|
namespace dts {
|
|
namespace fs = std::filesystem;
|
|
namespace {
|
|
|
|
void addUnique(std::vector<fs::path>& paths, const fs::path& candidate) {
|
|
std::error_code error;
|
|
if (!fs::is_regular_file(candidate, error)) {
|
|
return;
|
|
}
|
|
const auto canonical = fs::weakly_canonical(candidate, error);
|
|
const auto value = error ? candidate.lexically_normal() : canonical;
|
|
if (std::find(paths.begin(), paths.end(), value) == paths.end()) {
|
|
paths.push_back(value);
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
std::vector<fs::path> SpineEditorLocator::discover() const {
|
|
std::vector<fs::path> results;
|
|
|
|
#if defined(__APPLE__)
|
|
addUnique(results, "/Applications/Spine.app/Contents/MacOS/Spine");
|
|
if (const char* userHome = std::getenv("HOME")) {
|
|
addUnique(results, fs::path(userHome) / "Applications/Spine.app/Contents/MacOS/Spine");
|
|
}
|
|
#elif defined(_WIN32)
|
|
const auto addFromRoot = [&results](const char* variable) {
|
|
if (const char* root = std::getenv(variable)) {
|
|
addUnique(results, fs::path(root) / "Spine/Spine.com");
|
|
}
|
|
};
|
|
addFromRoot("ProgramFiles");
|
|
addFromRoot("ProgramFiles(x86)");
|
|
#endif
|
|
|
|
return results;
|
|
}
|
|
|
|
std::optional<fs::path> SpineEditorLocator::normalize(const fs::path& userPath) const {
|
|
std::error_code error;
|
|
auto candidate = userPath;
|
|
|
|
#if defined(__APPLE__)
|
|
if (candidate.extension() == ".app") {
|
|
candidate /= "Contents/MacOS/Spine";
|
|
} else if (fs::is_directory(candidate, error)) {
|
|
const auto appCandidate = candidate / "Spine.app/Contents/MacOS/Spine";
|
|
if (fs::is_regular_file(appCandidate, error)) {
|
|
candidate = appCandidate;
|
|
}
|
|
}
|
|
#elif defined(_WIN32)
|
|
if (fs::is_directory(candidate, error)) {
|
|
candidate /= "Spine.com";
|
|
} else if (candidate.extension() == ".exe") {
|
|
auto commandCandidate = candidate;
|
|
commandCandidate.replace_extension(".com");
|
|
if (fs::is_regular_file(commandCandidate, error)) {
|
|
candidate = commandCandidate;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (!fs::is_regular_file(candidate, error)) {
|
|
return std::nullopt;
|
|
}
|
|
const auto canonical = fs::weakly_canonical(candidate, error);
|
|
return error ? std::optional(candidate.lexically_normal()) : std::optional(canonical);
|
|
}
|
|
|
|
} // namespace dts
|
|
|