~ubuntu-branches/ubuntu/oneiric/protobuf/oneiric

« back to all changes in this revision

Viewing changes to gtest/src/gtest-port.cc

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2009-11-16 10:41:33 UTC
  • mfrom: (2.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20091116104133-ykhy3deg5l4975tw
Tags: 2.1.0-1ubuntu1
* Merge from Debian testing.
* Remaining Ubuntu changes:
  - Disable the death tests on IA64, now as a quilt patch.
  - Don't use python2.4, also as a quilt patch.

Show diffs side-by-side

added added

removed removed

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