Add support for line buffering
This commit is contained in:
parent
6f260455aa
commit
6435b169ec
@ -1517,6 +1517,12 @@ template <typename F> class apple_file : public file_base<F> {
|
|||||||
this->file_->_p += size;
|
this->file_->_p += size;
|
||||||
this->file_->_w -= size;
|
this->file_->_w -= size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool needs_flush() const {
|
||||||
|
if ((this->file_->_flags & 1) == 0) return false; // 1 is __SLBF.
|
||||||
|
return memchr(this->file_->_p + this->file_->_w, '\n',
|
||||||
|
to_unsigned(-this->file_->_w));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// A fallback FILE wrapper.
|
// A fallback FILE wrapper.
|
||||||
@ -1529,6 +1535,7 @@ template <typename F> class fallback_file : public file_base<F> {
|
|||||||
using file_base<F>::file_base;
|
using file_base<F>::file_base;
|
||||||
|
|
||||||
auto is_buffered() const -> bool { return false; }
|
auto is_buffered() const -> bool { return false; }
|
||||||
|
auto needs_flush() const -> bool { return false; }
|
||||||
|
|
||||||
auto get_read_buffer() const -> span<const char> {
|
auto get_read_buffer() const -> span<const char> {
|
||||||
return {&next_, has_next_ ? 1u : 0u};
|
return {&next_, has_next_ ? 1u : 0u};
|
||||||
@ -1581,7 +1588,9 @@ class file_print_buffer : public buffer<char> {
|
|||||||
}
|
}
|
||||||
~file_print_buffer() {
|
~file_print_buffer() {
|
||||||
file_.advance_write_buffer(size());
|
file_.advance_write_buffer(size());
|
||||||
|
bool flush = file_.needs_flush();
|
||||||
funlockfile(file_);
|
funlockfile(file_);
|
||||||
|
if (flush) fflush(file_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1752,6 +1752,21 @@ TEST(format_test, big_print) {
|
|||||||
EXPECT_WRITE(stdout, big_print(), std::string(count, 'x'));
|
EXPECT_WRITE(stdout, big_print(), std::string(count, 'x'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Windows CRT implements _IOLBF incorrectly (full buffering).
|
||||||
|
#if FMT_USE_FCNTL && !defined(_WIN32)
|
||||||
|
TEST(format_test, line_buffering) {
|
||||||
|
auto pipe = fmt::pipe();
|
||||||
|
auto read_end = pipe.read_end.fdopen("r");
|
||||||
|
auto write_end = pipe.write_end.fdopen("w");
|
||||||
|
setvbuf(write_end.get(), nullptr, _IOLBF, 4096);
|
||||||
|
write_end.print("42\n");
|
||||||
|
int n = 0;
|
||||||
|
int result = fscanf(read_end.get(), "%d", &n);
|
||||||
|
(void)result;
|
||||||
|
EXPECT_EQ(n, 42);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST(format_test, variadic) {
|
TEST(format_test, variadic) {
|
||||||
EXPECT_EQ(fmt::format("{}c{}", "ab", 1), "abc1");
|
EXPECT_EQ(fmt::format("{}c{}", "ab", 1), "abc1");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user