Added functions for detecting known folders per-platform. Not tested on Windows yet, but who cares?

This commit is contained in:
Patrick 2025-03-02 17:19:18 +01:00
parent ba23cb0c70
commit 8f2cee4968
7 changed files with 159 additions and 1 deletions

View File

@ -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

6
source/mijin/platform/.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,6 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

8
source/mijin/platform/.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/platform.iml" filepath="$PROJECT_DIR$/.idea/platform.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="CPP_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,106 @@
#include "./folders.hpp"
#include "../detect.hpp"
#include "../debug/assert.hpp"
#include <cstdlib>
#if MIJIN_TARGET_OS == MIJIN_OS_WINDOWS
# include <Shlobj.h>
#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
}
}

View File

@ -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 <filesystem>
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)

View File

@ -1,6 +1,8 @@
#include "./filesystem.hpp"
#include "../platform/folders.hpp"
namespace mijin
{
@ -37,7 +39,7 @@ std::vector<fs::path> OSFileSystemAdapter::getRoots()
fs::path OSFileSystemAdapter::getHomeFolder()
{
return "/home/mewin"; // very TODO
return getKnownFolder(KnownFolder::USER_HOME);
}
std::vector<FileInfo> OSFileSystemAdapter::listFiles(const fs::path& folder)