00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "gtest/internal/gtest-port.h"
00033
00034 #include <limits.h>
00035 #include <stdlib.h>
00036 #include <stdio.h>
00037 #include <string.h>
00038
00039 #if GTEST_OS_WINDOWS
00040 # include <windows.h>
00041 # include <io.h>
00042 # include <sys/stat.h>
00043 # include <map>
00044 #else
00045 # include <unistd.h>
00046 #endif // GTEST_OS_WINDOWS
00047
00048 #if GTEST_OS_MAC
00049 # include <mach/mach_init.h>
00050 # include <mach/task.h>
00051 # include <mach/vm_map.h>
00052 #endif // GTEST_OS_MAC
00053
00054 #if GTEST_OS_QNX
00055 # include <devctl.h>
00056 # include <fcntl.h>
00057 # include <sys/procfs.h>
00058 #endif // GTEST_OS_QNX
00059
00060 #include "gtest/gtest-spi.h"
00061 #include "gtest/gtest-message.h"
00062 #include "gtest/internal/gtest-internal.h"
00063 #include "gtest/internal/gtest-string.h"
00064
00065
00066
00067
00068
00069
00070 #define GTEST_IMPLEMENTATION_ 1
00071 #include "src/gtest-internal-inl.h"
00072 #undef GTEST_IMPLEMENTATION_
00073
00074 namespace testing {
00075 namespace internal {
00076
00077 #if defined(_MSC_VER) || defined(__BORLANDC__)
00078
00079 const int kStdOutFileno = 1;
00080 const int kStdErrFileno = 2;
00081 #else
00082 const int kStdOutFileno = STDOUT_FILENO;
00083 const int kStdErrFileno = STDERR_FILENO;
00084 #endif // _MSC_VER
00085
00086 #if GTEST_OS_MAC
00087
00088
00089
00090 size_t GetThreadCount() {
00091 const task_t task = mach_task_self();
00092 mach_msg_type_number_t thread_count;
00093 thread_act_array_t thread_list;
00094 const kern_return_t status = task_threads(task, &thread_list, &thread_count);
00095 if (status == KERN_SUCCESS) {
00096
00097
00098 vm_deallocate(task,
00099 reinterpret_cast<vm_address_t>(thread_list),
00100 sizeof(thread_t) * thread_count);
00101 return static_cast<size_t>(thread_count);
00102 } else {
00103 return 0;
00104 }
00105 }
00106
00107 #elif GTEST_OS_QNX
00108
00109
00110
00111 size_t GetThreadCount() {
00112 const int fd = open("/proc/self/as", O_RDONLY);
00113 if (fd < 0) {
00114 return 0;
00115 }
00116 procfs_info process_info;
00117 const int status =
00118 devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL);
00119 close(fd);
00120 if (status == EOK) {
00121 return static_cast<size_t>(process_info.num_threads);
00122 } else {
00123 return 0;
00124 }
00125 }
00126
00127 #else
00128
00129 size_t GetThreadCount() {
00130
00131
00132 return 0;
00133 }
00134
00135 #endif // GTEST_OS_MAC
00136
00137 #if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
00138
00139 void SleepMilliseconds(int n) {
00140 ::Sleep(n);
00141 }
00142
00143 AutoHandle::AutoHandle()
00144 : handle_(INVALID_HANDLE_VALUE) {}
00145
00146 AutoHandle::AutoHandle(Handle handle)
00147 : handle_(handle) {}
00148
00149 AutoHandle::~AutoHandle() {
00150 Reset();
00151 }
00152
00153 AutoHandle::Handle AutoHandle::Get() const {
00154 return handle_;
00155 }
00156
00157 void AutoHandle::Reset() {
00158 Reset(INVALID_HANDLE_VALUE);
00159 }
00160
00161 void AutoHandle::Reset(HANDLE handle) {
00162
00163 if (handle_ != handle) {
00164 if (IsCloseable()) {
00165 ::CloseHandle(handle_);
00166 }
00167 handle_ = handle;
00168 } else {
00169 GTEST_CHECK_(!IsCloseable())
00170 << "Resetting a valid handle to itself is likely a programmer error "
00171 "and thus not allowed.";
00172 }
00173 }
00174
00175 bool AutoHandle::IsCloseable() const {
00176
00177
00178 return handle_ != NULL && handle_ != INVALID_HANDLE_VALUE;
00179 }
00180
00181 Notification::Notification()
00182 : event_(::CreateEvent(NULL,
00183 TRUE,
00184 FALSE,
00185 NULL)) {
00186 GTEST_CHECK_(event_.Get() != NULL);
00187 }
00188
00189 void Notification::Notify() {
00190 GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE);
00191 }
00192
00193 void Notification::WaitForNotification() {
00194 GTEST_CHECK_(
00195 ::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0);
00196 }
00197
00198 Mutex::Mutex()
00199 : type_(kDynamic),
00200 owner_thread_id_(0),
00201 critical_section_init_phase_(0),
00202 critical_section_(new CRITICAL_SECTION) {
00203 ::InitializeCriticalSection(critical_section_);
00204 }
00205
00206 Mutex::~Mutex() {
00207
00208
00209
00210
00211
00212 if (type_ == kDynamic) {
00213 ::DeleteCriticalSection(critical_section_);
00214 delete critical_section_;
00215 critical_section_ = NULL;
00216 }
00217 }
00218
00219 void Mutex::Lock() {
00220 ThreadSafeLazyInit();
00221 ::EnterCriticalSection(critical_section_);
00222 owner_thread_id_ = ::GetCurrentThreadId();
00223 }
00224
00225 void Mutex::Unlock() {
00226 ThreadSafeLazyInit();
00227
00228
00229
00230 owner_thread_id_ = 0;
00231 ::LeaveCriticalSection(critical_section_);
00232 }
00233
00234
00235
00236 void Mutex::AssertHeld() {
00237 ThreadSafeLazyInit();
00238 GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId())
00239 << "The current thread is not holding the mutex @" << this;
00240 }
00241
00242
00243 void Mutex::ThreadSafeLazyInit() {
00244
00245 if (type_ == kStatic) {
00246 switch (
00247 ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) {
00248 case 0:
00249
00250
00251 owner_thread_id_ = 0;
00252 critical_section_ = new CRITICAL_SECTION;
00253 ::InitializeCriticalSection(critical_section_);
00254
00255
00256 GTEST_CHECK_(::InterlockedCompareExchange(
00257 &critical_section_init_phase_, 2L, 1L) ==
00258 1L);
00259 break;
00260 case 1:
00261
00262
00263 while (::InterlockedCompareExchange(&critical_section_init_phase_,
00264 2L,
00265 2L) != 2L) {
00266
00267
00268 ::Sleep(0);
00269 }
00270 break;
00271
00272 case 2:
00273 break;
00274
00275 default:
00276 GTEST_CHECK_(false)
00277 << "Unexpected value of critical_section_init_phase_ "
00278 << "while initializing a static mutex.";
00279 }
00280 }
00281 }
00282
00283 namespace {
00284
00285 class ThreadWithParamSupport : public ThreadWithParamBase {
00286 public:
00287 static HANDLE CreateThread(Runnable* runnable,
00288 Notification* thread_can_start) {
00289 ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start);
00290 DWORD thread_id;
00291
00292 HANDLE thread_handle = ::CreateThread(
00293 NULL,
00294 0,
00295 &ThreadWithParamSupport::ThreadMain,
00296 param,
00297 0x0,
00298 &thread_id);
00299 GTEST_CHECK_(thread_handle != NULL) << "CreateThread failed with error "
00300 << ::GetLastError() << ".";
00301 if (thread_handle == NULL) {
00302 delete param;
00303 }
00304 return thread_handle;
00305 }
00306
00307 private:
00308 struct ThreadMainParam {
00309 ThreadMainParam(Runnable* runnable, Notification* thread_can_start)
00310 : runnable_(runnable),
00311 thread_can_start_(thread_can_start) {
00312 }
00313 scoped_ptr<Runnable> runnable_;
00314
00315 Notification* thread_can_start_;
00316 };
00317
00318 static DWORD WINAPI ThreadMain(void* ptr) {
00319
00320 scoped_ptr<ThreadMainParam> param(static_cast<ThreadMainParam*>(ptr));
00321 if (param->thread_can_start_ != NULL)
00322 param->thread_can_start_->WaitForNotification();
00323 param->runnable_->Run();
00324 return 0;
00325 }
00326
00327
00328 ThreadWithParamSupport();
00329
00330 GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParamSupport);
00331 };
00332
00333 }
00334
00335 ThreadWithParamBase::ThreadWithParamBase(Runnable *runnable,
00336 Notification* thread_can_start)
00337 : thread_(ThreadWithParamSupport::CreateThread(runnable,
00338 thread_can_start)) {
00339 }
00340
00341 ThreadWithParamBase::~ThreadWithParamBase() {
00342 Join();
00343 }
00344
00345 void ThreadWithParamBase::Join() {
00346 GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0)
00347 << "Failed to join the thread with error " << ::GetLastError() << ".";
00348 }
00349
00350
00351
00352
00353
00354 class ThreadLocalRegistryImpl {
00355 public:
00356
00357
00358 static ThreadLocalValueHolderBase* GetValueOnCurrentThread(
00359 const ThreadLocalBase* thread_local_instance) {
00360 DWORD current_thread = ::GetCurrentThreadId();
00361 MutexLock lock(&mutex_);
00362 ThreadIdToThreadLocals* const thread_to_thread_locals =
00363 GetThreadLocalsMapLocked();
00364 ThreadIdToThreadLocals::iterator thread_local_pos =
00365 thread_to_thread_locals->find(current_thread);
00366 if (thread_local_pos == thread_to_thread_locals->end()) {
00367 thread_local_pos = thread_to_thread_locals->insert(
00368 std::make_pair(current_thread, ThreadLocalValues())).first;
00369 StartWatcherThreadFor(current_thread);
00370 }
00371 ThreadLocalValues& thread_local_values = thread_local_pos->second;
00372 ThreadLocalValues::iterator value_pos =
00373 thread_local_values.find(thread_local_instance);
00374 if (value_pos == thread_local_values.end()) {
00375 value_pos =
00376 thread_local_values
00377 .insert(std::make_pair(
00378 thread_local_instance,
00379 linked_ptr<ThreadLocalValueHolderBase>(
00380 thread_local_instance->NewValueForCurrentThread())))
00381 .first;
00382 }
00383 return value_pos->second.get();
00384 }
00385
00386 static void OnThreadLocalDestroyed(
00387 const ThreadLocalBase* thread_local_instance) {
00388 std::vector<linked_ptr<ThreadLocalValueHolderBase> > value_holders;
00389
00390
00391 {
00392 MutexLock lock(&mutex_);
00393 ThreadIdToThreadLocals* const thread_to_thread_locals =
00394 GetThreadLocalsMapLocked();
00395 for (ThreadIdToThreadLocals::iterator it =
00396 thread_to_thread_locals->begin();
00397 it != thread_to_thread_locals->end();
00398 ++it) {
00399 ThreadLocalValues& thread_local_values = it->second;
00400 ThreadLocalValues::iterator value_pos =
00401 thread_local_values.find(thread_local_instance);
00402 if (value_pos != thread_local_values.end()) {
00403 value_holders.push_back(value_pos->second);
00404 thread_local_values.erase(value_pos);
00405
00406
00407 }
00408 }
00409 }
00410
00411
00412 }
00413
00414 static void OnThreadExit(DWORD thread_id) {
00415 GTEST_CHECK_(thread_id != 0) << ::GetLastError();
00416 std::vector<linked_ptr<ThreadLocalValueHolderBase> > value_holders;
00417
00418
00419 {
00420 MutexLock lock(&mutex_);
00421 ThreadIdToThreadLocals* const thread_to_thread_locals =
00422 GetThreadLocalsMapLocked();
00423 ThreadIdToThreadLocals::iterator thread_local_pos =
00424 thread_to_thread_locals->find(thread_id);
00425 if (thread_local_pos != thread_to_thread_locals->end()) {
00426 ThreadLocalValues& thread_local_values = thread_local_pos->second;
00427 for (ThreadLocalValues::iterator value_pos =
00428 thread_local_values.begin();
00429 value_pos != thread_local_values.end();
00430 ++value_pos) {
00431 value_holders.push_back(value_pos->second);
00432 }
00433 thread_to_thread_locals->erase(thread_local_pos);
00434 }
00435 }
00436
00437
00438 }
00439
00440 private:
00441
00442 typedef std::map<const ThreadLocalBase*,
00443 linked_ptr<ThreadLocalValueHolderBase> > ThreadLocalValues;
00444
00445
00446 typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
00447
00448
00449
00450 typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle;
00451
00452 static void StartWatcherThreadFor(DWORD thread_id) {
00453
00454
00455 HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION,
00456 FALSE,
00457 thread_id);
00458 GTEST_CHECK_(thread != NULL);
00459
00460
00461 DWORD watcher_thread_id;
00462 HANDLE watcher_thread = ::CreateThread(
00463 NULL,
00464 0,
00465 &ThreadLocalRegistryImpl::WatcherThreadFunc,
00466 reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)),
00467 CREATE_SUSPENDED,
00468 &watcher_thread_id);
00469 GTEST_CHECK_(watcher_thread != NULL);
00470
00471
00472 ::SetThreadPriority(watcher_thread,
00473 ::GetThreadPriority(::GetCurrentThread()));
00474 ::ResumeThread(watcher_thread);
00475 ::CloseHandle(watcher_thread);
00476 }
00477
00478
00479
00480 static DWORD WINAPI WatcherThreadFunc(LPVOID param) {
00481 const ThreadIdAndHandle* tah =
00482 reinterpret_cast<const ThreadIdAndHandle*>(param);
00483 GTEST_CHECK_(
00484 ::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0);
00485 OnThreadExit(tah->first);
00486 ::CloseHandle(tah->second);
00487 delete tah;
00488 return 0;
00489 }
00490
00491
00492 static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {
00493 mutex_.AssertHeld();
00494 static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals;
00495 return map;
00496 }
00497
00498
00499 static Mutex mutex_;
00500
00501 static Mutex thread_map_mutex_;
00502 };
00503
00504 Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex);
00505 Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex);
00506
00507 ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread(
00508 const ThreadLocalBase* thread_local_instance) {
00509 return ThreadLocalRegistryImpl::GetValueOnCurrentThread(
00510 thread_local_instance);
00511 }
00512
00513 void ThreadLocalRegistry::OnThreadLocalDestroyed(
00514 const ThreadLocalBase* thread_local_instance) {
00515 ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance);
00516 }
00517
00518 #endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
00519
00520 #if GTEST_USES_POSIX_RE
00521
00522
00523
00524 RE::~RE() {
00525 if (is_valid_) {
00526
00527
00528
00529
00530 regfree(&partial_regex_);
00531 regfree(&full_regex_);
00532 }
00533 free(const_cast<char*>(pattern_));
00534 }
00535
00536
00537 bool RE::FullMatch(const char* str, const RE& re) {
00538 if (!re.is_valid_) return false;
00539
00540 regmatch_t match;
00541 return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
00542 }
00543
00544
00545
00546 bool RE::PartialMatch(const char* str, const RE& re) {
00547 if (!re.is_valid_) return false;
00548
00549 regmatch_t match;
00550 return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;
00551 }
00552
00553
00554 void RE::Init(const char* regex) {
00555 pattern_ = posix::StrDup(regex);
00556
00557
00558
00559 const size_t full_regex_len = strlen(regex) + 10;
00560 char* const full_pattern = new char[full_regex_len];
00561
00562 snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
00563 is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
00564
00565
00566
00567
00568
00569
00570
00571
00572 if (is_valid_) {
00573 const char* const partial_regex = (*regex == '\0') ? "()" : regex;
00574 is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
00575 }
00576 EXPECT_TRUE(is_valid_)
00577 << "Regular expression \"" << regex
00578 << "\" is not a valid POSIX Extended regular expression.";
00579
00580 delete[] full_pattern;
00581 }
00582
00583 #elif GTEST_USES_SIMPLE_RE
00584
00585
00586
00587 bool IsInSet(char ch, const char* str) {
00588 return ch != '\0' && strchr(str, ch) != NULL;
00589 }
00590
00591
00592
00593
00594 bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }
00595 bool IsAsciiPunct(char ch) {
00596 return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
00597 }
00598 bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); }
00599 bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); }
00600 bool IsAsciiWordChar(char ch) {
00601 return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
00602 ('0' <= ch && ch <= '9') || ch == '_';
00603 }
00604
00605
00606 bool IsValidEscape(char c) {
00607 return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW"));
00608 }
00609
00610
00611
00612 bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
00613 if (escaped) {
00614 switch (pattern_char) {
00615 case 'd': return IsAsciiDigit(ch);
00616 case 'D': return !IsAsciiDigit(ch);
00617 case 'f': return ch == '\f';
00618 case 'n': return ch == '\n';
00619 case 'r': return ch == '\r';
00620 case 's': return IsAsciiWhiteSpace(ch);
00621 case 'S': return !IsAsciiWhiteSpace(ch);
00622 case 't': return ch == '\t';
00623 case 'v': return ch == '\v';
00624 case 'w': return IsAsciiWordChar(ch);
00625 case 'W': return !IsAsciiWordChar(ch);
00626 }
00627 return IsAsciiPunct(pattern_char) && pattern_char == ch;
00628 }
00629
00630 return (pattern_char == '.' && ch != '\n') || pattern_char == ch;
00631 }
00632
00633
00634 std::string FormatRegexSyntaxError(const char* regex, int index) {
00635 return (Message() << "Syntax error at index " << index
00636 << " in simple regular expression \"" << regex << "\": ").GetString();
00637 }
00638
00639
00640
00641 bool ValidateRegex(const char* regex) {
00642 if (regex == NULL) {
00643
00644
00645
00646 ADD_FAILURE() << "NULL is not a valid simple regular expression.";
00647 return false;
00648 }
00649
00650 bool is_valid = true;
00651
00652
00653 bool prev_repeatable = false;
00654 for (int i = 0; regex[i]; i++) {
00655 if (regex[i] == '\\') {
00656 i++;
00657 if (regex[i] == '\0') {
00658 ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
00659 << "'\\' cannot appear at the end.";
00660 return false;
00661 }
00662
00663 if (!IsValidEscape(regex[i])) {
00664 ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
00665 << "invalid escape sequence \"\\" << regex[i] << "\".";
00666 is_valid = false;
00667 }
00668 prev_repeatable = true;
00669 } else {
00670 const char ch = regex[i];
00671
00672 if (ch == '^' && i > 0) {
00673 ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
00674 << "'^' can only appear at the beginning.";
00675 is_valid = false;
00676 } else if (ch == '$' && regex[i + 1] != '\0') {
00677 ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
00678 << "'$' can only appear at the end.";
00679 is_valid = false;
00680 } else if (IsInSet(ch, "()[]{}|")) {
00681 ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
00682 << "'" << ch << "' is unsupported.";
00683 is_valid = false;
00684 } else if (IsRepeat(ch) && !prev_repeatable) {
00685 ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
00686 << "'" << ch << "' can only follow a repeatable token.";
00687 is_valid = false;
00688 }
00689
00690 prev_repeatable = !IsInSet(ch, "^$?*+");
00691 }
00692 }
00693
00694 return is_valid;
00695 }
00696
00697
00698
00699
00700
00701
00702
00703
00704 bool MatchRepetitionAndRegexAtHead(
00705 bool escaped, char c, char repeat, const char* regex,
00706 const char* str) {
00707 const size_t min_count = (repeat == '+') ? 1 : 0;
00708 const size_t max_count = (repeat == '?') ? 1 :
00709 static_cast<size_t>(-1) - 1;
00710
00711
00712
00713 for (size_t i = 0; i <= max_count; ++i) {
00714
00715 if (i >= min_count && MatchRegexAtHead(regex, str + i)) {
00716
00717
00718
00719
00720 return true;
00721 }
00722 if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i]))
00723 return false;
00724 }
00725 return false;
00726 }
00727
00728
00729
00730
00731 bool MatchRegexAtHead(const char* regex, const char* str) {
00732 if (*regex == '\0')
00733 return true;
00734
00735
00736
00737 if (*regex == '$')
00738 return *str == '\0';
00739
00740
00741 const bool escaped = *regex == '\\';
00742 if (escaped)
00743 ++regex;
00744 if (IsRepeat(regex[1])) {
00745
00746
00747
00748 return MatchRepetitionAndRegexAtHead(
00749 escaped, regex[0], regex[1], regex + 2, str);
00750 } else {
00751
00752
00753
00754 return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) &&
00755 MatchRegexAtHead(regex + 1, str + 1);
00756 }
00757 }
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767 bool MatchRegexAnywhere(const char* regex, const char* str) {
00768 if (regex == NULL || str == NULL)
00769 return false;
00770
00771 if (*regex == '^')
00772 return MatchRegexAtHead(regex + 1, str);
00773
00774
00775 do {
00776 if (MatchRegexAtHead(regex, str))
00777 return true;
00778 } while (*str++ != '\0');
00779 return false;
00780 }
00781
00782
00783
00784 RE::~RE() {
00785 free(const_cast<char*>(pattern_));
00786 free(const_cast<char*>(full_pattern_));
00787 }
00788
00789
00790 bool RE::FullMatch(const char* str, const RE& re) {
00791 return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);
00792 }
00793
00794
00795
00796 bool RE::PartialMatch(const char* str, const RE& re) {
00797 return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);
00798 }
00799
00800
00801 void RE::Init(const char* regex) {
00802 pattern_ = full_pattern_ = NULL;
00803 if (regex != NULL) {
00804 pattern_ = posix::StrDup(regex);
00805 }
00806
00807 is_valid_ = ValidateRegex(regex);
00808 if (!is_valid_) {
00809
00810 return;
00811 }
00812
00813 const size_t len = strlen(regex);
00814
00815
00816
00817 char* buffer = static_cast<char*>(malloc(len + 3));
00818 full_pattern_ = buffer;
00819
00820 if (*regex != '^')
00821 *buffer++ = '^';
00822
00823
00824
00825 memcpy(buffer, regex, len);
00826 buffer += len;
00827
00828 if (len == 0 || regex[len - 1] != '$')
00829 *buffer++ = '$';
00830
00831 *buffer = '\0';
00832 }
00833
00834 #endif // GTEST_USES_POSIX_RE
00835
00836 const char kUnknownFile[] = "unknown file";
00837
00838
00839
00840 GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {
00841 const std::string file_name(file == NULL ? kUnknownFile : file);
00842
00843 if (line < 0) {
00844 return file_name + ":";
00845 }
00846 #ifdef _MSC_VER
00847 return file_name + "(" + StreamableToString(line) + "):";
00848 #else
00849 return file_name + ":" + StreamableToString(line) + ":";
00850 #endif // _MSC_VER
00851 }
00852
00853
00854
00855
00856
00857
00858 GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(
00859 const char* file, int line) {
00860 const std::string file_name(file == NULL ? kUnknownFile : file);
00861
00862 if (line < 0)
00863 return file_name;
00864 else
00865 return file_name + ":" + StreamableToString(line);
00866 }
00867
00868
00869 GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
00870 : severity_(severity) {
00871 const char* const marker =
00872 severity == GTEST_INFO ? "[ INFO ]" :
00873 severity == GTEST_WARNING ? "[WARNING]" :
00874 severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]";
00875 GetStream() << ::std::endl << marker << " "
00876 << FormatFileLocation(file, line).c_str() << ": ";
00877 }
00878
00879
00880 GTestLog::~GTestLog() {
00881 GetStream() << ::std::endl;
00882 if (severity_ == GTEST_FATAL) {
00883 fflush(stderr);
00884 posix::Abort();
00885 }
00886 }
00887
00888
00889 GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
00890
00891 #if GTEST_HAS_STREAM_REDIRECTION
00892
00893
00894 class CapturedStream {
00895 public:
00896
00897 explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
00898 # if GTEST_OS_WINDOWS
00899 char temp_dir_path[MAX_PATH + 1] = { '\0' };
00900 char temp_file_path[MAX_PATH + 1] = { '\0' };
00901
00902 ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
00903 const UINT success = ::GetTempFileNameA(temp_dir_path,
00904 "gtest_redir",
00905 0,
00906 temp_file_path);
00907 GTEST_CHECK_(success != 0)
00908 << "Unable to create a temporary file in " << temp_dir_path;
00909 const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
00910 GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
00911 << temp_file_path;
00912 filename_ = temp_file_path;
00913 # else
00914
00915
00916
00917
00918 # if GTEST_OS_LINUX_ANDROID
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933 char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX";
00934 # else
00935 char name_template[] = "/tmp/captured_stream.XXXXXX";
00936 # endif // GTEST_OS_LINUX_ANDROID
00937 const int captured_fd = mkstemp(name_template);
00938 filename_ = name_template;
00939 # endif // GTEST_OS_WINDOWS
00940 fflush(NULL);
00941 dup2(captured_fd, fd_);
00942 close(captured_fd);
00943 }
00944
00945 ~CapturedStream() {
00946 remove(filename_.c_str());
00947 }
00948
00949 std::string GetCapturedString() {
00950 if (uncaptured_fd_ != -1) {
00951
00952 fflush(NULL);
00953 dup2(uncaptured_fd_, fd_);
00954 close(uncaptured_fd_);
00955 uncaptured_fd_ = -1;
00956 }
00957
00958 FILE* const file = posix::FOpen(filename_.c_str(), "r");
00959 const std::string content = ReadEntireFile(file);
00960 posix::FClose(file);
00961 return content;
00962 }
00963
00964 private:
00965
00966 static std::string ReadEntireFile(FILE* file);
00967
00968
00969 static size_t GetFileSize(FILE* file);
00970
00971 const int fd_;
00972 int uncaptured_fd_;
00973
00974 ::std::string filename_;
00975
00976 GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
00977 };
00978
00979
00980 size_t CapturedStream::GetFileSize(FILE* file) {
00981 fseek(file, 0, SEEK_END);
00982 return static_cast<size_t>(ftell(file));
00983 }
00984
00985
00986 std::string CapturedStream::ReadEntireFile(FILE* file) {
00987 const size_t file_size = GetFileSize(file);
00988 char* const buffer = new char[file_size];
00989
00990 size_t bytes_last_read = 0;
00991 size_t bytes_read = 0;
00992
00993 fseek(file, 0, SEEK_SET);
00994
00995
00996
00997 do {
00998 bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
00999 bytes_read += bytes_last_read;
01000 } while (bytes_last_read > 0 && bytes_read < file_size);
01001
01002 const std::string content(buffer, bytes_read);
01003 delete[] buffer;
01004
01005 return content;
01006 }
01007
01008 GTEST_DISABLE_MSC_WARNINGS_POP_()
01009
01010 static CapturedStream* g_captured_stderr = NULL;
01011 static CapturedStream* g_captured_stdout = NULL;
01012
01013
01014 void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
01015 if (*stream != NULL) {
01016 GTEST_LOG_(FATAL) << "Only one " << stream_name
01017 << " capturer can exist at a time.";
01018 }
01019 *stream = new CapturedStream(fd);
01020 }
01021
01022
01023 std::string GetCapturedStream(CapturedStream** captured_stream) {
01024 const std::string content = (*captured_stream)->GetCapturedString();
01025
01026 delete *captured_stream;
01027 *captured_stream = NULL;
01028
01029 return content;
01030 }
01031
01032
01033 void CaptureStdout() {
01034 CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
01035 }
01036
01037
01038 void CaptureStderr() {
01039 CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
01040 }
01041
01042
01043 std::string GetCapturedStdout() {
01044 return GetCapturedStream(&g_captured_stdout);
01045 }
01046
01047
01048 std::string GetCapturedStderr() {
01049 return GetCapturedStream(&g_captured_stderr);
01050 }
01051
01052 #endif // GTEST_HAS_STREAM_REDIRECTION
01053
01054 #if GTEST_HAS_DEATH_TEST
01055
01056
01057 ::std::vector<testing::internal::string> g_argvs;
01058
01059 static const ::std::vector<testing::internal::string>* g_injected_test_argvs =
01060 NULL;
01061
01062 void SetInjectableArgvs(const ::std::vector<testing::internal::string>* argvs) {
01063 if (g_injected_test_argvs != argvs)
01064 delete g_injected_test_argvs;
01065 g_injected_test_argvs = argvs;
01066 }
01067
01068 const ::std::vector<testing::internal::string>& GetInjectableArgvs() {
01069 if (g_injected_test_argvs != NULL) {
01070 return *g_injected_test_argvs;
01071 }
01072 return g_argvs;
01073 }
01074 #endif // GTEST_HAS_DEATH_TEST
01075
01076 #if GTEST_OS_WINDOWS_MOBILE
01077 namespace posix {
01078 void Abort() {
01079 DebugBreak();
01080 TerminateProcess(GetCurrentProcess(), 1);
01081 }
01082 }
01083 #endif // GTEST_OS_WINDOWS_MOBILE
01084
01085
01086
01087
01088 static std::string FlagToEnvVar(const char* flag) {
01089 const std::string full_flag =
01090 (Message() << GTEST_FLAG_PREFIX_ << flag).GetString();
01091
01092 Message env_var;
01093 for (size_t i = 0; i != full_flag.length(); i++) {
01094 env_var << ToUpper(full_flag.c_str()[i]);
01095 }
01096
01097 return env_var.GetString();
01098 }
01099
01100
01101
01102
01103 bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
01104
01105 char* end = NULL;
01106 const long long_value = strtol(str, &end, 10);
01107
01108
01109 if (*end != '\0') {
01110
01111 Message msg;
01112 msg << "WARNING: " << src_text
01113 << " is expected to be a 32-bit integer, but actually"
01114 << " has value \"" << str << "\".\n";
01115 printf("%s", msg.GetString().c_str());
01116 fflush(stdout);
01117 return false;
01118 }
01119
01120
01121 const Int32 result = static_cast<Int32>(long_value);
01122 if (long_value == LONG_MAX || long_value == LONG_MIN ||
01123
01124
01125 result != long_value
01126
01127 ) {
01128 Message msg;
01129 msg << "WARNING: " << src_text
01130 << " is expected to be a 32-bit integer, but actually"
01131 << " has value " << str << ", which overflows.\n";
01132 printf("%s", msg.GetString().c_str());
01133 fflush(stdout);
01134 return false;
01135 }
01136
01137 *value = result;
01138 return true;
01139 }
01140
01141
01142
01143
01144
01145 bool BoolFromGTestEnv(const char* flag, bool default_value) {
01146 const std::string env_var = FlagToEnvVar(flag);
01147 const char* const string_value = posix::GetEnv(env_var.c_str());
01148 return string_value == NULL ?
01149 default_value : strcmp(string_value, "0") != 0;
01150 }
01151
01152
01153
01154
01155 Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
01156 const std::string env_var = FlagToEnvVar(flag);
01157 const char* const string_value = posix::GetEnv(env_var.c_str());
01158 if (string_value == NULL) {
01159
01160 return default_value;
01161 }
01162
01163 Int32 result = default_value;
01164 if (!ParseInt32(Message() << "Environment variable " << env_var,
01165 string_value, &result)) {
01166 printf("The default value %s is used.\n",
01167 (Message() << default_value).GetString().c_str());
01168 fflush(stdout);
01169 return default_value;
01170 }
01171
01172 return result;
01173 }
01174
01175
01176
01177 const char* StringFromGTestEnv(const char* flag, const char* default_value) {
01178 const std::string env_var = FlagToEnvVar(flag);
01179 const char* const value = posix::GetEnv(env_var.c_str());
01180 return value == NULL ? default_value : value;
01181 }
01182
01183 }
01184 }