eval: Add s flag, use p_fs by default, error out on unknown flag

This commit is contained in:
ZyX 2017-04-03 02:11:27 +03:00
parent 5dcf280445
commit 97a7f4745d
3 changed files with 27 additions and 13 deletions

View File

@ -7916,10 +7916,11 @@ writefile({list}, {fname} [, {flags}])
:call writefile(["foo"], "event.log", "a") :call writefile(["foo"], "event.log", "a")
:call writefile(["bar"], "event.log", "a") :call writefile(["bar"], "event.log", "a")
< <
When {flags} contains "S" fsync() call is not used. This means When {flags} contains "S" fsync() call is not used, with "s"
that writefile() will finish faster, but writes may be left in it is used, 'fsync' option applies by default. No fsync()
OS buffers and not yet written to disk. Such changes will means that writefile() will finish faster, but writes may be
disappear if system crashes before OS does writing. left in OS buffers and not yet written to disk. Such changes
will disappear if system crashes before OS does writing.
All NL characters are replaced with a NUL character. All NL characters are replaced with a NUL character.
Inserting CR characters needs to be done before passing {list} Inserting CR characters needs to be done before passing {list}

View File

@ -17421,20 +17421,24 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
bool binary = false; bool binary = false;
bool append = false; bool append = false;
bool do_fsync = true; bool do_fsync = !!p_fs;
if (argvars[2].v_type != VAR_UNKNOWN) { if (argvars[2].v_type != VAR_UNKNOWN) {
const char *const flags = tv_get_string_chk(&argvars[2]); const char *const flags = tv_get_string_chk(&argvars[2]);
if (flags == NULL) { if (flags == NULL) {
return; return;
} }
if (strchr(flags, 'b')) { for (const char *p = flags; *p; p++) {
binary = true; switch (*p) {
} case 'b': { binary = true; break; }
if (strchr(flags, 'a')) { case 'a': { append = true; break; }
append = true; case 's': { do_fsync = true; break; }
} case 'S': { do_fsync = false; break; }
if (strchr(flags, 'S')) { default: {
do_fsync = false; // Using %s, p and not %c, *p to preserve multibyte characters
emsgf(_("E5060: Unknown flag: %s"), p);
return;
}
}
} }
} }

View File

@ -80,6 +80,13 @@ describe('writefile()', function()
eq('a\0\0\0b', read_file(fname)) eq('a\0\0\0b', read_file(fname))
end) end)
it('writes with s and S', function()
eq(0, funcs.writefile({'\na\nb\n'}, fname, 'bs'))
eq('\0a\0b\0', read_file(fname))
eq(0, funcs.writefile({'a\n\n\nb'}, fname, 'bS'))
eq('a\0\0\0b', read_file(fname))
end)
it('correctly overwrites file', function() it('correctly overwrites file', function()
eq(0, funcs.writefile({'\na\nb\n'}, fname, 'b')) eq(0, funcs.writefile({'\na\nb\n'}, fname, 'b'))
eq('\0a\0b\0', read_file(fname)) eq('\0a\0b\0', read_file(fname))
@ -115,6 +122,8 @@ describe('writefile()', function()
eq('\nE729: using Funcref as a String', eq('\nE729: using Funcref as a String',
redir_exec(('call writefile(%s)'):format(args:format('function("tr")')))) redir_exec(('call writefile(%s)'):format(args:format('function("tr")'))))
end end
eq('\nE5060: Unknown flag: «»',
redir_exec(('call writefile([], "%s", "bs«»")'):format(fname)))
eq('TEST', read_file(fname)) eq('TEST', read_file(fname))
end) end)