gtest-extra.cc 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Formatting library for C++ - custom Google Test assertions
  2. //
  3. // Copyright (c) 2012 - present, Victor Zverovich
  4. // All rights reserved.
  5. //
  6. // For the license information refer to format.h.
  7. #include "gtest-extra.h"
  8. #if FMT_USE_FCNTL
  9. using fmt::file;
  10. void OutputRedirect::flush() {
  11. # if EOF != -1
  12. # error "FMT_RETRY assumes return value of -1 indicating failure"
  13. # endif
  14. int result = 0;
  15. FMT_RETRY(result, fflush(file_));
  16. if (result != 0) throw fmt::system_error(errno, "cannot flush stream");
  17. }
  18. void OutputRedirect::restore() {
  19. if (original_.descriptor() == -1) return; // Already restored.
  20. flush();
  21. // Restore the original file.
  22. original_.dup2(FMT_POSIX(fileno(file_)));
  23. original_.close();
  24. }
  25. OutputRedirect::OutputRedirect(FILE* f) : file_(f) {
  26. flush();
  27. int fd = FMT_POSIX(fileno(f));
  28. // Create a file object referring to the original file.
  29. original_ = file::dup(fd);
  30. // Create a pipe.
  31. file write_end;
  32. file::pipe(read_end_, write_end);
  33. // Connect the passed FILE object to the write end of the pipe.
  34. write_end.dup2(fd);
  35. }
  36. OutputRedirect::~OutputRedirect() FMT_NOEXCEPT {
  37. try {
  38. restore();
  39. } catch (const std::exception& e) {
  40. std::fputs(e.what(), stderr);
  41. }
  42. }
  43. std::string OutputRedirect::restore_and_read() {
  44. // Restore output.
  45. restore();
  46. // Read everything from the pipe.
  47. std::string content;
  48. if (read_end_.descriptor() == -1) return content; // Already read.
  49. enum { BUFFER_SIZE = 4096 };
  50. char buffer[BUFFER_SIZE];
  51. size_t count = 0;
  52. do {
  53. count = read_end_.read(buffer, BUFFER_SIZE);
  54. content.append(buffer, count);
  55. } while (count != 0);
  56. read_end_.close();
  57. return content;
  58. }
  59. std::string read(file& f, size_t count) {
  60. std::string buffer(count, '\0');
  61. size_t n = 0, offset = 0;
  62. do {
  63. n = f.read(&buffer[offset], count - offset);
  64. // We can't read more than size_t bytes since count has type size_t.
  65. offset += n;
  66. } while (offset < count && n != 0);
  67. buffer.resize(offset);
  68. return buffer;
  69. }
  70. #endif // FMT_USE_FCNTL
  71. std::string format_system_error(int error_code, fmt::string_view message) {
  72. fmt::memory_buffer out;
  73. format_system_error(out, error_code, message);
  74. return to_string(out);
  75. }