comparison dep/fmt/test/gtest-extra.cc @ 343:1faa72660932

*: transfer back to cmake from autotools autotools just made lots of things more complicated than they should have and many things broke (i.e. translations)
author Paper <paper@paper.us.eu.org>
date Thu, 20 Jun 2024 05:56:06 -0400
parents
children
comparison
equal deleted inserted replaced
342:adb79bdde329 343:1faa72660932
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
8 #include "gtest-extra.h"
9
10 #if FMT_USE_FCNTL
11
12 using fmt::file;
13
14 output_redirect::output_redirect(FILE* f, bool flush) : file_(f) {
15 if (flush) this->flush();
16 int fd = FMT_POSIX(fileno(f));
17 // Create a file object referring to the original file.
18 original_ = file::dup(fd);
19 // Create a pipe.
20 file write_end;
21 file::pipe(read_end_, write_end);
22 // Connect the passed FILE object to the write end of the pipe.
23 write_end.dup2(fd);
24 }
25
26 output_redirect::~output_redirect() noexcept {
27 try {
28 restore();
29 } catch (const std::exception& e) {
30 std::fputs(e.what(), stderr);
31 }
32 }
33
34 void output_redirect::flush() {
35 int result = 0;
36 do {
37 result = fflush(file_);
38 } while (result == EOF && errno == EINTR);
39 if (result != 0) throw fmt::system_error(errno, "cannot flush stream");
40 }
41
42 void output_redirect::restore() {
43 if (original_.descriptor() == -1) return; // Already restored.
44 flush();
45 // Restore the original file.
46 original_.dup2(FMT_POSIX(fileno(file_)));
47 original_.close();
48 }
49
50 std::string output_redirect::restore_and_read() {
51 // Restore output.
52 restore();
53
54 // Read everything from the pipe.
55 std::string content;
56 if (read_end_.descriptor() == -1) return content; // Already read.
57 enum { BUFFER_SIZE = 4096 };
58 char buffer[BUFFER_SIZE];
59 size_t count = 0;
60 do {
61 count = read_end_.read(buffer, BUFFER_SIZE);
62 content.append(buffer, count);
63 } while (count != 0);
64 read_end_.close();
65 return content;
66 }
67
68 std::string read(file& f, size_t count) {
69 std::string buffer(count, '\0');
70 size_t n = 0, offset = 0;
71 do {
72 n = f.read(&buffer[offset], count - offset);
73 // We can't read more than size_t bytes since count has type size_t.
74 offset += n;
75 } while (offset < count && n != 0);
76 buffer.resize(offset);
77 return buffer;
78 }
79
80 #endif // FMT_USE_FCNTL