Auto-detect default INI files by OS prefix
All checks were successful
Build / Build (push) Successful in 30s

Scan the browse directory for case-insensitive android*/linux*/lakka* .ini files at startup and use the first match, with legacy default filenames as fallback.
This commit is contained in:
Niklas Friesen
2026-04-23 17:09:31 +02:00
parent 4095980023
commit edf60b8178

View File

@@ -6,8 +6,12 @@
#include "app_config.h"
#include "ini_handler.h"
#include <dirent.h>
#include <sys/stat.h>
#include <algorithm>
#include <cctype>
#include <cstring>
#include <vector>
// Create parent directories for a file path
static void ensureParentDir(const std::string& filePath)
@@ -30,6 +34,70 @@ static void ensureParentDir(const std::string& filePath)
mkdir(dir.c_str(), 0755);
}
static std::string toLowerCopy(const std::string& s)
{
std::string out = s;
std::transform(out.begin(), out.end(), out.begin(),
[](unsigned char c) { return (char)std::tolower(c); });
return out;
}
static bool hasIniExtension(const std::string& name)
{
if (name.size() < 4)
return false;
std::string ext = toLowerCopy(name.substr(name.size() - 4));
return ext == ".ini";
}
static bool startsWithCaseInsensitive(const std::string& value, const std::string& prefix)
{
if (value.size() < prefix.size())
return false;
std::string valuePrefix = toLowerCopy(value.substr(0, prefix.size()));
return valuePrefix == toLowerCopy(prefix);
}
static std::string findIniByPrefix(const std::string& directory, const std::string& prefix, const std::string& fallbackPath)
{
DIR* dp = opendir(directory.c_str());
if (!dp)
return fallbackPath;
std::vector<std::string> matches;
struct dirent* ep;
while ((ep = readdir(dp)) != nullptr)
{
std::string name = ep->d_name;
if (name == "." || name == "..")
continue;
if (!hasIniExtension(name))
continue;
if (!startsWithCaseInsensitive(name, prefix))
continue;
matches.push_back(name);
}
closedir(dp);
if (matches.empty())
return fallbackPath;
std::sort(matches.begin(), matches.end(), [](const std::string& a, const std::string& b) {
return toLowerCopy(a) < toLowerCopy(b);
});
std::string fullPath = directory;
if (!fullPath.empty() && fullPath.back() != '/')
fullPath += '/';
fullPath += matches.front();
return fullPath;
}
AppConfig& AppConfig::get()
{
static AppConfig instance;
@@ -38,10 +106,10 @@ AppConfig& AppConfig::get()
AppConfig::AppConfig()
{
// Defaults
paths[(int)OsTarget::ANDROID] = DEFAULT_ANDROID_INI;
paths[(int)OsTarget::LINUX] = DEFAULT_LINUX_INI;
paths[(int)OsTarget::LAKKA] = DEFAULT_LAKKA_INI;
// Defaults: scan for case-insensitive prefixes first, fallback to legacy names.
paths[(int)OsTarget::ANDROID] = findIniByPrefix(DEFAULT_BROWSE_DIR, "android", DEFAULT_ANDROID_INI);
paths[(int)OsTarget::LINUX] = findIniByPrefix(DEFAULT_BROWSE_DIR, "linux", DEFAULT_LINUX_INI);
paths[(int)OsTarget::LAKKA] = findIniByPrefix(DEFAULT_BROWSE_DIR, "lakka", DEFAULT_LAKKA_INI);
}
void AppConfig::load()