about summary refs log tree commit diff
path: root/absl/strings
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings')
-rw-r--r--absl/strings/internal/str_format/arg.cc36
-rw-r--r--absl/strings/internal/str_format/arg.h2
-rw-r--r--absl/strings/internal/str_format/arg_test.cc4
-rw-r--r--absl/strings/internal/str_format/checker_test.cc8
-rw-r--r--absl/strings/internal/str_format/extension.cc15
-rw-r--r--absl/strings/internal/str_format/extension.h80
-rw-r--r--absl/strings/str_format.h4
-rw-r--r--absl/strings/str_format_test.cc97
8 files changed, 92 insertions, 154 deletions
diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc
index 02646addec11..9feb22487932 100644
--- a/absl/strings/internal/str_format/arg.cc
+++ b/absl/strings/internal/str_format/arg.cc
@@ -267,38 +267,42 @@ bool ConvertIntArg(T v, const FormatConversionSpecImpl conv,
   using U = typename MakeUnsigned<T>::type;
   IntDigits as_digits;
 
-  switch (conv.conversion_char()) {
-    case FormatConversionCharInternal::c:
+  // This odd casting is due to a bug in -Wswitch behavior in gcc49 which causes
+  // it to complain about a switch/case type mismatch, even though both are
+  // FormatConverionChar.  Likely this is because at this point
+  // FormatConversionChar is declared, but not defined.
+  switch (static_cast<uint8_t>(conv.conversion_char())) {
+    case static_cast<uint8_t>(FormatConversionCharInternal::c):
       return ConvertCharImpl(static_cast<unsigned char>(v), conv, sink);
 
-    case FormatConversionCharInternal::o:
+    case static_cast<uint8_t>(FormatConversionCharInternal::o):
       as_digits.PrintAsOct(static_cast<U>(v));
       break;
 
-    case FormatConversionCharInternal::x:
+    case static_cast<uint8_t>(FormatConversionCharInternal::x):
       as_digits.PrintAsHexLower(static_cast<U>(v));
       break;
-    case FormatConversionCharInternal::X:
+    case static_cast<uint8_t>(FormatConversionCharInternal::X):
       as_digits.PrintAsHexUpper(static_cast<U>(v));
       break;
 
-    case FormatConversionCharInternal::u:
+    case static_cast<uint8_t>(FormatConversionCharInternal::u):
       as_digits.PrintAsDec(static_cast<U>(v));
       break;
 
-    case FormatConversionCharInternal::d:
-    case FormatConversionCharInternal::i:
+    case static_cast<uint8_t>(FormatConversionCharInternal::d):
+    case static_cast<uint8_t>(FormatConversionCharInternal::i):
       as_digits.PrintAsDec(v);
       break;
 
-    case FormatConversionCharInternal::a:
-    case FormatConversionCharInternal::e:
-    case FormatConversionCharInternal::f:
-    case FormatConversionCharInternal::g:
-    case FormatConversionCharInternal::A:
-    case FormatConversionCharInternal::E:
-    case FormatConversionCharInternal::F:
-    case FormatConversionCharInternal::G:
+    case static_cast<uint8_t>(FormatConversionCharInternal::a):
+    case static_cast<uint8_t>(FormatConversionCharInternal::e):
+    case static_cast<uint8_t>(FormatConversionCharInternal::f):
+    case static_cast<uint8_t>(FormatConversionCharInternal::g):
+    case static_cast<uint8_t>(FormatConversionCharInternal::A):
+    case static_cast<uint8_t>(FormatConversionCharInternal::E):
+    case static_cast<uint8_t>(FormatConversionCharInternal::F):
+    case static_cast<uint8_t>(FormatConversionCharInternal::G):
       return ConvertFloatImpl(static_cast<double>(v), conv, sink);
 
     default:
diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h
index 8f79948bd91c..d441e87fff33 100644
--- a/absl/strings/internal/str_format/arg.h
+++ b/absl/strings/internal/str_format/arg.h
@@ -27,6 +27,8 @@ class FormatSink;
 
 namespace str_format_internal {
 
+class FormatConversionSpec;
+
 template <typename T, typename = void>
 struct HasUserDefinedConvert : std::false_type {};
 
diff --git a/absl/strings/internal/str_format/arg_test.cc b/absl/strings/internal/str_format/arg_test.cc
index 37e5b7545f84..bf3d7e8e3777 100644
--- a/absl/strings/internal/str_format/arg_test.cc
+++ b/absl/strings/internal/str_format/arg_test.cc
@@ -96,8 +96,8 @@ TEST_F(FormatArgImplTest, WorksWithCharArraysOfUnknownSize) {
   std::string s;
   FormatSinkImpl sink(&s);
   FormatConversionSpecImpl conv;
-  FormatConversionSpecImplFriend::SetConversionChar(FormatConversionChar::s,
-                                                    &conv);
+  FormatConversionSpecImplFriend::SetConversionChar(
+      FormatConversionCharInternal::s, &conv);
   FormatConversionSpecImplFriend::SetFlags(Flags(), &conv);
   FormatConversionSpecImplFriend::SetWidth(-1, &conv);
   FormatConversionSpecImplFriend::SetPrecision(-1, &conv);
diff --git a/absl/strings/internal/str_format/checker_test.cc b/absl/strings/internal/str_format/checker_test.cc
index 233481747bfd..a76d70b0586c 100644
--- a/absl/strings/internal/str_format/checker_test.cc
+++ b/absl/strings/internal/str_format/checker_test.cc
@@ -11,13 +11,13 @@ namespace {
 
 std::string ConvToString(FormatConversionCharSet conv) {
   std::string out;
-#define CONV_SET_CASE(c) \
-  if (Contains(conv, FormatConversionCharSet::c)) { \
-    out += #c; \
+#define CONV_SET_CASE(c)                                    \
+  if (Contains(conv, FormatConversionCharSetInternal::c)) { \
+    out += #c;                                              \
   }
   ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(CONV_SET_CASE, )
 #undef CONV_SET_CASE
-  if (Contains(conv, FormatConversionCharSet::kStar)) {
+  if (Contains(conv, FormatConversionCharSetInternal::kStar)) {
     out += "*";
   }
   return out;
diff --git a/absl/strings/internal/str_format/extension.cc b/absl/strings/internal/str_format/extension.cc
index 2e5bc2ce0be0..94f2b9c209aa 100644
--- a/absl/strings/internal/str_format/extension.cc
+++ b/absl/strings/internal/str_format/extension.cc
@@ -33,16 +33,17 @@ std::string Flags::ToString() const {
   return s;
 }
 
-bool FormatSinkImpl::PutPaddedString(string_view v, int w, int p, bool l) {
+bool FormatSinkImpl::PutPaddedString(string_view value, int width,
+                                     int precision, bool left) {
   size_t space_remaining = 0;
-  if (w >= 0) space_remaining = w;
-  size_t n = v.size();
-  if (p >= 0) n = std::min(n, static_cast<size_t>(p));
-  string_view shown(v.data(), n);
+  if (width >= 0) space_remaining = width;
+  size_t n = value.size();
+  if (precision >= 0) n = std::min(n, static_cast<size_t>(precision));
+  string_view shown(value.data(), n);
   space_remaining = Excess(shown.size(), space_remaining);
-  if (!l) Append(space_remaining, ' ');
+  if (!left) Append(space_remaining, ' ');
   Append(shown);
-  if (l) Append(space_remaining, ' ');
+  if (left) Append(space_remaining, ' ');
   return true;
 }
 
diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h
index 36e70646d7d1..6c60c6c3a379 100644
--- a/absl/strings/internal/str_format/extension.h
+++ b/absl/strings/internal/str_format/extension.h
@@ -32,8 +32,9 @@ namespace absl {
 ABSL_NAMESPACE_BEGIN
 
 namespace str_format_internal {
-enum class FormatConversionCharSet : uint64_t;
+
 enum class FormatConversionChar : uint8_t;
+enum class FormatConversionCharSet : uint64_t;
 
 class FormatRawSinkImpl {
  public:
@@ -106,7 +107,7 @@ class FormatSinkImpl {
   size_t size() const { return size_; }
 
   // Put 'v' to 'sink' with specified width, precision, and left flag.
-  bool PutPaddedString(string_view v, int w, int p, bool l);
+  bool PutPaddedString(string_view v, int width, int precision, bool left);
 
   template <typename T>
   T Wrap() {
@@ -420,81 +421,6 @@ inline size_t Excess(size_t used, size_t capacity) {
   return used < capacity ? capacity - used : 0;
 }
 
-class FormatConversionSpec {
- public:
-  // Width and precison are not specified, no flags are set.
-  bool is_basic() const { return impl_.is_basic(); }
-  bool has_left_flag() const { return impl_.has_left_flag(); }
-  bool has_show_pos_flag() const { return impl_.has_show_pos_flag(); }
-  bool has_sign_col_flag() const { return impl_.has_sign_col_flag(); }
-  bool has_alt_flag() const { return impl_.has_alt_flag(); }
-  bool has_zero_flag() const { return impl_.has_zero_flag(); }
-
-  FormatConversionChar conversion_char() const {
-    return impl_.conversion_char();
-  }
-
-  // Returns the specified width. If width is unspecfied, it returns a negative
-  // value.
-  int width() const { return impl_.width(); }
-  // Returns the specified precision. If precision is unspecfied, it returns a
-  // negative value.
-  int precision() const { return impl_.precision(); }
-
- private:
-  explicit FormatConversionSpec(
-      str_format_internal::FormatConversionSpecImpl impl)
-      : impl_(impl) {}
-
-  friend str_format_internal::FormatConversionSpecImpl;
-
-  absl::str_format_internal::FormatConversionSpecImpl impl_;
-};
-
-// clang-format off
-enum class FormatConversionChar : uint8_t {
-  c, s,                    // text
-  d, i, o, u, x, X,        // int
-  f, F, e, E, g, G, a, A,  // float
-  n, p                     // misc
-};
-// clang-format on
-
-enum class FormatConversionCharSet : uint64_t {
-  // text
-  c = str_format_internal::FormatConversionCharToConvInt('c'),
-  s = str_format_internal::FormatConversionCharToConvInt('s'),
-  // integer
-  d = str_format_internal::FormatConversionCharToConvInt('d'),
-  i = str_format_internal::FormatConversionCharToConvInt('i'),
-  o = str_format_internal::FormatConversionCharToConvInt('o'),
-  u = str_format_internal::FormatConversionCharToConvInt('u'),
-  x = str_format_internal::FormatConversionCharToConvInt('x'),
-  X = str_format_internal::FormatConversionCharToConvInt('X'),
-  // Float
-  f = str_format_internal::FormatConversionCharToConvInt('f'),
-  F = str_format_internal::FormatConversionCharToConvInt('F'),
-  e = str_format_internal::FormatConversionCharToConvInt('e'),
-  E = str_format_internal::FormatConversionCharToConvInt('E'),
-  g = str_format_internal::FormatConversionCharToConvInt('g'),
-  G = str_format_internal::FormatConversionCharToConvInt('G'),
-  a = str_format_internal::FormatConversionCharToConvInt('a'),
-  A = str_format_internal::FormatConversionCharToConvInt('A'),
-  // misc
-  n = str_format_internal::FormatConversionCharToConvInt('n'),
-  p = str_format_internal::FormatConversionCharToConvInt('p'),
-
-  // Used for width/precision '*' specification.
-  kStar = str_format_internal::FormatConversionCharToConvInt('*'),
-
-  // Some predefined values:
-  kIntegral = d | i | u | o | x | X,
-  kFloating = a | e | f | g | A | E | F | G,
-  kNumeric = kIntegral | kFloating,
-  kString = s,
-  kPointer = p,
-};
-
 }  // namespace str_format_internal
 
 ABSL_NAMESPACE_END
diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h
index f48510b45b3b..f833a80aba63 100644
--- a/absl/strings/str_format.h
+++ b/absl/strings/str_format.h
@@ -63,10 +63,6 @@
 //     loosely typed. `FormatUntyped()` is not a template and does not perform
 //     any compile-time checking of the format string; instead, it returns a
 //     boolean from a runtime check.
-//
-// In addition, the `str_format` library provides extension points for
-// augmenting formatting to new types. These extensions are fully documented
-// within the `str_format_extension.h` header file.
 
 #ifndef ABSL_STRINGS_STR_FORMAT_H_
 #define ABSL_STRINGS_STR_FORMAT_H_
diff --git a/absl/strings/str_format_test.cc b/absl/strings/str_format_test.cc
index 3f14dba3e352..49a68849f064 100644
--- a/absl/strings/str_format_test.cc
+++ b/absl/strings/str_format_test.cc
@@ -1,4 +1,6 @@
 
+#include "absl/strings/str_format.h"
+
 #include <cstdarg>
 #include <cstdint>
 #include <cstdio>
@@ -6,13 +8,14 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/strings/str_format.h"
+#include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 namespace {
 using str_format_internal::FormatArgImpl;
+using str_format_internal::FormatConversionCharSetInternal;
 
 using FormatEntryPointTest = ::testing::Test;
 
@@ -535,100 +538,106 @@ TEST_F(ParsedFormatTest, SimpleUncheckedIncorrect) {
 using absl::str_format_internal::FormatConversionCharSet;
 
 TEST_F(ParsedFormatTest, UncheckedCorrect) {
-  auto f = ExtendedParsedFormat<FormatConversionCharSet::d>::New("ABC%dDEF");
+  auto f =
+      ExtendedParsedFormat<FormatConversionCharSetInternal::d>::New("ABC%dDEF");
   ASSERT_TRUE(f);
   EXPECT_EQ("[ABC]{d:1$d}[DEF]", SummarizeParsedFormat(*f));
 
   std::string format = "%sFFF%dZZZ%f";
-  auto f2 =
-      ExtendedParsedFormat<FormatConversionCharSet::kString,
-                           FormatConversionCharSet::d,
-                           FormatConversionCharSet::kFloating>::New(format);
+  auto f2 = ExtendedParsedFormat<
+      FormatConversionCharSetInternal::kString,
+      FormatConversionCharSetInternal::d,
+      FormatConversionCharSetInternal::kFloating>::New(format);
 
   ASSERT_TRUE(f2);
   EXPECT_EQ("{s:1$s}[FFF]{d:2$d}[ZZZ]{f:3$f}", SummarizeParsedFormat(*f2));
 
-  f2 =
-      ExtendedParsedFormat<FormatConversionCharSet::kString,
-                           FormatConversionCharSet::d,
-                           FormatConversionCharSet::kFloating>::New("%s %d %f");
+  f2 = ExtendedParsedFormat<
+      FormatConversionCharSetInternal::kString,
+      FormatConversionCharSetInternal::d,
+      FormatConversionCharSetInternal::kFloating>::New("%s %d %f");
 
   ASSERT_TRUE(f2);
   EXPECT_EQ("{s:1$s}[ ]{d:2$d}[ ]{f:3$f}", SummarizeParsedFormat(*f2));
 
-  auto star = ExtendedParsedFormat<FormatConversionCharSet::kStar,
-                                   FormatConversionCharSet::d>::New("%*d");
+  auto star =
+      ExtendedParsedFormat<FormatConversionCharSetInternal::kStar,
+                           FormatConversionCharSetInternal::d>::New("%*d");
   ASSERT_TRUE(star);
   EXPECT_EQ("{*d:2$1$*d}", SummarizeParsedFormat(*star));
 
-  auto dollar =
-      ExtendedParsedFormat<FormatConversionCharSet::d,
-                           FormatConversionCharSet::s>::New("%2$s %1$d");
+  auto dollar = ExtendedParsedFormat<
+      FormatConversionCharSetInternal::d,
+      FormatConversionCharSetInternal::s>::New("%2$s %1$d");
   ASSERT_TRUE(dollar);
   EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}", SummarizeParsedFormat(*dollar));
   // with reuse
-  dollar =
-      ExtendedParsedFormat<FormatConversionCharSet::d,
-                           FormatConversionCharSet::s>::New("%2$s %1$d %1$d");
+  dollar = ExtendedParsedFormat<
+      FormatConversionCharSetInternal::d,
+      FormatConversionCharSetInternal::s>::New("%2$s %1$d %1$d");
   ASSERT_TRUE(dollar);
   EXPECT_EQ("{2$s:2$s}[ ]{1$d:1$d}[ ]{1$d:1$d}",
             SummarizeParsedFormat(*dollar));
 }
 
 TEST_F(ParsedFormatTest, UncheckedIgnoredArgs) {
-  EXPECT_FALSE((ExtendedParsedFormat<FormatConversionCharSet::d,
-                                     FormatConversionCharSet::s>::New("ABC")));
   EXPECT_FALSE(
-      (ExtendedParsedFormat<FormatConversionCharSet::d,
-                            FormatConversionCharSet::s>::New("%dABC")));
+      (ExtendedParsedFormat<FormatConversionCharSetInternal::d,
+                            FormatConversionCharSetInternal::s>::New("ABC")));
   EXPECT_FALSE(
-      (ExtendedParsedFormat<FormatConversionCharSet::d,
-                            FormatConversionCharSet::s>::New("ABC%2$s")));
-  auto f =
-      ExtendedParsedFormat<FormatConversionCharSet::d,
-                           FormatConversionCharSet::s>::NewAllowIgnored("ABC");
+      (ExtendedParsedFormat<FormatConversionCharSetInternal::d,
+                            FormatConversionCharSetInternal::s>::New("%dABC")));
+  EXPECT_FALSE((ExtendedParsedFormat<
+                FormatConversionCharSetInternal::d,
+                FormatConversionCharSetInternal::s>::New("ABC%2$s")));
+  auto f = ExtendedParsedFormat<
+      FormatConversionCharSetInternal::d,
+      FormatConversionCharSetInternal::s>::NewAllowIgnored("ABC");
   ASSERT_TRUE(f);
   EXPECT_EQ("[ABC]", SummarizeParsedFormat(*f));
   f = ExtendedParsedFormat<
-      FormatConversionCharSet::d,
-      FormatConversionCharSet::s>::NewAllowIgnored("%dABC");
+      FormatConversionCharSetInternal::d,
+      FormatConversionCharSetInternal::s>::NewAllowIgnored("%dABC");
   ASSERT_TRUE(f);
   EXPECT_EQ("{d:1$d}[ABC]", SummarizeParsedFormat(*f));
   f = ExtendedParsedFormat<
-      FormatConversionCharSet::d,
-      FormatConversionCharSet::s>::NewAllowIgnored("ABC%2$s");
+      FormatConversionCharSetInternal::d,
+      FormatConversionCharSetInternal::s>::NewAllowIgnored("ABC%2$s");
   ASSERT_TRUE(f);
   EXPECT_EQ("[ABC]{2$s:2$s}", SummarizeParsedFormat(*f));
 }
 
 TEST_F(ParsedFormatTest, UncheckedMultipleTypes) {
-  auto dx = ExtendedParsedFormat<FormatConversionCharSet::d |
-                                 FormatConversionCharSet::x>::New("%1$d %1$x");
+  auto dx = ExtendedParsedFormat<
+      FormatConversionCharSetInternal::d |
+      FormatConversionCharSetInternal::x>::New("%1$d %1$x");
   EXPECT_TRUE(dx);
   EXPECT_EQ("{1$d:1$d}[ ]{1$x:1$x}", SummarizeParsedFormat(*dx));
 
-  dx = ExtendedParsedFormat<FormatConversionCharSet::d |
-                            FormatConversionCharSet::x>::New("%1$d");
+  dx = ExtendedParsedFormat<FormatConversionCharSetInternal::d |
+                            FormatConversionCharSetInternal::x>::New("%1$d");
   EXPECT_TRUE(dx);
   EXPECT_EQ("{1$d:1$d}", SummarizeParsedFormat(*dx));
 }
 
 TEST_F(ParsedFormatTest, UncheckedIncorrect) {
-  EXPECT_FALSE(ExtendedParsedFormat<FormatConversionCharSet::d>::New(""));
-
   EXPECT_FALSE(
-      ExtendedParsedFormat<FormatConversionCharSet::d>::New("ABC%dDEF%d"));
+      ExtendedParsedFormat<FormatConversionCharSetInternal::d>::New(""));
+
+  EXPECT_FALSE(ExtendedParsedFormat<FormatConversionCharSetInternal::d>::New(
+      "ABC%dDEF%d"));
 
   std::string format = "%sFFF%dZZZ%f";
-  EXPECT_FALSE((ExtendedParsedFormat<FormatConversionCharSet::s,
-                                     FormatConversionCharSet::d,
-                                     FormatConversionCharSet::g>::New(format)));
+  EXPECT_FALSE(
+      (ExtendedParsedFormat<FormatConversionCharSetInternal::s,
+                            FormatConversionCharSetInternal::d,
+                            FormatConversionCharSetInternal::g>::New(format)));
 }
 
 TEST_F(ParsedFormatTest, RegressionMixPositional) {
-  EXPECT_FALSE(
-      (ExtendedParsedFormat<FormatConversionCharSet::d,
-                            FormatConversionCharSet::o>::New("%1$d %o")));
+  EXPECT_FALSE((ExtendedParsedFormat<
+                FormatConversionCharSetInternal::d,
+                FormatConversionCharSetInternal::o>::New("%1$d %o")));
 }
 
 using FormatWrapperTest = ::testing::Test;