Core: Clean up and extend config saving/loading

This commit is contained in:
Vicki Pfau 2020-12-08 19:31:01 -08:00
parent 67f8197493
commit f1592d350f
6 changed files with 84 additions and 58 deletions

View File

@ -36,6 +36,7 @@ bool ConfigurationRead(struct Configuration*, const char* path);
bool ConfigurationReadVFile(struct Configuration*, struct VFile* vf);
bool ConfigurationWrite(const struct Configuration*, const char* path);
bool ConfigurationWriteSection(const struct Configuration*, const char* path, const char* section);
bool ConfigurationWriteVFile(const struct Configuration*, struct VFile* vf);
void ConfigurationEnumerateSections(const struct Configuration* configuration, void (*handler)(const char* sectionName, void* user), void* user);
void ConfigurationEnumerate(const struct Configuration* configuration, const char* section, void (*handler)(const char* key, const char* value, void* user), void* user);

View File

@ -68,9 +68,13 @@ bool mCoreConfigLoad(struct mCoreConfig*);
bool mCoreConfigSave(const struct mCoreConfig*);
bool mCoreConfigLoadPath(struct mCoreConfig*, const char* path);
bool mCoreConfigSavePath(const struct mCoreConfig*, const char* path);
bool mCoreConfigLoadVFile(struct mCoreConfig*, struct VFile* vf);
bool mCoreConfigSaveVFile(const struct mCoreConfig*, struct VFile* vf);
void mCoreConfigMakePortable(const struct mCoreConfig*);
void mCoreConfigDirectory(char* out, size_t outLength);
void mCoreConfigPortablePath(char* out, size_t outLength);
bool mCoreConfigIsPortable(void);
#endif
const char* mCoreConfigGetValue(const struct mCoreConfig*, const char* key);

View File

@ -170,27 +170,23 @@ bool mCoreConfigSavePath(const struct mCoreConfig* config, const char* path) {
return ConfigurationWrite(&config->configTable, path);
}
bool mCoreConfigLoadVFile(struct mCoreConfig* config, struct VFile* vf) {
return ConfigurationReadVFile(&config->configTable, vf);
}
bool mCoreConfigSaveVFile(const struct mCoreConfig* config, struct VFile* vf) {
return ConfigurationWriteVFile(&config->configTable, vf);
}
void mCoreConfigMakePortable(const struct mCoreConfig* config) {
struct VFile* portable = 0;
#ifdef _WIN32
char out[MAX_PATH];
wchar_t wpath[MAX_PATH];
wchar_t wprojectName[MAX_PATH];
MultiByteToWideChar(CP_UTF8, 0, projectName, -1, wprojectName, MAX_PATH);
HMODULE hModule = GetModuleHandleW(NULL);
GetModuleFileNameW(hModule, wpath, MAX_PATH);
PathRemoveFileSpecW(wpath);
WideCharToMultiByte(CP_UTF8, 0, wpath, -1, out, MAX_PATH, 0, 0);
StringCchCatA(out, MAX_PATH, "\\portable.ini");
portable = VFileOpen(out, O_WRONLY | O_CREAT);
#elif defined(PSP2) || defined(_3DS) || defined(__SWITCH__) || defined(GEKKO)
// Already portable
#else
struct VFile* portable = NULL;
char out[PATH_MAX];
getcwd(out, PATH_MAX);
strncat(out, PATH_SEP "portable.ini", PATH_MAX - strlen(out));
mCoreConfigPortablePath(out, sizeof(out));
if (!out[0]) {
// Cannot be made portable
return;
}
portable = VFileOpen(out, O_WRONLY | O_CREAT);
#endif
if (portable) {
portable->close(portable);
mCoreConfigSave(config);
@ -199,62 +195,44 @@ void mCoreConfigMakePortable(const struct mCoreConfig* config) {
void mCoreConfigDirectory(char* out, size_t outLength) {
struct VFile* portable;
char portableDir[PATH_MAX];
mCoreConfigPortablePath(portableDir, sizeof(portableDir));
if (portableDir[0]) {
portable = VFileOpen(portableDir, O_RDONLY);
if (portable) {
portable->close(portable);
if (outLength < PATH_MAX) {
char outTmp[PATH_MAX];
separatePath(portableDir, outTmp, NULL, NULL);
strlcpy(out, outTmp, outLength);
} else {
separatePath(portableDir, out, NULL, NULL);
}
return;
}
}
#ifdef _WIN32
wchar_t wpath[MAX_PATH];
wchar_t wprojectName[MAX_PATH];
MultiByteToWideChar(CP_UTF8, 0, projectName, -1, wprojectName, MAX_PATH);
HMODULE hModule = GetModuleHandleW(NULL);
GetModuleFileNameW(hModule, wpath, MAX_PATH);
PathRemoveFileSpecW(wpath);
WideCharToMultiByte(CP_UTF8, 0, wpath, -1, out, outLength, 0, 0);
StringCchCatA(out, outLength, "\\portable.ini");
portable = VFileOpen(out, O_RDONLY);
if (portable) {
portable->close(portable);
} else {
wchar_t* home;
SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, NULL, &home);
StringCchPrintfW(wpath, MAX_PATH, L"%ws\\%ws", home, wprojectName);
CoTaskMemFree(home);
CreateDirectoryW(wpath, NULL);
}
WideCharToMultiByte(CP_UTF8, 0, wpath, -1, out, outLength, 0, 0);
wchar_t* home;
SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, NULL, &home);
StringCchPrintfW(wpath, MAX_PATH, L"%ws\\%ws", home, wprojectName);
CoTaskMemFree(home);
CreateDirectoryW(wpath, NULL);
#elif defined(PSP2)
UNUSED(portable);
snprintf(out, outLength, "ux0:data/%s", projectName);
sceIoMkdir(out, 0777);
#elif defined(GEKKO) || defined(__SWITCH__)
UNUSED(portable);
snprintf(out, outLength, "/%s", projectName);
mkdir(out, 0777);
#elif defined(_3DS)
UNUSED(portable);
snprintf(out, outLength, "/%s", projectName);
FSUSER_CreateDirectory(sdmcArchive, fsMakePath(PATH_ASCII, out), 0);
#elif defined(__HAIKU__)
getcwd(out, outLength);
strncat(out, PATH_SEP "portable.ini", outLength - strlen(out));
portable = VFileOpen(out, O_RDONLY);
if (portable) {
getcwd(out, outLength);
portable->close(portable);
return;
}
char path[B_PATH_NAME_LENGTH];
find_directory(B_USER_SETTINGS_DIRECTORY, 0, false, path, B_PATH_NAME_LENGTH);
snprintf(out, outLength, "%s/%s", path, binaryName);
mkdir(out, 0755);
#else
getcwd(out, outLength);
strncat(out, PATH_SEP "portable.ini", outLength - strlen(out));
portable = VFileOpen(out, O_RDONLY);
if (portable) {
getcwd(out, outLength);
portable->close(portable);
return;
}
char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
if (xdgConfigHome && xdgConfigHome[0] == '/') {
snprintf(out, outLength, "%s/%s", xdgConfigHome, binaryName);
@ -268,6 +246,39 @@ void mCoreConfigDirectory(char* out, size_t outLength) {
mkdir(out, 0755);
#endif
}
void mCoreConfigPortablePath(char* out, size_t outLength) {
#ifdef _WIN32
wchar_t wpath[MAX_PATH];
wchar_t wprojectName[MAX_PATH];
MultiByteToWideChar(CP_UTF8, 0, projectName, -1, wprojectName, MAX_PATH);
HMODULE hModule = GetModuleHandleW(NULL);
GetModuleFileNameW(hModule, wpath, MAX_PATH);
PathRemoveFileSpecW(wpath);
WideCharToMultiByte(CP_UTF8, 0, wpath, -1, out, outLength, 0, 0);
StringCchCatA(out, outLength, "\\portable.ini");
#elif defined(PSP2) || defined(GEKKO) || defined(__SWITCH__) || defined(_3DS)
out[0] = '\0';
#else
getcwd(out, outLength);
strncat(out, PATH_SEP "portable.ini", outLength - strlen(out));
#endif
}
bool mCoreConfigIsPortable(void) {
struct VFile* portable;
char portableDir[PATH_MAX];
mCoreConfigPortablePath(portableDir, sizeof(portableDir));
if (portableDir[0]) {
portable = VFileOpen(portableDir, O_RDONLY);
if (portable) {
portable->close(portable);
return true;
}
}
return false;
}
#endif
const char* mCoreConfigGetValue(const struct mCoreConfig* config, const char* key) {

View File

@ -297,6 +297,10 @@ void ConfigController::makePortable() {
m_settings = settings2;
}
bool ConfigController::isPortable() {
return mCoreConfigIsPortable();
}
const QString& ConfigController::configDir() {
if (s_configDir.isNull()) {
char path[PATH_MAX];

View File

@ -91,6 +91,7 @@ public:
mCoreConfig* config() { return &m_config; }
static const QString& configDir();
static bool isPortable();
public slots:
void setOption(const char* key, bool value);

View File

@ -177,9 +177,14 @@ bool ConfigurationWrite(const struct Configuration* configuration, const char* p
if (!vf) {
return false;
}
bool res = ConfigurationWriteVFile(configuration, vf);
vf->close(vf);
return true;
}
bool ConfigurationWriteVFile(const struct Configuration* configuration, struct VFile* vf) {
HashTableEnumerate(&configuration->root, _keyHandler, vf);
HashTableEnumerate(&configuration->sections, _sectionHandler, vf);
vf->close(vf);
return true;
}