00001
00002 #include <cstdarg>
00003 #include <cstdint>
00004 #include <cstdio>
00005 #include <string>
00006
00007 #include "gmock/gmock.h"
00008 #include "gtest/gtest.h"
00009 #include "absl/strings/str_format.h"
00010 #include "absl/strings/string_view.h"
00011
00012 namespace absl {
00013 namespace {
00014 using str_format_internal::FormatArgImpl;
00015
00016 using FormatEntryPointTest = ::testing::Test;
00017
00018 TEST_F(FormatEntryPointTest, Format) {
00019 std::string sink;
00020 EXPECT_TRUE(Format(&sink, "A format %d", 123));
00021 EXPECT_EQ("A format 123", sink);
00022 sink.clear();
00023
00024 ParsedFormat<'d'> pc("A format %d");
00025 EXPECT_TRUE(Format(&sink, pc, 123));
00026 EXPECT_EQ("A format 123", sink);
00027 }
00028 TEST_F(FormatEntryPointTest, UntypedFormat) {
00029 constexpr const char* formats[] = {
00030 "",
00031 "a",
00032 "%80d",
00033 #if !defined(_MSC_VER) && !defined(__ANDROID__)
00034
00035 "complicated multipart %% %1$d format %1$0999d",
00036 #endif // _MSC_VER
00037 };
00038 for (const char* fmt : formats) {
00039 std::string actual;
00040 int i = 123;
00041 FormatArgImpl arg_123(i);
00042 absl::Span<const FormatArgImpl> args(&arg_123, 1);
00043 UntypedFormatSpec format(fmt);
00044
00045 EXPECT_TRUE(FormatUntyped(&actual, format, args));
00046 char buf[4096]{};
00047 snprintf(buf, sizeof(buf), fmt, 123);
00048 EXPECT_EQ(
00049 str_format_internal::FormatPack(
00050 str_format_internal::UntypedFormatSpecImpl::Extract(format), args),
00051 buf);
00052 EXPECT_EQ(actual, buf);
00053 }
00054
00055 ParsedFormat<'d'> pc("A format %d");
00056 int i = 345;
00057 FormatArg arg(i);
00058 std::string out;
00059 EXPECT_TRUE(str_format_internal::FormatUntyped(
00060 &out, str_format_internal::UntypedFormatSpecImpl(&pc), {&arg, 1}));
00061 EXPECT_EQ("A format 345", out);
00062 }
00063
00064 TEST_F(FormatEntryPointTest, StringFormat) {
00065 EXPECT_EQ("123", StrFormat("%d", 123));
00066 constexpr absl::string_view view("=%d=", 4);
00067 EXPECT_EQ("=123=", StrFormat(view, 123));
00068 }
00069
00070 TEST_F(FormatEntryPointTest, AppendFormat) {
00071 std::string s;
00072 std::string& r = StrAppendFormat(&s, "%d", 123);
00073 EXPECT_EQ(&s, &r);
00074 EXPECT_EQ("123", r);
00075 }
00076
00077 TEST_F(FormatEntryPointTest, AppendFormatFail) {
00078 std::string s = "orig";
00079
00080 UntypedFormatSpec format(" more %d");
00081 FormatArgImpl arg("not an int");
00082
00083 EXPECT_EQ("orig",
00084 str_format_internal::AppendPack(
00085 &s, str_format_internal::UntypedFormatSpecImpl::Extract(format),
00086 {&arg, 1}));
00087 }
00088
00089
00090 TEST_F(FormatEntryPointTest, ManyArgs) {
00091 EXPECT_EQ("24", StrFormat("%24$d", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
00092 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24));
00093 EXPECT_EQ("60", StrFormat("%60$d", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
00094 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
00095 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
00096 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
00097 53, 54, 55, 56, 57, 58, 59, 60));
00098 }
00099
00100 TEST_F(FormatEntryPointTest, Preparsed) {
00101 ParsedFormat<'d'> pc("%d");
00102 EXPECT_EQ("123", StrFormat(pc, 123));
00103
00104 EXPECT_EQ("123", StrFormat(ParsedFormat<'d'>("%d"), 123));
00105 constexpr absl::string_view view("=%d=", 4);
00106 EXPECT_EQ("=123=", StrFormat(ParsedFormat<'d'>(view), 123));
00107 }
00108
00109 TEST_F(FormatEntryPointTest, FormatCountCapture) {
00110 int n = 0;
00111 EXPECT_EQ("", StrFormat("%n", FormatCountCapture(&n)));
00112 EXPECT_EQ(0, n);
00113 EXPECT_EQ("123", StrFormat("%d%n", 123, FormatCountCapture(&n)));
00114 EXPECT_EQ(3, n);
00115 }
00116
00117 TEST_F(FormatEntryPointTest, FormatCountCaptureWrongType) {
00118
00119 int n = 0;
00120 UntypedFormatSpec format("%d%n");
00121 int i = 123, *ip = &n;
00122 FormatArgImpl args[2] = {FormatArgImpl(i), FormatArgImpl(ip)};
00123
00124 EXPECT_EQ("", str_format_internal::FormatPack(
00125 str_format_internal::UntypedFormatSpecImpl::Extract(format),
00126 absl::MakeSpan(args)));
00127 }
00128
00129 TEST_F(FormatEntryPointTest, FormatCountCaptureMultiple) {
00130 int n1 = 0;
00131 int n2 = 0;
00132 EXPECT_EQ(" 1 2",
00133 StrFormat("%5d%n%10d%n", 1, FormatCountCapture(&n1), 2,
00134 FormatCountCapture(&n2)));
00135 EXPECT_EQ(5, n1);
00136 EXPECT_EQ(15, n2);
00137 }
00138
00139 TEST_F(FormatEntryPointTest, FormatCountCaptureExample) {
00140 int n;
00141 std::string s;
00142 StrAppendFormat(&s, "%s: %n%s\n", "(1,1)", FormatCountCapture(&n), "(1,2)");
00143 StrAppendFormat(&s, "%*s%s\n", n, "", "(2,2)");
00144 EXPECT_EQ(7, n);
00145 EXPECT_EQ(
00146 "(1,1): (1,2)\n"
00147 " (2,2)\n",
00148 s);
00149 }
00150
00151 TEST_F(FormatEntryPointTest, Stream) {
00152 const std::string formats[] = {
00153 "",
00154 "a",
00155 "%80d",
00156 #if !defined(_MSC_VER) && !defined(__ANDROID__)
00157
00158 "complicated multipart %% %1$d format %1$080d",
00159 #endif // _MSC_VER
00160 };
00161 std::string buf(4096, '\0');
00162 for (const auto& fmt : formats) {
00163 const auto parsed = ParsedFormat<'d'>::NewAllowIgnored(fmt);
00164 std::ostringstream oss;
00165 oss << StreamFormat(*parsed, 123);
00166 int fmt_result = snprintf(&*buf.begin(), buf.size(), fmt.c_str(), 123);
00167 ASSERT_TRUE(oss) << fmt;
00168 ASSERT_TRUE(fmt_result >= 0 && static_cast<size_t>(fmt_result) < buf.size())
00169 << fmt_result;
00170 EXPECT_EQ(buf.c_str(), oss.str());
00171 }
00172 }
00173
00174 TEST_F(FormatEntryPointTest, StreamOk) {
00175 std::ostringstream oss;
00176 oss << StreamFormat("hello %d", 123);
00177 EXPECT_EQ("hello 123", oss.str());
00178 EXPECT_TRUE(oss.good());
00179 }
00180
00181 TEST_F(FormatEntryPointTest, StreamFail) {
00182 std::ostringstream oss;
00183 UntypedFormatSpec format("hello %d");
00184 FormatArgImpl arg("non-numeric");
00185 oss << str_format_internal::Streamable(
00186 str_format_internal::UntypedFormatSpecImpl::Extract(format), {&arg, 1});
00187 EXPECT_EQ("hello ", oss.str());
00188 EXPECT_TRUE(oss.fail());
00189 }
00190
00191 std::string WithSnprintf(const char* fmt, ...) {
00192 std::string buf;
00193 buf.resize(128);
00194 va_list va;
00195 va_start(va, fmt);
00196 int r = vsnprintf(&*buf.begin(), buf.size(), fmt, va);
00197 va_end(va);
00198 EXPECT_GE(r, 0);
00199 EXPECT_LT(r, buf.size());
00200 buf.resize(r);
00201 return buf;
00202 }
00203
00204 TEST_F(FormatEntryPointTest, FloatPrecisionArg) {
00205
00206
00207
00208 EXPECT_EQ("0.1", StrFormat("%.1f", 0.1));
00209 EXPECT_EQ("0.1", WithSnprintf("%.1f", 0.1));
00210 EXPECT_EQ(" 0.1", StrFormat("%*.1f", 5, 0.1));
00211 EXPECT_EQ(" 0.1", WithSnprintf("%*.1f", 5, 0.1));
00212 EXPECT_EQ("0.1", StrFormat("%.*f", 1, 0.1));
00213 EXPECT_EQ("0.1", WithSnprintf("%.*f", 1, 0.1));
00214 EXPECT_EQ(" 0.1", StrFormat("%*.*f", 5, 1, 0.1));
00215 EXPECT_EQ(" 0.1", WithSnprintf("%*.*f", 5, 1, 0.1));
00216 }
00217 namespace streamed_test {
00218 struct X {};
00219 std::ostream& operator<<(std::ostream& os, const X&) {
00220 return os << "X";
00221 }
00222 }
00223
00224 TEST_F(FormatEntryPointTest, FormatStreamed) {
00225 EXPECT_EQ("123", StrFormat("%s", FormatStreamed(123)));
00226 EXPECT_EQ(" 123", StrFormat("%5s", FormatStreamed(123)));
00227 EXPECT_EQ("123 ", StrFormat("%-5s", FormatStreamed(123)));
00228 EXPECT_EQ("X", StrFormat("%s", FormatStreamed(streamed_test::X())));
00229 EXPECT_EQ("123", StrFormat("%s", FormatStreamed(StreamFormat("%d", 123))));
00230 }
00231
00232
00233
00234 class TempFile {
00235 public:
00236 TempFile() : file_(std::tmpfile()) {}
00237 ~TempFile() { std::fclose(file_); }
00238
00239 std::FILE* file() const { return file_; }
00240
00241
00242 std::string ReadFile() {
00243 std::fseek(file_, 0, SEEK_END);
00244 int size = std::ftell(file_);
00245 EXPECT_GT(size, 0);
00246 std::rewind(file_);
00247 std::string str(2 * size, ' ');
00248 int read_bytes = std::fread(&str[0], 1, str.size(), file_);
00249 EXPECT_EQ(read_bytes, size);
00250 str.resize(read_bytes);
00251 EXPECT_TRUE(std::feof(file_));
00252 return str;
00253 }
00254
00255 private:
00256 std::FILE* file_;
00257 };
00258
00259 TEST_F(FormatEntryPointTest, FPrintF) {
00260 TempFile tmp;
00261 int result =
00262 FPrintF(tmp.file(), "STRING: %s NUMBER: %010d", std::string("ABC"), -19);
00263 EXPECT_EQ(result, 30);
00264 EXPECT_EQ(tmp.ReadFile(), "STRING: ABC NUMBER: -000000019");
00265 }
00266
00267 TEST_F(FormatEntryPointTest, FPrintFError) {
00268 errno = 0;
00269 int result = FPrintF(stdin, "ABC");
00270 EXPECT_LT(result, 0);
00271 EXPECT_EQ(errno, EBADF);
00272 }
00273
00274 #if __GLIBC__
00275 TEST_F(FormatEntryPointTest, FprintfTooLarge) {
00276 std::FILE* f = std::fopen("/dev/null", "w");
00277 int width = 2000000000;
00278 errno = 0;
00279 int result = FPrintF(f, "%*d %*d", width, 0, width, 0);
00280 EXPECT_LT(result, 0);
00281 EXPECT_EQ(errno, EFBIG);
00282 std::fclose(f);
00283 }
00284
00285 TEST_F(FormatEntryPointTest, PrintF) {
00286 int stdout_tmp = dup(STDOUT_FILENO);
00287
00288 TempFile tmp;
00289 std::fflush(stdout);
00290 dup2(fileno(tmp.file()), STDOUT_FILENO);
00291
00292 int result = PrintF("STRING: %s NUMBER: %010d", std::string("ABC"), -19);
00293
00294 std::fflush(stdout);
00295 dup2(stdout_tmp, STDOUT_FILENO);
00296 close(stdout_tmp);
00297
00298 EXPECT_EQ(result, 30);
00299 EXPECT_EQ(tmp.ReadFile(), "STRING: ABC NUMBER: -000000019");
00300 }
00301 #endif // __GLIBC__
00302
00303 TEST_F(FormatEntryPointTest, SNPrintF) {
00304 char buffer[16];
00305 int result =
00306 SNPrintF(buffer, sizeof(buffer), "STRING: %s", std::string("ABC"));
00307 EXPECT_EQ(result, 11);
00308 EXPECT_EQ(std::string(buffer), "STRING: ABC");
00309
00310 result = SNPrintF(buffer, sizeof(buffer), "NUMBER: %d", 123456);
00311 EXPECT_EQ(result, 14);
00312 EXPECT_EQ(std::string(buffer), "NUMBER: 123456");
00313
00314 result = SNPrintF(buffer, sizeof(buffer), "NUMBER: %d", 1234567);
00315 EXPECT_EQ(result, 15);
00316 EXPECT_EQ(std::string(buffer), "NUMBER: 1234567");
00317
00318 result = SNPrintF(buffer, sizeof(buffer), "NUMBER: %d", 12345678);
00319 EXPECT_EQ(result, 16);
00320 EXPECT_EQ(std::string(buffer), "NUMBER: 1234567");
00321
00322 result = SNPrintF(buffer, sizeof(buffer), "NUMBER: %d", 123456789);
00323 EXPECT_EQ(result, 17);
00324 EXPECT_EQ(std::string(buffer), "NUMBER: 1234567");
00325
00326 result = SNPrintF(nullptr, 0, "Just checking the %s of the output.", "size");
00327 EXPECT_EQ(result, 37);
00328 }
00329
00330 TEST(StrFormat, BehavesAsDocumented) {
00331 std::string s = absl::StrFormat("%s, %d!", "Hello", 123);
00332 EXPECT_EQ("Hello, 123!", s);
00333
00334
00335 EXPECT_EQ(absl::StrFormat("%1$+3.2Lf", 1.1), "+1.10");
00336
00337
00338 EXPECT_EQ(StrFormat("%c", 'a'), "a");
00339 EXPECT_EQ(StrFormat("%c", 0x20), " ");
00340
00341 EXPECT_EQ(StrFormat("%c", int{'a'}), "a");
00342 EXPECT_EQ(StrFormat("%c", long{'a'}), "a");
00343 EXPECT_EQ(StrFormat("%c", uint64_t{'a'}), "a");
00344
00345
00346 EXPECT_EQ(StrFormat("%s", "C"), "C");
00347 EXPECT_EQ(StrFormat("%s", std::string("C++")), "C++");
00348 EXPECT_EQ(StrFormat("%s", string_view("view")), "view");
00349
00350
00351 EXPECT_EQ(StrFormat("%d", char{10}), "10");
00352 EXPECT_EQ(StrFormat("%d", int{10}), "10");
00353 EXPECT_EQ(StrFormat("%d", long{10}), "10");
00354 EXPECT_EQ(StrFormat("%d", uint64_t{10}), "10");
00355
00356 EXPECT_EQ(StrFormat("%d", -10), "-10");
00357 EXPECT_EQ(StrFormat("%i", -10), "-10");
00358
00359 EXPECT_EQ(StrFormat("%o", 10), "12");
00360
00361 EXPECT_EQ(StrFormat("%u", 10), "10");
00362
00363 EXPECT_EQ(StrFormat("%x", 10), "a");
00364 EXPECT_EQ(StrFormat("%X", 10), "A");
00365
00366
00367 EXPECT_EQ(StrFormat("%.1f", float{1}), "1.0");
00368 EXPECT_EQ(StrFormat("%.1f", double{1}), "1.0");
00369 const long double long_double = 1.0;
00370 EXPECT_EQ(StrFormat("%.1f", long_double), "1.0");
00371
00372 EXPECT_EQ(StrFormat("%.1f", char{1}), "1.0");
00373 EXPECT_EQ(StrFormat("%.1f", int{1}), "1.0");
00374 EXPECT_EQ(StrFormat("%.1f", long{1}), "1.0");
00375 EXPECT_EQ(StrFormat("%.1f", uint64_t{1}), "1.0");
00376
00377 EXPECT_EQ(StrFormat("%f", 123456789), "123456789.000000");
00378 EXPECT_EQ(StrFormat("%F", 123456789), "123456789.000000");
00379
00380 EXPECT_EQ(StrFormat("%e", .01), "1.000000e-02");
00381 EXPECT_EQ(StrFormat("%E", .01), "1.000000E-02");
00382
00383 EXPECT_EQ(StrFormat("%g", .01), "0.01");
00384 EXPECT_EQ(StrFormat("%g", 1e10), "1e+10");
00385 EXPECT_EQ(StrFormat("%G", 1e10), "1E+10");
00386
00387
00388
00389 #if !defined(__ANDROID_API__) || __ANDROID_API__ > 21
00390 EXPECT_EQ(StrFormat("%.1a", -3.0), "-0x1.8p+1");
00391 EXPECT_EQ(StrFormat("%.1A", -3.0), "-0X1.8P+1");
00392 #endif
00393
00394
00395 int64_t value = 0x7ffdeb4;
00396 auto ptr_value = static_cast<uintptr_t>(value);
00397 const int& something = *reinterpret_cast<const int*>(ptr_value);
00398 EXPECT_EQ(StrFormat("%p", &something), StrFormat("0x%x", ptr_value));
00399
00400
00401 EXPECT_EQ(StrFormat("%3d", 1), " 1");
00402 EXPECT_EQ(StrFormat("%3d", 123456), "123456");
00403 EXPECT_EQ(StrFormat("%06.2f", 1.234), "001.23");
00404 EXPECT_EQ(StrFormat("%+d", 1), "+1");
00405 EXPECT_EQ(StrFormat("% d", 1), " 1");
00406 EXPECT_EQ(StrFormat("%-4d", -1), "-1 ");
00407 EXPECT_EQ(StrFormat("%#o", 10), "012");
00408 EXPECT_EQ(StrFormat("%#x", 15), "0xf");
00409 EXPECT_EQ(StrFormat("%04d", 8), "0008");
00410
00411 EXPECT_EQ(absl::StrFormat("%2$s, %3$s, %1$s!", "vici", "veni", "vidi"),
00412 "veni, vidi, vici!");
00413
00414 EXPECT_EQ(StrFormat("%hhd", int{1}), "1");
00415 EXPECT_EQ(StrFormat("%hd", int{1}), "1");
00416 EXPECT_EQ(StrFormat("%ld", int{1}), "1");
00417 EXPECT_EQ(StrFormat("%lld", int{1}), "1");
00418 EXPECT_EQ(StrFormat("%Ld", int{1}), "1");
00419 EXPECT_EQ(StrFormat("%jd", int{1}), "1");
00420 EXPECT_EQ(StrFormat("%zd", int{1}), "1");
00421 EXPECT_EQ(StrFormat("%td", int{1}), "1");
00422 EXPECT_EQ(StrFormat("%qd", int{1}), "1");
00423 }
00424
00425 using str_format_internal::ExtendedParsedFormat;
00426 using str_format_internal::ParsedFormatBase;
00427
00428 struct SummarizeConsumer {
00429 std::string* out;
00430 explicit SummarizeConsumer(std::string* out) : out(out) {}
00431
00432 bool Append(string_view s) {
00433 *out += "[" + std::string(s) + "]";
00434 return true;
00435 }
00436
00437 bool ConvertOne(const str_format_internal::UnboundConversion& conv,
00438 string_view s) {
00439 *out += "{";
00440 *out += std::string(s);
00441 *out += ":";
00442 *out += std::to_string(conv.arg_position) + "$";
00443 if (conv.width.is_from_arg()) {
00444 *out += std::to_string(conv.width.get_from_arg()) + "$*";
00445 }
00446 if (conv.precision.is_from_arg()) {
00447 *out += "." + std::to_string(conv.precision.get_from_arg()) + "$*";
00448 }
00449 *out += conv.conv.Char();
00450 *out += "}";
00451 return true;
00452 }
00453 };
00454
00455 std::string SummarizeParsedFormat(const ParsedFormatBase& pc) {
00456 std::string out;
00457 if (!pc.ProcessFormat(SummarizeConsumer(&out))) out += "!";
00458 return out;
00459 }
00460
00461 using ParsedFormatTest = ::testing::Test;
00462
00463 TEST_F(ParsedFormatTest, SimpleChecked) {
00464 EXPECT_EQ("[ABC]{d:1$d}[DEF]",
00465 SummarizeParsedFormat(ParsedFormat<'d'>("ABC%dDEF")));
00466 EXPECT_EQ("{s:1$s}[FFF]{d:2$d}[ZZZ]{f:3$f}",
00467 SummarizeParsedFormat(ParsedFormat<'s', 'd', 'f'>("%sFFF%dZZZ%f")));
00468 EXPECT_EQ("{s:1$s}[ ]{.*d:3$.2$*d}",
00469 SummarizeParsedFormat(ParsedFormat<'s', '*', 'd'>("%s %.*d")));
00470 }
00471
00472 TEST_F(ParsedFormatTest, SimpleUncheckedCorrect) {
00473 auto f = ParsedFormat<'d'>::New("ABC%dDEF");
00474 ASSERT_TRUE(f);
00475 EXPECT_EQ("[ABC]{d:1$d}[DEF]", SummarizeParsedFormat(*f));
00476
00477 std::string format = "%sFFF%dZZZ%f";
00478 auto f2 = ParsedFormat<'s', 'd', 'f'>::New(format);
00479
00480 ASSERT_TRUE(f2);
00481 EXPECT_EQ("{s:1$s}[FFF]{d:2$d}[ZZZ]{f:3$f}", SummarizeParsedFormat(*f2));
00482
00483 f2 = ParsedFormat<'s', 'd', 'f'>::New("%s %d %f");
00484
00485 ASSERT_TRUE(f2);
00486 EXPECT_EQ("{s:1$s}[ ]{d:2$d}[ ]{f:3$f}", SummarizeParsedFormat(*f2));
00487
00488 auto star = ParsedFormat<'*', 'd'>::New("%*d");
00489 ASSERT_TRUE(star);
00490 EXPECT_EQ("{*d:2$1$*d}", SummarizeParsedFormat(*star));
00491
00492 auto dollar = ParsedFormat<'d', 's'>::New("%2$s %1$d");
00493 ASSERT_TRUE(dollar);
00494 EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}", SummarizeParsedFormat(*dollar));
00495
00496 dollar = ParsedFormat<'d', 's'>::New("%2$s %1$d %1$d");
00497 ASSERT_TRUE(dollar);
00498 EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}[ ]{1$d:1$d}",
00499 SummarizeParsedFormat(*dollar));
00500 }
00501
00502 TEST_F(ParsedFormatTest, SimpleUncheckedIgnoredArgs) {
00503 EXPECT_FALSE((ParsedFormat<'d', 's'>::New("ABC")));
00504 EXPECT_FALSE((ParsedFormat<'d', 's'>::New("%dABC")));
00505 EXPECT_FALSE((ParsedFormat<'d', 's'>::New("ABC%2$s")));
00506 auto f = ParsedFormat<'d', 's'>::NewAllowIgnored("ABC");
00507 ASSERT_TRUE(f);
00508 EXPECT_EQ("[ABC]", SummarizeParsedFormat(*f));
00509 f = ParsedFormat<'d', 's'>::NewAllowIgnored("%dABC");
00510 ASSERT_TRUE(f);
00511 EXPECT_EQ("{d:1$d}[ABC]", SummarizeParsedFormat(*f));
00512 f = ParsedFormat<'d', 's'>::NewAllowIgnored("ABC%2$s");
00513 ASSERT_TRUE(f);
00514 EXPECT_EQ("[ABC]{2$s:2$s}", SummarizeParsedFormat(*f));
00515 }
00516
00517 TEST_F(ParsedFormatTest, SimpleUncheckedUnsupported) {
00518 EXPECT_FALSE(ParsedFormat<'d'>::New("%1$d %1$x"));
00519 EXPECT_FALSE(ParsedFormat<'x'>::New("%1$d %1$x"));
00520 }
00521
00522 TEST_F(ParsedFormatTest, SimpleUncheckedIncorrect) {
00523 EXPECT_FALSE(ParsedFormat<'d'>::New(""));
00524
00525 EXPECT_FALSE(ParsedFormat<'d'>::New("ABC%dDEF%d"));
00526
00527 std::string format = "%sFFF%dZZZ%f";
00528 EXPECT_FALSE((ParsedFormat<'s', 'd', 'g'>::New(format)));
00529 }
00530
00531 using str_format_internal::Conv;
00532
00533 TEST_F(ParsedFormatTest, UncheckedCorrect) {
00534 auto f = ExtendedParsedFormat<Conv::d>::New("ABC%dDEF");
00535 ASSERT_TRUE(f);
00536 EXPECT_EQ("[ABC]{d:1$d}[DEF]", SummarizeParsedFormat(*f));
00537
00538 std::string format = "%sFFF%dZZZ%f";
00539 auto f2 =
00540 ExtendedParsedFormat<Conv::string, Conv::d, Conv::floating>::New(format);
00541
00542 ASSERT_TRUE(f2);
00543 EXPECT_EQ("{s:1$s}[FFF]{d:2$d}[ZZZ]{f:3$f}", SummarizeParsedFormat(*f2));
00544
00545 f2 = ExtendedParsedFormat<Conv::string, Conv::d, Conv::floating>::New(
00546 "%s %d %f");
00547
00548 ASSERT_TRUE(f2);
00549 EXPECT_EQ("{s:1$s}[ ]{d:2$d}[ ]{f:3$f}", SummarizeParsedFormat(*f2));
00550
00551 auto star = ExtendedParsedFormat<Conv::star, Conv::d>::New("%*d");
00552 ASSERT_TRUE(star);
00553 EXPECT_EQ("{*d:2$1$*d}", SummarizeParsedFormat(*star));
00554
00555 auto dollar = ExtendedParsedFormat<Conv::d, Conv::s>::New("%2$s %1$d");
00556 ASSERT_TRUE(dollar);
00557 EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}", SummarizeParsedFormat(*dollar));
00558
00559 dollar = ExtendedParsedFormat<Conv::d, Conv::s>::New("%2$s %1$d %1$d");
00560 ASSERT_TRUE(dollar);
00561 EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}[ ]{1$d:1$d}",
00562 SummarizeParsedFormat(*dollar));
00563 }
00564
00565 TEST_F(ParsedFormatTest, UncheckedIgnoredArgs) {
00566 EXPECT_FALSE((ExtendedParsedFormat<Conv::d, Conv::s>::New("ABC")));
00567 EXPECT_FALSE((ExtendedParsedFormat<Conv::d, Conv::s>::New("%dABC")));
00568 EXPECT_FALSE((ExtendedParsedFormat<Conv::d, Conv::s>::New("ABC%2$s")));
00569 auto f = ExtendedParsedFormat<Conv::d, Conv::s>::NewAllowIgnored("ABC");
00570 ASSERT_TRUE(f);
00571 EXPECT_EQ("[ABC]", SummarizeParsedFormat(*f));
00572 f = ExtendedParsedFormat<Conv::d, Conv::s>::NewAllowIgnored("%dABC");
00573 ASSERT_TRUE(f);
00574 EXPECT_EQ("{d:1$d}[ABC]", SummarizeParsedFormat(*f));
00575 f = ExtendedParsedFormat<Conv::d, Conv::s>::NewAllowIgnored("ABC%2$s");
00576 ASSERT_TRUE(f);
00577 EXPECT_EQ("[ABC]{2$s:2$s}", SummarizeParsedFormat(*f));
00578 }
00579
00580 TEST_F(ParsedFormatTest, UncheckedMultipleTypes) {
00581 auto dx = ExtendedParsedFormat<Conv::d | Conv::x>::New("%1$d %1$x");
00582 EXPECT_TRUE(dx);
00583 EXPECT_EQ("{1$d:1$d}[ ]{1$x:1$x}", SummarizeParsedFormat(*dx));
00584
00585 dx = ExtendedParsedFormat<Conv::d | Conv::x>::New("%1$d");
00586 EXPECT_TRUE(dx);
00587 EXPECT_EQ("{1$d:1$d}", SummarizeParsedFormat(*dx));
00588 }
00589
00590 TEST_F(ParsedFormatTest, UncheckedIncorrect) {
00591 EXPECT_FALSE(ExtendedParsedFormat<Conv::d>::New(""));
00592
00593 EXPECT_FALSE(ExtendedParsedFormat<Conv::d>::New("ABC%dDEF%d"));
00594
00595 std::string format = "%sFFF%dZZZ%f";
00596 EXPECT_FALSE((ExtendedParsedFormat<Conv::s, Conv::d, Conv::g>::New(format)));
00597 }
00598
00599 TEST_F(ParsedFormatTest, RegressionMixPositional) {
00600 EXPECT_FALSE((ExtendedParsedFormat<Conv::d, Conv::o>::New("%1$d %o")));
00601 }
00602
00603 using FormatWrapperTest = ::testing::Test;
00604
00605
00606 template <typename... Args>
00607 std::string WrappedFormat(const absl::FormatSpec<Args...>& format,
00608 const Args&... args) {
00609 return StrFormat(format, args...);
00610 }
00611
00612 TEST_F(FormatWrapperTest, ConstexprStringFormat) {
00613 EXPECT_EQ(WrappedFormat("%s there", "hello"), "hello there");
00614 }
00615
00616 TEST_F(FormatWrapperTest, ParsedFormat) {
00617 ParsedFormat<'s'> format("%s there");
00618 EXPECT_EQ(WrappedFormat(format, "hello"), "hello there");
00619 }
00620
00621 }
00622 }
00623
00624
00625
00626
00627 std::string CodegenAbslStrFormatInt(int i) {
00628 return absl::StrFormat("%d", i);
00629 }
00630
00631 std::string CodegenAbslStrFormatIntStringInt64(int i, const std::string& s,
00632 int64_t i64) {
00633 return absl::StrFormat("%d %s %d", i, s, i64);
00634 }
00635
00636 void CodegenAbslStrAppendFormatInt(std::string* out, int i) {
00637 absl::StrAppendFormat(out, "%d", i);
00638 }
00639
00640 void CodegenAbslStrAppendFormatIntStringInt64(std::string* out, int i,
00641 const std::string& s,
00642 int64_t i64) {
00643 absl::StrAppendFormat(out, "%d %s %d", i, s, i64);
00644 }