| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 | // 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_FCNTLusing fmt::file;output_redirect::output_redirect(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);}output_redirect::~output_redirect() noexcept {  try {    restore();  } catch (const std::exception& e) {    std::fputs(e.what(), stderr);  }}void output_redirect::flush() {  int result = 0;  do {    result = fflush(file_);  } while (result == EOF && errno == EINTR);  if (result != 0) throw fmt::system_error(errno, "cannot flush stream");}void output_redirect::restore() {  if (original_.descriptor() == -1) return;  // Already restored.  flush();  // Restore the original file.  original_.dup2(FMT_POSIX(fileno(file_)));  original_.close();}std::string output_redirect::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
 |