diff --git a/docs/changelog.txt b/docs/changelog.txt index 67f4c817c..6c1b46841 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -48,6 +48,11 @@ USERS hacks (DOS) when copying blocks between boards in the editor. + Fixed text input bugs caused by a 2.93b change accidentally reenabling old deadcode for exiting intake(). ++ Fixed crash when saving editor config files/"Set as Default" + after the file fails to open for write. If the ".editor.cnf" + file fails to save or load, MZX will attempt to save or load a + ".cne" file instead. This allows this feature to work in DOS + builds when there is no long filename (LFN) support. DEVELOPERS diff --git a/src/editor/configure.c b/src/editor/configure.c index d6543194a..e1ca3612f 100644 --- a/src/editor/configure.c +++ b/src/editor/configure.c @@ -882,28 +882,77 @@ void free_editor_config(void) __free_editor_config(&editor_conf_backup); } +static size_t editor_config_full_name(char *dest, size_t dest_len, + const char *path, size_t path_len) +{ + size_t ret = snprintf(dest, dest_len, "%.*s.editor.cnf", + (int)path_len - 4, path); + dest[dest_len - 1] = '\0'; + return ret; +} + +static size_t editor_config_dos_name(char *dest, size_t dest_len, + const char *path, size_t path_len) +{ + size_t ret = snprintf(dest, dest_len, "%.*s.cne", + (int)path_len - 4, path); + dest[dest_len - 1] = '\0'; + return ret; +} + +/* Get the existing world file editor config name, if present. It may have + * the extension .editor.cnf (usual) or the extension .cne (DOS). */ +size_t get_local_editor_config_name(char *dest, size_t dest_len, + const char *mzx_file_path) +{ + struct stat file_info; + size_t path_len = strlen(mzx_file_path); + size_t ret; + + if(path_len < 4) + return 0; + + ret = editor_config_full_name(dest, dest_len, mzx_file_path, path_len); + if(ret < dest_len && + vstat(dest, &file_info) >= 0 && S_ISREG(file_info.st_mode)) + { + debug("found editor config: %s\n", dest); + return ret; + } + + ret = editor_config_dos_name(dest, dest_len, mzx_file_path, path_len); + if(ret < dest_len && + vstat(dest, &file_info) >= 0 && S_ISREG(file_info.st_mode)) + { + debug("found editor config: %s\n", dest); + return ret; + } + + return 0; +} + +// TODO: update this function once there's a good config rewriting routine. void save_local_editor_config(struct editor_config_info *conf, const char *mzx_file_path) { - int mzx_file_len = strlen(mzx_file_path) - 4; + size_t mzx_file_len = strlen(mzx_file_path); char config_file_name[MAX_PATH]; const char comment[] = "\n############################################################"; const char comment_a[] = "\n##### Editor generated configuration - do not modify #####"; const char comment_b[] = "\n##### End editor generated configuration #####"; const char *value; - vfile *vf; + vfile *vf = NULL; + boolean exists = false; int i; - if(mzx_file_len <= 0) + if(mzx_file_len < 4) return; - // Get our filename - snprintf(config_file_name, MAX_PATH, "%.*s.editor.cnf", - mzx_file_len, mzx_file_path); - // Does it exist? - vf = vfopen_unsafe(config_file_name, "rb"); + if(get_local_editor_config_name(config_file_name, MAX_PATH, mzx_file_path) > 0) + vf = vfopen_unsafe(config_file_name, "rb"); + if(vf) { char *a, *b; @@ -912,6 +961,8 @@ void save_local_editor_config(struct editor_config_info *conf, int config_file_size = 0; int config_file_size_b = 0; + exists = true; + config_file_size = vfilelength(vf, true); config_file = cmalloc(config_file_size + 1); @@ -952,6 +1003,11 @@ void save_local_editor_config(struct editor_config_info *conf, } vf = vfopen_unsafe(config_file_name, "wb"); + if(!vf) + { + warn("failed to rewrite editor config file\n"); + return; + } if(config_file_size) vfwrite(config_file, 1, config_file_size, vf); @@ -962,7 +1018,29 @@ void save_local_editor_config(struct editor_config_info *conf, free(config_file); } + if(!exists) + { + // Try creating a file with the normal name first. This may fail in DOS. + editor_config_full_name(config_file_name, MAX_PATH, + mzx_file_path, mzx_file_len); + } + vf = vfopen_unsafe(config_file_name, "a"); + if(!vf) + { + if(!exists) + { + editor_config_dos_name(config_file_name, MAX_PATH, + mzx_file_path, mzx_file_len); + vf = vfopen_unsafe(config_file_name, "a"); + } + if(!vf) + { + warn("failed to rewrite editor config file\n"); + return; + } + } + debug("writing editor config: %s\n", config_file_name); vf_printf(vf, "%s%s%s\n\n", comment, comment_a, comment); diff --git a/src/editor/configure.h b/src/editor/configure.h index 19e2f86a8..9bb632f1b 100644 --- a/src/editor/configure.h +++ b/src/editor/configure.h @@ -139,6 +139,8 @@ EDITOR_LIBSPEC void free_editor_config(void); EDITOR_LIBSPEC struct editor_config_info *get_editor_config(void); void load_editor_config_backup(void); +size_t get_local_editor_config_name(char *dest, size_t dest_len, + const char *mzx_file_path); void save_local_editor_config(struct editor_config_info *conf, const char *mzx_file_path); diff --git a/src/editor/edit.c b/src/editor/edit.c index dd03d2214..8a175a244 100644 --- a/src/editor/edit.c +++ b/src/editor/edit.c @@ -218,9 +218,7 @@ static boolean editor_reload_world(struct editor_context *editor, { struct world *mzx_world = ((context *)editor)->world; - int file_name_len = strlen(file) - 4; char config_file_name[MAX_PATH]; - struct stat file_info; boolean ignore; if(!reload_world(mzx_world, file, &ignore)) @@ -230,11 +228,7 @@ static boolean editor_reload_world(struct editor_context *editor, load_editor_config_backup(); // Part 2: Now load the new world.editor.cnf. - - snprintf(config_file_name, MAX_PATH, "%.*s.editor.cnf", file_name_len, file); - config_file_name[MAX_PATH - 1] = '\0'; - - if(vstat(config_file_name, &file_info) >= 0) + if(get_local_editor_config_name(config_file_name, MAX_PATH, file) > 0) set_config_from_file(GAME_EDITOR_CNF, config_file_name); edit_menu_show_board_mod(editor->edit_menu);