core: Add support for specifying an arbitrary portable directory.

This commit is contained in:
Steveice10 2024-01-21 15:09:30 -08:00 committed by Vicki Pfau
parent 3e86758a9f
commit 398df56ac9
3 changed files with 65 additions and 30 deletions

View File

@ -72,8 +72,9 @@ 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 mCoreConfigMakePortable(const struct mCoreConfig*, const char* path);
void mCoreConfigDirectory(char* out, size_t outLength);
void mCoreConfigPortableIniPath(char* out, size_t outLength);
void mCoreConfigPortablePath(char* out, size_t outLength);
bool mCoreConfigIsPortable(void);
#endif

View File

@ -198,38 +198,46 @@ bool mCoreConfigSaveVFile(const struct mCoreConfig* config, struct VFile* vf) {
return ConfigurationWriteVFile(&config->configTable, vf);
}
void mCoreConfigMakePortable(const struct mCoreConfig* config) {
void mCoreConfigMakePortable(const struct mCoreConfig* config, const char* path) {
struct VFile* portable = NULL;
struct Configuration portableConfig;
char out[PATH_MAX];
mCoreConfigPortablePath(out, sizeof(out));
mCoreConfigPortableIniPath(out, sizeof(out));
if (!out[0]) {
// Cannot be made portable
return;
}
portable = VFileOpen(out, O_WRONLY | O_CREAT);
ConfigurationInit(&portableConfig);
portable = VFileOpen(out, O_RDONLY);
if (portable) {
ConfigurationReadVFile(&portableConfig, portable);
portable->close(portable);
mCoreConfigSave(config);
}
if (path && path[0]) {
ConfigurationSetValue(&portableConfig, "portable", "path", path);
} else {
ConfigurationClearValue(&portableConfig, "portable", "path");
}
portable = VFileOpen(out, O_WRONLY | O_CREAT | O_TRUNC);
if (portable) {
ConfigurationWriteVFile(&portableConfig, portable);
portable->close(portable);
}
ConfigurationDeinit(&portableConfig);
mCoreConfigSave(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;
}
strlcpy(out, portableDir, outLength);
return;
}
#ifdef _WIN32
WCHAR wpath[MAX_PATH];
@ -276,7 +284,7 @@ void mCoreConfigDirectory(char* out, size_t outLength) {
#endif
}
void mCoreConfigPortablePath(char* out, size_t outLength) {
void mCoreConfigPortableIniPath(char* out, size_t outLength) {
#ifdef _WIN32
wchar_t wpath[MAX_PATH];
GetModuleFileNameW(NULL, wpath, MAX_PATH);
@ -308,18 +316,44 @@ void mCoreConfigPortablePath(char* out, size_t outLength) {
#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;
void mCoreConfigPortablePath(char* out, size_t outLength) {
struct VFile* portableIni;
char portableIniPath[PATH_MAX];
mCoreConfigPortableIniPath(portableIniPath, sizeof(portableIniPath));
out[0] = '\0';
if (portableIniPath[0]) {
portableIni = VFileOpen(portableIniPath, O_RDONLY);
if (portableIni) {
// Start with the path that the portable.ini file exists in.
char iniDir[PATH_MAX];
separatePath(portableIniPath, iniDir, NULL, NULL);
strlcpy(out, iniDir, outLength);
struct Configuration portableConfig;
ConfigurationInit(&portableConfig);
if (ConfigurationReadVFile(&portableConfig, portableIni)) {
const char* path = ConfigurationGetValue(&portableConfig, "portable", "path");
if (path) {
if (path[0] == '/') {
// User specified an absolute path.
strlcpy(out, path, outLength);
} else {
// User specified a relative path, append to the portable.ini path.
snprintf(out, outLength, "%s" PATH_SEP "%s", iniDir, path);
}
}
}
ConfigurationDeinit(&portableConfig);
portableIni->close(portableIni);
}
}
return false;
}
bool mCoreConfigIsPortable(void) {
char portableDir[PATH_MAX];
mCoreConfigPortablePath(portableDir, sizeof(portableDir));
return portableDir[0];
}
#endif

View File

@ -366,7 +366,7 @@ void ConfigController::write() {
}
void ConfigController::makePortable() {
mCoreConfigMakePortable(&m_config);
mCoreConfigMakePortable(&m_config, nullptr);
QString fileName(configDir());
fileName.append(QDir::separator());