xref: /aosp_15_r20/external/abseil-cpp/absl/flags/marshalling.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
1*9356374aSAndroid Build Coastguard Worker //
2*9356374aSAndroid Build Coastguard Worker //  Copyright 2019 The Abseil Authors.
3*9356374aSAndroid Build Coastguard Worker //
4*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
5*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
6*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
7*9356374aSAndroid Build Coastguard Worker //
8*9356374aSAndroid Build Coastguard Worker //      https://www.apache.org/licenses/LICENSE-2.0
9*9356374aSAndroid Build Coastguard Worker //
10*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
11*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
12*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
14*9356374aSAndroid Build Coastguard Worker // limitations under the License.
15*9356374aSAndroid Build Coastguard Worker 
16*9356374aSAndroid Build Coastguard Worker #include "absl/flags/marshalling.h"
17*9356374aSAndroid Build Coastguard Worker 
18*9356374aSAndroid Build Coastguard Worker #include <stddef.h>
19*9356374aSAndroid Build Coastguard Worker 
20*9356374aSAndroid Build Coastguard Worker #include <cmath>
21*9356374aSAndroid Build Coastguard Worker #include <limits>
22*9356374aSAndroid Build Coastguard Worker #include <sstream>
23*9356374aSAndroid Build Coastguard Worker #include <string>
24*9356374aSAndroid Build Coastguard Worker #include <type_traits>
25*9356374aSAndroid Build Coastguard Worker #include <vector>
26*9356374aSAndroid Build Coastguard Worker 
27*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h"
28*9356374aSAndroid Build Coastguard Worker #include "absl/base/log_severity.h"
29*9356374aSAndroid Build Coastguard Worker #include "absl/base/macros.h"
30*9356374aSAndroid Build Coastguard Worker #include "absl/numeric/int128.h"
31*9356374aSAndroid Build Coastguard Worker #include "absl/strings/ascii.h"
32*9356374aSAndroid Build Coastguard Worker #include "absl/strings/match.h"
33*9356374aSAndroid Build Coastguard Worker #include "absl/strings/numbers.h"
34*9356374aSAndroid Build Coastguard Worker #include "absl/strings/str_cat.h"
35*9356374aSAndroid Build Coastguard Worker #include "absl/strings/str_format.h"
36*9356374aSAndroid Build Coastguard Worker #include "absl/strings/str_join.h"
37*9356374aSAndroid Build Coastguard Worker #include "absl/strings/str_split.h"
38*9356374aSAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
39*9356374aSAndroid Build Coastguard Worker 
40*9356374aSAndroid Build Coastguard Worker namespace absl {
41*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN
42*9356374aSAndroid Build Coastguard Worker namespace flags_internal {
43*9356374aSAndroid Build Coastguard Worker 
44*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
45*9356374aSAndroid Build Coastguard Worker // AbslParseFlag specializations for boolean type.
46*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,bool * dst,std::string *)47*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, bool* dst, std::string*) {
48*9356374aSAndroid Build Coastguard Worker   const char* kTrue[] = {"1", "t", "true", "y", "yes"};
49*9356374aSAndroid Build Coastguard Worker   const char* kFalse[] = {"0", "f", "false", "n", "no"};
50*9356374aSAndroid Build Coastguard Worker   static_assert(sizeof(kTrue) == sizeof(kFalse), "true_false_equal");
51*9356374aSAndroid Build Coastguard Worker 
52*9356374aSAndroid Build Coastguard Worker   text = absl::StripAsciiWhitespace(text);
53*9356374aSAndroid Build Coastguard Worker 
54*9356374aSAndroid Build Coastguard Worker   for (size_t i = 0; i < ABSL_ARRAYSIZE(kTrue); ++i) {
55*9356374aSAndroid Build Coastguard Worker     if (absl::EqualsIgnoreCase(text, kTrue[i])) {
56*9356374aSAndroid Build Coastguard Worker       *dst = true;
57*9356374aSAndroid Build Coastguard Worker       return true;
58*9356374aSAndroid Build Coastguard Worker     } else if (absl::EqualsIgnoreCase(text, kFalse[i])) {
59*9356374aSAndroid Build Coastguard Worker       *dst = false;
60*9356374aSAndroid Build Coastguard Worker       return true;
61*9356374aSAndroid Build Coastguard Worker     }
62*9356374aSAndroid Build Coastguard Worker   }
63*9356374aSAndroid Build Coastguard Worker   return false;  // didn't match a legal input
64*9356374aSAndroid Build Coastguard Worker }
65*9356374aSAndroid Build Coastguard Worker 
66*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
67*9356374aSAndroid Build Coastguard Worker // AbslParseFlag for integral types.
68*9356374aSAndroid Build Coastguard Worker 
69*9356374aSAndroid Build Coastguard Worker // Return the base to use for parsing text as an integer.  Leading 0x
70*9356374aSAndroid Build Coastguard Worker // puts us in base 16.  But leading 0 does not put us in base 8. It
71*9356374aSAndroid Build Coastguard Worker // caused too many bugs when we had that behavior.
NumericBase(absl::string_view text)72*9356374aSAndroid Build Coastguard Worker static int NumericBase(absl::string_view text) {
73*9356374aSAndroid Build Coastguard Worker   if (text.empty()) return 0;
74*9356374aSAndroid Build Coastguard Worker   size_t num_start = (text[0] == '-' || text[0] == '+') ? 1 : 0;
75*9356374aSAndroid Build Coastguard Worker   const bool hex = (text.size() >= num_start + 2 && text[num_start] == '0' &&
76*9356374aSAndroid Build Coastguard Worker                     (text[num_start + 1] == 'x' || text[num_start + 1] == 'X'));
77*9356374aSAndroid Build Coastguard Worker   return hex ? 16 : 10;
78*9356374aSAndroid Build Coastguard Worker }
79*9356374aSAndroid Build Coastguard Worker 
80*9356374aSAndroid Build Coastguard Worker template <typename IntType>
ParseFlagImpl(absl::string_view text,IntType & dst)81*9356374aSAndroid Build Coastguard Worker inline bool ParseFlagImpl(absl::string_view text, IntType& dst) {
82*9356374aSAndroid Build Coastguard Worker   text = absl::StripAsciiWhitespace(text);
83*9356374aSAndroid Build Coastguard Worker 
84*9356374aSAndroid Build Coastguard Worker   return absl::numbers_internal::safe_strtoi_base(text, &dst,
85*9356374aSAndroid Build Coastguard Worker                                                   NumericBase(text));
86*9356374aSAndroid Build Coastguard Worker }
87*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,short * dst,std::string *)88*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, short* dst, std::string*) {
89*9356374aSAndroid Build Coastguard Worker   int val;
90*9356374aSAndroid Build Coastguard Worker   if (!ParseFlagImpl(text, val)) return false;
91*9356374aSAndroid Build Coastguard Worker   if (static_cast<short>(val) != val)  // worked, but number out of range
92*9356374aSAndroid Build Coastguard Worker     return false;
93*9356374aSAndroid Build Coastguard Worker   *dst = static_cast<short>(val);
94*9356374aSAndroid Build Coastguard Worker   return true;
95*9356374aSAndroid Build Coastguard Worker }
96*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,unsigned short * dst,std::string *)97*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, unsigned short* dst, std::string*) {
98*9356374aSAndroid Build Coastguard Worker   unsigned int val;
99*9356374aSAndroid Build Coastguard Worker   if (!ParseFlagImpl(text, val)) return false;
100*9356374aSAndroid Build Coastguard Worker   if (static_cast<unsigned short>(val) !=
101*9356374aSAndroid Build Coastguard Worker       val)  // worked, but number out of range
102*9356374aSAndroid Build Coastguard Worker     return false;
103*9356374aSAndroid Build Coastguard Worker   *dst = static_cast<unsigned short>(val);
104*9356374aSAndroid Build Coastguard Worker   return true;
105*9356374aSAndroid Build Coastguard Worker }
106*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,int * dst,std::string *)107*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, int* dst, std::string*) {
108*9356374aSAndroid Build Coastguard Worker   return ParseFlagImpl(text, *dst);
109*9356374aSAndroid Build Coastguard Worker }
110*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,unsigned int * dst,std::string *)111*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, unsigned int* dst, std::string*) {
112*9356374aSAndroid Build Coastguard Worker   return ParseFlagImpl(text, *dst);
113*9356374aSAndroid Build Coastguard Worker }
114*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,long * dst,std::string *)115*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, long* dst, std::string*) {
116*9356374aSAndroid Build Coastguard Worker   return ParseFlagImpl(text, *dst);
117*9356374aSAndroid Build Coastguard Worker }
118*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,unsigned long * dst,std::string *)119*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, unsigned long* dst, std::string*) {
120*9356374aSAndroid Build Coastguard Worker   return ParseFlagImpl(text, *dst);
121*9356374aSAndroid Build Coastguard Worker }
122*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,long long * dst,std::string *)123*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, long long* dst, std::string*) {
124*9356374aSAndroid Build Coastguard Worker   return ParseFlagImpl(text, *dst);
125*9356374aSAndroid Build Coastguard Worker }
126*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,unsigned long long * dst,std::string *)127*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, unsigned long long* dst,
128*9356374aSAndroid Build Coastguard Worker                    std::string*) {
129*9356374aSAndroid Build Coastguard Worker   return ParseFlagImpl(text, *dst);
130*9356374aSAndroid Build Coastguard Worker }
131*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,absl::int128 * dst,std::string *)132*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, absl::int128* dst, std::string*) {
133*9356374aSAndroid Build Coastguard Worker   text = absl::StripAsciiWhitespace(text);
134*9356374aSAndroid Build Coastguard Worker 
135*9356374aSAndroid Build Coastguard Worker   // check hex
136*9356374aSAndroid Build Coastguard Worker   int base = NumericBase(text);
137*9356374aSAndroid Build Coastguard Worker   if (!absl::numbers_internal::safe_strto128_base(text, dst, base)) {
138*9356374aSAndroid Build Coastguard Worker     return false;
139*9356374aSAndroid Build Coastguard Worker   }
140*9356374aSAndroid Build Coastguard Worker 
141*9356374aSAndroid Build Coastguard Worker   return base == 16 ? absl::SimpleHexAtoi(text, dst)
142*9356374aSAndroid Build Coastguard Worker                     : absl::SimpleAtoi(text, dst);
143*9356374aSAndroid Build Coastguard Worker }
144*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,absl::uint128 * dst,std::string *)145*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, absl::uint128* dst, std::string*) {
146*9356374aSAndroid Build Coastguard Worker   text = absl::StripAsciiWhitespace(text);
147*9356374aSAndroid Build Coastguard Worker 
148*9356374aSAndroid Build Coastguard Worker   // check hex
149*9356374aSAndroid Build Coastguard Worker   int base = NumericBase(text);
150*9356374aSAndroid Build Coastguard Worker   if (!absl::numbers_internal::safe_strtou128_base(text, dst, base)) {
151*9356374aSAndroid Build Coastguard Worker     return false;
152*9356374aSAndroid Build Coastguard Worker   }
153*9356374aSAndroid Build Coastguard Worker 
154*9356374aSAndroid Build Coastguard Worker   return base == 16 ? absl::SimpleHexAtoi(text, dst)
155*9356374aSAndroid Build Coastguard Worker                     : absl::SimpleAtoi(text, dst);
156*9356374aSAndroid Build Coastguard Worker }
157*9356374aSAndroid Build Coastguard Worker 
158*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
159*9356374aSAndroid Build Coastguard Worker // AbslParseFlag for floating point types.
160*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,float * dst,std::string *)161*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, float* dst, std::string*) {
162*9356374aSAndroid Build Coastguard Worker   return absl::SimpleAtof(text, dst);
163*9356374aSAndroid Build Coastguard Worker }
164*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,double * dst,std::string *)165*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, double* dst, std::string*) {
166*9356374aSAndroid Build Coastguard Worker   return absl::SimpleAtod(text, dst);
167*9356374aSAndroid Build Coastguard Worker }
168*9356374aSAndroid Build Coastguard Worker 
169*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
170*9356374aSAndroid Build Coastguard Worker // AbslParseFlag for strings.
171*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,std::string * dst,std::string *)172*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, std::string* dst, std::string*) {
173*9356374aSAndroid Build Coastguard Worker   dst->assign(text.data(), text.size());
174*9356374aSAndroid Build Coastguard Worker   return true;
175*9356374aSAndroid Build Coastguard Worker }
176*9356374aSAndroid Build Coastguard Worker 
177*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
178*9356374aSAndroid Build Coastguard Worker // AbslParseFlag for vector of strings.
179*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,std::vector<std::string> * dst,std::string *)180*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, std::vector<std::string>* dst,
181*9356374aSAndroid Build Coastguard Worker                    std::string*) {
182*9356374aSAndroid Build Coastguard Worker   // An empty flag value corresponds to an empty vector, not a vector
183*9356374aSAndroid Build Coastguard Worker   // with a single, empty std::string.
184*9356374aSAndroid Build Coastguard Worker   if (text.empty()) {
185*9356374aSAndroid Build Coastguard Worker     dst->clear();
186*9356374aSAndroid Build Coastguard Worker     return true;
187*9356374aSAndroid Build Coastguard Worker   }
188*9356374aSAndroid Build Coastguard Worker   *dst = absl::StrSplit(text, ',', absl::AllowEmpty());
189*9356374aSAndroid Build Coastguard Worker   return true;
190*9356374aSAndroid Build Coastguard Worker }
191*9356374aSAndroid Build Coastguard Worker 
192*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------------------
193*9356374aSAndroid Build Coastguard Worker // AbslUnparseFlag specializations for various builtin flag types.
194*9356374aSAndroid Build Coastguard Worker 
Unparse(bool v)195*9356374aSAndroid Build Coastguard Worker std::string Unparse(bool v) { return v ? "true" : "false"; }
Unparse(short v)196*9356374aSAndroid Build Coastguard Worker std::string Unparse(short v) { return absl::StrCat(v); }
Unparse(unsigned short v)197*9356374aSAndroid Build Coastguard Worker std::string Unparse(unsigned short v) { return absl::StrCat(v); }
Unparse(int v)198*9356374aSAndroid Build Coastguard Worker std::string Unparse(int v) { return absl::StrCat(v); }
Unparse(unsigned int v)199*9356374aSAndroid Build Coastguard Worker std::string Unparse(unsigned int v) { return absl::StrCat(v); }
Unparse(long v)200*9356374aSAndroid Build Coastguard Worker std::string Unparse(long v) { return absl::StrCat(v); }
Unparse(unsigned long v)201*9356374aSAndroid Build Coastguard Worker std::string Unparse(unsigned long v) { return absl::StrCat(v); }
Unparse(long long v)202*9356374aSAndroid Build Coastguard Worker std::string Unparse(long long v) { return absl::StrCat(v); }
Unparse(unsigned long long v)203*9356374aSAndroid Build Coastguard Worker std::string Unparse(unsigned long long v) { return absl::StrCat(v); }
Unparse(absl::int128 v)204*9356374aSAndroid Build Coastguard Worker std::string Unparse(absl::int128 v) {
205*9356374aSAndroid Build Coastguard Worker   std::stringstream ss;
206*9356374aSAndroid Build Coastguard Worker   ss << v;
207*9356374aSAndroid Build Coastguard Worker   return ss.str();
208*9356374aSAndroid Build Coastguard Worker }
Unparse(absl::uint128 v)209*9356374aSAndroid Build Coastguard Worker std::string Unparse(absl::uint128 v) {
210*9356374aSAndroid Build Coastguard Worker   std::stringstream ss;
211*9356374aSAndroid Build Coastguard Worker   ss << v;
212*9356374aSAndroid Build Coastguard Worker   return ss.str();
213*9356374aSAndroid Build Coastguard Worker }
214*9356374aSAndroid Build Coastguard Worker 
215*9356374aSAndroid Build Coastguard Worker template <typename T>
UnparseFloatingPointVal(T v)216*9356374aSAndroid Build Coastguard Worker std::string UnparseFloatingPointVal(T v) {
217*9356374aSAndroid Build Coastguard Worker   // digits10 is guaranteed to roundtrip correctly in string -> value -> string
218*9356374aSAndroid Build Coastguard Worker   // conversions, but may not be enough to represent all the values correctly.
219*9356374aSAndroid Build Coastguard Worker   std::string digit10_str =
220*9356374aSAndroid Build Coastguard Worker       absl::StrFormat("%.*g", std::numeric_limits<T>::digits10, v);
221*9356374aSAndroid Build Coastguard Worker   if (std::isnan(v) || std::isinf(v)) return digit10_str;
222*9356374aSAndroid Build Coastguard Worker 
223*9356374aSAndroid Build Coastguard Worker   T roundtrip_val = 0;
224*9356374aSAndroid Build Coastguard Worker   std::string err;
225*9356374aSAndroid Build Coastguard Worker   if (absl::ParseFlag(digit10_str, &roundtrip_val, &err) &&
226*9356374aSAndroid Build Coastguard Worker       roundtrip_val == v) {
227*9356374aSAndroid Build Coastguard Worker     return digit10_str;
228*9356374aSAndroid Build Coastguard Worker   }
229*9356374aSAndroid Build Coastguard Worker 
230*9356374aSAndroid Build Coastguard Worker   // max_digits10 is the number of base-10 digits that are necessary to uniquely
231*9356374aSAndroid Build Coastguard Worker   // represent all distinct values.
232*9356374aSAndroid Build Coastguard Worker   return absl::StrFormat("%.*g", std::numeric_limits<T>::max_digits10, v);
233*9356374aSAndroid Build Coastguard Worker }
Unparse(float v)234*9356374aSAndroid Build Coastguard Worker std::string Unparse(float v) { return UnparseFloatingPointVal(v); }
Unparse(double v)235*9356374aSAndroid Build Coastguard Worker std::string Unparse(double v) { return UnparseFloatingPointVal(v); }
AbslUnparseFlag(absl::string_view v)236*9356374aSAndroid Build Coastguard Worker std::string AbslUnparseFlag(absl::string_view v) { return std::string(v); }
AbslUnparseFlag(const std::vector<std::string> & v)237*9356374aSAndroid Build Coastguard Worker std::string AbslUnparseFlag(const std::vector<std::string>& v) {
238*9356374aSAndroid Build Coastguard Worker   return absl::StrJoin(v, ",");
239*9356374aSAndroid Build Coastguard Worker }
240*9356374aSAndroid Build Coastguard Worker 
241*9356374aSAndroid Build Coastguard Worker }  // namespace flags_internal
242*9356374aSAndroid Build Coastguard Worker 
AbslParseFlag(absl::string_view text,absl::LogSeverity * dst,std::string * err)243*9356374aSAndroid Build Coastguard Worker bool AbslParseFlag(absl::string_view text, absl::LogSeverity* dst,
244*9356374aSAndroid Build Coastguard Worker                    std::string* err) {
245*9356374aSAndroid Build Coastguard Worker   text = absl::StripAsciiWhitespace(text);
246*9356374aSAndroid Build Coastguard Worker   if (text.empty()) {
247*9356374aSAndroid Build Coastguard Worker     *err = "no value provided";
248*9356374aSAndroid Build Coastguard Worker     return false;
249*9356374aSAndroid Build Coastguard Worker   }
250*9356374aSAndroid Build Coastguard Worker   if (absl::EqualsIgnoreCase(text, "dfatal")) {
251*9356374aSAndroid Build Coastguard Worker     *dst = absl::kLogDebugFatal;
252*9356374aSAndroid Build Coastguard Worker     return true;
253*9356374aSAndroid Build Coastguard Worker   }
254*9356374aSAndroid Build Coastguard Worker   if (absl::EqualsIgnoreCase(text, "klogdebugfatal")) {
255*9356374aSAndroid Build Coastguard Worker     *dst = absl::kLogDebugFatal;
256*9356374aSAndroid Build Coastguard Worker     return true;
257*9356374aSAndroid Build Coastguard Worker   }
258*9356374aSAndroid Build Coastguard Worker   if (text.front() == 'k' || text.front() == 'K') text.remove_prefix(1);
259*9356374aSAndroid Build Coastguard Worker   if (absl::EqualsIgnoreCase(text, "info")) {
260*9356374aSAndroid Build Coastguard Worker     *dst = absl::LogSeverity::kInfo;
261*9356374aSAndroid Build Coastguard Worker     return true;
262*9356374aSAndroid Build Coastguard Worker   }
263*9356374aSAndroid Build Coastguard Worker   if (absl::EqualsIgnoreCase(text, "warning")) {
264*9356374aSAndroid Build Coastguard Worker     *dst = absl::LogSeverity::kWarning;
265*9356374aSAndroid Build Coastguard Worker     return true;
266*9356374aSAndroid Build Coastguard Worker   }
267*9356374aSAndroid Build Coastguard Worker   if (absl::EqualsIgnoreCase(text, "error")) {
268*9356374aSAndroid Build Coastguard Worker     *dst = absl::LogSeverity::kError;
269*9356374aSAndroid Build Coastguard Worker     return true;
270*9356374aSAndroid Build Coastguard Worker   }
271*9356374aSAndroid Build Coastguard Worker   if (absl::EqualsIgnoreCase(text, "fatal")) {
272*9356374aSAndroid Build Coastguard Worker     *dst = absl::LogSeverity::kFatal;
273*9356374aSAndroid Build Coastguard Worker     return true;
274*9356374aSAndroid Build Coastguard Worker   }
275*9356374aSAndroid Build Coastguard Worker   std::underlying_type<absl::LogSeverity>::type numeric_value;
276*9356374aSAndroid Build Coastguard Worker   if (absl::ParseFlag(text, &numeric_value, err)) {
277*9356374aSAndroid Build Coastguard Worker     *dst = static_cast<absl::LogSeverity>(numeric_value);
278*9356374aSAndroid Build Coastguard Worker     return true;
279*9356374aSAndroid Build Coastguard Worker   }
280*9356374aSAndroid Build Coastguard Worker   *err =
281*9356374aSAndroid Build Coastguard Worker       "only integers, absl::LogSeverity enumerators, and DFATAL are accepted";
282*9356374aSAndroid Build Coastguard Worker   return false;
283*9356374aSAndroid Build Coastguard Worker }
284*9356374aSAndroid Build Coastguard Worker 
AbslUnparseFlag(absl::LogSeverity v)285*9356374aSAndroid Build Coastguard Worker std::string AbslUnparseFlag(absl::LogSeverity v) {
286*9356374aSAndroid Build Coastguard Worker   if (v == absl::NormalizeLogSeverity(v)) return absl::LogSeverityName(v);
287*9356374aSAndroid Build Coastguard Worker   return absl::UnparseFlag(static_cast<int>(v));
288*9356374aSAndroid Build Coastguard Worker }
289*9356374aSAndroid Build Coastguard Worker 
290*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END
291*9356374aSAndroid Build Coastguard Worker }  // namespace absl
292