mirror of
https://github.com/neovim/neovim.git
synced 2025-10-08 02:46:31 +00:00
vim-patch:9.0.0379: cleaning up after writefile() is a hassle
Problem: Cleaning up after writefile() is a hassle.
Solution: Add the 'D' flag to defer deleting the written file. Very useful
in tests.
806a273f3c
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
@@ -9296,6 +9296,7 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
|
||||
bool binary = false;
|
||||
bool append = false;
|
||||
bool defer = false;
|
||||
bool do_fsync = !!p_fs;
|
||||
bool mkdir_p = false;
|
||||
if (argvars[2].v_type != VAR_UNKNOWN) {
|
||||
@@ -9309,6 +9310,8 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
binary = true; break;
|
||||
case 'a':
|
||||
append = true; break;
|
||||
case 'D':
|
||||
defer = true; break;
|
||||
case 's':
|
||||
do_fsync = true; break;
|
||||
case 'S':
|
||||
@@ -9328,6 +9331,12 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
if (fname == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (defer && get_current_funccal() == NULL) {
|
||||
semsg(_(e_str_not_inside_function), "defer");
|
||||
return;
|
||||
}
|
||||
|
||||
FileDescriptor fp;
|
||||
int error;
|
||||
if (*fname == NUL) {
|
||||
@@ -9336,9 +9345,17 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
((append ? kFileAppend : kFileTruncate)
|
||||
| (mkdir_p ? kFileMkDir : kFileCreate)
|
||||
| kFileCreate), 0666)) != 0) {
|
||||
semsg(_("E482: Can't open file %s for writing: %s"),
|
||||
fname, os_strerror(error));
|
||||
semsg(_("E482: Can't open file %s for writing: %s"), fname, os_strerror(error));
|
||||
} else {
|
||||
if (defer) {
|
||||
typval_T tv = {
|
||||
.v_type = VAR_STRING,
|
||||
.v_lock = VAR_UNLOCKED,
|
||||
.vval.v_string = xstrdup(fname),
|
||||
};
|
||||
add_defer("delete", 1, &tv);
|
||||
}
|
||||
|
||||
bool write_ok;
|
||||
if (argvars[0].v_type == VAR_BLOB) {
|
||||
write_ok = write_blob(&fp, argvars[0].vval.v_blob);
|
||||
|
@@ -478,6 +478,7 @@ void emsg_funcname(const char *errmsg, const char *name)
|
||||
|
||||
/// Get function arguments at "*arg" and advance it.
|
||||
/// Return them in "*argvars[MAX_FUNC_ARGS + 1]" and the count in "argcount".
|
||||
/// On failure FAIL is returned but the "argvars[argcount]" are still set.
|
||||
static int get_func_arguments(char **arg, evalarg_T *const evalarg, int partial_argc,
|
||||
typval_T *argvars, int *argcount)
|
||||
{
|
||||
@@ -3119,16 +3120,28 @@ static int ex_defer_inner(char *name, char **arg, evalarg_T *const evalarg)
|
||||
{
|
||||
typval_T argvars[MAX_FUNC_ARGS + 1]; // vars for arguments
|
||||
int argcount = 0; // number of arguments found
|
||||
int ret = FAIL;
|
||||
|
||||
if (current_funccal == NULL) {
|
||||
semsg(_(e_str_not_inside_function), "defer");
|
||||
return FAIL;
|
||||
}
|
||||
if (get_func_arguments(arg, evalarg, false, argvars, &argcount) == FAIL) {
|
||||
goto theend;
|
||||
while (--argcount >= 0) {
|
||||
tv_clear(&argvars[argcount]);
|
||||
}
|
||||
return FAIL;
|
||||
}
|
||||
add_defer(name, argcount, argvars);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/// Add a deferred call for "name" with arguments "argvars[argcount]".
|
||||
/// Consumes "argvars[]".
|
||||
/// Caller must check that current_funccal is not NULL.
|
||||
void add_defer(char *name, int argcount_arg, typval_T *argvars)
|
||||
{
|
||||
char *saved_name = xstrdup(name);
|
||||
int argcount = argcount_arg;
|
||||
|
||||
if (current_funccal->fc_defer.ga_itemsize == 0) {
|
||||
ga_init(¤t_funccal->fc_defer, sizeof(defer_T), 10);
|
||||
@@ -3140,13 +3153,6 @@ static int ex_defer_inner(char *name, char **arg, evalarg_T *const evalarg)
|
||||
argcount--;
|
||||
dr->dr_argvars[argcount] = argvars[argcount];
|
||||
}
|
||||
ret = OK;
|
||||
|
||||
theend:
|
||||
while (--argcount >= 0) {
|
||||
tv_clear(&argvars[argcount]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Invoked after a function has finished: invoke ":defer" functions.
|
||||
|
Reference in New Issue
Block a user