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)