diff --git a/SModule b/SModule index 8e26762..3e96f9f 100644 --- a/SModule +++ b/SModule @@ -13,6 +13,7 @@ mijin_sources = Split(""" source/mijin/net/http.cpp source/mijin/net/ip.cpp source/mijin/net/socket.cpp + source/mijin/platform/folders.cpp source/mijin/util/os.cpp source/mijin/types/name.cpp source/mijin/virtual_filesystem/filesystem.cpp diff --git a/source/mijin/platform/.idea/.gitignore b/source/mijin/platform/.idea/.gitignore new file mode 100644 index 0000000..8bf4d45 --- /dev/null +++ b/source/mijin/platform/.idea/.gitignore @@ -0,0 +1,6 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/source/mijin/platform/.idea/modules.xml b/source/mijin/platform/.idea/modules.xml new file mode 100644 index 0000000..86d7edf --- /dev/null +++ b/source/mijin/platform/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/source/mijin/platform/.idea/platform.iml b/source/mijin/platform/.idea/platform.iml new file mode 100644 index 0000000..bc2cd87 --- /dev/null +++ b/source/mijin/platform/.idea/platform.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/source/mijin/platform/folders.cpp b/source/mijin/platform/folders.cpp new file mode 100644 index 0000000..e80c84f --- /dev/null +++ b/source/mijin/platform/folders.cpp @@ -0,0 +1,106 @@ + +#include "./folders.hpp" + + +#include "../detect.hpp" +#include "../debug/assert.hpp" + +#include + +#if MIJIN_TARGET_OS == MIJIN_OS_WINDOWS +# include +#endif + +namespace mijin +{ +fs::path getKnownFolder(KnownFolder folder) MIJIN_NOEXCEPT +{ +#if MIJIN_TARGET_OS == MIJIN_OS_LINUX + switch (folder) + { + case KnownFolder::USER_HOME: + if (const char* val = std::getenv("HOME"); val != nullptr) + { + return val; + } + return "/"; + case KnownFolder::TEMP: + for (const char* varname : {"TMPDIR", "TEMP", "TMP"}) + { + if (const char* val = std::getenv(varname); val != nullptr) + { + return val; + } + } + return "/tmp"; + case KnownFolder::CACHE_ROOT: + if (const char* val = std::getenv("XDG_CACHE_HOME"); val != nullptr) + { + return val; + } + return getKnownFolder(KnownFolder::USER_HOME) / ".cache"; + case KnownFolder::USER_CONFIG_ROOT: + if (const char* val = std::getenv("XDG_CONFIG_HOME"); val != nullptr) + { + return val; + } + return getKnownFolder(KnownFolder::USER_HOME) / ".config"; + case KnownFolder::USER_DATA_ROOT: + if (const char* val = std::getenv("XDG_DATA_HOME"); val != nullptr) + { + return val; + } + return getKnownFolder(KnownFolder::USER_HOME) / ".local/share"; + } + MIJIN_ERROR("Invalid value passed to getKnownFolder()."); + return {}; +#elif MIJIN_TARGET_OS == MIJIN_OS_WINDOWS + // TODO: this is 100% untested on Windows + + auto getKnownFolderPath = [](REFKNOWNFOLDERID rfid) -> fs::path + { + WSTR path = nullptr; + if (!SUCCEEDED(SHGetKnownFolderPath(rfid, KF_FLAG_DEFAULT, nullptr, &path))) + { + CoTaskMemFree(path); + return {}; + } + fs::path result(path); + CoTaskMemFree(path); + return result; + }; + + switch (folder) + { + case KnownFolder::USER_HOME: + if (const fs::path path = getKnownFolderPath(FOLDERID_Profile); !path.empty()) + { + return path; + } + return "C:\\"; + case KnownFolder::TEMP: + case KnownFolder::CACHE_ROOT: + for (const char* varname : {"TMPDIR", "TEMP", "TMP"}) + { + if (const char* val = std::getenv(varname); val != nullptr) + { + return val; + } + } + return getKnownFolder(KnownFolder::USER_DATA_ROOT) / "Temp"; + case KnownFolder::USER_CONFIG_ROOT: + case KnownFolder::USER_DATA_ROOT: + if (const fs::path path = getKnownFolderPath(FOLDERID_LocalAppData); !path.empty()) + { + return path; + } + return getKnownFolder(KnownFolder::USER_HOME) / "AppData" / "Local"; + } + MIJIN_ERROR("Invalid value passed to getKnownFolder()."); + return {}; +#else + MIJIN_ERROR("Known folders not implemented for this platform."); + return {}; // don't know :/ +#endif +} +} \ No newline at end of file diff --git a/source/mijin/platform/folders.hpp b/source/mijin/platform/folders.hpp new file mode 100644 index 0000000..1e189dc --- /dev/null +++ b/source/mijin/platform/folders.hpp @@ -0,0 +1,27 @@ +#pragma once + +#if !defined(MIJIN_PLATFORM_FOLDERS_HPP_INCLUDED) +#define MIJIN_PLATFORM_FOLDERS_HPP_INCLUDED 1 + +#include "../internal/common.hpp" + +#include + +namespace fs = std::filesystem; + +namespace mijin +{ +enum class KnownFolder +{ + USER_HOME, + TEMP, + CACHE_ROOT, + USER_CONFIG_ROOT, + USER_DATA_ROOT +}; + +[[nodiscard]] +fs::path getKnownFolder(KnownFolder folder) MIJIN_NOEXCEPT; +} + +#endif // defined(MIJIN_PLATFORM_FOLDERS_HPP_INCLUDED) diff --git a/source/mijin/virtual_filesystem/filesystem.cpp b/source/mijin/virtual_filesystem/filesystem.cpp index 3bd0aa4..21651aa 100644 --- a/source/mijin/virtual_filesystem/filesystem.cpp +++ b/source/mijin/virtual_filesystem/filesystem.cpp @@ -1,6 +1,8 @@ #include "./filesystem.hpp" +#include "../platform/folders.hpp" + namespace mijin { @@ -37,7 +39,7 @@ std::vector OSFileSystemAdapter::getRoots() fs::path OSFileSystemAdapter::getHomeFolder() { - return "/home/mewin"; // very TODO + return getKnownFolder(KnownFolder::USER_HOME); } std::vector OSFileSystemAdapter::listFiles(const fs::path& folder)