mirror of
https://github.com/neovim/neovim.git
synced 2026-03-29 11:52:04 +00:00
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`.
This commit is contained in:
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user