From 0c27c1175b0ab168778fe0dfdff441885486dda3 Mon Sep 17 00:00:00 2001 From: yilisharcs Date: Wed, 17 Dec 2025 13:05:16 -0300 Subject: [PATCH] refactor(editor): extract backup name generation logic #37001 Problem: The logic for generating backup file names is duplicated in `buf_write_make_backup` and difficult to reuse. Solution: Extract name generation logic into `buf_get_backup_name`. --- src/nvim/bufwrite.c | 107 ++++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 69 deletions(-) diff --git a/src/nvim/bufwrite.c b/src/nvim/bufwrite.c index 1200660722..f6c6139372 100644 --- a/src/nvim/bufwrite.c +++ b/src/nvim/bufwrite.c @@ -715,6 +715,40 @@ static int get_fileinfo(buf_T *buf, char *fname, bool overwriting, bool forceit, return OK; } +/// @return The backup file name +char *buf_get_backup_name(char *fname, char **dirp, bool no_prepend_dot, char *backup_ext) +{ + char *backup = NULL; + // Isolate one directory name, using an entry in 'bdir'. + size_t dir_len = copy_option_part(dirp, IObuff, IOSIZE, ","); + char *p = IObuff + dir_len; + if (**dirp == NUL && !os_isdir(IObuff)) { + int ret; + char *failed_dir; + if ((ret = os_mkdir_recurse(IObuff, 0755, &failed_dir, NULL)) != 0) { + semsg(_("E303: Unable to create directory \"%s\" for backup file: %s"), + failed_dir, os_strerror(ret)); + xfree(failed_dir); + } + } + if (after_pathsep(IObuff, p) && p[-1] == p[-2]) { + // path ends with '//', use full path + if ((p = make_percent_swname(IObuff, p, fname)) + != NULL) { + backup = modname(p, backup_ext, no_prepend_dot); + xfree(p); + } + } + if (backup == NULL) { + char *rootname = get_file_in_dir(fname, IObuff); + if (rootname != NULL) { + backup = modname(rootname, backup_ext, no_prepend_dot); + xfree(rootname); + } + } + return backup; +} + static int buf_write_make_backup(char *fname, bool append, FileInfo *file_info_old, vim_acl_T acl, int perm, unsigned bkc, bool file_readonly, bool forceit, bool *backup_copyp, char **backupp, Error_T *err) @@ -810,48 +844,14 @@ static int buf_write_make_backup(char *fname, bool append, FileInfo *file_info_o // and reused. Creation of a backup COPY will be attempted. char *dirp = p_bdir; while (*dirp) { - // Isolate one directory name, using an entry in 'bdir'. - size_t dir_len = copy_option_part(&dirp, IObuff, IOSIZE, ","); - char *p = IObuff + dir_len; - if (*dirp == NUL && !os_isdir(IObuff)) { - int ret; - char *failed_dir; - if ((ret = os_mkdir_recurse(IObuff, 0755, &failed_dir, NULL)) != 0) { - semsg(_("E303: Unable to create directory \"%s\" for backup file: %s"), - failed_dir, os_strerror(ret)); - xfree(failed_dir); - } - } - if (after_pathsep(IObuff, p) && p[-1] == p[-2]) { - // Ends with '//', Use Full path - if ((p = make_percent_swname(IObuff, p, fname)) - != NULL) { - *backupp = modname(p, backup_ext, no_prepend_dot); - xfree(p); - } - } - - char *rootname = get_file_in_dir(fname, IObuff); - if (rootname == NULL) { + *backupp = buf_get_backup_name(fname, &dirp, no_prepend_dot, backup_ext); + if (*backupp == NULL) { some_error = true; // out of memory goto nobackup; } FileInfo file_info_new; { - // - // Make the backup file name. - // - if (*backupp == NULL) { - *backupp = modname(rootname, backup_ext, no_prepend_dot); - } - - if (*backupp == NULL) { - xfree(rootname); - some_error = true; // out of memory - goto nobackup; - } - // Check if backup file already exists. if (os_fileinfo(*backupp, &file_info_new)) { if (os_fileinfo_id_equal(&file_info_new, file_info_old)) { @@ -880,7 +880,6 @@ static int buf_write_make_backup(char *fname, bool append, FileInfo *file_info_o } } } - xfree(rootname); // Try to create the backup file if (*backupp != NULL) { @@ -946,43 +945,13 @@ nobackup: // that works is used. char *dirp = p_bdir; while (*dirp) { - // Isolate one directory name and make the backup file name. - size_t dir_len = copy_option_part(&dirp, IObuff, IOSIZE, ","); - char *p = IObuff + dir_len; - if (*dirp == NUL && !os_isdir(IObuff)) { - int ret; - char *failed_dir; - if ((ret = os_mkdir_recurse(IObuff, 0755, &failed_dir, NULL)) != 0) { - semsg(_("E303: Unable to create directory \"%s\" for backup file: %s"), - failed_dir, os_strerror(ret)); - xfree(failed_dir); - } - } - if (after_pathsep(IObuff, p) && p[-1] == p[-2]) { - // path ends with '//', use full path - if ((p = make_percent_swname(IObuff, p, fname)) - != NULL) { - *backupp = modname(p, backup_ext, no_prepend_dot); - xfree(p); - } - } - - if (*backupp == NULL) { - char *rootname = get_file_in_dir(fname, IObuff); - if (rootname == NULL) { - *backupp = NULL; - } else { - *backupp = modname(rootname, backup_ext, no_prepend_dot); - xfree(rootname); - } - } - + *backupp = buf_get_backup_name(fname, &dirp, no_prepend_dot, backup_ext); if (*backupp != NULL) { // If we are not going to keep the backup file, don't // delete an existing one, try to use another name. // Change one character, just before the extension. if (!p_bk && os_path_exists(*backupp)) { - p = *backupp + strlen(*backupp) - 1 - strlen(backup_ext); + char *p = *backupp + strlen(*backupp) - 1 - strlen(backup_ext); p = MAX(p, *backupp); // empty file name ??? *p = 'z'; while (*p > 'a' && os_path_exists(*backupp)) {