gtest-port.cc (46442B)
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 31 #include "gtest/internal/gtest-port.h" 32 33 #include <limits.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <string.h> 37 #include <fstream> 38 #include <memory> 39 40 #if GTEST_OS_WINDOWS 41 # include <windows.h> 42 # include <io.h> 43 # include <sys/stat.h> 44 # include <map> // Used in ThreadLocal. 45 # ifdef _MSC_VER 46 # include <crtdbg.h> 47 # endif // _MSC_VER 48 #else 49 # include <unistd.h> 50 #endif // GTEST_OS_WINDOWS 51 52 #if GTEST_OS_MAC 53 # include <mach/mach_init.h> 54 # include <mach/task.h> 55 # include <mach/vm_map.h> 56 #endif // GTEST_OS_MAC 57 58 #if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \ 59 GTEST_OS_NETBSD || GTEST_OS_OPENBSD 60 # include <sys/sysctl.h> 61 # if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD 62 # include <sys/user.h> 63 # endif 64 #endif 65 66 #if GTEST_OS_QNX 67 # include <devctl.h> 68 # include <fcntl.h> 69 # include <sys/procfs.h> 70 #endif // GTEST_OS_QNX 71 72 #if GTEST_OS_AIX 73 # include <procinfo.h> 74 # include <sys/types.h> 75 #endif // GTEST_OS_AIX 76 77 #if GTEST_OS_FUCHSIA 78 # include <zircon/process.h> 79 # include <zircon/syscalls.h> 80 #endif // GTEST_OS_FUCHSIA 81 82 #include "gtest/gtest-spi.h" 83 #include "gtest/gtest-message.h" 84 #include "gtest/internal/gtest-internal.h" 85 #include "gtest/internal/gtest-string.h" 86 #include "src/gtest-internal-inl.h" 87 88 namespace testing { 89 namespace internal { 90 91 #if defined(_MSC_VER) || defined(__BORLANDC__) 92 // MSVC and C++Builder do not provide a definition of STDERR_FILENO. 93 const int kStdOutFileno = 1; 94 const int kStdErrFileno = 2; 95 #else 96 const int kStdOutFileno = STDOUT_FILENO; 97 const int kStdErrFileno = STDERR_FILENO; 98 #endif // _MSC_VER 99 100 #if GTEST_OS_LINUX 101 102 namespace { 103 template <typename T> 104 T ReadProcFileField(const std::string& filename, int field) { 105 std::string dummy; 106 std::ifstream file(filename.c_str()); 107 while (field-- > 0) { 108 file >> dummy; 109 } 110 T output = 0; 111 file >> output; 112 return output; 113 } 114 } // namespace 115 116 // Returns the number of active threads, or 0 when there is an error. 117 size_t GetThreadCount() { 118 const std::string filename = 119 (Message() << "/proc/" << getpid() << "/stat").GetString(); 120 return ReadProcFileField<size_t>(filename, 19); 121 } 122 123 #elif GTEST_OS_MAC 124 125 size_t GetThreadCount() { 126 const task_t task = mach_task_self(); 127 mach_msg_type_number_t thread_count; 128 thread_act_array_t thread_list; 129 const kern_return_t status = task_threads(task, &thread_list, &thread_count); 130 if (status == KERN_SUCCESS) { 131 // task_threads allocates resources in thread_list and we need to free them 132 // to avoid leaks. 133 vm_deallocate(task, 134 reinterpret_cast<vm_address_t>(thread_list), 135 sizeof(thread_t) * thread_count); 136 return static_cast<size_t>(thread_count); 137 } else { 138 return 0; 139 } 140 } 141 142 #elif GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \ 143 GTEST_OS_NETBSD 144 145 #if GTEST_OS_NETBSD 146 #undef KERN_PROC 147 #define KERN_PROC KERN_PROC2 148 #define kinfo_proc kinfo_proc2 149 #endif 150 151 #if GTEST_OS_DRAGONFLY 152 #define KP_NLWP(kp) (kp.kp_nthreads) 153 #elif GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD 154 #define KP_NLWP(kp) (kp.ki_numthreads) 155 #elif GTEST_OS_NETBSD 156 #define KP_NLWP(kp) (kp.p_nlwps) 157 #endif 158 159 // Returns the number of threads running in the process, or 0 to indicate that 160 // we cannot detect it. 161 size_t GetThreadCount() { 162 int mib[] = { 163 CTL_KERN, 164 KERN_PROC, 165 KERN_PROC_PID, 166 getpid(), 167 #if GTEST_OS_NETBSD 168 sizeof(struct kinfo_proc), 169 1, 170 #endif 171 }; 172 u_int miblen = sizeof(mib) / sizeof(mib[0]); 173 struct kinfo_proc info; 174 size_t size = sizeof(info); 175 if (sysctl(mib, miblen, &info, &size, NULL, 0)) { 176 return 0; 177 } 178 return static_cast<size_t>(KP_NLWP(info)); 179 } 180 #elif GTEST_OS_OPENBSD 181 182 // Returns the number of threads running in the process, or 0 to indicate that 183 // we cannot detect it. 184 size_t GetThreadCount() { 185 int mib[] = { 186 CTL_KERN, 187 KERN_PROC, 188 KERN_PROC_PID | KERN_PROC_SHOW_THREADS, 189 getpid(), 190 sizeof(struct kinfo_proc), 191 0, 192 }; 193 u_int miblen = sizeof(mib) / sizeof(mib[0]); 194 195 // get number of structs 196 size_t size; 197 if (sysctl(mib, miblen, NULL, &size, NULL, 0)) { 198 return 0; 199 } 200 mib[5] = size / mib[4]; 201 202 // populate array of structs 203 struct kinfo_proc info[mib[5]]; 204 if (sysctl(mib, miblen, &info, &size, NULL, 0)) { 205 return 0; 206 } 207 208 // exclude empty members 209 int nthreads = 0; 210 for (int i = 0; i < size / mib[4]; i++) { 211 if (info[i].p_tid != -1) 212 nthreads++; 213 } 214 return nthreads; 215 } 216 217 #elif GTEST_OS_QNX 218 219 // Returns the number of threads running in the process, or 0 to indicate that 220 // we cannot detect it. 221 size_t GetThreadCount() { 222 const int fd = open("/proc/self/as", O_RDONLY); 223 if (fd < 0) { 224 return 0; 225 } 226 procfs_info process_info; 227 const int status = 228 devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), nullptr); 229 close(fd); 230 if (status == EOK) { 231 return static_cast<size_t>(process_info.num_threads); 232 } else { 233 return 0; 234 } 235 } 236 237 #elif GTEST_OS_AIX 238 239 size_t GetThreadCount() { 240 struct procentry64 entry; 241 pid_t pid = getpid(); 242 int status = getprocs64(&entry, sizeof(entry), nullptr, 0, &pid, 1); 243 if (status == 1) { 244 return entry.pi_thcount; 245 } else { 246 return 0; 247 } 248 } 249 250 #elif GTEST_OS_FUCHSIA 251 252 size_t GetThreadCount() { 253 int dummy_buffer; 254 size_t avail; 255 zx_status_t status = zx_object_get_info( 256 zx_process_self(), 257 ZX_INFO_PROCESS_THREADS, 258 &dummy_buffer, 259 0, 260 nullptr, 261 &avail); 262 if (status == ZX_OK) { 263 return avail; 264 } else { 265 return 0; 266 } 267 } 268 269 #else 270 271 size_t GetThreadCount() { 272 // There's no portable way to detect the number of threads, so we just 273 // return 0 to indicate that we cannot detect it. 274 return 0; 275 } 276 277 #endif // GTEST_OS_LINUX 278 279 #if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS 280 281 void SleepMilliseconds(int n) { 282 ::Sleep(static_cast<DWORD>(n)); 283 } 284 285 AutoHandle::AutoHandle() 286 : handle_(INVALID_HANDLE_VALUE) {} 287 288 AutoHandle::AutoHandle(Handle handle) 289 : handle_(handle) {} 290 291 AutoHandle::~AutoHandle() { 292 Reset(); 293 } 294 295 AutoHandle::Handle AutoHandle::Get() const { 296 return handle_; 297 } 298 299 void AutoHandle::Reset() { 300 Reset(INVALID_HANDLE_VALUE); 301 } 302 303 void AutoHandle::Reset(HANDLE handle) { 304 // Resetting with the same handle we already own is invalid. 305 if (handle_ != handle) { 306 if (IsCloseable()) { 307 ::CloseHandle(handle_); 308 } 309 handle_ = handle; 310 } else { 311 GTEST_CHECK_(!IsCloseable()) 312 << "Resetting a valid handle to itself is likely a programmer error " 313 "and thus not allowed."; 314 } 315 } 316 317 bool AutoHandle::IsCloseable() const { 318 // Different Windows APIs may use either of these values to represent an 319 // invalid handle. 320 return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE; 321 } 322 323 Notification::Notification() 324 : event_(::CreateEvent(nullptr, // Default security attributes. 325 TRUE, // Do not reset automatically. 326 FALSE, // Initially unset. 327 nullptr)) { // Anonymous event. 328 GTEST_CHECK_(event_.Get() != nullptr); 329 } 330 331 void Notification::Notify() { 332 GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE); 333 } 334 335 void Notification::WaitForNotification() { 336 GTEST_CHECK_( 337 ::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0); 338 } 339 340 Mutex::Mutex() 341 : owner_thread_id_(0), 342 type_(kDynamic), 343 critical_section_init_phase_(0), 344 critical_section_(new CRITICAL_SECTION) { 345 ::InitializeCriticalSection(critical_section_); 346 } 347 348 Mutex::~Mutex() { 349 // Static mutexes are leaked intentionally. It is not thread-safe to try 350 // to clean them up. 351 if (type_ == kDynamic) { 352 ::DeleteCriticalSection(critical_section_); 353 delete critical_section_; 354 critical_section_ = nullptr; 355 } 356 } 357 358 void Mutex::Lock() { 359 ThreadSafeLazyInit(); 360 ::EnterCriticalSection(critical_section_); 361 owner_thread_id_ = ::GetCurrentThreadId(); 362 } 363 364 void Mutex::Unlock() { 365 ThreadSafeLazyInit(); 366 // We don't protect writing to owner_thread_id_ here, as it's the 367 // caller's responsibility to ensure that the current thread holds the 368 // mutex when this is called. 369 owner_thread_id_ = 0; 370 ::LeaveCriticalSection(critical_section_); 371 } 372 373 // Does nothing if the current thread holds the mutex. Otherwise, crashes 374 // with high probability. 375 void Mutex::AssertHeld() { 376 ThreadSafeLazyInit(); 377 GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId()) 378 << "The current thread is not holding the mutex @" << this; 379 } 380 381 namespace { 382 383 #ifdef _MSC_VER 384 // Use the RAII idiom to flag mem allocs that are intentionally never 385 // deallocated. The motivation is to silence the false positive mem leaks 386 // that are reported by the debug version of MS's CRT which can only detect 387 // if an alloc is missing a matching deallocation. 388 // Example: 389 // MemoryIsNotDeallocated memory_is_not_deallocated; 390 // critical_section_ = new CRITICAL_SECTION; 391 // 392 class MemoryIsNotDeallocated 393 { 394 public: 395 MemoryIsNotDeallocated() : old_crtdbg_flag_(0) { 396 old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); 397 // Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT 398 // doesn't report mem leak if there's no matching deallocation. 399 _CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF); 400 } 401 402 ~MemoryIsNotDeallocated() { 403 // Restore the original _CRTDBG_ALLOC_MEM_DF flag 404 _CrtSetDbgFlag(old_crtdbg_flag_); 405 } 406 407 private: 408 int old_crtdbg_flag_; 409 410 GTEST_DISALLOW_COPY_AND_ASSIGN_(MemoryIsNotDeallocated); 411 }; 412 #endif // _MSC_VER 413 414 } // namespace 415 416 // Initializes owner_thread_id_ and critical_section_ in static mutexes. 417 void Mutex::ThreadSafeLazyInit() { 418 // Dynamic mutexes are initialized in the constructor. 419 if (type_ == kStatic) { 420 switch ( 421 ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) { 422 case 0: 423 // If critical_section_init_phase_ was 0 before the exchange, we 424 // are the first to test it and need to perform the initialization. 425 owner_thread_id_ = 0; 426 { 427 // Use RAII to flag that following mem alloc is never deallocated. 428 #ifdef _MSC_VER 429 MemoryIsNotDeallocated memory_is_not_deallocated; 430 #endif // _MSC_VER 431 critical_section_ = new CRITICAL_SECTION; 432 } 433 ::InitializeCriticalSection(critical_section_); 434 // Updates the critical_section_init_phase_ to 2 to signal 435 // initialization complete. 436 GTEST_CHECK_(::InterlockedCompareExchange( 437 &critical_section_init_phase_, 2L, 1L) == 438 1L); 439 break; 440 case 1: 441 // Somebody else is already initializing the mutex; spin until they 442 // are done. 443 while (::InterlockedCompareExchange(&critical_section_init_phase_, 444 2L, 445 2L) != 2L) { 446 // Possibly yields the rest of the thread's time slice to other 447 // threads. 448 ::Sleep(0); 449 } 450 break; 451 452 case 2: 453 break; // The mutex is already initialized and ready for use. 454 455 default: 456 GTEST_CHECK_(false) 457 << "Unexpected value of critical_section_init_phase_ " 458 << "while initializing a static mutex."; 459 } 460 } 461 } 462 463 namespace { 464 465 class ThreadWithParamSupport : public ThreadWithParamBase { 466 public: 467 static HANDLE CreateThread(Runnable* runnable, 468 Notification* thread_can_start) { 469 ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start); 470 DWORD thread_id; 471 HANDLE thread_handle = ::CreateThread( 472 nullptr, // Default security. 473 0, // Default stack size. 474 &ThreadWithParamSupport::ThreadMain, 475 param, // Parameter to ThreadMainStatic 476 0x0, // Default creation flags. 477 &thread_id); // Need a valid pointer for the call to work under Win98. 478 GTEST_CHECK_(thread_handle != nullptr) 479 << "CreateThread failed with error " << ::GetLastError() << "."; 480 if (thread_handle == nullptr) { 481 delete param; 482 } 483 return thread_handle; 484 } 485 486 private: 487 struct ThreadMainParam { 488 ThreadMainParam(Runnable* runnable, Notification* thread_can_start) 489 : runnable_(runnable), 490 thread_can_start_(thread_can_start) { 491 } 492 std::unique_ptr<Runnable> runnable_; 493 // Does not own. 494 Notification* thread_can_start_; 495 }; 496 497 static DWORD WINAPI ThreadMain(void* ptr) { 498 // Transfers ownership. 499 std::unique_ptr<ThreadMainParam> param(static_cast<ThreadMainParam*>(ptr)); 500 if (param->thread_can_start_ != nullptr) 501 param->thread_can_start_->WaitForNotification(); 502 param->runnable_->Run(); 503 return 0; 504 } 505 506 // Prohibit instantiation. 507 ThreadWithParamSupport(); 508 509 GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParamSupport); 510 }; 511 512 } // namespace 513 514 ThreadWithParamBase::ThreadWithParamBase(Runnable *runnable, 515 Notification* thread_can_start) 516 : thread_(ThreadWithParamSupport::CreateThread(runnable, 517 thread_can_start)) { 518 } 519 520 ThreadWithParamBase::~ThreadWithParamBase() { 521 Join(); 522 } 523 524 void ThreadWithParamBase::Join() { 525 GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0) 526 << "Failed to join the thread with error " << ::GetLastError() << "."; 527 } 528 529 // Maps a thread to a set of ThreadIdToThreadLocals that have values 530 // instantiated on that thread and notifies them when the thread exits. A 531 // ThreadLocal instance is expected to persist until all threads it has 532 // values on have terminated. 533 class ThreadLocalRegistryImpl { 534 public: 535 // Registers thread_local_instance as having value on the current thread. 536 // Returns a value that can be used to identify the thread from other threads. 537 static ThreadLocalValueHolderBase* GetValueOnCurrentThread( 538 const ThreadLocalBase* thread_local_instance) { 539 DWORD current_thread = ::GetCurrentThreadId(); 540 MutexLock lock(&mutex_); 541 ThreadIdToThreadLocals* const thread_to_thread_locals = 542 GetThreadLocalsMapLocked(); 543 ThreadIdToThreadLocals::iterator thread_local_pos = 544 thread_to_thread_locals->find(current_thread); 545 if (thread_local_pos == thread_to_thread_locals->end()) { 546 thread_local_pos = thread_to_thread_locals->insert( 547 std::make_pair(current_thread, ThreadLocalValues())).first; 548 StartWatcherThreadFor(current_thread); 549 } 550 ThreadLocalValues& thread_local_values = thread_local_pos->second; 551 ThreadLocalValues::iterator value_pos = 552 thread_local_values.find(thread_local_instance); 553 if (value_pos == thread_local_values.end()) { 554 value_pos = 555 thread_local_values 556 .insert(std::make_pair( 557 thread_local_instance, 558 std::shared_ptr<ThreadLocalValueHolderBase>( 559 thread_local_instance->NewValueForCurrentThread()))) 560 .first; 561 } 562 return value_pos->second.get(); 563 } 564 565 static void OnThreadLocalDestroyed( 566 const ThreadLocalBase* thread_local_instance) { 567 std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders; 568 // Clean up the ThreadLocalValues data structure while holding the lock, but 569 // defer the destruction of the ThreadLocalValueHolderBases. 570 { 571 MutexLock lock(&mutex_); 572 ThreadIdToThreadLocals* const thread_to_thread_locals = 573 GetThreadLocalsMapLocked(); 574 for (ThreadIdToThreadLocals::iterator it = 575 thread_to_thread_locals->begin(); 576 it != thread_to_thread_locals->end(); 577 ++it) { 578 ThreadLocalValues& thread_local_values = it->second; 579 ThreadLocalValues::iterator value_pos = 580 thread_local_values.find(thread_local_instance); 581 if (value_pos != thread_local_values.end()) { 582 value_holders.push_back(value_pos->second); 583 thread_local_values.erase(value_pos); 584 // This 'if' can only be successful at most once, so theoretically we 585 // could break out of the loop here, but we don't bother doing so. 586 } 587 } 588 } 589 // Outside the lock, let the destructor for 'value_holders' deallocate the 590 // ThreadLocalValueHolderBases. 591 } 592 593 static void OnThreadExit(DWORD thread_id) { 594 GTEST_CHECK_(thread_id != 0) << ::GetLastError(); 595 std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders; 596 // Clean up the ThreadIdToThreadLocals data structure while holding the 597 // lock, but defer the destruction of the ThreadLocalValueHolderBases. 598 { 599 MutexLock lock(&mutex_); 600 ThreadIdToThreadLocals* const thread_to_thread_locals = 601 GetThreadLocalsMapLocked(); 602 ThreadIdToThreadLocals::iterator thread_local_pos = 603 thread_to_thread_locals->find(thread_id); 604 if (thread_local_pos != thread_to_thread_locals->end()) { 605 ThreadLocalValues& thread_local_values = thread_local_pos->second; 606 for (ThreadLocalValues::iterator value_pos = 607 thread_local_values.begin(); 608 value_pos != thread_local_values.end(); 609 ++value_pos) { 610 value_holders.push_back(value_pos->second); 611 } 612 thread_to_thread_locals->erase(thread_local_pos); 613 } 614 } 615 // Outside the lock, let the destructor for 'value_holders' deallocate the 616 // ThreadLocalValueHolderBases. 617 } 618 619 private: 620 // In a particular thread, maps a ThreadLocal object to its value. 621 typedef std::map<const ThreadLocalBase*, 622 std::shared_ptr<ThreadLocalValueHolderBase> > 623 ThreadLocalValues; 624 // Stores all ThreadIdToThreadLocals having values in a thread, indexed by 625 // thread's ID. 626 typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals; 627 628 // Holds the thread id and thread handle that we pass from 629 // StartWatcherThreadFor to WatcherThreadFunc. 630 typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle; 631 632 static void StartWatcherThreadFor(DWORD thread_id) { 633 // The returned handle will be kept in thread_map and closed by 634 // watcher_thread in WatcherThreadFunc. 635 HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, 636 FALSE, 637 thread_id); 638 GTEST_CHECK_(thread != nullptr); 639 // We need to pass a valid thread ID pointer into CreateThread for it 640 // to work correctly under Win98. 641 DWORD watcher_thread_id; 642 HANDLE watcher_thread = ::CreateThread( 643 nullptr, // Default security. 644 0, // Default stack size 645 &ThreadLocalRegistryImpl::WatcherThreadFunc, 646 reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)), 647 CREATE_SUSPENDED, &watcher_thread_id); 648 GTEST_CHECK_(watcher_thread != nullptr); 649 // Give the watcher thread the same priority as ours to avoid being 650 // blocked by it. 651 ::SetThreadPriority(watcher_thread, 652 ::GetThreadPriority(::GetCurrentThread())); 653 ::ResumeThread(watcher_thread); 654 ::CloseHandle(watcher_thread); 655 } 656 657 // Monitors exit from a given thread and notifies those 658 // ThreadIdToThreadLocals about thread termination. 659 static DWORD WINAPI WatcherThreadFunc(LPVOID param) { 660 const ThreadIdAndHandle* tah = 661 reinterpret_cast<const ThreadIdAndHandle*>(param); 662 GTEST_CHECK_( 663 ::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); 664 OnThreadExit(tah->first); 665 ::CloseHandle(tah->second); 666 delete tah; 667 return 0; 668 } 669 670 // Returns map of thread local instances. 671 static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() { 672 mutex_.AssertHeld(); 673 #ifdef _MSC_VER 674 MemoryIsNotDeallocated memory_is_not_deallocated; 675 #endif // _MSC_VER 676 static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals(); 677 return map; 678 } 679 680 // Protects access to GetThreadLocalsMapLocked() and its return value. 681 static Mutex mutex_; 682 // Protects access to GetThreadMapLocked() and its return value. 683 static Mutex thread_map_mutex_; 684 }; 685 686 Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); 687 Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); 688 689 ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread( 690 const ThreadLocalBase* thread_local_instance) { 691 return ThreadLocalRegistryImpl::GetValueOnCurrentThread( 692 thread_local_instance); 693 } 694 695 void ThreadLocalRegistry::OnThreadLocalDestroyed( 696 const ThreadLocalBase* thread_local_instance) { 697 ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance); 698 } 699 700 #endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS 701 702 #if GTEST_USES_POSIX_RE 703 704 // Implements RE. Currently only needed for death tests. 705 706 RE::~RE() { 707 if (is_valid_) { 708 // regfree'ing an invalid regex might crash because the content 709 // of the regex is undefined. Since the regex's are essentially 710 // the same, one cannot be valid (or invalid) without the other 711 // being so too. 712 regfree(&partial_regex_); 713 regfree(&full_regex_); 714 } 715 free(const_cast<char*>(pattern_)); 716 } 717 718 // Returns true if and only if regular expression re matches the entire str. 719 bool RE::FullMatch(const char* str, const RE& re) { 720 if (!re.is_valid_) return false; 721 722 regmatch_t match; 723 return regexec(&re.full_regex_, str, 1, &match, 0) == 0; 724 } 725 726 // Returns true if and only if regular expression re matches a substring of 727 // str (including str itself). 728 bool RE::PartialMatch(const char* str, const RE& re) { 729 if (!re.is_valid_) return false; 730 731 regmatch_t match; 732 return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; 733 } 734 735 // Initializes an RE from its string representation. 736 void RE::Init(const char* regex) { 737 pattern_ = posix::StrDup(regex); 738 739 // Reserves enough bytes to hold the regular expression used for a 740 // full match. 741 const size_t full_regex_len = strlen(regex) + 10; 742 char* const full_pattern = new char[full_regex_len]; 743 744 snprintf(full_pattern, full_regex_len, "^(%s)$", regex); 745 is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; 746 // We want to call regcomp(&partial_regex_, ...) even if the 747 // previous expression returns false. Otherwise partial_regex_ may 748 // not be properly initialized can may cause trouble when it's 749 // freed. 750 // 751 // Some implementation of POSIX regex (e.g. on at least some 752 // versions of Cygwin) doesn't accept the empty string as a valid 753 // regex. We change it to an equivalent form "()" to be safe. 754 if (is_valid_) { 755 const char* const partial_regex = (*regex == '\0') ? "()" : regex; 756 is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; 757 } 758 EXPECT_TRUE(is_valid_) 759 << "Regular expression \"" << regex 760 << "\" is not a valid POSIX Extended regular expression."; 761 762 delete[] full_pattern; 763 } 764 765 #elif GTEST_USES_SIMPLE_RE 766 767 // Returns true if and only if ch appears anywhere in str (excluding the 768 // terminating '\0' character). 769 bool IsInSet(char ch, const char* str) { 770 return ch != '\0' && strchr(str, ch) != nullptr; 771 } 772 773 // Returns true if and only if ch belongs to the given classification. 774 // Unlike similar functions in <ctype.h>, these aren't affected by the 775 // current locale. 776 bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } 777 bool IsAsciiPunct(char ch) { 778 return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); 779 } 780 bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } 781 bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } 782 bool IsAsciiWordChar(char ch) { 783 return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || 784 ('0' <= ch && ch <= '9') || ch == '_'; 785 } 786 787 // Returns true if and only if "\\c" is a supported escape sequence. 788 bool IsValidEscape(char c) { 789 return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); 790 } 791 792 // Returns true if and only if the given atom (specified by escaped and 793 // pattern) matches ch. The result is undefined if the atom is invalid. 794 bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { 795 if (escaped) { // "\\p" where p is pattern_char. 796 switch (pattern_char) { 797 case 'd': return IsAsciiDigit(ch); 798 case 'D': return !IsAsciiDigit(ch); 799 case 'f': return ch == '\f'; 800 case 'n': return ch == '\n'; 801 case 'r': return ch == '\r'; 802 case 's': return IsAsciiWhiteSpace(ch); 803 case 'S': return !IsAsciiWhiteSpace(ch); 804 case 't': return ch == '\t'; 805 case 'v': return ch == '\v'; 806 case 'w': return IsAsciiWordChar(ch); 807 case 'W': return !IsAsciiWordChar(ch); 808 } 809 return IsAsciiPunct(pattern_char) && pattern_char == ch; 810 } 811 812 return (pattern_char == '.' && ch != '\n') || pattern_char == ch; 813 } 814 815 // Helper function used by ValidateRegex() to format error messages. 816 static std::string FormatRegexSyntaxError(const char* regex, int index) { 817 return (Message() << "Syntax error at index " << index 818 << " in simple regular expression \"" << regex << "\": ").GetString(); 819 } 820 821 // Generates non-fatal failures and returns false if regex is invalid; 822 // otherwise returns true. 823 bool ValidateRegex(const char* regex) { 824 if (regex == nullptr) { 825 ADD_FAILURE() << "NULL is not a valid simple regular expression."; 826 return false; 827 } 828 829 bool is_valid = true; 830 831 // True if and only if ?, *, or + can follow the previous atom. 832 bool prev_repeatable = false; 833 for (int i = 0; regex[i]; i++) { 834 if (regex[i] == '\\') { // An escape sequence 835 i++; 836 if (regex[i] == '\0') { 837 ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) 838 << "'\\' cannot appear at the end."; 839 return false; 840 } 841 842 if (!IsValidEscape(regex[i])) { 843 ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) 844 << "invalid escape sequence \"\\" << regex[i] << "\"."; 845 is_valid = false; 846 } 847 prev_repeatable = true; 848 } else { // Not an escape sequence. 849 const char ch = regex[i]; 850 851 if (ch == '^' && i > 0) { 852 ADD_FAILURE() << FormatRegexSyntaxError(regex, i) 853 << "'^' can only appear at the beginning."; 854 is_valid = false; 855 } else if (ch == '$' && regex[i + 1] != '\0') { 856 ADD_FAILURE() << FormatRegexSyntaxError(regex, i) 857 << "'$' can only appear at the end."; 858 is_valid = false; 859 } else if (IsInSet(ch, "()[]{}|")) { 860 ADD_FAILURE() << FormatRegexSyntaxError(regex, i) 861 << "'" << ch << "' is unsupported."; 862 is_valid = false; 863 } else if (IsRepeat(ch) && !prev_repeatable) { 864 ADD_FAILURE() << FormatRegexSyntaxError(regex, i) 865 << "'" << ch << "' can only follow a repeatable token."; 866 is_valid = false; 867 } 868 869 prev_repeatable = !IsInSet(ch, "^$?*+"); 870 } 871 } 872 873 return is_valid; 874 } 875 876 // Matches a repeated regex atom followed by a valid simple regular 877 // expression. The regex atom is defined as c if escaped is false, 878 // or \c otherwise. repeat is the repetition meta character (?, *, 879 // or +). The behavior is undefined if str contains too many 880 // characters to be indexable by size_t, in which case the test will 881 // probably time out anyway. We are fine with this limitation as 882 // std::string has it too. 883 bool MatchRepetitionAndRegexAtHead( 884 bool escaped, char c, char repeat, const char* regex, 885 const char* str) { 886 const size_t min_count = (repeat == '+') ? 1 : 0; 887 const size_t max_count = (repeat == '?') ? 1 : 888 static_cast<size_t>(-1) - 1; 889 // We cannot call numeric_limits::max() as it conflicts with the 890 // max() macro on Windows. 891 892 for (size_t i = 0; i <= max_count; ++i) { 893 // We know that the atom matches each of the first i characters in str. 894 if (i >= min_count && MatchRegexAtHead(regex, str + i)) { 895 // We have enough matches at the head, and the tail matches too. 896 // Since we only care about *whether* the pattern matches str 897 // (as opposed to *how* it matches), there is no need to find a 898 // greedy match. 899 return true; 900 } 901 if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) 902 return false; 903 } 904 return false; 905 } 906 907 // Returns true if and only if regex matches a prefix of str. regex must 908 // be a valid simple regular expression and not start with "^", or the 909 // result is undefined. 910 bool MatchRegexAtHead(const char* regex, const char* str) { 911 if (*regex == '\0') // An empty regex matches a prefix of anything. 912 return true; 913 914 // "$" only matches the end of a string. Note that regex being 915 // valid guarantees that there's nothing after "$" in it. 916 if (*regex == '$') 917 return *str == '\0'; 918 919 // Is the first thing in regex an escape sequence? 920 const bool escaped = *regex == '\\'; 921 if (escaped) 922 ++regex; 923 if (IsRepeat(regex[1])) { 924 // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so 925 // here's an indirect recursion. It terminates as the regex gets 926 // shorter in each recursion. 927 return MatchRepetitionAndRegexAtHead( 928 escaped, regex[0], regex[1], regex + 2, str); 929 } else { 930 // regex isn't empty, isn't "$", and doesn't start with a 931 // repetition. We match the first atom of regex with the first 932 // character of str and recurse. 933 return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && 934 MatchRegexAtHead(regex + 1, str + 1); 935 } 936 } 937 938 // Returns true if and only if regex matches any substring of str. regex must 939 // be a valid simple regular expression, or the result is undefined. 940 // 941 // The algorithm is recursive, but the recursion depth doesn't exceed 942 // the regex length, so we won't need to worry about running out of 943 // stack space normally. In rare cases the time complexity can be 944 // exponential with respect to the regex length + the string length, 945 // but usually it's must faster (often close to linear). 946 bool MatchRegexAnywhere(const char* regex, const char* str) { 947 if (regex == nullptr || str == nullptr) return false; 948 949 if (*regex == '^') 950 return MatchRegexAtHead(regex + 1, str); 951 952 // A successful match can be anywhere in str. 953 do { 954 if (MatchRegexAtHead(regex, str)) 955 return true; 956 } while (*str++ != '\0'); 957 return false; 958 } 959 960 // Implements the RE class. 961 962 RE::~RE() { 963 free(const_cast<char*>(pattern_)); 964 free(const_cast<char*>(full_pattern_)); 965 } 966 967 // Returns true if and only if regular expression re matches the entire str. 968 bool RE::FullMatch(const char* str, const RE& re) { 969 return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); 970 } 971 972 // Returns true if and only if regular expression re matches a substring of 973 // str (including str itself). 974 bool RE::PartialMatch(const char* str, const RE& re) { 975 return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); 976 } 977 978 // Initializes an RE from its string representation. 979 void RE::Init(const char* regex) { 980 pattern_ = full_pattern_ = nullptr; 981 if (regex != nullptr) { 982 pattern_ = posix::StrDup(regex); 983 } 984 985 is_valid_ = ValidateRegex(regex); 986 if (!is_valid_) { 987 // No need to calculate the full pattern when the regex is invalid. 988 return; 989 } 990 991 const size_t len = strlen(regex); 992 // Reserves enough bytes to hold the regular expression used for a 993 // full match: we need space to prepend a '^', append a '$', and 994 // terminate the string with '\0'. 995 char* buffer = static_cast<char*>(malloc(len + 3)); 996 full_pattern_ = buffer; 997 998 if (*regex != '^') 999 *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. 1000 1001 // We don't use snprintf or strncpy, as they trigger a warning when 1002 // compiled with VC++ 8.0. 1003 memcpy(buffer, regex, len); 1004 buffer += len; 1005 1006 if (len == 0 || regex[len - 1] != '$') 1007 *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. 1008 1009 *buffer = '\0'; 1010 } 1011 1012 #endif // GTEST_USES_POSIX_RE 1013 1014 const char kUnknownFile[] = "unknown file"; 1015 1016 // Formats a source file path and a line number as they would appear 1017 // in an error message from the compiler used to compile this code. 1018 GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { 1019 const std::string file_name(file == nullptr ? kUnknownFile : file); 1020 1021 if (line < 0) { 1022 return file_name + ":"; 1023 } 1024 #ifdef _MSC_VER 1025 return file_name + "(" + StreamableToString(line) + "):"; 1026 #else 1027 return file_name + ":" + StreamableToString(line) + ":"; 1028 #endif // _MSC_VER 1029 } 1030 1031 // Formats a file location for compiler-independent XML output. 1032 // Although this function is not platform dependent, we put it next to 1033 // FormatFileLocation in order to contrast the two functions. 1034 // Note that FormatCompilerIndependentFileLocation() does NOT append colon 1035 // to the file location it produces, unlike FormatFileLocation(). 1036 GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( 1037 const char* file, int line) { 1038 const std::string file_name(file == nullptr ? kUnknownFile : file); 1039 1040 if (line < 0) 1041 return file_name; 1042 else 1043 return file_name + ":" + StreamableToString(line); 1044 } 1045 1046 GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) 1047 : severity_(severity) { 1048 const char* const marker = 1049 severity == GTEST_INFO ? "[ INFO ]" : 1050 severity == GTEST_WARNING ? "[WARNING]" : 1051 severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; 1052 GetStream() << ::std::endl << marker << " " 1053 << FormatFileLocation(file, line).c_str() << ": "; 1054 } 1055 1056 // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. 1057 GTestLog::~GTestLog() { 1058 GetStream() << ::std::endl; 1059 if (severity_ == GTEST_FATAL) { 1060 fflush(stderr); 1061 posix::Abort(); 1062 } 1063 } 1064 1065 // Disable Microsoft deprecation warnings for POSIX functions called from 1066 // this class (creat, dup, dup2, and close) 1067 GTEST_DISABLE_MSC_DEPRECATED_PUSH_() 1068 1069 #if GTEST_HAS_STREAM_REDIRECTION 1070 1071 // Object that captures an output stream (stdout/stderr). 1072 class CapturedStream { 1073 public: 1074 // The ctor redirects the stream to a temporary file. 1075 explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { 1076 # if GTEST_OS_WINDOWS 1077 char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT 1078 char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT 1079 1080 ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); 1081 const UINT success = ::GetTempFileNameA(temp_dir_path, 1082 "gtest_redir", 1083 0, // Generate unique file name. 1084 temp_file_path); 1085 GTEST_CHECK_(success != 0) 1086 << "Unable to create a temporary file in " << temp_dir_path; 1087 const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); 1088 GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " 1089 << temp_file_path; 1090 filename_ = temp_file_path; 1091 # else 1092 // There's no guarantee that a test has write access to the current 1093 // directory, so we create the temporary file in the /tmp directory 1094 // instead. We use /tmp on most systems, and /sdcard on Android. 1095 // That's because Android doesn't have /tmp. 1096 # if GTEST_OS_LINUX_ANDROID 1097 // Note: Android applications are expected to call the framework's 1098 // Context.getExternalStorageDirectory() method through JNI to get 1099 // the location of the world-writable SD Card directory. However, 1100 // this requires a Context handle, which cannot be retrieved 1101 // globally from native code. Doing so also precludes running the 1102 // code as part of a regular standalone executable, which doesn't 1103 // run in a Dalvik process (e.g. when running it through 'adb shell'). 1104 // 1105 // The location /data/local/tmp is directly accessible from native code. 1106 // '/sdcard' and other variants cannot be relied on, as they are not 1107 // guaranteed to be mounted, or may have a delay in mounting. 1108 char name_template[] = "/data/local/tmp/gtest_captured_stream.XXXXXX"; 1109 # else 1110 char name_template[] = "/tmp/captured_stream.XXXXXX"; 1111 # endif // GTEST_OS_LINUX_ANDROID 1112 const int captured_fd = mkstemp(name_template); 1113 if (captured_fd == -1) { 1114 GTEST_LOG_(WARNING) 1115 << "Failed to create tmp file " << name_template 1116 << " for test; does the test have access to the /tmp directory?"; 1117 } 1118 filename_ = name_template; 1119 # endif // GTEST_OS_WINDOWS 1120 fflush(nullptr); 1121 dup2(captured_fd, fd_); 1122 close(captured_fd); 1123 } 1124 1125 ~CapturedStream() { 1126 remove(filename_.c_str()); 1127 } 1128 1129 std::string GetCapturedString() { 1130 if (uncaptured_fd_ != -1) { 1131 // Restores the original stream. 1132 fflush(nullptr); 1133 dup2(uncaptured_fd_, fd_); 1134 close(uncaptured_fd_); 1135 uncaptured_fd_ = -1; 1136 } 1137 1138 FILE* const file = posix::FOpen(filename_.c_str(), "r"); 1139 if (file == nullptr) { 1140 GTEST_LOG_(FATAL) << "Failed to open tmp file " << filename_ 1141 << " for capturing stream."; 1142 } 1143 const std::string content = ReadEntireFile(file); 1144 posix::FClose(file); 1145 return content; 1146 } 1147 1148 private: 1149 const int fd_; // A stream to capture. 1150 int uncaptured_fd_; 1151 // Name of the temporary file holding the stderr output. 1152 ::std::string filename_; 1153 1154 GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); 1155 }; 1156 1157 GTEST_DISABLE_MSC_DEPRECATED_POP_() 1158 1159 static CapturedStream* g_captured_stderr = nullptr; 1160 static CapturedStream* g_captured_stdout = nullptr; 1161 1162 // Starts capturing an output stream (stdout/stderr). 1163 static void CaptureStream(int fd, const char* stream_name, 1164 CapturedStream** stream) { 1165 if (*stream != nullptr) { 1166 GTEST_LOG_(FATAL) << "Only one " << stream_name 1167 << " capturer can exist at a time."; 1168 } 1169 *stream = new CapturedStream(fd); 1170 } 1171 1172 // Stops capturing the output stream and returns the captured string. 1173 static std::string GetCapturedStream(CapturedStream** captured_stream) { 1174 const std::string content = (*captured_stream)->GetCapturedString(); 1175 1176 delete *captured_stream; 1177 *captured_stream = nullptr; 1178 1179 return content; 1180 } 1181 1182 // Starts capturing stdout. 1183 void CaptureStdout() { 1184 CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); 1185 } 1186 1187 // Starts capturing stderr. 1188 void CaptureStderr() { 1189 CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); 1190 } 1191 1192 // Stops capturing stdout and returns the captured string. 1193 std::string GetCapturedStdout() { 1194 return GetCapturedStream(&g_captured_stdout); 1195 } 1196 1197 // Stops capturing stderr and returns the captured string. 1198 std::string GetCapturedStderr() { 1199 return GetCapturedStream(&g_captured_stderr); 1200 } 1201 1202 #endif // GTEST_HAS_STREAM_REDIRECTION 1203 1204 1205 1206 1207 1208 size_t GetFileSize(FILE* file) { 1209 fseek(file, 0, SEEK_END); 1210 return static_cast<size_t>(ftell(file)); 1211 } 1212 1213 std::string ReadEntireFile(FILE* file) { 1214 const size_t file_size = GetFileSize(file); 1215 char* const buffer = new char[file_size]; 1216 1217 size_t bytes_last_read = 0; // # of bytes read in the last fread() 1218 size_t bytes_read = 0; // # of bytes read so far 1219 1220 fseek(file, 0, SEEK_SET); 1221 1222 // Keeps reading the file until we cannot read further or the 1223 // pre-determined file size is reached. 1224 do { 1225 bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); 1226 bytes_read += bytes_last_read; 1227 } while (bytes_last_read > 0 && bytes_read < file_size); 1228 1229 const std::string content(buffer, bytes_read); 1230 delete[] buffer; 1231 1232 return content; 1233 } 1234 1235 #if GTEST_HAS_DEATH_TEST 1236 static const std::vector<std::string>* g_injected_test_argvs = 1237 nullptr; // Owned. 1238 1239 std::vector<std::string> GetInjectableArgvs() { 1240 if (g_injected_test_argvs != nullptr) { 1241 return *g_injected_test_argvs; 1242 } 1243 return GetArgvs(); 1244 } 1245 1246 void SetInjectableArgvs(const std::vector<std::string>* new_argvs) { 1247 if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs; 1248 g_injected_test_argvs = new_argvs; 1249 } 1250 1251 void SetInjectableArgvs(const std::vector<std::string>& new_argvs) { 1252 SetInjectableArgvs( 1253 new std::vector<std::string>(new_argvs.begin(), new_argvs.end())); 1254 } 1255 1256 void ClearInjectableArgvs() { 1257 delete g_injected_test_argvs; 1258 g_injected_test_argvs = nullptr; 1259 } 1260 #endif // GTEST_HAS_DEATH_TEST 1261 1262 #if GTEST_OS_WINDOWS_MOBILE 1263 namespace posix { 1264 void Abort() { 1265 DebugBreak(); 1266 TerminateProcess(GetCurrentProcess(), 1); 1267 } 1268 } // namespace posix 1269 #endif // GTEST_OS_WINDOWS_MOBILE 1270 1271 // Returns the name of the environment variable corresponding to the 1272 // given flag. For example, FlagToEnvVar("foo") will return 1273 // "GTEST_FOO" in the open-source version. 1274 static std::string FlagToEnvVar(const char* flag) { 1275 const std::string full_flag = 1276 (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); 1277 1278 Message env_var; 1279 for (size_t i = 0; i != full_flag.length(); i++) { 1280 env_var << ToUpper(full_flag.c_str()[i]); 1281 } 1282 1283 return env_var.GetString(); 1284 } 1285 1286 // Parses 'str' for a 32-bit signed integer. If successful, writes 1287 // the result to *value and returns true; otherwise leaves *value 1288 // unchanged and returns false. 1289 bool ParseInt32(const Message& src_text, const char* str, Int32* value) { 1290 // Parses the environment variable as a decimal integer. 1291 char* end = nullptr; 1292 const long long_value = strtol(str, &end, 10); // NOLINT 1293 1294 // Has strtol() consumed all characters in the string? 1295 if (*end != '\0') { 1296 // No - an invalid character was encountered. 1297 Message msg; 1298 msg << "WARNING: " << src_text 1299 << " is expected to be a 32-bit integer, but actually" 1300 << " has value \"" << str << "\".\n"; 1301 printf("%s", msg.GetString().c_str()); 1302 fflush(stdout); 1303 return false; 1304 } 1305 1306 // Is the parsed value in the range of an Int32? 1307 const Int32 result = static_cast<Int32>(long_value); 1308 if (long_value == LONG_MAX || long_value == LONG_MIN || 1309 // The parsed value overflows as a long. (strtol() returns 1310 // LONG_MAX or LONG_MIN when the input overflows.) 1311 result != long_value 1312 // The parsed value overflows as an Int32. 1313 ) { 1314 Message msg; 1315 msg << "WARNING: " << src_text 1316 << " is expected to be a 32-bit integer, but actually" 1317 << " has value " << str << ", which overflows.\n"; 1318 printf("%s", msg.GetString().c_str()); 1319 fflush(stdout); 1320 return false; 1321 } 1322 1323 *value = result; 1324 return true; 1325 } 1326 1327 // Reads and returns the Boolean environment variable corresponding to 1328 // the given flag; if it's not set, returns default_value. 1329 // 1330 // The value is considered true if and only if it's not "0". 1331 bool BoolFromGTestEnv(const char* flag, bool default_value) { 1332 #if defined(GTEST_GET_BOOL_FROM_ENV_) 1333 return GTEST_GET_BOOL_FROM_ENV_(flag, default_value); 1334 #else 1335 const std::string env_var = FlagToEnvVar(flag); 1336 const char* const string_value = posix::GetEnv(env_var.c_str()); 1337 return string_value == nullptr ? default_value 1338 : strcmp(string_value, "0") != 0; 1339 #endif // defined(GTEST_GET_BOOL_FROM_ENV_) 1340 } 1341 1342 // Reads and returns a 32-bit integer stored in the environment 1343 // variable corresponding to the given flag; if it isn't set or 1344 // doesn't represent a valid 32-bit integer, returns default_value. 1345 Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { 1346 #if defined(GTEST_GET_INT32_FROM_ENV_) 1347 return GTEST_GET_INT32_FROM_ENV_(flag, default_value); 1348 #else 1349 const std::string env_var = FlagToEnvVar(flag); 1350 const char* const string_value = posix::GetEnv(env_var.c_str()); 1351 if (string_value == nullptr) { 1352 // The environment variable is not set. 1353 return default_value; 1354 } 1355 1356 Int32 result = default_value; 1357 if (!ParseInt32(Message() << "Environment variable " << env_var, 1358 string_value, &result)) { 1359 printf("The default value %s is used.\n", 1360 (Message() << default_value).GetString().c_str()); 1361 fflush(stdout); 1362 return default_value; 1363 } 1364 1365 return result; 1366 #endif // defined(GTEST_GET_INT32_FROM_ENV_) 1367 } 1368 1369 // As a special case for the 'output' flag, if GTEST_OUTPUT is not 1370 // set, we look for XML_OUTPUT_FILE, which is set by the Bazel build 1371 // system. The value of XML_OUTPUT_FILE is a filename without the 1372 // "xml:" prefix of GTEST_OUTPUT. 1373 // Note that this is meant to be called at the call site so it does 1374 // not check that the flag is 'output' 1375 // In essence this checks an env variable called XML_OUTPUT_FILE 1376 // and if it is set we prepend "xml:" to its value, if it not set we return "" 1377 std::string OutputFlagAlsoCheckEnvVar(){ 1378 std::string default_value_for_output_flag = ""; 1379 const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE"); 1380 if (nullptr != xml_output_file_env) { 1381 default_value_for_output_flag = std::string("xml:") + xml_output_file_env; 1382 } 1383 return default_value_for_output_flag; 1384 } 1385 1386 // Reads and returns the string environment variable corresponding to 1387 // the given flag; if it's not set, returns default_value. 1388 const char* StringFromGTestEnv(const char* flag, const char* default_value) { 1389 #if defined(GTEST_GET_STRING_FROM_ENV_) 1390 return GTEST_GET_STRING_FROM_ENV_(flag, default_value); 1391 #else 1392 const std::string env_var = FlagToEnvVar(flag); 1393 const char* const value = posix::GetEnv(env_var.c_str()); 1394 return value == nullptr ? default_value : value; 1395 #endif // defined(GTEST_GET_STRING_FROM_ENV_) 1396 } 1397 1398 } // namespace internal 1399 } // namespace testing