123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- // Formatting library for C++ - custom Google Test assertions
- //
- // Copyright (c) 2012 - present, Victor Zverovich
- // All rights reserved.
- //
- // For the license information refer to format.h.
- #include "gtest-extra.h"
- #if FMT_USE_FCNTL
- using fmt::file;
- void OutputRedirect::flush() {
- # if EOF != -1
- # error "FMT_RETRY assumes return value of -1 indicating failure"
- # endif
- int result = 0;
- FMT_RETRY(result, fflush(file_));
- if (result != 0) throw fmt::system_error(errno, "cannot flush stream");
- }
- void OutputRedirect::restore() {
- if (original_.descriptor() == -1) return; // Already restored.
- flush();
- // Restore the original file.
- original_.dup2(FMT_POSIX(fileno(file_)));
- original_.close();
- }
- OutputRedirect::OutputRedirect(FILE* f) : file_(f) {
- flush();
- int fd = FMT_POSIX(fileno(f));
- // Create a file object referring to the original file.
- original_ = file::dup(fd);
- // Create a pipe.
- file write_end;
- file::pipe(read_end_, write_end);
- // Connect the passed FILE object to the write end of the pipe.
- write_end.dup2(fd);
- }
- OutputRedirect::~OutputRedirect() FMT_NOEXCEPT {
- try {
- restore();
- } catch (const std::exception& e) {
- std::fputs(e.what(), stderr);
- }
- }
- std::string OutputRedirect::restore_and_read() {
- // Restore output.
- restore();
- // Read everything from the pipe.
- std::string content;
- if (read_end_.descriptor() == -1) return content; // Already read.
- enum { BUFFER_SIZE = 4096 };
- char buffer[BUFFER_SIZE];
- size_t count = 0;
- do {
- count = read_end_.read(buffer, BUFFER_SIZE);
- content.append(buffer, count);
- } while (count != 0);
- read_end_.close();
- return content;
- }
- std::string read(file& f, size_t count) {
- std::string buffer(count, '\0');
- size_t n = 0, offset = 0;
- do {
- n = f.read(&buffer[offset], count - offset);
- // We can't read more than size_t bytes since count has type size_t.
- offset += n;
- } while (offset < count && n != 0);
- buffer.resize(offset);
- return buffer;
- }
- #endif // FMT_USE_FCNTL
- std::string format_system_error(int error_code, fmt::string_view message) {
- fmt::memory_buffer out;
- format_system_error(out, error_code, message);
- return to_string(out);
- }
|