[ARM] Fix for MVE VPT block pass
[llvm-complete.git] / utils / benchmark / src / commandlineflags.cc
blob2fc92517a32c710626b84da0d9775c00d2996338
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
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
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
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"
17 #include <cctype>
18 #include <cstdlib>
19 #include <cstring>
20 #include <iostream>
21 #include <limits>
23 namespace benchmark {
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.
29 char* end = nullptr;
30 const long long_value = strtol(str, &end, 10); // NOLINT
32 // Has strtol() consumed all characters in the string?
33 if (*end != '\0') {
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";
37 return false;
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.)
46 result != long_value
47 // The parsed value overflows as an Int32.
48 ) {
49 std::cerr << src_text << " is expected to be a 32-bit integer, "
50 << "but actually has value \"" << str << "\", "
51 << "which overflows.\n";
52 return false;
55 *value = result;
56 return true;
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.
63 char* end = nullptr;
64 const double double_value = strtod(str, &end); // NOLINT
66 // Has strtol() consumed all characters in the string?
67 if (*end != '\0') {
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";
71 return false;
74 *value = double_value;
75 return true;
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);
84 std::string env_var;
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,
115 &result)) {
116 std::cout << "The default value " << default_value << " is used.\n";
117 return default_value;
120 return result;
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,
137 bool def_optional) {
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
154 // the flag name.
155 if (flag_end[0] != '=') return nullptr;
157 // Returns the string after "=".
158 return flag_end + 1;
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);
170 return true;
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,
182 value);
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,
194 value);
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;
204 *value = value_str;
205 return true;
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;
214 char ch = value[0];
215 return isalnum(ch) &&
216 !(ch == '0' || ch == 'f' || ch == 'F' || ch == 'n' || ch == 'N');
218 } // end namespace benchmark