mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-22 22:48:08 +03:00
QE/LE: Handle backslashes in filenames
Rance 5D uses filename `Save\\Rance5dSystem.asd`. This caused issues: - On Windows, saving would fail if the `Save` directory did not exist. - On other platforms, files were created with literal backslashes in their names. This change addresses these problems by: - In commandQE, normalizing backslashes to forward slashes in the path and ensuring that the target directory exists by calling mkdir_p(). - In commandLE, first attempting to load files with normalized forward slashes. If that fails, it retries with the original path (containing backslashes) for compatibility with older saves.
This commit is contained in:
+18
-2
@@ -110,21 +110,35 @@ void commandLT() {
|
||||
void commandLE(char terminator) {
|
||||
int type = sl_getc();
|
||||
const char *filename = sl_getString(terminator);
|
||||
char *fname_utf8 = toUTF8(filename);
|
||||
char *fallback_fname = NULL;
|
||||
if (strchr(fname_utf8, '\\')) {
|
||||
fallback_fname = strdup(fname_utf8);
|
||||
for (char *p = fname_utf8; *p; p++) {
|
||||
if (*p == '\\')
|
||||
*p = '/';
|
||||
}
|
||||
}
|
||||
|
||||
int var, cnt;
|
||||
struct VarRef vref;
|
||||
|
||||
char *fname_utf8 = toUTF8(filename);
|
||||
switch (type) {
|
||||
case 0:
|
||||
getCaliArray(&vref);
|
||||
var = vref.var;
|
||||
cnt = getCaliValue();
|
||||
sysVar[0] = load_vars_from_file(fname_utf8, &vref, cnt);
|
||||
// For compatibility; the QE command in v2.16.1 and earlier did not
|
||||
// convert backslashes to slashes.
|
||||
if (sysVar[0] == SAVE_LOADERR && fallback_fname)
|
||||
sysVar[0] = load_vars_from_file(fallback_fname, &vref, cnt);
|
||||
break;
|
||||
case 1:
|
||||
var = getCaliValue();
|
||||
cnt = getCaliValue();
|
||||
sysVar[0] = load_strs_from_file(fname_utf8, var, cnt);
|
||||
if (sysVar[0] == SAVE_LOADERR && fallback_fname)
|
||||
sysVar[0] = load_strs_from_file(fallback_fname, var, cnt);
|
||||
break;
|
||||
default:
|
||||
var = getCaliValue();
|
||||
@@ -132,6 +146,8 @@ void commandLE(char terminator) {
|
||||
WARNING("Unknown LE command %d", type);
|
||||
break;
|
||||
}
|
||||
if (fallback_fname)
|
||||
free(fallback_fname);
|
||||
free(fname_utf8);
|
||||
|
||||
TRACE("LE %d,%s,%d,%d:",type, filename, var, cnt);
|
||||
|
||||
+15
-2
@@ -29,6 +29,7 @@
|
||||
#include "scenario.h"
|
||||
#include "savedata.h"
|
||||
#include "utfsjis.h"
|
||||
#include "filecheck.h"
|
||||
#include "cmd_check.h"
|
||||
|
||||
void commandQD() {
|
||||
@@ -83,10 +84,22 @@ void commandQC() {
|
||||
void commandQE(char terminator) {
|
||||
int type = sl_getc();
|
||||
const char *filename = sl_getString(terminator);
|
||||
char *fname_utf8 = toUTF8(filename);
|
||||
char *last_slash = NULL;
|
||||
for (char *p = fname_utf8; *p; p++) {
|
||||
if (*p == '\\') {
|
||||
*p = '/';
|
||||
last_slash = p;
|
||||
}
|
||||
}
|
||||
if (last_slash) {
|
||||
*last_slash = '\0';
|
||||
mkdir_p(fname_utf8);
|
||||
*last_slash = '/';
|
||||
}
|
||||
|
||||
int var, cnt;
|
||||
struct VarRef vref;
|
||||
|
||||
char *fname_utf8 = toUTF8(filename);
|
||||
switch (type) {
|
||||
case 0:
|
||||
getCaliArray(&vref);
|
||||
|
||||
+8
-8
@@ -67,28 +67,28 @@ static int make_dir(const char *path)
|
||||
#endif
|
||||
|
||||
// Adapted from http://stackoverflow.com/a/2336245/119527
|
||||
static int mkdir_p(const char *path)
|
||||
int mkdir_p(const char *path_utf8)
|
||||
{
|
||||
const size_t len = strlen(path);
|
||||
char _path[PATH_MAX];
|
||||
const size_t len = strlen(path_utf8);
|
||||
char path[PATH_MAX];
|
||||
char *p;
|
||||
|
||||
errno = 0;
|
||||
|
||||
// Copy string so its mutable
|
||||
if (len > sizeof(_path)-1) {
|
||||
if (len > sizeof(path)-1) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
strcpy(_path, path);
|
||||
strcpy(path, path_utf8);
|
||||
|
||||
// Iterate the string
|
||||
for (p = _path + 1; *p; p++) {
|
||||
for (p = path + 1; *p; p++) {
|
||||
if (*p == '/') {
|
||||
// Temporarily truncate
|
||||
*p = '\0';
|
||||
|
||||
if (make_dir(_path) != 0) {
|
||||
if (make_dir(path) != 0) {
|
||||
if (errno != EEXIST)
|
||||
return -1;
|
||||
}
|
||||
@@ -97,7 +97,7 @@ static int mkdir_p(const char *path)
|
||||
}
|
||||
}
|
||||
|
||||
if (make_dir(_path) != 0) {
|
||||
if (make_dir(path) != 0) {
|
||||
if (errno != EEXIST)
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -31,5 +31,6 @@ char *fc_get_path(const char *fname_utf8);
|
||||
bool fc_exists(const char *fname_utf8);
|
||||
FILE *fc_open(const char *fname_utf8, char type);
|
||||
void fc_backup_oldfile(const char *filename);
|
||||
int mkdir_p(const char *path_utf8);
|
||||
|
||||
#endif /* !__FILECHECK_H__ */
|
||||
|
||||
Reference in New Issue
Block a user