abseil-cpp/absl/strings/str_format_test.cc
Go to the documentation of this file.
1 // Copyright 2020 The Abseil Authors.
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 // https://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 "absl/strings/str_format.h"
16 
17 #include <cstdarg>
18 #include <cstdint>
19 #include <cstdio>
20 #include <string>
21 
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "absl/strings/cord.h"
25 #include "absl/strings/str_cat.h"
26 #include "absl/strings/string_view.h"
27 
28 namespace absl {
30 namespace {
31 using str_format_internal::FormatArgImpl;
32 
34 
37  EXPECT_TRUE(Format(&sink, "A format %d", 123));
38  EXPECT_EQ("A format 123", sink);
39  sink.clear();
40 
41  ParsedFormat<'d'> pc("A format %d");
42  EXPECT_TRUE(Format(&sink, pc, 123));
43  EXPECT_EQ("A format 123", sink);
44 }
45 TEST_F(FormatEntryPointTest, UntypedFormat) {
46  constexpr const char* formats[] = {
47  "",
48  "a",
49  "%80d",
50 #if !defined(_MSC_VER) && !defined(__ANDROID__) && !defined(__native_client__)
51  // MSVC, NaCL and Android don't support positional syntax.
52  "complicated multipart %% %1$d format %1$0999d",
53 #endif // _MSC_VER
54  };
55  for (const char* fmt : formats) {
56  std::string actual;
57  int i = 123;
58  FormatArgImpl arg_123(i);
61 
63  char buf[4096]{};
64  snprintf(buf, sizeof(buf), fmt, 123);
65  EXPECT_EQ(
68  buf);
69  EXPECT_EQ(actual, buf);
70  }
71  // The internal version works with a preparsed format.
72  ParsedFormat<'d'> pc("A format %d");
73  int i = 345;
74  FormatArg arg(i);
78  EXPECT_EQ("A format 345", out);
79 }
80 
81 TEST_F(FormatEntryPointTest, StringFormat) {
82  EXPECT_EQ("123", StrFormat("%d", 123));
83  constexpr absl::string_view view("=%d=", 4);
84  EXPECT_EQ("=123=", StrFormat(view, 123));
85 }
86 
87 TEST_F(FormatEntryPointTest, AppendFormat) {
88  std::string s;
89  std::string& r = StrAppendFormat(&s, "%d", 123);
90  EXPECT_EQ(&s, &r); // should be same object
91  EXPECT_EQ("123", r);
92 }
93 
94 TEST_F(FormatEntryPointTest, AppendFormatFail) {
95  std::string s = "orig";
96 
97  UntypedFormatSpec format(" more %d");
98  FormatArgImpl arg("not an int");
99 
100  EXPECT_EQ("orig",
103  {&arg, 1}));
104 }
105 
106 
108  EXPECT_EQ("24", StrFormat("%24$d", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
109  14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24));
110  EXPECT_EQ("60", StrFormat("%60$d", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
111  14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
112  27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
113  40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
114  53, 54, 55, 56, 57, 58, 59, 60));
115 }
116 
118  ParsedFormat<'d'> pc("%d");
119  EXPECT_EQ("123", StrFormat(pc, 123));
120  // rvalue ok?
121  EXPECT_EQ("123", StrFormat(ParsedFormat<'d'>("%d"), 123));
122  constexpr absl::string_view view("=%d=", 4);
123  EXPECT_EQ("=123=", StrFormat(ParsedFormat<'d'>(view), 123));
124 }
125 
127  int n = 0;
128  EXPECT_EQ("", StrFormat("%n", FormatCountCapture(&n)));
129  EXPECT_EQ(0, n);
130  EXPECT_EQ("123", StrFormat("%d%n", 123, FormatCountCapture(&n)));
131  EXPECT_EQ(3, n);
132 }
133 
134 TEST_F(FormatEntryPointTest, FormatCountCaptureWrongType) {
135  // Should reject int*.
136  int n = 0;
137  UntypedFormatSpec format("%d%n");
138  int i = 123, *ip = &n;
140 
143  absl::MakeSpan(args)));
144 }
145 
146 TEST_F(FormatEntryPointTest, FormatCountCaptureMultiple) {
147  int n1 = 0;
148  int n2 = 0;
149  EXPECT_EQ(" 1 2",
150  StrFormat("%5d%n%10d%n", 1, FormatCountCapture(&n1), 2,
151  FormatCountCapture(&n2)));
152  EXPECT_EQ(5, n1);
153  EXPECT_EQ(15, n2);
154 }
155 
156 TEST_F(FormatEntryPointTest, FormatCountCaptureExample) {
157  int n;
158  std::string s;
159  StrAppendFormat(&s, "%s: %n%s\n", "(1,1)", FormatCountCapture(&n), "(1,2)");
160  StrAppendFormat(&s, "%*s%s\n", n, "", "(2,2)");
161  EXPECT_EQ(7, n);
162  EXPECT_EQ(
163  "(1,1): (1,2)\n"
164  " (2,2)\n",
165  s);
166 }
167 
169  const std::string formats[] = {
170  "",
171  "a",
172  "%80d",
173  "%d %u %c %s %f %g",
174 #if !defined(_MSC_VER) && !defined(__ANDROID__) && !defined(__native_client__)
175  // MSVC, NaCL and Android don't support positional syntax.
176  "complicated multipart %% %1$d format %1$080d",
177 #endif // _MSC_VER
178  };
179  std::string buf(4096, '\0');
180  for (const auto& fmt : formats) {
181  const auto parsed =
183  std::ostringstream oss;
184  oss << StreamFormat(*parsed, 123, 3, 49, "multistreaming!!!", 1.01, 1.01);
185  int fmt_result = snprintf(&*buf.begin(), buf.size(), fmt.c_str(), //
186  123, 3, 49, "multistreaming!!!", 1.01, 1.01);
187  ASSERT_TRUE(oss) << fmt;
188  ASSERT_TRUE(fmt_result >= 0 && static_cast<size_t>(fmt_result) < buf.size())
189  << fmt_result;
190  EXPECT_EQ(buf.c_str(), oss.str());
191  }
192 }
193 
195  std::ostringstream oss;
196  oss << StreamFormat("hello %d", 123);
197  EXPECT_EQ("hello 123", oss.str());
198  EXPECT_TRUE(oss.good());
199 }
200 
202  std::ostringstream oss;
203  UntypedFormatSpec format("hello %d");
204  FormatArgImpl arg("non-numeric");
207  EXPECT_EQ("hello ", oss.str()); // partial write
208  EXPECT_TRUE(oss.fail());
209 }
210 
211 std::string WithSnprintf(const char* fmt, ...) {
213  buf.resize(128);
214  va_list va;
215  va_start(va, fmt);
216  int r = vsnprintf(&*buf.begin(), buf.size(), fmt, va);
217  va_end(va);
218  EXPECT_GE(r, 0);
219  EXPECT_LT(r, buf.size());
220  buf.resize(r);
221  return buf;
222 }
223 
224 TEST_F(FormatEntryPointTest, FloatPrecisionArg) {
225  // Test that positional parameters for width and precision
226  // are indexed to precede the value.
227  // Also sanity check the same formats against snprintf.
228  EXPECT_EQ("0.1", StrFormat("%.1f", 0.1));
229  EXPECT_EQ("0.1", WithSnprintf("%.1f", 0.1));
230  EXPECT_EQ(" 0.1", StrFormat("%*.1f", 5, 0.1));
231  EXPECT_EQ(" 0.1", WithSnprintf("%*.1f", 5, 0.1));
232  EXPECT_EQ("0.1", StrFormat("%.*f", 1, 0.1));
233  EXPECT_EQ("0.1", WithSnprintf("%.*f", 1, 0.1));
234  EXPECT_EQ(" 0.1", StrFormat("%*.*f", 5, 1, 0.1));
235  EXPECT_EQ(" 0.1", WithSnprintf("%*.*f", 5, 1, 0.1));
236 }
237 namespace streamed_test {
238 struct X {};
239 std::ostream& operator<<(std::ostream& os, const X&) {
240  return os << "X";
241 }
242 } // streamed_test
243 
245  EXPECT_EQ("123", StrFormat("%s", FormatStreamed(123)));
246  EXPECT_EQ(" 123", StrFormat("%5s", FormatStreamed(123)));
247  EXPECT_EQ("123 ", StrFormat("%-5s", FormatStreamed(123)));
249  EXPECT_EQ("123", StrFormat("%s", FormatStreamed(StreamFormat("%d", 123))));
250 }
251 
252 // Helper class that creates a temporary file and exposes a FILE* to it.
253 // It will close the file on destruction.
254 class TempFile {
255  public:
256  TempFile() : file_(std::tmpfile()) {}
258 
259  std::FILE* file() const { return file_; }
260 
261  // Read the file into a string.
263  std::fseek(file_, 0, SEEK_END);
264  int size = std::ftell(file_);
265  EXPECT_GT(size, 0);
266  std::rewind(file_);
267  std::string str(2 * size, ' ');
268  int read_bytes = std::fread(&str[0], 1, str.size(), file_);
270  str.resize(read_bytes);
271  EXPECT_TRUE(std::feof(file_));
272  return str;
273  }
274 
275  private:
277 };
278 
280  TempFile tmp;
281  int result =
282  FPrintF(tmp.file(), "STRING: %s NUMBER: %010d", std::string("ABC"), -19);
283  EXPECT_EQ(result, 30);
284  EXPECT_EQ(tmp.ReadFile(), "STRING: ABC NUMBER: -000000019");
285 }
286 
287 TEST_F(FormatEntryPointTest, FPrintFError) {
288  errno = 0;
289  int result = FPrintF(stdin, "ABC");
290  EXPECT_LT(result, 0);
291  EXPECT_EQ(errno, EBADF);
292 }
293 
294 #ifdef __GLIBC__
295 TEST_F(FormatEntryPointTest, FprintfTooLarge) {
296  std::FILE* f = std::fopen("/dev/null", "w");
297  int width = 2000000000;
298  errno = 0;
299  int result = FPrintF(f, "%*d %*d", width, 0, width, 0);
300  EXPECT_LT(result, 0);
301  EXPECT_EQ(errno, EFBIG);
302  std::fclose(f);
303 }
304 
306  int stdout_tmp = dup(STDOUT_FILENO);
307 
308  TempFile tmp;
309  std::fflush(stdout);
310  dup2(fileno(tmp.file()), STDOUT_FILENO);
311 
312  int result = PrintF("STRING: %s NUMBER: %010d", std::string("ABC"), -19);
313 
314  std::fflush(stdout);
315  dup2(stdout_tmp, STDOUT_FILENO);
316  close(stdout_tmp);
317 
318  EXPECT_EQ(result, 30);
319  EXPECT_EQ(tmp.ReadFile(), "STRING: ABC NUMBER: -000000019");
320 }
321 #endif // __GLIBC__
322 
324  char buffer[16];
325  int result =
326  SNPrintF(buffer, sizeof(buffer), "STRING: %s", std::string("ABC"));
327  EXPECT_EQ(result, 11);
328  EXPECT_EQ(std::string(buffer), "STRING: ABC");
329 
330  result = SNPrintF(buffer, sizeof(buffer), "NUMBER: %d", 123456);
331  EXPECT_EQ(result, 14);
332  EXPECT_EQ(std::string(buffer), "NUMBER: 123456");
333 
334  result = SNPrintF(buffer, sizeof(buffer), "NUMBER: %d", 1234567);
335  EXPECT_EQ(result, 15);
336  EXPECT_EQ(std::string(buffer), "NUMBER: 1234567");
337 
338  result = SNPrintF(buffer, sizeof(buffer), "NUMBER: %d", 12345678);
339  EXPECT_EQ(result, 16);
340  EXPECT_EQ(std::string(buffer), "NUMBER: 1234567");
341 
342  result = SNPrintF(buffer, sizeof(buffer), "NUMBER: %d", 123456789);
343  EXPECT_EQ(result, 17);
344  EXPECT_EQ(std::string(buffer), "NUMBER: 1234567");
345 
346  result = SNPrintF(nullptr, 0, "Just checking the %s of the output.", "size");
347  EXPECT_EQ(result, 37);
348 }
349 
350 TEST(StrFormat, BehavesAsDocumented) {
351  std::string s = absl::StrFormat("%s, %d!", "Hello", 123);
352  EXPECT_EQ("Hello, 123!", s);
353  // The format of a replacement is
354  // '%'[position][flags][width['.'precision]][length_modifier][format]
355  EXPECT_EQ(absl::StrFormat("%1$+3.2Lf", 1.1), "+1.10");
356  // Text conversion:
357  // "c" - Character. Eg: 'a' -> "A", 20 -> " "
358  EXPECT_EQ(StrFormat("%c", 'a'), "a");
359  EXPECT_EQ(StrFormat("%c", 0x20), " ");
360  // Formats char and integral types: int, long, uint64_t, etc.
361  EXPECT_EQ(StrFormat("%c", int{'a'}), "a");
362  EXPECT_EQ(StrFormat("%c", long{'a'}), "a"); // NOLINT
363  EXPECT_EQ(StrFormat("%c", uint64_t{'a'}), "a");
364  // "s" - string Eg: "C" -> "C", std::string("C++") -> "C++"
365  // Formats std::string, char*, string_view, and Cord.
366  EXPECT_EQ(StrFormat("%s", "C"), "C");
367  EXPECT_EQ(StrFormat("%s", std::string("C++")), "C++");
368  EXPECT_EQ(StrFormat("%s", string_view("view")), "view");
369  EXPECT_EQ(StrFormat("%s", absl::Cord("cord")), "cord");
370  // Integral Conversion
371  // These format integral types: char, int, long, uint64_t, etc.
372  EXPECT_EQ(StrFormat("%d", char{10}), "10");
373  EXPECT_EQ(StrFormat("%d", int{10}), "10");
374  EXPECT_EQ(StrFormat("%d", long{10}), "10"); // NOLINT
375  EXPECT_EQ(StrFormat("%d", uint64_t{10}), "10");
376  // d,i - signed decimal Eg: -10 -> "-10"
377  EXPECT_EQ(StrFormat("%d", -10), "-10");
378  EXPECT_EQ(StrFormat("%i", -10), "-10");
379  // o - octal Eg: 10 -> "12"
380  EXPECT_EQ(StrFormat("%o", 10), "12");
381  // u - unsigned decimal Eg: 10 -> "10"
382  EXPECT_EQ(StrFormat("%u", 10), "10");
383  // x/X - lower,upper case hex Eg: 10 -> "a"/"A"
384  EXPECT_EQ(StrFormat("%x", 10), "a");
385  EXPECT_EQ(StrFormat("%X", 10), "A");
386  // Floating-point, with upper/lower-case output.
387  // These format floating points types: float, double, long double, etc.
388  EXPECT_EQ(StrFormat("%.1f", float{1}), "1.0");
389  EXPECT_EQ(StrFormat("%.1f", double{1}), "1.0");
390  const long double long_double = 1.0;
391  EXPECT_EQ(StrFormat("%.1f", long_double), "1.0");
392  // These also format integral types: char, int, long, uint64_t, etc.:
393  EXPECT_EQ(StrFormat("%.1f", char{1}), "1.0");
394  EXPECT_EQ(StrFormat("%.1f", int{1}), "1.0");
395  EXPECT_EQ(StrFormat("%.1f", long{1}), "1.0"); // NOLINT
396  EXPECT_EQ(StrFormat("%.1f", uint64_t{1}), "1.0");
397  // f/F - decimal. Eg: 123456789 -> "123456789.000000"
398  EXPECT_EQ(StrFormat("%f", 123456789), "123456789.000000");
399  EXPECT_EQ(StrFormat("%F", 123456789), "123456789.000000");
400  // e/E - exponentiated Eg: .01 -> "1.00000e-2"/"1.00000E-2"
401  EXPECT_EQ(StrFormat("%e", .01), "1.000000e-02");
402  EXPECT_EQ(StrFormat("%E", .01), "1.000000E-02");
403  // g/G - exponentiate to fit Eg: .01 -> "0.01", 1e10 ->"1e+10"/"1E+10"
404  EXPECT_EQ(StrFormat("%g", .01), "0.01");
405  EXPECT_EQ(StrFormat("%g", 1e10), "1e+10");
406  EXPECT_EQ(StrFormat("%G", 1e10), "1E+10");
407  // a/A - lower,upper case hex Eg: -3.0 -> "-0x1.8p+1"/"-0X1.8P+1"
408 
409 // On Android platform <=21, there is a regression in hexfloat formatting.
410 #if !defined(__ANDROID_API__) || __ANDROID_API__ > 21
411  EXPECT_EQ(StrFormat("%.1a", -3.0), "-0x1.8p+1"); // .1 to fix MSVC output
412  EXPECT_EQ(StrFormat("%.1A", -3.0), "-0X1.8P+1"); // .1 to fix MSVC output
413 #endif
414 
415  // Other conversion
416  int64_t value = 0x7ffdeb4;
417  auto ptr_value = static_cast<uintptr_t>(value);
418  const int& something = *reinterpret_cast<const int*>(ptr_value);
419  EXPECT_EQ(StrFormat("%p", &something), StrFormat("0x%x", ptr_value));
420 
421  // Output widths are supported, with optional flags.
422  EXPECT_EQ(StrFormat("%3d", 1), " 1");
423  EXPECT_EQ(StrFormat("%3d", 123456), "123456");
424  EXPECT_EQ(StrFormat("%06.2f", 1.234), "001.23");
425  EXPECT_EQ(StrFormat("%+d", 1), "+1");
426  EXPECT_EQ(StrFormat("% d", 1), " 1");
427  EXPECT_EQ(StrFormat("%-4d", -1), "-1 ");
428  EXPECT_EQ(StrFormat("%#o", 10), "012");
429  EXPECT_EQ(StrFormat("%#x", 15), "0xf");
430  EXPECT_EQ(StrFormat("%04d", 8), "0008");
431  // Posix positional substitution.
432  EXPECT_EQ(absl::StrFormat("%2$s, %3$s, %1$s!", "vici", "veni", "vidi"),
433  "veni, vidi, vici!");
434  // Length modifiers are ignored.
435  EXPECT_EQ(StrFormat("%hhd", int{1}), "1");
436  EXPECT_EQ(StrFormat("%hd", int{1}), "1");
437  EXPECT_EQ(StrFormat("%ld", int{1}), "1");
438  EXPECT_EQ(StrFormat("%lld", int{1}), "1");
439  EXPECT_EQ(StrFormat("%Ld", int{1}), "1");
440  EXPECT_EQ(StrFormat("%jd", int{1}), "1");
441  EXPECT_EQ(StrFormat("%zd", int{1}), "1");
442  EXPECT_EQ(StrFormat("%td", int{1}), "1");
443  EXPECT_EQ(StrFormat("%qd", int{1}), "1");
444 }
445 
448 
452 
453  bool Append(string_view s) {
454  *out += "[" + std::string(s) + "]";
455  return true;
456  }
457 
459  string_view s) {
460  *out += "{";
461  *out += std::string(s);
462  *out += ":";
463  *out += std::to_string(conv.arg_position) + "$";
464  if (conv.width.is_from_arg()) {
465  *out += std::to_string(conv.width.get_from_arg()) + "$*";
466  }
467  if (conv.precision.is_from_arg()) {
468  *out += "." + std::to_string(conv.precision.get_from_arg()) + "$*";
469  }
471  *out += "}";
472  return true;
473  }
474 };
475 
478  if (!pc.ProcessFormat(SummarizeConsumer(&out))) out += "!";
479  return out;
480 }
481 
483 
484 TEST_F(ParsedFormatTest, SimpleChecked) {
485  EXPECT_EQ("[ABC]{d:1$d}[DEF]",
487  EXPECT_EQ("{s:1$s}[FFF]{d:2$d}[ZZZ]{f:3$f}",
489  EXPECT_EQ("{s:1$s}[ ]{.*d:3$.2$*d}",
491 }
492 
493 TEST_F(ParsedFormatTest, SimpleUncheckedCorrect) {
494  auto f = ParsedFormat<'d'>::New("ABC%dDEF");
495  ASSERT_TRUE(f);
496  EXPECT_EQ("[ABC]{d:1$d}[DEF]", SummarizeParsedFormat(*f));
497 
498  std::string format = "%sFFF%dZZZ%f";
500 
501  ASSERT_TRUE(f2);
502  EXPECT_EQ("{s:1$s}[FFF]{d:2$d}[ZZZ]{f:3$f}", SummarizeParsedFormat(*f2));
503 
504  f2 = ParsedFormat<'s', 'd', 'f'>::New("%s %d %f");
505 
506  ASSERT_TRUE(f2);
507  EXPECT_EQ("{s:1$s}[ ]{d:2$d}[ ]{f:3$f}", SummarizeParsedFormat(*f2));
508 
509  auto star = ParsedFormat<'*', 'd'>::New("%*d");
510  ASSERT_TRUE(star);
511  EXPECT_EQ("{*d:2$1$*d}", SummarizeParsedFormat(*star));
512 
513  auto dollar = ParsedFormat<'d', 's'>::New("%2$s %1$d");
514  ASSERT_TRUE(dollar);
515  EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}", SummarizeParsedFormat(*dollar));
516  // with reuse
517  dollar = ParsedFormat<'d', 's'>::New("%2$s %1$d %1$d");
518  ASSERT_TRUE(dollar);
519  EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}[ ]{1$d:1$d}",
520  SummarizeParsedFormat(*dollar));
521 }
522 
523 TEST_F(ParsedFormatTest, SimpleUncheckedIgnoredArgs) {
528  ASSERT_TRUE(f);
529  EXPECT_EQ("[ABC]", SummarizeParsedFormat(*f));
531  ASSERT_TRUE(f);
532  EXPECT_EQ("{d:1$d}[ABC]", SummarizeParsedFormat(*f));
534  ASSERT_TRUE(f);
535  EXPECT_EQ("[ABC]{2$s:2$s}", SummarizeParsedFormat(*f));
536 }
537 
538 TEST_F(ParsedFormatTest, SimpleUncheckedUnsupported) {
539  EXPECT_FALSE(ParsedFormat<'d'>::New("%1$d %1$x"));
540  EXPECT_FALSE(ParsedFormat<'x'>::New("%1$d %1$x"));
541 }
542 
543 TEST_F(ParsedFormatTest, SimpleUncheckedIncorrect) {
545 
546  EXPECT_FALSE(ParsedFormat<'d'>::New("ABC%dDEF%d"));
547 
548  std::string format = "%sFFF%dZZZ%f";
550 }
551 
552 #if defined(__cpp_nontype_template_parameter_auto)
553 
554 template <auto T>
555 std::true_type IsValidParsedFormatArgTest(ParsedFormat<T>*);
556 
557 template <auto T>
558 std::false_type IsValidParsedFormatArgTest(...);
559 
560 template <auto T>
561 using IsValidParsedFormatArg = decltype(IsValidParsedFormatArgTest<T>(nullptr));
562 
563 TEST_F(ParsedFormatTest, OnlyValidTypesAllowed) {
565 
567 
568  ASSERT_TRUE(IsValidParsedFormatArg<absl::FormatConversionCharSet::d |
570  ASSERT_TRUE(
572 
573  // This is an easy mistake to make, however, this will reduce to an integer
574  // which has no meaning, so we need to ensure it doesn't compile.
576 
577  // For now, we disallow construction based on ConversionChar (rather than
578  // CharSet)
580 }
581 
582 TEST_F(ParsedFormatTest, ExtendedTyping) {
586  ASSERT_TRUE(v1);
588  ASSERT_TRUE(v2);
591  's'>::New("%d%s");
592  ASSERT_TRUE(v3);
595  's'>::New("%s%s");
596  ASSERT_TRUE(v4);
597 }
598 #endif
599 
600 TEST_F(ParsedFormatTest, UncheckedCorrect) {
601  auto f =
603  ASSERT_TRUE(f);
604  EXPECT_EQ("[ABC]{d:1$d}[DEF]", SummarizeParsedFormat(*f));
605 
606  std::string format = "%sFFF%dZZZ%f";
607  auto f2 = ExtendedParsedFormat<
610 
611  ASSERT_TRUE(f2);
612  EXPECT_EQ("{s:1$s}[FFF]{d:2$d}[ZZZ]{f:3$f}", SummarizeParsedFormat(*f2));
613 
617 
618  ASSERT_TRUE(f2);
619  EXPECT_EQ("{s:1$s}[ ]{d:2$d}[ ]{f:3$f}", SummarizeParsedFormat(*f2));
620 
621  auto star =
624  ASSERT_TRUE(star);
625  EXPECT_EQ("{*d:2$1$*d}", SummarizeParsedFormat(*star));
626 
627  auto dollar =
630  ASSERT_TRUE(dollar);
631  EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}", SummarizeParsedFormat(*dollar));
632  // with reuse
633  dollar = ExtendedParsedFormat<
635  absl::FormatConversionCharSet::s>::New("%2$s %1$d %1$d");
636  ASSERT_TRUE(dollar);
637  EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}[ ]{1$d:1$d}",
638  SummarizeParsedFormat(*dollar));
639 }
640 
641 TEST_F(ParsedFormatTest, UncheckedIgnoredArgs) {
642  EXPECT_FALSE(
645  EXPECT_FALSE(
648  EXPECT_FALSE(
650  absl::FormatConversionCharSet::s>::New("ABC%2$s")));
651  auto f = ExtendedParsedFormat<
653  absl::FormatConversionCharSet::s>::NewAllowIgnored("ABC");
654  ASSERT_TRUE(f);
655  EXPECT_EQ("[ABC]", SummarizeParsedFormat(*f));
658  absl::FormatConversionCharSet::s>::NewAllowIgnored("%dABC");
659  ASSERT_TRUE(f);
660  EXPECT_EQ("{d:1$d}[ABC]", SummarizeParsedFormat(*f));
663  absl::FormatConversionCharSet::s>::NewAllowIgnored("ABC%2$s");
664  ASSERT_TRUE(f);
665  EXPECT_EQ("[ABC]{2$s:2$s}", SummarizeParsedFormat(*f));
666 }
667 
668 TEST_F(ParsedFormatTest, UncheckedMultipleTypes) {
669  auto dx =
672  EXPECT_TRUE(dx);
673  EXPECT_EQ("{1$d:1$d}[ ]{1$x:1$x}", SummarizeParsedFormat(*dx));
674 
677  EXPECT_TRUE(dx);
678  EXPECT_EQ("{1$d:1$d}", SummarizeParsedFormat(*dx));
679 }
680 
681 TEST_F(ParsedFormatTest, UncheckedIncorrect) {
683 
685  "ABC%dDEF%d"));
686 
687  std::string format = "%sFFF%dZZZ%f";
688  EXPECT_FALSE(
692 }
693 
694 TEST_F(ParsedFormatTest, RegressionMixPositional) {
695  EXPECT_FALSE(
697  absl::FormatConversionCharSet::o>::New("%1$d %o")));
698 }
699 
701 
702 // Plain wrapper for StrFormat.
703 template <typename... Args>
705  const Args&... args) {
706  return StrFormat(format, args...);
707 }
708 
709 TEST_F(FormatWrapperTest, ConstexprStringFormat) {
710  EXPECT_EQ(WrappedFormat("%s there", "hello"), "hello there");
711 }
712 
714  ParsedFormat<'s'> format("%s there");
715  EXPECT_EQ(WrappedFormat(format, "hello"), "hello there");
716 }
717 
718 } // namespace
720 } // namespace absl
721 
722 namespace {
724 
725 struct Point {
729  absl::FormatSink* s) {
730  if (spec.conversion_char() == absl::FormatConversionChar::s) {
731  s->Append(absl::StrCat("x=", p.x, " y=", p.y));
732  } else {
733  s->Append(absl::StrCat(p.x, ",", p.y));
734  }
735  return {true};
736  }
737 
738  int x = 10;
739  int y = 20;
740 };
741 
742 TEST_F(FormatExtensionTest, AbslFormatConvertExample) {
743  Point p;
744  EXPECT_EQ(absl::StrFormat("a %s z", p), "a x=10 y=20 z");
745  EXPECT_EQ(absl::StrFormat("a %d z", p), "a 10,20 z");
746 
747  // Typed formatting will fail to compile an invalid format.
748  // StrFormat("%f", p); // Does not compile.
749  std::string actual;
751  // FormatUntyped will return false for bad character.
753 }
754 } // namespace
755 
756 // Some codegen thunks that we can use to easily dump the generated assembly for
757 // different StrFormat calls.
758 
760  return absl::StrFormat("%d", i);
761 }
762 
764  int64_t i64) { // NOLINT
765  return absl::StrFormat("%d %s %d", i, s, i64);
766 }
767 
769  absl::StrAppendFormat(out, "%d", i);
770 }
771 
773  const std::string& s,
774  int64_t i64) { // NOLINT
775  absl::StrAppendFormat(out, "%d %s %d", i, s, i64);
776 }
absl::StrAppendFormat
std::string & StrAppendFormat(std::string *dst, const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:356
absl::str_format_internal::FormatUntyped
bool FormatUntyped(FormatRawSinkImpl raw_sink, const UntypedFormatSpecImpl format, absl::Span< const FormatArgImpl > args)
Definition: abseil-cpp/absl/strings/internal/str_format/bind.cc:195
xds_interop_client.str
str
Definition: xds_interop_client.py:487
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
Stream
Definition: bm_chttp2_transport.cc:199
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
absl::Cord
Definition: abseil-cpp/absl/strings/cord.h:150
width
int width
Definition: libuv/docs/code/tty-gravity/main.c:10
absl::ABSL_NAMESPACE_BEGIN::TempFile::ReadFile
std::string ReadFile()
Definition: abseil-cpp/absl/strings/str_format_test.cc:262
SEEK_END
#define SEEK_END
Definition: bloaty/third_party/zlib/contrib/minizip/zip.c:84
vsnprintf
int __cdecl vsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
Definition: libc.cpp:135
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
absl::FormatConversionCharSet::kString
@ kString
absl::str_format_internal::FormatArgImpl
Definition: abseil-cpp/absl/strings/internal/str_format/arg.h:312
http2_test_server.format
format
Definition: http2_test_server.py:118
Test
void Test(StringPiece pattern, const RE2::Options &options, StringPiece text)
Definition: bloaty/third_party/re2/re2/fuzzing/re2_fuzzer.cc:20
CodegenAbslStrFormatIntStringInt64
std::string CodegenAbslStrFormatIntStringInt64(int i, const std::string &s, int64_t i64)
Definition: abseil-cpp/absl/strings/str_format_test.cc:763
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
absl::StrFormat
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:338
demumble_test.stdout
stdout
Definition: demumble_test.py:38
absl::str_format_internal::UntypedFormatSpecImpl::Extract
static const UntypedFormatSpecImpl & Extract(const T &s)
Definition: abseil-cpp/absl/strings/internal/str_format/bind.h:69
absl::ABSL_NAMESPACE_BEGIN::TempFile::file_
std::FILE * file_
Definition: abseil-cpp/absl/strings/str_format_test.cc:276
absl::str_format_internal::AbslFormatConvert
void AbslFormatConvert()
xds_manager.f1
f1
Definition: xds_manager.py:42
absl::operator<<
ABSL_NAMESPACE_BEGIN std::ostream & operator<<(std::ostream &os, absl::LogSeverity s)
Definition: abseil-cpp/absl/base/log_severity.cc:24
absl::Span
Definition: abseil-cpp/absl/types/span.h:152
y
const double y
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3611
absl::ABSL_NAMESPACE_BEGIN::SummarizeConsumer::ConvertOne
bool ConvertOne(const str_format_internal::UnboundConversion &conv, string_view s)
Definition: abseil-cpp/absl/strings/str_format_test.cc:458
file_
FileDescriptorProto * file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/annotation_test_util.cc:68
absl::str_format_internal::AppendPack
std::string & AppendPack(std::string *out, const UntypedFormatSpecImpl format, absl::Span< const FormatArgImpl > args)
Definition: abseil-cpp/absl/strings/internal/str_format/bind.cc:208
google::protobuf.internal::true_type
integral_constant< bool, true > true_type
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/template_util.h:89
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
google::protobuf.internal::false_type
integral_constant< bool, false > false_type
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/template_util.h:90
EXPECT_GT
#define EXPECT_GT(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2036
absl::UntypedFormatSpec
Definition: abseil-cpp/absl/strings/str_format.h:96
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
absl::ABSL_NAMESPACE_BEGIN::streamed_test::X
Definition: abseil-cpp/absl/strings/str_format_test.cc:238
New
T * New(Args &&... args)
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:195
absl::str_format_internal::UnboundConversion
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser.h:43
absl::ABSL_NAMESPACE_BEGIN::ParsedFormatTest
::testing::Test ParsedFormatTest
Definition: abseil-cpp/absl/strings/str_format_test.cc:482
absl::str_format_internal::Streamable
Definition: abseil-cpp/absl/strings/internal/str_format/bind.h:176
absl::TEST
TEST(NotificationTest, SanityTest)
Definition: abseil-cpp/absl/synchronization/notification_test.cc:126
absl::FormatConversionChar::s
@ s
CodegenAbslStrFormatInt
std::string CodegenAbslStrFormatInt(int i)
Definition: abseil-cpp/absl/strings/str_format_test.cc:759
xds_manager.p
p
Definition: xds_manager.py:60
absl::ABSL_NAMESPACE_BEGIN::TempFile::TempFile
TempFile()
Definition: abseil-cpp/absl/strings/str_format_test.cc:256
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
run_interop_tests.spec
def spec
Definition: run_interop_tests.py:1394
absl::str_format_internal::FormatSpecTemplate
Definition: abseil-cpp/absl/strings/internal/str_format/bind.h:87
demumble_test.stdin
stdin
Definition: demumble_test.py:37
testing::Test
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:402
CodegenAbslStrAppendFormatInt
void CodegenAbslStrAppendFormatInt(std::string *out, int i)
Definition: abseil-cpp/absl/strings/str_format_test.cc:768
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
absl::ABSL_NAMESPACE_BEGIN::SummarizeParsedFormat
std::string SummarizeParsedFormat(const ParsedFormatBase &pc)
Definition: abseil-cpp/absl/strings/str_format_test.cc:476
route_guide_pb2.Point
Point
Definition: multiplex/route_guide_pb2.py:242
absl::FPrintF
int FPrintF(std::FILE *output, const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:416
absl::ParsedFormat
str_format_internal::ExtendedParsedFormat< absl::str_format_internal::ToFormatConversionCharSet(Conv)... > ParsedFormat
Definition: abseil-cpp/absl/strings/str_format.h:312
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
absl::FormatConversionCharSet::kStar
@ kStar
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
str_format_internal::ParsedFormatBase
hpack_encoder_fixtures::Args
Args({0, 16384})
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
absl::str_format_internal::ParsedFormatBase
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser.h:210
absl::FormatArg
str_format_internal::FormatArgImpl FormatArg
Definition: abseil-cpp/absl/strings/str_format.h:520
absl::FormatConversionCharSet::d
@ d
absl::ABSL_NAMESPACE_BEGIN::WrappedFormat
std::string WrappedFormat(const absl::FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format_test.cc:704
absl::FormatSink
Definition: abseil-cpp/absl/strings/str_format.h:776
conv
const FormatConversionSpecImpl & conv
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:449
absl::FormatConversionCharSet::o
@ o
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
absl::str_format_internal::FormatPack
std::string FormatPack(const UntypedFormatSpecImpl format, absl::Span< const FormatArgImpl > args)
Definition: abseil-cpp/absl/strings/internal/str_format/bind.cc:217
absl::FormatConversionCharSet::g
@ g
absl::FormatConversionSpec
Definition: abseil-cpp/absl/strings/str_format.h:648
absl::FormatUntyped
ABSL_MUST_USE_RESULT bool FormatUntyped(FormatRawSink raw_sink, const UntypedFormatSpec &format, absl::Span< const FormatArg > args)
Definition: abseil-cpp/absl/strings/str_format.h:561
absl::FormatConversionCharSet::kFloating
@ kFloating
close
#define close
Definition: test-fs.c:48
read_bytes
static int read_bytes(int fd, char *buf, size_t read_size, int spin)
Definition: low_level_ping_pong.cc:71
absl::str_format_internal::ExtendedParsedFormat::NewAllowIgnored
static std::unique_ptr< ExtendedParsedFormat > NewAllowIgnored(string_view format)
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser.h:338
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
absl::StreamFormat
ABSL_MUST_USE_RESULT str_format_internal::Streamable StreamFormat(const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:375
buffer
char buffer[1024]
Definition: libuv/docs/code/idle-compute/main.c:8
uintptr_t
_W64 unsigned int uintptr_t
Definition: stdint-msvc2008.h:119
absl::str_format_internal::UntypedFormatSpecImpl
Definition: abseil-cpp/absl/strings/internal/str_format/bind.h:47
absl::ABSL_NAMESPACE_BEGIN::SummarizeConsumer
Definition: abseil-cpp/absl/strings/str_format_test.cc:449
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
absl::ABSL_NAMESPACE_BEGIN::SummarizeConsumer::SummarizeConsumer
SummarizeConsumer(std::string *out)
Definition: abseil-cpp/absl/strings/str_format_test.cc:451
value
const char * value
Definition: hpack_parser_table.cc:165
absl::ABSL_NAMESPACE_BEGIN::TempFile::~TempFile
~TempFile()
Definition: abseil-cpp/absl/strings/str_format_test.cc:257
testing::internal::fmt
GTEST_API_ const char * fmt
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1808
absl::ABSL_NAMESPACE_BEGIN::TempFile
Definition: abseil-cpp/absl/strings/str_format_test.cc:254
absl::ABSL_NAMESPACE_BEGIN::SummarizeConsumer::out
std::string * out
Definition: abseil-cpp/absl/strings/str_format_test.cc:450
benchmark.FILE
FILE
Definition: benchmark.py:21
absl::FormatConvertResult
Definition: abseil-cpp/absl/strings/internal/str_format/arg.h:43
sink
FormatSinkImpl * sink
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:450
absl::ABSL_NAMESPACE_BEGIN::TempFile::file
std::FILE * file() const
Definition: abseil-cpp/absl/strings/str_format_test.cc:259
absl::str_format_internal::FormatConversionCharToChar
char FormatConversionCharToChar(FormatConversionChar c)
Definition: abseil-cpp/absl/strings/internal/str_format/extension.h:247
grpc::fclose
fclose(creds_file)
absl::SNPrintF
int SNPrintF(char *output, std::size_t size, const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:445
absl::FormatStreamed
str_format_internal::StreamedWrapper< T > FormatStreamed(const T &v)
Definition: abseil-cpp/absl/strings/str_format.h:123
absl::str_format_internal::ExtendedParsedFormat
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser.h:310
absl::ABSL_NAMESPACE_BEGIN::WithSnprintf
std::string WithSnprintf(const char *fmt,...)
Definition: abseil-cpp/absl/strings/str_format_test.cc:211
fix_build_deps.r
r
Definition: fix_build_deps.py:491
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
string_view
absl::string_view string_view
Definition: attr.cc:22
EXPECT_LT
#define EXPECT_LT(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2032
absl::FormatCountCapture
Definition: abseil-cpp/absl/strings/str_format.h:143
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1973
ASSERT_FALSE
#define ASSERT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1976
absl::Format
bool Format(FormatRawSink raw_sink, const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:504
arg
struct arg arg
EXPECT_GE
#define EXPECT_GE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2034
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
absl::FormatConversionCharSet::kIntegral
@ kIntegral
absl::FormatConversionCharSet::s
@ s
absl::str_format_internal::ParsedFormatBase::ProcessFormat
bool ProcessFormat(Consumer consumer) const
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser.h:241
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
xds_manager.f2
f2
Definition: xds_manager.py:85
absl::PrintF
int PrintF(const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:396
absl::out
char * out
Definition: abseil-cpp/absl/synchronization/mutex.h:1048
autogen_x86imm.tmp
tmp
Definition: autogen_x86imm.py:12
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
absl::ABSL_NAMESPACE_BEGIN::TEST_F
TEST_F(FormatWrapperTest, ParsedFormat)
Definition: abseil-cpp/absl/strings/str_format_test.cc:713
absl::ABSL_NAMESPACE_BEGIN::SummarizeConsumer::Append
bool Append(string_view s)
Definition: abseil-cpp/absl/strings/str_format_test.cc:453
CodegenAbslStrAppendFormatIntStringInt64
void CodegenAbslStrAppendFormatIntStringInt64(std::string *out, int i, const std::string &s, int64_t i64)
Definition: abseil-cpp/absl/strings/str_format_test.cc:772
to_string
static bool to_string(zval *from)
Definition: protobuf/php/ext/google/protobuf/convert.c:333
absl::ABSL_NAMESPACE_BEGIN::FormatEntryPointTest
::testing::Test FormatEntryPointTest
Definition: abseil-cpp/absl/strings/str_format_test.cc:33
absl::MakeSpan
constexpr Span< T > MakeSpan(T *ptr, size_t size) noexcept
Definition: abseil-cpp/absl/types/span.h:661
absl::str_format_internal::ExtendedParsedFormat::New
static std::unique_ptr< ExtendedParsedFormat > New(string_view format)
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser.h:335
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
absl::FormatConversionCharSet::x
@ x


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:19