Use the Abseil flags library when Abseil is present

When built with `--define=absl=1` under Bazel, GoogleTest
flags use ABSL_FLAG instead of GoogleTest's own implementation.

There are some minor behavior differences in this mode.

The most notable difference is that unrecognized flags result
in a flag parsing error, and are not returned to the user though
a modified argc/argv, unless they appear after the positional
argument delimiter ("--").

For example, to pass a non-Abseil flag, you would have to do
./mytest --gtest_color=false -- --myflag=myvalue

The documentation at https://abseil.io/docs/cpp/guides/flags
may be helpful in understanding the behavior.

There are some other minor differences. For example,
passing --help results in the program returning 1 instead of 0.

https://github.com/google/googletest/issues/3646

PiperOrigin-RevId: 439312700
Change-Id: Id696a25f50f24a5b1785c45ca8fa59794f86fd5c
This commit is contained in:
Derek Mauro
2022-04-04 07:38:23 -07:00
committed by Copybara-Service
parent af29db7ec2
commit 25dcdc7e8b
9 changed files with 244 additions and 115 deletions

View File

@@ -42,7 +42,6 @@
#include <assert.h>
#include <stdlib.h>
#include <cstdint>
#include <iostream>
@@ -57,6 +56,11 @@
#include "gmock/internal/custom/gmock-port.h"
#include "gtest/internal/gtest-port.h"
#if GTEST_HAS_ABSL
#include "absl/flags/declare.h"
#include "absl/flags/flag.h"
#endif
// For MS Visual C++, check the compiler version. At least VS 2015 is
// required to compile Google Mock.
#if defined(_MSC_VER) && _MSC_VER < 1900
@@ -65,9 +69,50 @@
// Macro for referencing flags. This is public as we want the user to
// use this syntax to reference Google Mock flags.
#define GMOCK_FLAG_NAME_(name) gmock_##name
#define GMOCK_FLAG(name) FLAGS_gmock_##name
#if !defined(GMOCK_DECLARE_bool_)
// Pick a command line flags implementation.
#if GTEST_HAS_ABSL
// Macros for defining flags.
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
ABSL_FLAG(bool, GMOCK_FLAG_NAME_(name), default_val, doc)
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
ABSL_FLAG(int32_t, GMOCK_FLAG_NAME_(name), default_val, doc)
#define GMOCK_DEFINE_string_(name, default_val, doc) \
ABSL_FLAG(std::string, GMOCK_FLAG_NAME_(name), default_val, doc)
// Macros for declaring flags.
#define GMOCK_DECLARE_bool_(name) \
ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name))
#define GMOCK_DECLARE_int32_(name) \
ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name))
#define GMOCK_DECLARE_string_(name) \
ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name))
#define GMOCK_FLAG_GET(name) ::absl::GetFlag(GMOCK_FLAG(name))
#define GMOCK_FLAG_SET(name, value) \
(void)(::absl::SetFlag(&GMOCK_FLAG(name), value))
#else // GTEST_HAS_ABSL
// Macros for defining flags.
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
namespace testing { \
GTEST_API_ bool GMOCK_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
namespace testing { \
GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GMOCK_DEFINE_string_(name, default_val, doc) \
namespace testing { \
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")
// Macros for declaring flags.
#define GMOCK_DECLARE_bool_(name) \
@@ -86,27 +131,9 @@
} \
static_assert(true, "no-op to require trailing semicolon")
// Macros for defining flags.
#define GMOCK_DEFINE_bool_(name, default_val, doc) \
namespace testing { \
GTEST_API_ bool GMOCK_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GMOCK_DEFINE_int32_(name, default_val, doc) \
namespace testing { \
GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")
#define GMOCK_DEFINE_string_(name, default_val, doc) \
namespace testing { \
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")
#endif // !defined(GMOCK_DECLARE_bool_)
#if !defined(GMOCK_FLAG_GET)
#define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name)
#define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value)
#endif // !defined(GMOCK_FLAG_GET)
#endif // GTEST_HAS_ABSL
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_