1 // Copyright 2015 Google Inc. All rights reserved.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 #include "commandlineflags.h"
24 // Parses 'str' for a 32-bit signed integer. If successful, writes
25 // the result to *value and returns true; otherwise leaves *value
26 // unchanged and returns false.
27 bool ParseInt32(const std::string
& src_text
, const char* str
, int32_t* value
) {
28 // Parses the environment variable as a decimal integer.
30 const long long_value
= strtol(str
, &end
, 10); // NOLINT
32 // Has strtol() consumed all characters in the string?
34 // No - an invalid character was encountered.
35 std::cerr
<< src_text
<< " is expected to be a 32-bit integer, "
36 << "but actually has value \"" << str
<< "\".\n";
40 // Is the parsed value in the range of an Int32?
41 const int32_t result
= static_cast<int32_t>(long_value
);
42 if (long_value
== std::numeric_limits
<long>::max() ||
43 long_value
== std::numeric_limits
<long>::min() ||
44 // The parsed value overflows as a long. (strtol() returns
45 // LONG_MAX or LONG_MIN when the input overflows.)
47 // The parsed value overflows as an Int32.
49 std::cerr
<< src_text
<< " is expected to be a 32-bit integer, "
50 << "but actually has value \"" << str
<< "\", "
51 << "which overflows.\n";
59 // Parses 'str' for a double. If successful, writes the result to *value and
60 // returns true; otherwise leaves *value unchanged and returns false.
61 bool ParseDouble(const std::string
& src_text
, const char* str
, double* value
) {
62 // Parses the environment variable as a decimal integer.
64 const double double_value
= strtod(str
, &end
); // NOLINT
66 // Has strtol() consumed all characters in the string?
68 // No - an invalid character was encountered.
69 std::cerr
<< src_text
<< " is expected to be a double, "
70 << "but actually has value \"" << str
<< "\".\n";
74 *value
= double_value
;
78 // Returns the name of the environment variable corresponding to the
79 // given flag. For example, FlagToEnvVar("foo") will return
80 // "BENCHMARK_FOO" in the open-source version.
81 static std::string
FlagToEnvVar(const char* flag
) {
82 const std::string
flag_str(flag
);
85 for (size_t i
= 0; i
!= flag_str
.length(); ++i
)
86 env_var
+= static_cast<char>(::toupper(flag_str
.c_str()[i
]));
88 return "BENCHMARK_" + env_var
;
91 // Reads and returns the Boolean environment variable corresponding to
92 // the given flag; if it's not set, returns default_value.
94 // The value is considered true iff it's not "0".
95 bool BoolFromEnv(const char* flag
, bool default_value
) {
96 const std::string env_var
= FlagToEnvVar(flag
);
97 const char* const string_value
= getenv(env_var
.c_str());
98 return string_value
== nullptr ? default_value
99 : strcmp(string_value
, "0") != 0;
102 // Reads and returns a 32-bit integer stored in the environment
103 // variable corresponding to the given flag; if it isn't set or
104 // doesn't represent a valid 32-bit integer, returns default_value.
105 int32_t Int32FromEnv(const char* flag
, int32_t default_value
) {
106 const std::string env_var
= FlagToEnvVar(flag
);
107 const char* const string_value
= getenv(env_var
.c_str());
108 if (string_value
== nullptr) {
109 // The environment variable is not set.
110 return default_value
;
113 int32_t result
= default_value
;
114 if (!ParseInt32(std::string("Environment variable ") + env_var
, string_value
,
116 std::cout
<< "The default value " << default_value
<< " is used.\n";
117 return default_value
;
123 // Reads and returns the string environment variable corresponding to
124 // the given flag; if it's not set, returns default_value.
125 const char* StringFromEnv(const char* flag
, const char* default_value
) {
126 const std::string env_var
= FlagToEnvVar(flag
);
127 const char* const value
= getenv(env_var
.c_str());
128 return value
== nullptr ? default_value
: value
;
131 // Parses a string as a command line flag. The string should have
132 // the format "--flag=value". When def_optional is true, the "=value"
133 // part can be omitted.
135 // Returns the value of the flag, or nullptr if the parsing failed.
136 const char* ParseFlagValue(const char* str
, const char* flag
,
138 // str and flag must not be nullptr.
139 if (str
== nullptr || flag
== nullptr) return nullptr;
141 // The flag must start with "--".
142 const std::string flag_str
= std::string("--") + std::string(flag
);
143 const size_t flag_len
= flag_str
.length();
144 if (strncmp(str
, flag_str
.c_str(), flag_len
) != 0) return nullptr;
146 // Skips the flag name.
147 const char* flag_end
= str
+ flag_len
;
149 // When def_optional is true, it's OK to not have a "=value" part.
150 if (def_optional
&& (flag_end
[0] == '\0')) return flag_end
;
152 // If def_optional is true and there are more characters after the
153 // flag name, or if def_optional is false, there must be a '=' after
155 if (flag_end
[0] != '=') return nullptr;
157 // Returns the string after "=".
161 bool ParseBoolFlag(const char* str
, const char* flag
, bool* value
) {
162 // Gets the value of the flag as a string.
163 const char* const value_str
= ParseFlagValue(str
, flag
, true);
165 // Aborts if the parsing failed.
166 if (value_str
== nullptr) return false;
168 // Converts the string value to a bool.
169 *value
= IsTruthyFlagValue(value_str
);
173 bool ParseInt32Flag(const char* str
, const char* flag
, int32_t* value
) {
174 // Gets the value of the flag as a string.
175 const char* const value_str
= ParseFlagValue(str
, flag
, false);
177 // Aborts if the parsing failed.
178 if (value_str
== nullptr) return false;
180 // Sets *value to the value of the flag.
181 return ParseInt32(std::string("The value of flag --") + flag
, value_str
,
185 bool ParseDoubleFlag(const char* str
, const char* flag
, double* value
) {
186 // Gets the value of the flag as a string.
187 const char* const value_str
= ParseFlagValue(str
, flag
, false);
189 // Aborts if the parsing failed.
190 if (value_str
== nullptr) return false;
192 // Sets *value to the value of the flag.
193 return ParseDouble(std::string("The value of flag --") + flag
, value_str
,
197 bool ParseStringFlag(const char* str
, const char* flag
, std::string
* value
) {
198 // Gets the value of the flag as a string.
199 const char* const value_str
= ParseFlagValue(str
, flag
, false);
201 // Aborts if the parsing failed.
202 if (value_str
== nullptr) return false;
208 bool IsFlag(const char* str
, const char* flag
) {
209 return (ParseFlagValue(str
, flag
, true) != nullptr);
212 bool IsTruthyFlagValue(const std::string
& value
) {
213 if (value
.empty()) return true;
215 return isalnum(ch
) &&
216 !(ch
== '0' || ch
== 'f' || ch
== 'F' || ch
== 'n' || ch
== 'N');
218 } // end namespace benchmark