// File: halfflat[P]tinyopt/test/googletest/googletest/src/gtest.cc
// Function: testing::internal::UnitTestImpl::RunAllTests()
bool UnitTestImpl::RunAllTests() {
  // True if and only if Google Test is initialized before RUN_ALL_TESTS() is
  // called.
  const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized();

  // Do not run any test if the --help flag was specified.
  if (g_help_flag) return true;

  // Repeats the call to the post-flag parsing initialization in case the
  // user didn't call InitGoogleTest.
  PostFlagParsingInit();

#if GTEST_HAS_FILE_SYSTEM
  // Even if sharding is not on, test runners may want to use the
  // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
  // protocol.
  internal::WriteToShardStatusFileIfNeeded();
#endif  // GTEST_HAS_FILE_SYSTEM

  // True if and only if we are in a subprocess for running a thread-safe-style
  // death test.
  bool in_subprocess_for_death_test = false;

#ifdef GTEST_HAS_DEATH_TEST
  in_subprocess_for_death_test = (internal_run_death_test_flag_ != nullptr);
#if defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)
  if (in_subprocess_for_death_test) {
    GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_();
  }
#endif  // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)
#endif  // GTEST_HAS_DEATH_TEST

  const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,
                                        in_subprocess_for_death_test);

  // Compares the full test names with the filter to decide which
  // tests to run.
  const bool has_tests_to_run =
      FilterTests(should_shard ? HONOR_SHARDING_PROTOCOL
                               : IGNORE_SHARDING_PROTOCOL) > 0;

  // Lists the tests and exits if the --gtest_list_tests flag was specified.
  if (GTEST_FLAG_GET(list_tests)) {
    // This must be called *after* FilterTests() has been called.
    ListTestsMatchingFilter();
    return true;
  }

  random_seed_ = GetRandomSeedFromFlag(GTEST_FLAG_GET(random_seed));

  // True if and only if at least one test has failed.
  bool failed = false;

  TestEventListener* repeater = listeners()->repeater();

  start_timestamp_ = GetTimeInMillis();
  repeater->OnTestProgramStart(*parent_);

  // How many times to repeat the tests?  We don't want to repeat them
  // when we are inside the subprocess of a death test.
  const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG_GET(repeat);

  // Repeats forever if the repeat count is negative.
  const bool gtest_repeat_forever = repeat < 0;

  // Should test environments be set up and torn down for each repeat, or only
  // set up on the first and torn down on the last iteration? If there is no
  // "last" iteration because the tests will repeat forever, always recreate the
  // environments to avoid leaks in case one of the environments is using
  // resources that are external to this process. Without this check there would
  // be no way to clean up those external resources automatically.
  const bool recreate_environments_when_repeating =
      GTEST_FLAG_GET(recreate_environments_when_repeating) ||
      gtest_repeat_forever;

  for (int i = 0; gtest_repeat_forever || i != repeat; i++) {
    // We want to preserve failures generated by ad-hoc test
    // assertions executed before RUN_ALL_TESTS().
    ClearNonAdHocTestResult();

    Timer timer;

    // Shuffles test suites and tests if requested.
    if (has_tests_to_run && GTEST_FLAG_GET(shuffle)) {
      random()->Reseed(static_cast<uint32_t>(random_seed_));
      // This should be done before calling OnTestIterationStart(),
      // such that a test event listener can see the actual test order
      // in the event.
      ShuffleTests();
    }

    // Tells the unit test event listeners that the tests are about to start.
    repeater->OnTestIterationStart(*parent_, i);

    // Runs each test suite if there is at least one test to run.
    if (has_tests_to_run) {
      // Sets up all environments beforehand. If test environments aren't
      // recreated for each iteration, only do so on the first iteration.
      if (i == 0 || recreate_environments_when_repeating) {
        repeater->OnEnvironmentsSetUpStart(*parent_);
        ForEach(environments_, SetUpEnvironment);
        repeater->OnEnvironmentsSetUpEnd(*parent_);
      }

      // Runs the tests only if there was no fatal failure or skip triggered
      // during global set-up.
      if (Test::IsSkipped()) {
        // Emit diagnostics when global set-up calls skip, as it will not be
        // emitted by default.
        TestResult& test_result =
            *internal::GetUnitTestImpl()->current_test_result();
        for (int j = 0; j < test_result.total_part_count(); ++j) {
          const TestPartResult& test_part_result =
              test_result.GetTestPartResult(j);
          if (test_part_result.type() == TestPartResult::kSkip) {
            const std::string& result = test_part_result.message();
            printf("%s\n", result.c_str());
          }
        }
        fflush(stdout);
      } else if (!Test::HasFatalFailure()) {
        for (int test_index = 0; test_index < total_test_suite_count();
             test_index++) {
          GetMutableSuiteCase(test_index)->Run();
          if (GTEST_FLAG_GET(fail_fast) &&
              GetMutableSuiteCase(test_index)->Failed()) {
            for (int j = test_index + 1; j < total_test_suite_count(); j++) {
              GetMutableSuiteCase(j)->Skip();
            }
            break;
          }
        }
      } else if (Test::HasFatalFailure()) {
        // If there was a fatal failure during the global setup then we know we
        // aren't going to run any tests. Explicitly mark all of the tests as
        // skipped to make this obvious in the output.
        for (int test_index = 0; test_index < total_test_suite_count();
             test_index++) {
          GetMutableSuiteCase(test_index)->Skip();
        }
      }

      // Tears down all environments in reverse order afterwards. If test
      // environments aren't recreated for each iteration, only do so on the
      // last iteration.
      if (i == repeat - 1 || recreate_environments_when_repeating) {
        repeater->OnEnvironmentsTearDownStart(*parent_);
        std::for_each(environments_.rbegin(), environments_.rend(),
                      TearDownEnvironment);
        repeater->OnEnvironmentsTearDownEnd(*parent_);
      }
    }

    elapsed_time_ = timer.Elapsed();

    // Tells the unit test event listener that the tests have just finished.
    repeater->OnTestIterationEnd(*parent_, i);

    // Gets the result and clears it.
    if (!Passed()) {
      failed = true;
    }

    // Restores the original test order after the iteration.  This
    // allows the user to quickly repro a failure that happens in the
    // N-th iteration without repeating the first (N - 1) iterations.
    // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in
    // case the user somehow changes the value of the flag somewhere
    // (it's always safe to unshuffle the tests).
    UnshuffleTests();

    if (GTEST_FLAG_GET(shuffle)) {
      // Picks a new random seed for each iteration.
      random_seed_ = GetNextRandomSeed(random_seed_);
    }
  }

  repeater->OnTestProgramEnd(*parent_);
  // Destroy environments in normal code, not in static teardown.
  bool delete_environment_on_teardown = true;
  if (delete_environment_on_teardown) {
    ForEach(environments_, internal::Delete<Environment>);
    environments_.clear();
  }

  if (!gtest_is_initialized_before_run_all_tests) {
    ColoredPrintf(
        GTestColor::kRed,
        "\nIMPORTANT NOTICE - DO NOT IGNORE:\n"
        "This test program did NOT call " GTEST_INIT_GOOGLE_TEST_NAME_
        "() before calling RUN_ALL_TESTS(). This is INVALID. Soon " GTEST_NAME_
        " will start to enforce the valid usage. "
        "Please fix it ASAP, or IT WILL START TO FAIL.\n");  // NOLINT
  }

  return !failed;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xb8(%rbp)
callq 0x9bc30
andb $0x1, %al
movb %al, -0x11(%rbp)
testb $0x1, 0x7d916(%rip)     # 0x117ad1
je 0x9a1c6
movb $0x1, -0x1(%rbp)
jmp 0x9a830
movq -0xb8(%rbp), %rdi
callq 0x9b720
callq 0x9bc70
movq -0xb8(%rbp), %rdi
movb $0x0, -0x12(%rbp)
addq $0x238, %rdi            # imm = 0x238
xorl %eax, %eax
movl %eax, %esi
callq 0xaaa70
andb $0x1, %al
movb %al, -0x12(%rbp)
movb -0x12(%rbp), %al
leaq 0x3263f(%rip), %rdi     # 0xcc840
leaq 0x32658(%rip), %rsi     # 0xcc860
andb $0x1, %al
movzbl %al, %edx
callq 0x8b810
movq -0xb8(%rbp), %rdi
andb $0x1, %al
movb %al, -0x13(%rbp)
movb -0x13(%rbp), %cl
movl $0x1, %esi
xorl %eax, %eax
testb $0x1, %cl
cmovnel %eax, %esi
callq 0x9bcf0
cmpl $0x0, %eax
setg %al
andb $0x1, %al
movb %al, -0x14(%rbp)
testb $0x1, 0x7d8d4(%rip)     # 0x117b19
je 0x9a25c
movq -0xb8(%rbp), %rdi
callq 0x9c330
movb $0x1, -0x1(%rbp)
jmp 0x9a830
movl 0x7d8e2(%rip), %edi     # 0x117b44
callq 0xab150
movq -0xb8(%rbp), %rdi
movl %eax, 0x21c(%rdi)
movb $0x0, -0x15(%rbp)
callq 0xa3250
movq %rax, %rdi
callq 0x83a90
movq %rax, -0x20(%rbp)
callq 0x84120
movq %rax, %rcx
movq -0xb8(%rbp), %rax
movq %rcx, 0x228(%rax)
movq -0x20(%rbp), %rdi
movq 0x8(%rax), %rsi
movq (%rdi), %rax
callq *0x10(%rax)
testb $0x1, -0x12(%rbp)
je 0x9a2c0
movl $0x1, %eax
movl %eax, -0xbc(%rbp)
jmp 0x9a2cc
movl 0x7d882(%rip), %eax     # 0x117b48
movl %eax, -0xbc(%rbp)
movl -0xbc(%rbp), %eax
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
setl %al
andb $0x1, %al
movb %al, -0x25(%rbp)
movb $0x1, %al
testb $0x1, 0x7d862(%rip)     # 0x117b4c
movb %al, -0xbd(%rbp)
jne 0x9a2fb
movb -0x25(%rbp), %al
movb %al, -0xbd(%rbp)
movb -0xbd(%rbp), %al
andb $0x1, %al
movb %al, -0x26(%rbp)
movl $0x0, -0x2c(%rbp)
movb $0x1, %al
testb $0x1, -0x25(%rbp)
movb %al, -0xbe(%rbp)
jne 0x9a32a
movl -0x2c(%rbp), %eax
cmpl -0x24(%rbp), %eax
setne %al
movb %al, -0xbe(%rbp)
movb -0xbe(%rbp), %al
testb $0x1, %al
jne 0x9a339
jmp 0x9a7b8
movq -0xb8(%rbp), %rdi
callq 0xab1a0
leaq -0x38(%rbp), %rdi
callq 0xa8290
testb $0x1, -0x14(%rbp)
je 0x9a38a
testb $0x1, 0x7d7f3(%rip)     # 0x117b4e
je 0x9a38a
movq -0xb8(%rbp), %rdi
callq 0xab1d0
movq %rax, %rdi
movq -0xb8(%rbp), %rax
movl 0x21c(%rax), %esi
callq 0xab1f0
movq -0xb8(%rbp), %rdi
callq 0x9c870
movq -0xb8(%rbp), %rax
movq -0x20(%rbp), %rdi
movq 0x8(%rax), %rsi
movl -0x2c(%rbp), %edx
movq (%rdi), %rax
callq *0x18(%rax)
testb $0x1, -0x14(%rbp)
je 0x9a730
cmpl $0x0, -0x2c(%rbp)
je 0x9a3b8
testb $0x1, -0x26(%rbp)
je 0x9a3fc
movq -0xb8(%rbp), %rax
movq -0x20(%rbp), %rdi
movq 0x8(%rax), %rsi
movq (%rdi), %rax
callq *0x20(%rax)
movq -0xb8(%rbp), %rdi
addq $0xa0, %rdi
leaq 0x258e(%rip), %rsi      # 0x9c970
callq 0xaaa20
movq -0xb8(%rbp), %rax
movq -0x20(%rbp), %rdi
movq 0x8(%rax), %rsi
movq (%rdi), %rax
callq *0x28(%rax)
callq 0x899e0
testb $0x1, %al
jne 0x9a40a
jmp 0x9a53b
callq 0xa29e0
movq %rax, %rdi
callq 0x839f0
movq %rax, -0x40(%rbp)
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
movl %eax, -0xc4(%rbp)
movq -0x40(%rbp), %rdi
callq 0x88580
movl %eax, %ecx
movl -0xc4(%rbp), %eax
cmpl %ecx, %eax
jge 0x9a527
movq -0x40(%rbp), %rdi
movl -0x44(%rbp), %esi
callq 0x88520
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
callq 0xa48d0
cmpl $0x3, %eax
jne 0x9a517
movq -0x50(%rbp), %rdi
callq 0xa48e0
movq %rax, -0xd8(%rbp)
leaq -0x79(%rbp), %rdi
movq %rdi, -0xd0(%rbp)
callq 0x10e10
movq -0xd8(%rbp), %rsi
movq -0xd0(%rbp), %rdx
leaq -0x78(%rbp), %rdi
callq 0x1d070
jmp 0x9a49f
leaq -0x79(%rbp), %rdi
callq 0x10810
leaq -0x78(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rdi
callq 0x102c0
movq %rax, %rsi
leaq 0x346ba(%rip), %rdi     # 0xceb7d
xorl %eax, %eax
callq 0x10090
jmp 0x9a4cc
leaq -0x78(%rbp), %rdi
callq 0x10fc8
jmp 0x9a517
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x79(%rbp), %rdi
callq 0x10810
jmp 0x9a83e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x10fc8
jmp 0x9a83e
jmp 0x9a519
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x9a422
movq 0x7ca52(%rip), %rax     # 0x116f80
movq (%rax), %rdi
callq 0x10930
jmp 0x9a6a3
callq 0x899c0
testb $0x1, %al
jne 0x9a639
movl $0x0, -0x90(%rbp)
movq -0xb8(%rbp), %rdi
movl -0x90(%rbp), %eax
movl %eax, -0xdc(%rbp)
callq 0x83c00
movl %eax, %ecx
movl -0xdc(%rbp), %eax
cmpl %ecx, %eax
jge 0x9a637
movq -0xb8(%rbp), %rdi
movl -0x90(%rbp), %esi
callq 0xa9b50
movq %rax, %rdi
callq 0x8aad0
testb $0x1, 0x7d537(%rip)     # 0x117ad2
je 0x9a621
movq -0xb8(%rbp), %rdi
movl -0x90(%rbp), %esi
callq 0xa9b50
movq %rax, %rdi
callq 0xab210
testb $0x1, %al
jne 0x9a5c1
jmp 0x9a621
movl -0x90(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x94(%rbp)
movq -0xb8(%rbp), %rdi
movl -0x94(%rbp), %eax
movl %eax, -0xe0(%rbp)
callq 0x83c00
movl %eax, %ecx
movl -0xe0(%rbp), %eax
cmpl %ecx, %eax
jge 0x9a61f
movq -0xb8(%rbp), %rdi
movl -0x94(%rbp), %esi
callq 0xa9b50
movq %rax, %rdi
callq 0x8adb0
movl -0x94(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x94(%rbp)
jmp 0x9a5d0
jmp 0x9a637
jmp 0x9a623
movl -0x90(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x90(%rbp)
jmp 0x9a552
jmp 0x9a6a1
callq 0x899c0
testb $0x1, %al
jne 0x9a644
jmp 0x9a69f
movl $0x0, -0x98(%rbp)
movq -0xb8(%rbp), %rdi
movl -0x98(%rbp), %eax
movl %eax, -0xe4(%rbp)
callq 0x83c00
movl %eax, %ecx
movl -0xe4(%rbp), %eax
cmpl %ecx, %eax
jge 0x9a69d
movq -0xb8(%rbp), %rdi
movl -0x98(%rbp), %esi
callq 0xa9b50
movq %rax, %rdi
callq 0x8adb0
movl -0x98(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x98(%rbp)
jmp 0x9a64e
jmp 0x9a69f
jmp 0x9a6a1
jmp 0x9a6a3
movl -0x2c(%rbp), %eax
movl -0x24(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
je 0x9a6b6
testb $0x1, -0x26(%rbp)
je 0x9a72e
movq -0xb8(%rbp), %rax
movq -0x20(%rbp), %rdi
movq 0x8(%rax), %rsi
movq (%rdi), %rax
callq *0x70(%rax)
movq -0xb8(%rbp), %rsi
addq $0xa0, %rsi
leaq -0xa0(%rbp), %rdi
callq 0xab2d0
movq -0xb8(%rbp), %rsi
addq $0xa0, %rsi
leaq -0xa8(%rbp), %rdi
callq 0xab320
leaq -0xa0(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
leaq 0x227c(%rip), %rdx      # 0x9c990
callq 0xab260
movq -0xb8(%rbp), %rax
movq -0x20(%rbp), %rdi
movq 0x8(%rax), %rsi
movq (%rdi), %rax
callq *0x78(%rax)
jmp 0x9a730
leaq -0x38(%rbp), %rdi
callq 0xa85a0
movq %rax, %rcx
movq -0xb8(%rbp), %rax
movq %rcx, 0x230(%rax)
movq -0x20(%rbp), %rdi
movq 0x8(%rax), %rsi
movl -0x2c(%rbp), %edx
movq (%rdi), %rax
callq *0x80(%rax)
movq -0xb8(%rbp), %rdi
callq 0xa9a20
testb $0x1, %al
jne 0x9a772
movb $0x1, -0x15(%rbp)
movq -0xb8(%rbp), %rdi
callq 0x9c9b0
testb $0x1, 0x7d3c9(%rip)     # 0x117b4e
je 0x9a7a8
movq -0xb8(%rbp), %rax
movl 0x21c(%rax), %edi
callq 0xab370
movl %eax, %ecx
movq -0xb8(%rbp), %rax
movl %ecx, 0x21c(%rax)
jmp 0x9a7aa
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x9a30d
movq -0xb8(%rbp), %rax
movq -0x20(%rbp), %rdi
movq 0x8(%rax), %rsi
movq (%rdi), %rax
callq *0x88(%rax)
movb $0x1, -0xa9(%rbp)
testb $0x1, -0xa9(%rbp)
je 0x9a80d
movq -0xb8(%rbp), %rdi
addq $0xa0, %rdi
leaq 0x96b(%rip), %rsi       # 0x9b160
callq 0xaaa20
movq -0xb8(%rbp), %rdi
addq $0xa0, %rdi
callq 0xab4b0
testb $0x1, -0x11(%rbp)
jne 0x9a826
movl $0x1, %edi
leaq 0x34a56(%rip), %rsi     # 0xcf275
movb $0x0, %al
callq 0x8b660
movb -0x15(%rbp), %al
xorb $-0x1, %al
andb $0x1, %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xf0, %rsp
popq %rbp
retq
movq -0x88(%rbp), %rdi
callq 0x10e00
nopw (%rax,%rax)