mirror of https://github.com/google/benchmark.git
Initialize option flags from environment variables values if they are defined, eg. `BENCHMARK_OUT=<filename>` for `--benchmark_out=<filename>`. Command line flag value always prevails. Fixes https://github.com/google/benchmark/issues/881.
This commit is contained in:
parent
309de5988e
commit
bc200ed8ee
|
@ -73,14 +73,14 @@ DEFINE_int32(benchmark_repetitions, 1);
|
|||
// Report the result of each benchmark repetitions. When 'true' is specified
|
||||
// only the mean, standard deviation, and other statistics are reported for
|
||||
// repeated benchmarks. Affects all reporters.
|
||||
DEFINE_bool( benchmark_report_aggregates_only, false);
|
||||
DEFINE_bool(benchmark_report_aggregates_only, false);
|
||||
|
||||
// Display the result of each benchmark repetitions. When 'true' is specified
|
||||
// only the mean, standard deviation, and other statistics are displayed for
|
||||
// repeated benchmarks. Unlike benchmark_report_aggregates_only, only affects
|
||||
// the display reporter, but *NOT* file reporter, which will still contain
|
||||
// all the output.
|
||||
DEFINE_bool( benchmark_display_aggregates_only, false);
|
||||
DEFINE_bool(benchmark_display_aggregates_only, false);
|
||||
|
||||
// The format to use for console output.
|
||||
// Valid values are 'console', 'json', or 'csv'.
|
||||
|
@ -142,7 +142,7 @@ State::State(IterationCount max_iters, const std::vector<int64_t>& ranges,
|
|||
// which must be suppressed.
|
||||
#if defined(__INTEL_COMPILER)
|
||||
#pragma warning push
|
||||
#pragma warning(disable:1875)
|
||||
#pragma warning(disable : 1875)
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Winvalid-offsetof"
|
||||
|
@ -309,7 +309,6 @@ std::unique_ptr<BenchmarkReporter> CreateReporter(
|
|||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
} // end namespace
|
||||
|
||||
bool IsZero(double n) {
|
||||
|
@ -318,7 +317,7 @@ bool IsZero(double n) {
|
|||
|
||||
ConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color) {
|
||||
int output_opts = ConsoleReporter::OO_Defaults;
|
||||
auto is_benchmark_color = [force_no_color] () -> bool {
|
||||
auto is_benchmark_color = [force_no_color]() -> bool {
|
||||
if (force_no_color) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "commandlineflags.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
@ -92,44 +93,40 @@ static std::string FlagToEnvVar(const char* flag) {
|
|||
|
||||
} // namespace
|
||||
|
||||
// Reads and returns the Boolean environment variable corresponding to
|
||||
// the given flag; if it's not set, returns default_value.
|
||||
//
|
||||
// The value is considered true iff it's not "0".
|
||||
bool BoolFromEnv(const char* flag, bool default_value) {
|
||||
bool BoolFromEnv(const char* flag, bool default_val) {
|
||||
const std::string env_var = FlagToEnvVar(flag);
|
||||
const char* const string_value = getenv(env_var.c_str());
|
||||
return string_value == nullptr ? default_value
|
||||
: strcmp(string_value, "0") != 0;
|
||||
const char* const value_str = getenv(env_var.c_str());
|
||||
return value_str == nullptr ? default_val : IsTruthyFlagValue(value_str);
|
||||
}
|
||||
|
||||
// Reads and returns a 32-bit integer stored in the environment
|
||||
// variable corresponding to the given flag; if it isn't set or
|
||||
// doesn't represent a valid 32-bit integer, returns default_value.
|
||||
int32_t Int32FromEnv(const char* flag, int32_t default_value) {
|
||||
int32_t Int32FromEnv(const char* flag, int32_t default_val) {
|
||||
const std::string env_var = FlagToEnvVar(flag);
|
||||
const char* const string_value = getenv(env_var.c_str());
|
||||
if (string_value == nullptr) {
|
||||
// The environment variable is not set.
|
||||
return default_value;
|
||||
const char* const value_str = getenv(env_var.c_str());
|
||||
int32_t value = default_val;
|
||||
if (value_str == nullptr ||
|
||||
!ParseInt32(std::string("Environment variable ") + env_var, value_str,
|
||||
&value)) {
|
||||
return default_val;
|
||||
}
|
||||
|
||||
int32_t result = default_value;
|
||||
if (!ParseInt32(std::string("Environment variable ") + env_var, string_value,
|
||||
&result)) {
|
||||
std::cout << "The default value " << default_value << " is used.\n";
|
||||
return default_value;
|
||||
}
|
||||
|
||||
return result;
|
||||
return value;
|
||||
}
|
||||
|
||||
// Reads and returns the string environment variable corresponding to
|
||||
// the given flag; if it's not set, returns default_value.
|
||||
const char* StringFromEnv(const char* flag, const char* default_value) {
|
||||
double DoubleFromEnv(const char* flag, double default_val) {
|
||||
const std::string env_var = FlagToEnvVar(flag);
|
||||
const char* const value_str = getenv(env_var.c_str());
|
||||
double value = default_val;
|
||||
if (value_str == nullptr ||
|
||||
!ParseDouble(std::string("Environment variable ") + env_var, value_str,
|
||||
&value)) {
|
||||
return default_val;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
const char* StringFromEnv(const char* flag, const char* default_val) {
|
||||
const std::string env_var = FlagToEnvVar(flag);
|
||||
const char* const value = getenv(env_var.c_str());
|
||||
return value == nullptr ? default_value : value;
|
||||
return value == nullptr ? default_val : value;
|
||||
}
|
||||
|
||||
// Parses a string as a command line flag. The string should have
|
||||
|
@ -214,9 +211,18 @@ bool IsFlag(const char* str, const char* flag) {
|
|||
}
|
||||
|
||||
bool IsTruthyFlagValue(const std::string& value) {
|
||||
if (value.empty()) return true;
|
||||
char ch = value[0];
|
||||
return isalnum(ch) &&
|
||||
!(ch == '0' || ch == 'f' || ch == 'F' || ch == 'n' || ch == 'N');
|
||||
if (value.size() == 1) {
|
||||
char v = value[0];
|
||||
return isalnum(v) &&
|
||||
!(v == '0' || v == 'f' || v == 'F' || v == 'n' || v == 'N');
|
||||
} else if (!value.empty()) {
|
||||
std::string value_lower(value);
|
||||
std::transform(value_lower.begin(), value_lower.end(),
|
||||
value_lower.begin(), ::tolower);
|
||||
return !(value_lower == "false" || value_lower == "no" ||
|
||||
value_lower == "off");
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
|
||||
} // end namespace benchmark
|
||||
|
|
|
@ -10,22 +10,51 @@
|
|||
// Macros for declaring flags.
|
||||
#define DECLARE_bool(name) extern bool FLAG(name)
|
||||
#define DECLARE_int32(name) extern int32_t FLAG(name)
|
||||
#define DECLARE_int64(name) extern int64_t FLAG(name)
|
||||
#define DECLARE_double(name) extern double FLAG(name)
|
||||
#define DECLARE_string(name) extern std::string FLAG(name)
|
||||
|
||||
// Macros for defining flags.
|
||||
#define DEFINE_bool(name, default_val) bool FLAG(name) = (default_val)
|
||||
#define DEFINE_int32(name, default_val) int32_t FLAG(name) = (default_val)
|
||||
#define DEFINE_int64(name, default_val) int64_t FLAG(name) = (default_val)
|
||||
#define DEFINE_double(name, default_val) double FLAG(name) = (default_val)
|
||||
#define DEFINE_string(name, default_val) std::string FLAG(name) = (default_val)
|
||||
#define DEFINE_bool(name, default_val) \
|
||||
bool FLAG(name) = \
|
||||
benchmark::BoolFromEnv(#name, default_val)
|
||||
#define DEFINE_int32(name, default_val) \
|
||||
int32_t FLAG(name) = \
|
||||
benchmark::Int32FromEnv(#name, default_val)
|
||||
#define DEFINE_double(name, default_val) \
|
||||
double FLAG(name) = \
|
||||
benchmark::DoubleFromEnv(#name, default_val)
|
||||
#define DEFINE_string(name, default_val) \
|
||||
std::string FLAG(name) = \
|
||||
benchmark::StringFromEnv(#name, default_val)
|
||||
|
||||
namespace benchmark {
|
||||
// Parses a bool/Int32/string from the environment variable
|
||||
// corresponding to the given Google Test flag.
|
||||
|
||||
// Parses a bool from the environment variable
|
||||
// corresponding to the given flag.
|
||||
//
|
||||
// If the variable exists, returns IsTruthyFlagValue() value; if not,
|
||||
// returns the given default value.
|
||||
bool BoolFromEnv(const char* flag, bool default_val);
|
||||
|
||||
// Parses an Int32 from the environment variable
|
||||
// corresponding to the given flag.
|
||||
//
|
||||
// If the variable exists, returns ParseInt32() value; if not, returns
|
||||
// the given default value.
|
||||
int32_t Int32FromEnv(const char* flag, int32_t default_val);
|
||||
|
||||
// Parses an Double from the environment variable
|
||||
// corresponding to the given flag.
|
||||
//
|
||||
// If the variable exists, returns ParseDouble(); if not, returns
|
||||
// the given default value.
|
||||
double DoubleFromEnv(const char* flag, double default_val);
|
||||
|
||||
// Parses a string from the environment variable
|
||||
// corresponding to the given flag.
|
||||
//
|
||||
// If variable exists, returns its value; if not, returns
|
||||
// the given default value.
|
||||
const char* StringFromEnv(const char* flag, const char* default_val);
|
||||
|
||||
// Parses a string for a bool flag, in the form of either
|
||||
|
@ -64,9 +93,11 @@ bool ParseStringFlag(const char* str, const char* flag, std::string* value);
|
|||
bool IsFlag(const char* str, const char* flag);
|
||||
|
||||
// Returns true unless value starts with one of: '0', 'f', 'F', 'n' or 'N', or
|
||||
// some non-alphanumeric character. As a special case, also returns true if
|
||||
// value is the empty string.
|
||||
// some non-alphanumeric character. Also returns false if the value matches
|
||||
// one of 'no', 'false', 'off' (case-insensitive). As a special case, also
|
||||
// returns true if value is the empty string.
|
||||
bool IsTruthyFlagValue(const std::string& value);
|
||||
|
||||
} // end namespace benchmark
|
||||
|
||||
#endif // BENCHMARK_COMMANDLINEFLAGS_H_
|
||||
|
|
|
@ -34,6 +34,58 @@ TEST(BoolFromEnv, False) {
|
|||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "0", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", true), false);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "N", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", true), false);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "n", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", true), false);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "NO", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", true), false);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "No", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", true), false);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "no", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", true), false);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "F", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", true), false);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "f", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", true), false);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "FALSE", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", true), false);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "False", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", true), false);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "false", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", true), false);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "OFF", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", true), false);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "Off", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", true), false);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "off", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", true), false);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
}
|
||||
|
||||
TEST(BoolFromEnv, True) {
|
||||
|
@ -41,9 +93,63 @@ TEST(BoolFromEnv, True) {
|
|||
EXPECT_EQ(BoolFromEnv("in_env", false), true);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "foo", 1), 0);
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "Y", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", false), true);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "y", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", false), true);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "YES", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", false), true);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "Yes", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", false), true);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "yes", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", false), true);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "T", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", false), true);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "t", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", false), true);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "TRUE", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", false), true);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "True", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", false), true);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "true", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", false), true);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "ON", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", false), true);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "On", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", false), true);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "on", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", false), true);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
|
||||
#ifndef BENCHMARK_OS_WINDOWS
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "", 1), 0);
|
||||
EXPECT_EQ(BoolFromEnv("in_env", false), true);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Int32FromEnv, NotInEnv) {
|
||||
|
@ -54,7 +160,7 @@ TEST(Int32FromEnv, NotInEnv) {
|
|||
TEST(Int32FromEnv, InvalidInteger) {
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "foo", 1), 0);
|
||||
EXPECT_EQ(Int32FromEnv("in_env", 42), 42);
|
||||
ASSERT_EQ(unsetenv("BENCHMARK_IN_ENV"), 0);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
}
|
||||
|
||||
TEST(Int32FromEnv, ValidInteger) {
|
||||
|
@ -63,6 +169,23 @@ TEST(Int32FromEnv, ValidInteger) {
|
|||
unsetenv("BENCHMARK_IN_ENV");
|
||||
}
|
||||
|
||||
TEST(DoubleFromEnv, NotInEnv) {
|
||||
ASSERT_EQ(unsetenv("BENCHMARK_NOT_IN_ENV"), 0);
|
||||
EXPECT_EQ(DoubleFromEnv("not_in_env", 0.51), 0.51);
|
||||
}
|
||||
|
||||
TEST(DoubleFromEnv, InvalidReal) {
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "foo", 1), 0);
|
||||
EXPECT_EQ(DoubleFromEnv("in_env", 0.51), 0.51);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
}
|
||||
|
||||
TEST(DoubleFromEnv, ValidReal) {
|
||||
ASSERT_EQ(setenv("BENCHMARK_IN_ENV", "0.51", 1), 0);
|
||||
EXPECT_EQ(DoubleFromEnv("in_env", 0.71), 0.51);
|
||||
unsetenv("BENCHMARK_IN_ENV");
|
||||
}
|
||||
|
||||
TEST(StringFromEnv, Default) {
|
||||
ASSERT_EQ(unsetenv("BENCHMARK_NOT_IN_ENV"), 0);
|
||||
EXPECT_STREQ(StringFromEnv("not_in_env", "foo"), "foo");
|
||||
|
|
Loading…
Reference in New Issue