diff --git a/src/cmdl.c b/src/cmdl.c index eac76f0..43c7c8e 100644 --- a/src/cmdl.c +++ b/src/cmdl.c @@ -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); diff --git a/src/cmdq.c b/src/cmdq.c index f7c69b7..d3a0a15 100644 --- a/src/cmdq.c +++ b/src/cmdq.c @@ -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); diff --git a/src/filecheck.c b/src/filecheck.c index 9c5bba7..6da3025 100644 --- a/src/filecheck.c +++ b/src/filecheck.c @@ -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; } diff --git a/src/filecheck.h b/src/filecheck.h index 85e3d2d..76a6eb4 100644 --- a/src/filecheck.h +++ b/src/filecheck.h @@ -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__ */