| 
									
										
										
										
											2018-03-04 09:16:51 -08:00
										 |  |  | // 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.
 | 
					
						
							| 
									
										
										
										
											2014-05-03 09:48:54 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "gtest-extra.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 05:41:14 -08:00
										 |  |  | #if FMT_USE_FCNTL
 | 
					
						
							| 
									
										
										
										
											2014-05-03 09:48:54 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-19 10:32:53 -07:00
										 |  |  | using fmt::file; | 
					
						
							| 
									
										
										
										
											2014-05-04 06:44:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-29 07:50:05 -07:00
										 |  |  | void OutputRedirect::flush() { | 
					
						
							| 
									
										
										
										
											2019-01-12 18:27:38 -08:00
										 |  |  | #  if EOF != -1
 | 
					
						
							|  |  |  | #    error "FMT_RETRY assumes return value of -1 indicating failure"
 | 
					
						
							|  |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2014-05-04 09:01:18 -07:00
										 |  |  |   int result = 0; | 
					
						
							|  |  |  |   FMT_RETRY(result, fflush(file_)); | 
					
						
							| 
									
										
										
										
											2019-01-12 18:27:38 -08:00
										 |  |  |   if (result != 0) throw fmt::system_error(errno, "cannot flush stream"); | 
					
						
							| 
									
										
										
										
											2014-05-04 09:01:18 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-29 07:50:05 -07:00
										 |  |  | void OutputRedirect::restore() { | 
					
						
							| 
									
										
										
										
											2019-01-12 18:27:38 -08:00
										 |  |  |   if (original_.descriptor() == -1) return;  // Already restored.
 | 
					
						
							| 
									
										
										
										
											2014-07-29 07:50:05 -07:00
										 |  |  |   flush(); | 
					
						
							| 
									
										
										
										
											2014-05-04 09:01:18 -07:00
										 |  |  |   // Restore the original file.
 | 
					
						
							|  |  |  |   original_.dup2(FMT_POSIX(fileno(file_))); | 
					
						
							| 
									
										
										
										
											2014-05-04 10:08:29 -07:00
										 |  |  |   original_.close(); | 
					
						
							| 
									
										
										
										
											2014-05-04 09:01:18 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 18:27:38 -08:00
										 |  |  | OutputRedirect::OutputRedirect(FILE* f) : file_(f) { | 
					
						
							| 
									
										
										
										
											2014-07-29 07:50:05 -07:00
										 |  |  |   flush(); | 
					
						
							| 
									
										
										
										
											2018-05-19 10:32:53 -07:00
										 |  |  |   int fd = FMT_POSIX(fileno(f)); | 
					
						
							|  |  |  |   // Create a file object referring to the original file.
 | 
					
						
							|  |  |  |   original_ = file::dup(fd); | 
					
						
							| 
									
										
										
										
											2014-05-03 16:47:00 -07:00
										 |  |  |   // Create a pipe.
 | 
					
						
							| 
									
										
										
										
											2018-05-19 10:32:53 -07:00
										 |  |  |   file write_end; | 
					
						
							|  |  |  |   file::pipe(read_end_, write_end); | 
					
						
							| 
									
										
										
										
											2014-05-04 09:01:18 -07:00
										 |  |  |   // Connect the passed FILE object to the write end of the pipe.
 | 
					
						
							| 
									
										
										
										
											2014-05-03 12:28:02 -07:00
										 |  |  |   write_end.dup2(fd); | 
					
						
							| 
									
										
										
										
											2014-05-03 09:48:54 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-14 09:58:29 +08:00
										 |  |  | OutputRedirect::~OutputRedirect() FMT_NOEXCEPT { | 
					
						
							| 
									
										
										
										
											2014-05-03 16:47:00 -07:00
										 |  |  |   try { | 
					
						
							| 
									
										
										
										
											2014-07-29 07:50:05 -07:00
										 |  |  |     restore(); | 
					
						
							| 
									
										
										
										
											2019-01-12 18:27:38 -08:00
										 |  |  |   } catch (const std::exception& e) { | 
					
						
							| 
									
										
										
										
											2014-05-04 10:08:29 -07:00
										 |  |  |     std::fputs(e.what(), stderr); | 
					
						
							| 
									
										
										
										
											2014-05-03 16:47:00 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-29 07:50:05 -07:00
										 |  |  | std::string OutputRedirect::restore_and_read() { | 
					
						
							| 
									
										
										
										
											2014-05-03 09:48:54 -07:00
										 |  |  |   // Restore output.
 | 
					
						
							| 
									
										
										
										
											2014-07-29 07:50:05 -07:00
										 |  |  |   restore(); | 
					
						
							| 
									
										
										
										
											2014-05-03 09:48:54 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-03 11:26:46 -07:00
										 |  |  |   // Read everything from the pipe.
 | 
					
						
							|  |  |  |   std::string content; | 
					
						
							| 
									
										
										
										
											2019-01-12 18:27:38 -08:00
										 |  |  |   if (read_end_.descriptor() == -1) return content;  // Already read.
 | 
					
						
							| 
									
										
										
										
											2014-05-03 11:26:46 -07:00
										 |  |  |   enum { BUFFER_SIZE = 4096 }; | 
					
						
							| 
									
										
										
										
											2014-05-03 09:48:54 -07:00
										 |  |  |   char buffer[BUFFER_SIZE]; | 
					
						
							| 
									
										
										
										
											2016-03-02 07:53:14 -08:00
										 |  |  |   std::size_t count = 0; | 
					
						
							| 
									
										
										
										
											2014-05-03 11:26:46 -07:00
										 |  |  |   do { | 
					
						
							| 
									
										
										
										
											2014-05-03 12:28:02 -07:00
										 |  |  |     count = read_end_.read(buffer, BUFFER_SIZE); | 
					
						
							| 
									
										
										
										
											2016-03-02 07:53:14 -08:00
										 |  |  |     content.append(buffer, count); | 
					
						
							| 
									
										
										
										
											2014-05-03 11:26:46 -07:00
										 |  |  |   } while (count != 0); | 
					
						
							| 
									
										
										
										
											2014-05-04 10:08:29 -07:00
										 |  |  |   read_end_.close(); | 
					
						
							| 
									
										
										
										
											2014-05-03 11:26:46 -07:00
										 |  |  |   return content; | 
					
						
							| 
									
										
										
										
											2014-05-03 09:48:54 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 18:27:38 -08:00
										 |  |  | std::string read(file& f, std::size_t count) { | 
					
						
							| 
									
										
										
										
											2015-06-24 09:16:03 -07:00
										 |  |  |   std::string buffer(count, '\0'); | 
					
						
							| 
									
										
										
										
											2016-03-02 07:53:14 -08:00
										 |  |  |   std::size_t n = 0, offset = 0; | 
					
						
							| 
									
										
										
										
											2015-06-24 09:16:03 -07:00
										 |  |  |   do { | 
					
						
							|  |  |  |     n = f.read(&buffer[offset], count - offset); | 
					
						
							|  |  |  |     // We can't read more than size_t bytes since count has type size_t.
 | 
					
						
							| 
									
										
										
										
											2018-06-06 16:57:59 +03:00
										 |  |  |     offset += n; | 
					
						
							| 
									
										
										
										
											2015-06-24 09:16:03 -07:00
										 |  |  |   } while (offset < count && n != 0); | 
					
						
							|  |  |  |   buffer.resize(offset); | 
					
						
							|  |  |  |   return buffer; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-03 09:48:54 -07:00
										 |  |  | #endif  // FMT_USE_FILE_DESCRIPTORS
 | 
					
						
							| 
									
										
										
										
											2014-05-06 06:11:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-18 06:52:52 -08:00
										 |  |  | std::string format_system_error(int error_code, fmt::string_view message) { | 
					
						
							| 
									
										
										
										
											2017-02-18 09:13:12 -08:00
										 |  |  |   fmt::memory_buffer out; | 
					
						
							|  |  |  |   format_system_error(out, error_code, message); | 
					
						
							| 
									
										
										
										
											2017-02-14 16:29:47 -05:00
										 |  |  |   return to_string(out); | 
					
						
							| 
									
										
										
										
											2014-05-06 06:11:39 -07:00
										 |  |  | } |