Use Abseil Flag public API for flag parsing.
This change brings InitGoogleTest semantic in accordance with the official documentation: only GoogleTest flags are removed from argc/argv. The rest of the flags remains in place. We do nothing special for flags with unrecognized gunit_/gtest_ prefix and we do not report them. PiperOrigin-RevId: 527257221 Change-Id: Ibb29a1bda1a44251a4ee579c0fb5bbdfd9965c21
This commit is contained in:
		
				
					committed by
					
						
						Copybara-Service
					
				
			
			
				
	
			
			
			
						parent
						
							ccdeec888e
						
					
				
				
					commit
					dea0484e4d
				
			@@ -44,6 +44,7 @@
 | 
				
			|||||||
#include <chrono>  // NOLINT
 | 
					#include <chrono>  // NOLINT
 | 
				
			||||||
#include <cmath>
 | 
					#include <cmath>
 | 
				
			||||||
#include <cstdint>
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					#include <cstdlib>
 | 
				
			||||||
#include <cstring>
 | 
					#include <cstring>
 | 
				
			||||||
#include <initializer_list>
 | 
					#include <initializer_list>
 | 
				
			||||||
#include <iomanip>
 | 
					#include <iomanip>
 | 
				
			||||||
@@ -140,6 +141,7 @@
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef GTEST_HAS_ABSL
 | 
					#ifdef GTEST_HAS_ABSL
 | 
				
			||||||
 | 
					#include "absl/container/flat_hash_set.h"
 | 
				
			||||||
#include "absl/debugging/failure_signal_handler.h"
 | 
					#include "absl/debugging/failure_signal_handler.h"
 | 
				
			||||||
#include "absl/debugging/stacktrace.h"
 | 
					#include "absl/debugging/stacktrace.h"
 | 
				
			||||||
#include "absl/debugging/symbolize.h"
 | 
					#include "absl/debugging/symbolize.h"
 | 
				
			||||||
@@ -147,6 +149,8 @@
 | 
				
			|||||||
#include "absl/flags/usage.h"
 | 
					#include "absl/flags/usage.h"
 | 
				
			||||||
#include "absl/strings/str_cat.h"
 | 
					#include "absl/strings/str_cat.h"
 | 
				
			||||||
#include "absl/strings/str_replace.h"
 | 
					#include "absl/strings/str_replace.h"
 | 
				
			||||||
 | 
					#include "absl/strings/string_view.h"
 | 
				
			||||||
 | 
					#include "absl/strings/strip.h"
 | 
				
			||||||
#endif  // GTEST_HAS_ABSL
 | 
					#endif  // GTEST_HAS_ABSL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Checks builtin compiler feature |x| while avoiding an extra layer of #ifdefs
 | 
					// Checks builtin compiler feature |x| while avoiding an extra layer of #ifdefs
 | 
				
			||||||
@@ -6686,25 +6690,60 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Parses the command line for Google Test flags, without initializing
 | 
					// Parses the command line for Google Test flags, without initializing
 | 
				
			||||||
// other parts of Google Test.
 | 
					// other parts of Google Test. This function updates argc and argv by removing
 | 
				
			||||||
 | 
					// flags that are known to GoogleTest (including other user flags defined using
 | 
				
			||||||
 | 
					// ABSL_FLAG if GoogleTest is built with GTEST_USE_ABSL). Other arguments
 | 
				
			||||||
 | 
					// remain in place. Unrecognized flags are not reported and do not cause the
 | 
				
			||||||
 | 
					// program to exit.
 | 
				
			||||||
void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
 | 
					void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
 | 
				
			||||||
#ifdef GTEST_HAS_ABSL
 | 
					#ifdef GTEST_HAS_ABSL
 | 
				
			||||||
  if (*argc > 0) {
 | 
					  if (*argc <= 0) return;
 | 
				
			||||||
    // absl::ParseCommandLine() requires *argc > 0.
 | 
					
 | 
				
			||||||
    auto positional_args = absl::flags_internal::ParseCommandLineImpl(
 | 
					  std::vector<char*> positional_args;
 | 
				
			||||||
        *argc, argv, absl::flags_internal::UsageFlagsAction::kHandleUsage,
 | 
					  std::vector<absl::UnrecognizedFlag> unrecognized_flags;
 | 
				
			||||||
        absl::flags_internal::OnUndefinedFlag::kReportUndefined);
 | 
					  absl::ParseAbseilFlagsOnly(*argc, argv, positional_args, unrecognized_flags);
 | 
				
			||||||
    // Any command-line positional arguments not part of any command-line flag
 | 
					  absl::flat_hash_set<absl::string_view> unrecognized;
 | 
				
			||||||
    // (or arguments to a flag) are copied back out to argv, with the program
 | 
					  for (const auto& flag : unrecognized_flags) {
 | 
				
			||||||
    // invocation name at position 0, and argc is resized. This includes
 | 
					    unrecognized.insert(flag.flag_name);
 | 
				
			||||||
    // positional arguments after the flag-terminating delimiter '--'.
 | 
					  }
 | 
				
			||||||
    // See https://abseil.io/docs/cpp/guides/flags.
 | 
					  absl::flat_hash_set<char*> positional;
 | 
				
			||||||
    std::copy(positional_args.begin(), positional_args.end(), argv);
 | 
					  for (const auto& arg : positional_args) {
 | 
				
			||||||
    if (static_cast<int>(positional_args.size()) < *argc) {
 | 
					    positional.insert(arg);
 | 
				
			||||||
      argv[positional_args.size()] = nullptr;
 | 
					  }
 | 
				
			||||||
      *argc = static_cast<int>(positional_args.size());
 | 
					
 | 
				
			||||||
 | 
					  int out_pos = 1;
 | 
				
			||||||
 | 
					  int in_pos = 1;
 | 
				
			||||||
 | 
					  for (; in_pos < *argc; ++in_pos) {
 | 
				
			||||||
 | 
					    char* arg = argv[in_pos];
 | 
				
			||||||
 | 
					    absl::string_view arg_str(arg);
 | 
				
			||||||
 | 
					    if (absl::ConsumePrefix(&arg_str, "--")) {
 | 
				
			||||||
 | 
					      // Flag-like argument. If the flag was unrecognized, keep it.
 | 
				
			||||||
 | 
					      // If it was a GoogleTest flag, remove it.
 | 
				
			||||||
 | 
					      if (unrecognized.contains(arg_str)) {
 | 
				
			||||||
 | 
					        argv[out_pos++] = argv[in_pos];
 | 
				
			||||||
 | 
					        continue;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (arg_str.empty()) {
 | 
				
			||||||
 | 
					      ++in_pos;
 | 
				
			||||||
 | 
					      break;  // '--' indicates that the rest of the arguments are positional
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Probably a positional argument. If it is in fact positional, keep it.
 | 
				
			||||||
 | 
					    // If it was a value for the flag argument, remove it.
 | 
				
			||||||
 | 
					    if (positional.contains(arg)) {
 | 
				
			||||||
 | 
					      argv[out_pos++] = arg;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // The rest are positional args for sure.
 | 
				
			||||||
 | 
					  while (in_pos < *argc) {
 | 
				
			||||||
 | 
					    argv[out_pos++] = argv[in_pos++];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  *argc = out_pos;
 | 
				
			||||||
 | 
					  argv[out_pos] = nullptr;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
  ParseGoogleTestFlagsOnlyImpl(argc, argv);
 | 
					  ParseGoogleTestFlagsOnlyImpl(argc, argv);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,7 +54,6 @@ PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_')
 | 
				
			|||||||
FLAG_PREFIX = '--gtest_'
 | 
					FLAG_PREFIX = '--gtest_'
 | 
				
			||||||
DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style'
 | 
					DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style'
 | 
				
			||||||
STREAM_RESULT_TO_FLAG = FLAG_PREFIX + 'stream_result_to'
 | 
					STREAM_RESULT_TO_FLAG = FLAG_PREFIX + 'stream_result_to'
 | 
				
			||||||
UNKNOWN_GTEST_PREFIXED_FLAG = FLAG_PREFIX + 'unknown_flag_for_testing'
 | 
					 | 
				
			||||||
LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests'
 | 
					LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests'
 | 
				
			||||||
INTERNAL_FLAG_FOR_TESTING = FLAG_PREFIX + 'internal_flag_for_testing'
 | 
					INTERNAL_FLAG_FOR_TESTING = FLAG_PREFIX + 'internal_flag_for_testing'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -177,16 +176,6 @@ class GTestHelpTest(gtest_test_utils.TestCase):
 | 
				
			|||||||
  def testPrintsHelpWithFullFlag(self):
 | 
					  def testPrintsHelpWithFullFlag(self):
 | 
				
			||||||
    self.TestHelpFlag('--help')
 | 
					    self.TestHelpFlag('--help')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def testPrintsHelpWithUnrecognizedGoogleTestFlag(self):
 | 
					 | 
				
			||||||
    # The behavior is slightly different when Abseil flags is
 | 
					 | 
				
			||||||
    # used. Abseil flags rejects all unknown flags, while the builtin
 | 
					 | 
				
			||||||
    # GTest flags implementation interprets an unknown flag with a
 | 
					 | 
				
			||||||
    # '--gtest_' prefix as a request for help.
 | 
					 | 
				
			||||||
    if HAS_ABSL_FLAGS:
 | 
					 | 
				
			||||||
      self.TestUnknownFlagWithAbseil(UNKNOWN_GTEST_PREFIXED_FLAG)
 | 
					 | 
				
			||||||
    else:
 | 
					 | 
				
			||||||
      self.TestHelpFlag(UNKNOWN_GTEST_PREFIXED_FLAG)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def testRunsTestsWithoutHelpFlag(self):
 | 
					  def testRunsTestsWithoutHelpFlag(self):
 | 
				
			||||||
    """Verifies correct behavior when no help flag is specified.
 | 
					    """Verifies correct behavior when no help flag is specified.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6220,6 +6220,15 @@ TEST_F(ParseFlagsTest, AbseilPositionalFlags) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST_F(ParseFlagsTest, UnrecognizedFlags) {
 | 
				
			||||||
 | 
					  const char* argv[] = {"foo.exe", "--gtest_filter=abcd", "--other_flag",
 | 
				
			||||||
 | 
					                        nullptr};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const char* argv2[] = {"foo.exe", "--other_flag", nullptr};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("abcd"), false);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef GTEST_OS_WINDOWS
 | 
					#ifdef GTEST_OS_WINDOWS
 | 
				
			||||||
// Tests parsing wide strings.
 | 
					// Tests parsing wide strings.
 | 
				
			||||||
TEST_F(ParseFlagsTest, WideStrings) {
 | 
					TEST_F(ParseFlagsTest, WideStrings) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,8 +15,8 @@ def googletest_deps():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if not native.existing_rule("com_google_absl"):
 | 
					    if not native.existing_rule("com_google_absl"):
 | 
				
			||||||
        http_archive(
 | 
					        http_archive(
 | 
				
			||||||
            name = "com_google_absl",  # 2023-02-27T15:50:25Z
 | 
					            name = "com_google_absl",  # 2023-04-06T14:42:25Z
 | 
				
			||||||
            sha256 = "baf8e734ac3ce213a889ce7c248b981ee1730e2093e32808e0f0a910dc985f76",
 | 
					            sha256 = "a50452f02402262f9a61a8eedda60f76dda6b9538d36b34b55bce9f74a4d5ef8",
 | 
				
			||||||
            strip_prefix = "abseil-cpp-0c1114c4fb83c844c7fd74708338cca1d3d9b0dc",
 | 
					            strip_prefix = "abseil-cpp-e73b9139ee9b853a4bd7812531442c138da09084",
 | 
				
			||||||
            urls = ["https://github.com/abseil/abseil-cpp/archive/0c1114c4fb83c844c7fd74708338cca1d3d9b0dc.zip"],
 | 
					            urls = ["https://github.com/abseil/abseil-cpp/archive/e73b9139ee9b853a4bd7812531442c138da09084.zip"],
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user