gtest-port.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. // Copyright 2008, Google Inc.
  2. // All rights reserved.
  3. //
  4. // Redistribution and use in source and binary forms, with or without
  5. // modification, are permitted provided that the following conditions are
  6. // met:
  7. //
  8. // * Redistributions of source code must retain the above copyright
  9. // notice, this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above
  11. // copyright notice, this list of conditions and the following disclaimer
  12. // in the documentation and/or other materials provided with the
  13. // distribution.
  14. // * Neither the name of Google Inc. nor the names of its
  15. // contributors may be used to endorse or promote products derived from
  16. // this software without specific prior written permission.
  17. //
  18. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. //
  30. // Author: [email protected] (Zhanyong Wan)
  31. #include "gtest/internal/gtest-port.h"
  32. #include <limits.h>
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #include <string.h>
  36. #if GTEST_OS_WINDOWS_MOBILE
  37. # include <windows.h> // For TerminateProcess()
  38. #elif GTEST_OS_WINDOWS
  39. # include <io.h>
  40. # include <sys/stat.h>
  41. #else
  42. # include <unistd.h>
  43. #endif // GTEST_OS_WINDOWS_MOBILE
  44. #if GTEST_OS_MAC
  45. # include <mach/mach_init.h>
  46. # include <mach/task.h>
  47. # include <mach/vm_map.h>
  48. #endif // GTEST_OS_MAC
  49. #include "gtest/gtest-spi.h"
  50. #include "gtest/gtest-message.h"
  51. #include "gtest/internal/gtest-internal.h"
  52. #include "gtest/internal/gtest-string.h"
  53. // Indicates that this translation unit is part of Google Test's
  54. // implementation. It must come before gtest-internal-inl.h is
  55. // included, or there will be a compiler error. This trick is to
  56. // prevent a user from accidentally including gtest-internal-inl.h in
  57. // his code.
  58. #define GTEST_IMPLEMENTATION_ 1
  59. #include "src/gtest-internal-inl.h"
  60. #undef GTEST_IMPLEMENTATION_
  61. namespace testing {
  62. namespace internal {
  63. #if defined(_MSC_VER) || defined(__BORLANDC__)
  64. // MSVC and C++Builder do not provide a definition of STDERR_FILENO.
  65. const int kStdOutFileno = 1;
  66. const int kStdErrFileno = 2;
  67. #else
  68. const int kStdOutFileno = STDOUT_FILENO;
  69. const int kStdErrFileno = STDERR_FILENO;
  70. #endif // _MSC_VER
  71. #if GTEST_OS_MAC
  72. // Returns the number of threads running in the process, or 0 to indicate that
  73. // we cannot detect it.
  74. size_t GetThreadCount() {
  75. const task_t task = mach_task_self();
  76. mach_msg_type_number_t thread_count;
  77. thread_act_array_t thread_list;
  78. const kern_return_t status = task_threads(task, &thread_list, &thread_count);
  79. if (status == KERN_SUCCESS) {
  80. // task_threads allocates resources in thread_list and we need to free them
  81. // to avoid leaks.
  82. vm_deallocate(task,
  83. reinterpret_cast<vm_address_t>(thread_list),
  84. sizeof(thread_t) * thread_count);
  85. return static_cast<size_t>(thread_count);
  86. } else {
  87. return 0;
  88. }
  89. }
  90. #else
  91. size_t GetThreadCount() {
  92. // There's no portable way to detect the number of threads, so we just
  93. // return 0 to indicate that we cannot detect it.
  94. return 0;
  95. }
  96. #endif // GTEST_OS_MAC
  97. #if GTEST_USES_POSIX_RE
  98. // Implements RE. Currently only needed for death tests.
  99. RE::~RE() {
  100. if (is_valid_) {
  101. // regfree'ing an invalid regex might crash because the content
  102. // of the regex is undefined. Since the regex's are essentially
  103. // the same, one cannot be valid (or invalid) without the other
  104. // being so too.
  105. regfree(&partial_regex_);
  106. regfree(&full_regex_);
  107. }
  108. free(const_cast<char*>(pattern_));
  109. }
  110. // Returns true iff regular expression re matches the entire str.
  111. bool RE::FullMatch(const char* str, const RE& re) {
  112. if (!re.is_valid_) return false;
  113. regmatch_t match;
  114. return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
  115. }
  116. // Returns true iff regular expression re matches a substring of str
  117. // (including str itself).
  118. bool RE::PartialMatch(const char* str, const RE& re) {
  119. if (!re.is_valid_) return false;
  120. regmatch_t match;
  121. return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;
  122. }
  123. // Initializes an RE from its string representation.
  124. void RE::Init(const char* regex) {
  125. pattern_ = posix::StrDup(regex);
  126. // Reserves enough bytes to hold the regular expression used for a
  127. // full match.
  128. const size_t full_regex_len = strlen(regex) + 10;
  129. char* const full_pattern = new char[full_regex_len];
  130. snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
  131. is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
  132. // We want to call regcomp(&partial_regex_, ...) even if the
  133. // previous expression returns false. Otherwise partial_regex_ may
  134. // not be properly initialized can may cause trouble when it's
  135. // freed.
  136. //
  137. // Some implementation of POSIX regex (e.g. on at least some
  138. // versions of Cygwin) doesn't accept the empty string as a valid
  139. // regex. We change it to an equivalent form "()" to be safe.
  140. if (is_valid_) {
  141. const char* const partial_regex = (*regex == '\0') ? "()" : regex;
  142. is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
  143. }
  144. EXPECT_TRUE(is_valid_)
  145. << "Regular expression \"" << regex
  146. << "\" is not a valid POSIX Extended regular expression.";
  147. delete[] full_pattern;
  148. }
  149. #elif GTEST_USES_SIMPLE_RE
  150. // Returns true iff ch appears anywhere in str (excluding the
  151. // terminating '\0' character).
  152. bool IsInSet(char ch, const char* str) {
  153. return ch != '\0' && strchr(str, ch) != NULL;
  154. }
  155. // Returns true iff ch belongs to the given classification. Unlike
  156. // similar functions in <ctype.h>, these aren't affected by the
  157. // current locale.
  158. bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }
  159. bool IsAsciiPunct(char ch) {
  160. return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
  161. }
  162. bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); }
  163. bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); }
  164. bool IsAsciiWordChar(char ch) {
  165. return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
  166. ('0' <= ch && ch <= '9') || ch == '_';
  167. }
  168. // Returns true iff "\\c" is a supported escape sequence.
  169. bool IsValidEscape(char c) {
  170. return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW"));
  171. }
  172. // Returns true iff the given atom (specified by escaped and pattern)
  173. // matches ch. The result is undefined if the atom is invalid.
  174. bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
  175. if (escaped) { // "\\p" where p is pattern_char.
  176. switch (pattern_char) {
  177. case 'd': return IsAsciiDigit(ch);
  178. case 'D': return !IsAsciiDigit(ch);
  179. case 'f': return ch == '\f';
  180. case 'n': return ch == '\n';
  181. case 'r': return ch == '\r';
  182. case 's': return IsAsciiWhiteSpace(ch);
  183. case 'S': return !IsAsciiWhiteSpace(ch);
  184. case 't': return ch == '\t';
  185. case 'v': return ch == '\v';
  186. case 'w': return IsAsciiWordChar(ch);
  187. case 'W': return !IsAsciiWordChar(ch);
  188. }
  189. return IsAsciiPunct(pattern_char) && pattern_char == ch;
  190. }
  191. return (pattern_char == '.' && ch != '\n') || pattern_char == ch;
  192. }
  193. // Helper function used by ValidateRegex() to format error messages.
  194. String FormatRegexSyntaxError(const char* regex, int index) {
  195. return (Message() << "Syntax error at index " << index
  196. << " in simple regular expression \"" << regex << "\": ").GetString();
  197. }
  198. // Generates non-fatal failures and returns false if regex is invalid;
  199. // otherwise returns true.
  200. bool ValidateRegex(const char* regex) {
  201. if (regex == NULL) {
  202. // TODO([email protected]): fix the source file location in the
  203. // assertion failures to match where the regex is used in user
  204. // code.
  205. ADD_FAILURE() << "NULL is not a valid simple regular expression.";
  206. return false;
  207. }
  208. bool is_valid = true;
  209. // True iff ?, *, or + can follow the previous atom.
  210. bool prev_repeatable = false;
  211. for (int i = 0; regex[i]; i++) {
  212. if (regex[i] == '\\') { // An escape sequence
  213. i++;
  214. if (regex[i] == '\0') {
  215. ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
  216. << "'\\' cannot appear at the end.";
  217. return false;
  218. }
  219. if (!IsValidEscape(regex[i])) {
  220. ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
  221. << "invalid escape sequence \"\\" << regex[i] << "\".";
  222. is_valid = false;
  223. }
  224. prev_repeatable = true;
  225. } else { // Not an escape sequence.
  226. const char ch = regex[i];
  227. if (ch == '^' && i > 0) {
  228. ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
  229. << "'^' can only appear at the beginning.";
  230. is_valid = false;
  231. } else if (ch == '$' && regex[i + 1] != '\0') {
  232. ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
  233. << "'$' can only appear at the end.";
  234. is_valid = false;
  235. } else if (IsInSet(ch, "()[]{}|")) {
  236. ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
  237. << "'" << ch << "' is unsupported.";
  238. is_valid = false;
  239. } else if (IsRepeat(ch) && !prev_repeatable) {
  240. ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
  241. << "'" << ch << "' can only follow a repeatable token.";
  242. is_valid = false;
  243. }
  244. prev_repeatable = !IsInSet(ch, "^$?*+");
  245. }
  246. }
  247. return is_valid;
  248. }
  249. // Matches a repeated regex atom followed by a valid simple regular
  250. // expression. The regex atom is defined as c if escaped is false,
  251. // or \c otherwise. repeat is the repetition meta character (?, *,
  252. // or +). The behavior is undefined if str contains too many
  253. // characters to be indexable by size_t, in which case the test will
  254. // probably time out anyway. We are fine with this limitation as
  255. // std::string has it too.
  256. bool MatchRepetitionAndRegexAtHead(
  257. bool escaped, char c, char repeat, const char* regex,
  258. const char* str) {
  259. const size_t min_count = (repeat == '+') ? 1 : 0;
  260. const size_t max_count = (repeat == '?') ? 1 :
  261. static_cast<size_t>(-1) - 1;
  262. // We cannot call numeric_limits::max() as it conflicts with the
  263. // max() macro on Windows.
  264. for (size_t i = 0; i <= max_count; ++i) {
  265. // We know that the atom matches each of the first i characters in str.
  266. if (i >= min_count && MatchRegexAtHead(regex, str + i)) {
  267. // We have enough matches at the head, and the tail matches too.
  268. // Since we only care about *whether* the pattern matches str
  269. // (as opposed to *how* it matches), there is no need to find a
  270. // greedy match.
  271. return true;
  272. }
  273. if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i]))
  274. return false;
  275. }
  276. return false;
  277. }
  278. // Returns true iff regex matches a prefix of str. regex must be a
  279. // valid simple regular expression and not start with "^", or the
  280. // result is undefined.
  281. bool MatchRegexAtHead(const char* regex, const char* str) {
  282. if (*regex == '\0') // An empty regex matches a prefix of anything.
  283. return true;
  284. // "$" only matches the end of a string. Note that regex being
  285. // valid guarantees that there's nothing after "$" in it.
  286. if (*regex == '$')
  287. return *str == '\0';
  288. // Is the first thing in regex an escape sequence?
  289. const bool escaped = *regex == '\\';
  290. if (escaped)
  291. ++regex;
  292. if (IsRepeat(regex[1])) {
  293. // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so
  294. // here's an indirect recursion. It terminates as the regex gets
  295. // shorter in each recursion.
  296. return MatchRepetitionAndRegexAtHead(
  297. escaped, regex[0], regex[1], regex + 2, str);
  298. } else {
  299. // regex isn't empty, isn't "$", and doesn't start with a
  300. // repetition. We match the first atom of regex with the first
  301. // character of str and recurse.
  302. return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) &&
  303. MatchRegexAtHead(regex + 1, str + 1);
  304. }
  305. }
  306. // Returns true iff regex matches any substring of str. regex must be
  307. // a valid simple regular expression, or the result is undefined.
  308. //
  309. // The algorithm is recursive, but the recursion depth doesn't exceed
  310. // the regex length, so we won't need to worry about running out of
  311. // stack space normally. In rare cases the time complexity can be
  312. // exponential with respect to the regex length + the string length,
  313. // but usually it's must faster (often close to linear).
  314. bool MatchRegexAnywhere(const char* regex, const char* str) {
  315. if (regex == NULL || str == NULL)
  316. return false;
  317. if (*regex == '^')
  318. return MatchRegexAtHead(regex + 1, str);
  319. // A successful match can be anywhere in str.
  320. do {
  321. if (MatchRegexAtHead(regex, str))
  322. return true;
  323. } while (*str++ != '\0');
  324. return false;
  325. }
  326. // Implements the RE class.
  327. RE::~RE() {
  328. free(const_cast<char*>(pattern_));
  329. free(const_cast<char*>(full_pattern_));
  330. }
  331. // Returns true iff regular expression re matches the entire str.
  332. bool RE::FullMatch(const char* str, const RE& re) {
  333. return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);
  334. }
  335. // Returns true iff regular expression re matches a substring of str
  336. // (including str itself).
  337. bool RE::PartialMatch(const char* str, const RE& re) {
  338. return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);
  339. }
  340. // Initializes an RE from its string representation.
  341. void RE::Init(const char* regex) {
  342. pattern_ = full_pattern_ = NULL;
  343. if (regex != NULL) {
  344. pattern_ = posix::StrDup(regex);
  345. }
  346. is_valid_ = ValidateRegex(regex);
  347. if (!is_valid_) {
  348. // No need to calculate the full pattern when the regex is invalid.
  349. return;
  350. }
  351. const size_t len = strlen(regex);
  352. // Reserves enough bytes to hold the regular expression used for a
  353. // full match: we need space to prepend a '^', append a '$', and
  354. // terminate the string with '\0'.
  355. char* buffer = static_cast<char*>(malloc(len + 3));
  356. full_pattern_ = buffer;
  357. if (*regex != '^')
  358. *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'.
  359. // We don't use snprintf or strncpy, as they trigger a warning when
  360. // compiled with VC++ 8.0.
  361. memcpy(buffer, regex, len);
  362. buffer += len;
  363. if (len == 0 || regex[len - 1] != '$')
  364. *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'.
  365. *buffer = '\0';
  366. }
  367. #endif // GTEST_USES_POSIX_RE
  368. const char kUnknownFile[] = "unknown file";
  369. // Formats a source file path and a line number as they would appear
  370. // in an error message from the compiler used to compile this code.
  371. GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {
  372. const char* const file_name = file == NULL ? kUnknownFile : file;
  373. if (line < 0) {
  374. return String::Format("%s:", file_name).c_str();
  375. }
  376. #ifdef _MSC_VER
  377. return String::Format("%s(%d):", file_name, line).c_str();
  378. #else
  379. return String::Format("%s:%d:", file_name, line).c_str();
  380. #endif // _MSC_VER
  381. }
  382. // Formats a file location for compiler-independent XML output.
  383. // Although this function is not platform dependent, we put it next to
  384. // FormatFileLocation in order to contrast the two functions.
  385. // Note that FormatCompilerIndependentFileLocation() does NOT append colon
  386. // to the file location it produces, unlike FormatFileLocation().
  387. GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(
  388. const char* file, int line) {
  389. const char* const file_name = file == NULL ? kUnknownFile : file;
  390. if (line < 0)
  391. return file_name;
  392. else
  393. return String::Format("%s:%d", file_name, line).c_str();
  394. }
  395. GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
  396. : severity_(severity) {
  397. const char* const marker =
  398. severity == GTEST_INFO ? "[ INFO ]" :
  399. severity == GTEST_WARNING ? "[WARNING]" :
  400. severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]";
  401. GetStream() << ::std::endl << marker << " "
  402. << FormatFileLocation(file, line).c_str() << ": ";
  403. }
  404. // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
  405. GTestLog::~GTestLog() {
  406. GetStream() << ::std::endl;
  407. if (severity_ == GTEST_FATAL) {
  408. fflush(stderr);
  409. posix::Abort();
  410. }
  411. }
  412. // Disable Microsoft deprecation warnings for POSIX functions called from
  413. // this class (creat, dup, dup2, and close)
  414. #ifdef _MSC_VER
  415. # pragma warning(push)
  416. # pragma warning(disable: 4996)
  417. #endif // _MSC_VER
  418. #if GTEST_HAS_STREAM_REDIRECTION
  419. // Object that captures an output stream (stdout/stderr).
  420. class CapturedStream {
  421. public:
  422. // The ctor redirects the stream to a temporary file.
  423. CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
  424. # if GTEST_OS_WINDOWS
  425. char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT
  426. char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT
  427. ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
  428. const UINT success = ::GetTempFileNameA(temp_dir_path,
  429. "gtest_redir",
  430. 0, // Generate unique file name.
  431. temp_file_path);
  432. GTEST_CHECK_(success != 0)
  433. << "Unable to create a temporary file in " << temp_dir_path;
  434. const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
  435. GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
  436. << temp_file_path;
  437. filename_ = temp_file_path;
  438. # else
  439. // There's no guarantee that a test has write access to the
  440. // current directory, so we create the temporary file in the /tmp
  441. // directory instead.
  442. char name_template[] = "/tmp/captured_stream.XXXXXX";
  443. const int captured_fd = mkstemp(name_template);
  444. filename_ = name_template;
  445. # endif // GTEST_OS_WINDOWS
  446. fflush(NULL);
  447. dup2(captured_fd, fd_);
  448. close(captured_fd);
  449. }
  450. ~CapturedStream() {
  451. remove(filename_.c_str());
  452. }
  453. String GetCapturedString() {
  454. if (uncaptured_fd_ != -1) {
  455. // Restores the original stream.
  456. fflush(NULL);
  457. dup2(uncaptured_fd_, fd_);
  458. close(uncaptured_fd_);
  459. uncaptured_fd_ = -1;
  460. }
  461. FILE* const file = posix::FOpen(filename_.c_str(), "r");
  462. const String content = ReadEntireFile(file);
  463. posix::FClose(file);
  464. return content;
  465. }
  466. private:
  467. // Reads the entire content of a file as a String.
  468. static String ReadEntireFile(FILE* file);
  469. // Returns the size (in bytes) of a file.
  470. static size_t GetFileSize(FILE* file);
  471. const int fd_; // A stream to capture.
  472. int uncaptured_fd_;
  473. // Name of the temporary file holding the stderr output.
  474. ::std::string filename_;
  475. GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
  476. };
  477. // Returns the size (in bytes) of a file.
  478. size_t CapturedStream::GetFileSize(FILE* file) {
  479. fseek(file, 0, SEEK_END);
  480. return static_cast<size_t>(ftell(file));
  481. }
  482. // Reads the entire content of a file as a string.
  483. String CapturedStream::ReadEntireFile(FILE* file) {
  484. const size_t file_size = GetFileSize(file);
  485. char* const buffer = new char[file_size];
  486. size_t bytes_last_read = 0; // # of bytes read in the last fread()
  487. size_t bytes_read = 0; // # of bytes read so far
  488. fseek(file, 0, SEEK_SET);
  489. // Keeps reading the file until we cannot read further or the
  490. // pre-determined file size is reached.
  491. do {
  492. bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
  493. bytes_read += bytes_last_read;
  494. } while (bytes_last_read > 0 && bytes_read < file_size);
  495. const String content(buffer, bytes_read);
  496. delete[] buffer;
  497. return content;
  498. }
  499. # ifdef _MSC_VER
  500. # pragma warning(pop)
  501. # endif // _MSC_VER
  502. static CapturedStream* g_captured_stderr = NULL;
  503. static CapturedStream* g_captured_stdout = NULL;
  504. // Starts capturing an output stream (stdout/stderr).
  505. void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
  506. if (*stream != NULL) {
  507. GTEST_LOG_(FATAL) << "Only one " << stream_name
  508. << " capturer can exist at a time.";
  509. }
  510. *stream = new CapturedStream(fd);
  511. }
  512. // Stops capturing the output stream and returns the captured string.
  513. String GetCapturedStream(CapturedStream** captured_stream) {
  514. const String content = (*captured_stream)->GetCapturedString();
  515. delete *captured_stream;
  516. *captured_stream = NULL;
  517. return content;
  518. }
  519. // Starts capturing stdout.
  520. void CaptureStdout() {
  521. CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
  522. }
  523. // Starts capturing stderr.
  524. void CaptureStderr() {
  525. CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
  526. }
  527. // Stops capturing stdout and returns the captured string.
  528. String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); }
  529. // Stops capturing stderr and returns the captured string.
  530. String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); }
  531. #endif // GTEST_HAS_STREAM_REDIRECTION
  532. #if GTEST_HAS_DEATH_TEST
  533. // A copy of all command line arguments. Set by InitGoogleTest().
  534. ::std::vector<String> g_argvs;
  535. // Returns the command line as a vector of strings.
  536. const ::std::vector<String>& GetArgvs() { return g_argvs; }
  537. #endif // GTEST_HAS_DEATH_TEST
  538. #if GTEST_OS_WINDOWS_MOBILE
  539. namespace posix {
  540. void Abort() {
  541. DebugBreak();
  542. TerminateProcess(GetCurrentProcess(), 1);
  543. }
  544. } // namespace posix
  545. #endif // GTEST_OS_WINDOWS_MOBILE
  546. // Returns the name of the environment variable corresponding to the
  547. // given flag. For example, FlagToEnvVar("foo") will return
  548. // "GTEST_FOO" in the open-source version.
  549. static String FlagToEnvVar(const char* flag) {
  550. const String full_flag =
  551. (Message() << GTEST_FLAG_PREFIX_ << flag).GetString();
  552. Message env_var;
  553. for (size_t i = 0; i != full_flag.length(); i++) {
  554. env_var << ToUpper(full_flag.c_str()[i]);
  555. }
  556. return env_var.GetString();
  557. }
  558. // Parses 'str' for a 32-bit signed integer. If successful, writes
  559. // the result to *value and returns true; otherwise leaves *value
  560. // unchanged and returns false.
  561. bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
  562. // Parses the environment variable as a decimal integer.
  563. char* end = NULL;
  564. const long long_value = strtol(str, &end, 10); // NOLINT
  565. // Has strtol() consumed all characters in the string?
  566. if (*end != '\0') {
  567. // No - an invalid character was encountered.
  568. Message msg;
  569. msg << "WARNING: " << src_text
  570. << " is expected to be a 32-bit integer, but actually"
  571. << " has value \"" << str << "\".\n";
  572. printf("%s", msg.GetString().c_str());
  573. fflush(stdout);
  574. return false;
  575. }
  576. // Is the parsed value in the range of an Int32?
  577. const Int32 result = static_cast<Int32>(long_value);
  578. if (long_value == LONG_MAX || long_value == LONG_MIN ||
  579. // The parsed value overflows as a long. (strtol() returns
  580. // LONG_MAX or LONG_MIN when the input overflows.)
  581. result != long_value
  582. // The parsed value overflows as an Int32.
  583. ) {
  584. Message msg;
  585. msg << "WARNING: " << src_text
  586. << " is expected to be a 32-bit integer, but actually"
  587. << " has value " << str << ", which overflows.\n";
  588. printf("%s", msg.GetString().c_str());
  589. fflush(stdout);
  590. return false;
  591. }
  592. *value = result;
  593. return true;
  594. }
  595. // Reads and returns the Boolean environment variable corresponding to
  596. // the given flag; if it's not set, returns default_value.
  597. //
  598. // The value is considered true iff it's not "0".
  599. bool BoolFromGTestEnv(const char* flag, bool default_value) {
  600. const String env_var = FlagToEnvVar(flag);
  601. const char* const string_value = posix::GetEnv(env_var.c_str());
  602. return string_value == NULL ?
  603. default_value : strcmp(string_value, "0") != 0;
  604. }
  605. // Reads and returns a 32-bit integer stored in the environment
  606. // variable corresponding to the given flag; if it isn't set or
  607. // doesn't represent a valid 32-bit integer, returns default_value.
  608. Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
  609. const String env_var = FlagToEnvVar(flag);
  610. const char* const string_value = posix::GetEnv(env_var.c_str());
  611. if (string_value == NULL) {
  612. // The environment variable is not set.
  613. return default_value;
  614. }
  615. Int32 result = default_value;
  616. if (!ParseInt32(Message() << "Environment variable " << env_var,
  617. string_value, &result)) {
  618. printf("The default value %s is used.\n",
  619. (Message() << default_value).GetString().c_str());
  620. fflush(stdout);
  621. return default_value;
  622. }
  623. return result;
  624. }
  625. // Reads and returns the string environment variable corresponding to
  626. // the given flag; if it's not set, returns default_value.
  627. const char* StringFromGTestEnv(const char* flag, const char* default_value) {
  628. const String env_var = FlagToEnvVar(flag);
  629. const char* const value = posix::GetEnv(env_var.c_str());
  630. return value == NULL ? default_value : value;
  631. }
  632. } // namespace internal
  633. } // namespace testing