Refactor write_buffer_to_file to use a flags param

That is clearer than two boolean parameters.
This commit is contained in:
Maxime Coste 2019-02-12 20:18:34 +11:00
parent 6da4761065
commit e8f26cbae7
4 changed files with 34 additions and 25 deletions

View File

@ -328,7 +328,7 @@ const ParameterDesc write_params{
ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 1 ParameterDesc::Flags::SwitchesOnlyAtStart, 0, 1
}; };
void do_write_buffer(Context& context, Optional<String> filename, bool sync_file, bool force) void do_write_buffer(Context& context, Optional<String> filename, WriteFlags flags)
{ {
Buffer& buffer = context.buffer(); Buffer& buffer = context.buffer();
@ -344,7 +344,7 @@ void do_write_buffer(Context& context, Optional<String> filename, bool sync_file
auto effective_filename = not filename ? buffer.name() : parse_filename(*filename); auto effective_filename = not filename ? buffer.name() : parse_filename(*filename);
context.hooks().run_hook(Hook::BufWritePre, effective_filename, context); context.hooks().run_hook(Hook::BufWritePre, effective_filename, context);
write_buffer_to_file(buffer, effective_filename, force, sync_file); write_buffer_to_file(buffer, effective_filename, flags);
context.hooks().run_hook(Hook::BufWritePost, effective_filename, context); context.hooks().run_hook(Hook::BufWritePost, effective_filename, context);
} }
@ -353,7 +353,8 @@ void write_buffer(const ParametersParser& parser, Context& context, const ShellC
{ {
return do_write_buffer(context, return do_write_buffer(context,
parser.positional_count() > 0 ? parser[0] : Optional<String>{}, parser.positional_count() > 0 ? parser[0] : Optional<String>{},
(bool)parser.get_switch("sync"), force); (parser.get_switch("sync") ? WriteFlags::Sync : WriteFlags::None) |
(force ? WriteFlags::Force : WriteFlags::None));
} }
const CommandDesc write_cmd = { const CommandDesc write_cmd = {
@ -395,7 +396,7 @@ void write_all_buffers(Context& context, bool sync = false)
and !(buffer->flags() & Buffer::Flags::ReadOnly)) and !(buffer->flags() & Buffer::Flags::ReadOnly))
{ {
buffer->run_hook_in_own_context(Hook::BufWritePre, buffer->name(), context.name()); buffer->run_hook_in_own_context(Hook::BufWritePre, buffer->name(), context.name());
write_buffer_to_file(*buffer, buffer->name(), sync); write_buffer_to_file(*buffer, buffer->name(), sync ? WriteFlags::Sync : WriteFlags::None);
buffer->run_hook_in_own_context(Hook::BufWritePost, buffer->name(), context.name()); buffer->run_hook_in_own_context(Hook::BufWritePost, buffer->name(), context.name());
} }
} }
@ -520,7 +521,7 @@ template<bool force>
void write_quit(const ParametersParser& parser, Context& context, void write_quit(const ParametersParser& parser, Context& context,
const ShellContext& shell_context) const ShellContext& shell_context)
{ {
do_write_buffer(context, {}, (bool)parser.get_switch("sync"), false); do_write_buffer(context, {}, parser.get_switch("sync") ? WriteFlags::Sync : WriteFlags::None);
quit<force>(parser, context, shell_context); quit<force>(parser, context, shell_context);
} }

View File

@ -257,7 +257,7 @@ void write(int fd, StringView data)
} }
} }
void write_buffer_to_fd(Buffer& buffer, int fd, bool sync) void write_buffer_to_fd(Buffer& buffer, int fd)
{ {
auto eolformat = buffer.options()["eolformat"].get<EolFormat>(); auto eolformat = buffer.options()["eolformat"].get<EolFormat>();
StringView eoldata; StringView eoldata;
@ -278,38 +278,35 @@ void write_buffer_to_fd(Buffer& buffer, int fd, bool sync)
write(fd, linedata.substr(0, linedata.length()-1)); write(fd, linedata.substr(0, linedata.length()-1));
write(fd, eoldata); write(fd, eoldata);
} }
if (sync)
::fsync(fd);
} }
void write_buffer_to_file(Buffer& buffer, StringView filename, bool force, bool sync) void write_buffer_to_file(Buffer& buffer, StringView filename, WriteFlags flags)
{ {
struct stat st; struct stat st;
auto zfilename = filename.zstr(); auto zfilename = filename.zstr();
if (force) if (flags & WriteFlags::Force and ::stat(zfilename, &st) == 0)
{ {
if (::stat(zfilename, &st) == 0) if (::chmod(zfilename, st.st_mode | S_IWUSR) < 0)
{ throw runtime_error("unable to change file permissions");
if (::chmod(zfilename, st.st_mode | S_IWUSR) < 0)
throw runtime_error("unable to change file permissions");
}
else
force = false;
} }
else
flags |= ~WriteFlags::Force;
auto restore_mode = on_scope_end([&]{ auto restore_mode = on_scope_end([&]{
if (force and ::chmod(zfilename, st.st_mode) < 0) if (flags & WriteFlags::Force and ::chmod(zfilename, st.st_mode) < 0)
throw runtime_error("unable to restore file permissions"); throw runtime_error("unable to restore file permissions");
}); });
int fd = open(zfilename, O_CREAT | O_WRONLY | O_TRUNC, 0644); const int fd = open(zfilename, O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (fd == -1) if (fd == -1)
throw file_access_error(filename, strerror(errno)); throw file_access_error(filename, strerror(errno));
{ {
auto close_fd = on_scope_end([fd]{ close(fd); }); auto close_fd = on_scope_end([fd]{ close(fd); });
write_buffer_to_fd(buffer, fd, sync); write_buffer_to_fd(buffer, fd);
if (flags & WriteFlags::Sync)
::fsync(fd);
} }
if ((buffer.flags() & Buffer::Flags::File) and if ((buffer.flags() & Buffer::Flags::File) and

View File

@ -51,8 +51,17 @@ struct MappedFile
struct stat st {}; struct stat st {};
}; };
void write_buffer_to_file(Buffer& buffer, StringView filename, bool force = false, bool sync = false); enum class WriteFlags
void write_buffer_to_fd(Buffer& buffer, int fd, bool sync = false); {
None = 0,
Force = 0b01,
Sync = 0b10
};
constexpr bool with_bit_ops(Meta::Type<WriteFlags>) { return true; }
void write_buffer_to_file(Buffer& buffer, StringView filename,
WriteFlags flags);
void write_buffer_to_fd(Buffer& buffer, int fd);
void write_buffer_to_backup_file(Buffer& buffer); void write_buffer_to_backup_file(Buffer& buffer);
String find_file(StringView filename, StringView buf_dir, ConstArrayView<String> paths); String find_file(StringView filename, StringView buf_dir, ConstArrayView<String> paths);

View File

@ -847,9 +847,11 @@ int run_filter(StringView keystr, ConstArrayView<StringView> files, bool quiet,
{ {
Buffer* buffer = open_file_buffer(file, Buffer::Flags::NoHooks); Buffer* buffer = open_file_buffer(file, Buffer::Flags::NoHooks);
if (not suffix_backup.empty()) if (not suffix_backup.empty())
write_buffer_to_file(*buffer, buffer->name() + suffix_backup); write_buffer_to_file(*buffer, buffer->name() + suffix_backup,
WriteFlags::None);
apply_to_buffer(*buffer); apply_to_buffer(*buffer);
write_buffer_to_file(*buffer, buffer->name()); write_buffer_to_file(*buffer, buffer->name(),
WriteFlags::None);
buffer_manager.delete_buffer(*buffer); buffer_manager.delete_buffer(*buffer);
} }
if (not isatty(0)) if (not isatty(0))