]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/opentelemetry-cpp/third_party/benchmark/src/commandlineflags.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / third_party / benchmark / src / commandlineflags.cc
CommitLineData
1e59de90
TL
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.
14
15#include "commandlineflags.h"
16
17#include <algorithm>
18#include <cctype>
19#include <cstdlib>
20#include <cstring>
21#include <iostream>
22#include <limits>
23
24namespace benchmark {
25namespace {
26
27// Parses 'str' for a 32-bit signed integer. If successful, writes
28// the result to *value and returns true; otherwise leaves *value
29// unchanged and returns false.
30bool ParseInt32(const std::string& src_text, const char* str, int32_t* value) {
31 // Parses the environment variable as a decimal integer.
32 char* end = nullptr;
33 const long long_value = strtol(str, &end, 10); // NOLINT
34
35 // Has strtol() consumed all characters in the string?
36 if (*end != '\0') {
37 // No - an invalid character was encountered.
38 std::cerr << src_text << " is expected to be a 32-bit integer, "
39 << "but actually has value \"" << str << "\".\n";
40 return false;
41 }
42
43 // Is the parsed value in the range of an Int32?
44 const int32_t result = static_cast<int32_t>(long_value);
45 if (long_value == std::numeric_limits<long>::max() ||
46 long_value == std::numeric_limits<long>::min() ||
47 // The parsed value overflows as a long. (strtol() returns
48 // LONG_MAX or LONG_MIN when the input overflows.)
49 result != long_value
50 // The parsed value overflows as an Int32.
51 ) {
52 std::cerr << src_text << " is expected to be a 32-bit integer, "
53 << "but actually has value \"" << str << "\", "
54 << "which overflows.\n";
55 return false;
56 }
57
58 *value = result;
59 return true;
60}
61
62// Parses 'str' for a double. If successful, writes the result to *value and
63// returns true; otherwise leaves *value unchanged and returns false.
64bool ParseDouble(const std::string& src_text, const char* str, double* value) {
65 // Parses the environment variable as a decimal integer.
66 char* end = nullptr;
67 const double double_value = strtod(str, &end); // NOLINT
68
69 // Has strtol() consumed all characters in the string?
70 if (*end != '\0') {
71 // No - an invalid character was encountered.
72 std::cerr << src_text << " is expected to be a double, "
73 << "but actually has value \"" << str << "\".\n";
74 return false;
75 }
76
77 *value = double_value;
78 return true;
79}
80
81// Returns the name of the environment variable corresponding to the
82// given flag. For example, FlagToEnvVar("foo") will return
83// "BENCHMARK_FOO" in the open-source version.
84static std::string FlagToEnvVar(const char* flag) {
85 const std::string flag_str(flag);
86
87 std::string env_var;
88 for (size_t i = 0; i != flag_str.length(); ++i)
89 env_var += static_cast<char>(::toupper(flag_str.c_str()[i]));
90
91 return env_var;
92}
93
94} // namespace
95
96bool BoolFromEnv(const char* flag, bool default_val) {
97 const std::string env_var = FlagToEnvVar(flag);
98 const char* const value_str = getenv(env_var.c_str());
99 return value_str == nullptr ? default_val : IsTruthyFlagValue(value_str);
100}
101
102int32_t Int32FromEnv(const char* flag, int32_t default_val) {
103 const std::string env_var = FlagToEnvVar(flag);
104 const char* const value_str = getenv(env_var.c_str());
105 int32_t value = default_val;
106 if (value_str == nullptr ||
107 !ParseInt32(std::string("Environment variable ") + env_var, value_str,
108 &value)) {
109 return default_val;
110 }
111 return value;
112}
113
114double DoubleFromEnv(const char* flag, double default_val) {
115 const std::string env_var = FlagToEnvVar(flag);
116 const char* const value_str = getenv(env_var.c_str());
117 double value = default_val;
118 if (value_str == nullptr ||
119 !ParseDouble(std::string("Environment variable ") + env_var, value_str,
120 &value)) {
121 return default_val;
122 }
123 return value;
124}
125
126const char* StringFromEnv(const char* flag, const char* default_val) {
127 const std::string env_var = FlagToEnvVar(flag);
128 const char* const value = getenv(env_var.c_str());
129 return value == nullptr ? default_val : value;
130}
131
132// Parses a string as a command line flag. The string should have
133// the format "--flag=value". When def_optional is true, the "=value"
134// part can be omitted.
135//
136// Returns the value of the flag, or nullptr if the parsing failed.
137const char* ParseFlagValue(const char* str, const char* flag,
138 bool def_optional) {
139 // str and flag must not be nullptr.
140 if (str == nullptr || flag == nullptr) return nullptr;
141
142 // The flag must start with "--".
143 const std::string flag_str = std::string("--") + std::string(flag);
144 const size_t flag_len = flag_str.length();
145 if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
146
147 // Skips the flag name.
148 const char* flag_end = str + flag_len;
149
150 // When def_optional is true, it's OK to not have a "=value" part.
151 if (def_optional && (flag_end[0] == '\0')) return flag_end;
152
153 // If def_optional is true and there are more characters after the
154 // flag name, or if def_optional is false, there must be a '=' after
155 // the flag name.
156 if (flag_end[0] != '=') return nullptr;
157
158 // Returns the string after "=".
159 return flag_end + 1;
160}
161
162bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
163 // Gets the value of the flag as a string.
164 const char* const value_str = ParseFlagValue(str, flag, true);
165
166 // Aborts if the parsing failed.
167 if (value_str == nullptr) return false;
168
169 // Converts the string value to a bool.
170 *value = IsTruthyFlagValue(value_str);
171 return true;
172}
173
174bool ParseInt32Flag(const char* str, const char* flag, int32_t* value) {
175 // Gets the value of the flag as a string.
176 const char* const value_str = ParseFlagValue(str, flag, false);
177
178 // Aborts if the parsing failed.
179 if (value_str == nullptr) return false;
180
181 // Sets *value to the value of the flag.
182 return ParseInt32(std::string("The value of flag --") + flag, value_str,
183 value);
184}
185
186bool ParseDoubleFlag(const char* str, const char* flag, double* value) {
187 // Gets the value of the flag as a string.
188 const char* const value_str = ParseFlagValue(str, flag, false);
189
190 // Aborts if the parsing failed.
191 if (value_str == nullptr) return false;
192
193 // Sets *value to the value of the flag.
194 return ParseDouble(std::string("The value of flag --") + flag, value_str,
195 value);
196}
197
198bool ParseStringFlag(const char* str, const char* flag, std::string* value) {
199 // Gets the value of the flag as a string.
200 const char* const value_str = ParseFlagValue(str, flag, false);
201
202 // Aborts if the parsing failed.
203 if (value_str == nullptr) return false;
204
205 *value = value_str;
206 return true;
207}
208
209bool IsFlag(const char* str, const char* flag) {
210 return (ParseFlagValue(str, flag, true) != nullptr);
211}
212
213bool IsTruthyFlagValue(const std::string& value) {
214 if (value.size() == 1) {
215 char v = value[0];
216 return isalnum(v) &&
217 !(v == '0' || v == 'f' || v == 'F' || v == 'n' || v == 'N');
218 } else if (!value.empty()) {
219 std::string value_lower(value);
220 std::transform(value_lower.begin(), value_lower.end(), value_lower.begin(),
221 [](char c) { return static_cast<char>(::tolower(c)); });
222 return !(value_lower == "false" || value_lower == "no" ||
223 value_lower == "off");
224 } else
225 return true;
226}
227
228} // end namespace benchmark