00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "absl/flags/marshalling.h"
00017
00018 #include <limits>
00019
00020 #include "absl/base/macros.h"
00021 #include "absl/strings/match.h"
00022 #include "absl/strings/numbers.h"
00023 #include "absl/strings/str_cat.h"
00024 #include "absl/strings/str_format.h"
00025 #include "absl/strings/str_join.h"
00026 #include "absl/strings/str_split.h"
00027
00028 namespace absl {
00029 namespace flags_internal {
00030
00031
00032
00033
00034 bool AbslParseFlag(absl::string_view text, bool* dst, std::string*) {
00035 const char* kTrue[] = {"1", "t", "true", "y", "yes"};
00036 const char* kFalse[] = {"0", "f", "false", "n", "no"};
00037 static_assert(sizeof(kTrue) == sizeof(kFalse), "true_false_equal");
00038
00039 text = absl::StripAsciiWhitespace(text);
00040
00041 for (size_t i = 0; i < ABSL_ARRAYSIZE(kTrue); ++i) {
00042 if (absl::EqualsIgnoreCase(text, kTrue[i])) {
00043 *dst = true;
00044 return true;
00045 } else if (absl::EqualsIgnoreCase(text, kFalse[i])) {
00046 *dst = false;
00047 return true;
00048 }
00049 }
00050 return false;
00051 }
00052
00053
00054
00055
00056
00057
00058
00059 static int NumericBase(absl::string_view text) {
00060 const bool hex = (text.size() >= 2 && text[0] == '0' &&
00061 (text[1] == 'x' || text[1] == 'X'));
00062 return hex ? 16 : 10;
00063 }
00064
00065 template <typename IntType>
00066 inline bool ParseFlagImpl(absl::string_view text, IntType* dst) {
00067 text = absl::StripAsciiWhitespace(text);
00068
00069 return absl::numbers_internal::safe_strtoi_base(text, dst, NumericBase(text));
00070 }
00071
00072 bool AbslParseFlag(absl::string_view text, short* dst, std::string*) {
00073 int val;
00074 if (!ParseFlagImpl(text, &val)) return false;
00075 if (static_cast<short>(val) != val)
00076 return false;
00077 *dst = static_cast<short>(val);
00078 return true;
00079 }
00080
00081 bool AbslParseFlag(absl::string_view text, unsigned short* dst, std::string*) {
00082 unsigned int val;
00083 if (!ParseFlagImpl(text, &val)) return false;
00084 if (static_cast<unsigned short>(val) !=
00085 val)
00086 return false;
00087 *dst = static_cast<unsigned short>(val);
00088 return true;
00089 }
00090
00091 bool AbslParseFlag(absl::string_view text, int* dst, std::string*) {
00092 return ParseFlagImpl(text, dst);
00093 }
00094
00095 bool AbslParseFlag(absl::string_view text, unsigned int* dst, std::string*) {
00096 return ParseFlagImpl(text, dst);
00097 }
00098
00099 bool AbslParseFlag(absl::string_view text, long* dst, std::string*) {
00100 return ParseFlagImpl(text, dst);
00101 }
00102
00103 bool AbslParseFlag(absl::string_view text, unsigned long* dst, std::string*) {
00104 return ParseFlagImpl(text, dst);
00105 }
00106
00107 bool AbslParseFlag(absl::string_view text, long long* dst, std::string*) {
00108 return ParseFlagImpl(text, dst);
00109 }
00110
00111 bool AbslParseFlag(absl::string_view text, unsigned long long* dst,
00112 std::string*) {
00113 return ParseFlagImpl(text, dst);
00114 }
00115
00116
00117
00118
00119 bool AbslParseFlag(absl::string_view text, float* dst, std::string*) {
00120 return absl::SimpleAtof(text, dst);
00121 }
00122
00123 bool AbslParseFlag(absl::string_view text, double* dst, std::string*) {
00124 return absl::SimpleAtod(text, dst);
00125 }
00126
00127
00128
00129
00130 bool AbslParseFlag(absl::string_view text, std::string* dst, std::string*) {
00131 dst->assign(text.data(), text.size());
00132 return true;
00133 }
00134
00135
00136
00137
00138 bool AbslParseFlag(absl::string_view text, std::vector<std::string>* dst,
00139 std::string*) {
00140
00141
00142 if (text.empty()) {
00143 dst->clear();
00144 return true;
00145 }
00146 *dst = absl::StrSplit(text, ',', absl::AllowEmpty());
00147 return true;
00148 }
00149
00150
00151
00152
00153 std::string Unparse(bool v) { return v ? "true" : "false"; }
00154 std::string Unparse(short v) { return absl::StrCat(v); }
00155 std::string Unparse(unsigned short v) { return absl::StrCat(v); }
00156 std::string Unparse(int v) { return absl::StrCat(v); }
00157 std::string Unparse(unsigned int v) { return absl::StrCat(v); }
00158 std::string Unparse(long v) { return absl::StrCat(v); }
00159 std::string Unparse(unsigned long v) { return absl::StrCat(v); }
00160 std::string Unparse(long long v) { return absl::StrCat(v); }
00161 std::string Unparse(unsigned long long v) { return absl::StrCat(v); }
00162 template <typename T>
00163 std::string UnparseFloatingPointVal(T v) {
00164
00165
00166 std::string digit10_str =
00167 absl::StrFormat("%.*g", std::numeric_limits<T>::digits10, v);
00168 if (std::isnan(v) || std::isinf(v)) return digit10_str;
00169
00170 T roundtrip_val = 0;
00171 std::string err;
00172 if (absl::ParseFlag(digit10_str, &roundtrip_val, &err) &&
00173 roundtrip_val == v) {
00174 return digit10_str;
00175 }
00176
00177
00178
00179 return absl::StrFormat("%.*g", std::numeric_limits<T>::max_digits10, v);
00180 }
00181 std::string Unparse(float v) { return UnparseFloatingPointVal(v); }
00182 std::string Unparse(double v) { return UnparseFloatingPointVal(v); }
00183 std::string AbslUnparseFlag(absl::string_view v) { return std::string(v); }
00184 std::string AbslUnparseFlag(const std::vector<std::string>& v) {
00185 return absl::StrJoin(v, ",");
00186 }
00187
00188 }
00189 }