X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=folly%2FFormat.cpp;h=9ad5395e8f04f507c4496c9ed046a26622680148;hb=f805cad2ece30186014139b1a1dc71aa09a352c4;hp=d3a433ab06b51f2fcf6363d6b8fbdbe57638f957;hpb=321542683a01c3f334047531e9b487f047129775;p=folly.git diff --git a/folly/Format.cpp b/folly/Format.cpp index d3a433ab..9ad5395e 100644 --- a/folly/Format.cpp +++ b/folly/Format.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2016 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,9 @@ #include +#include +#include + #include namespace folly { @@ -24,7 +27,7 @@ namespace detail { extern const FormatArg::Align formatAlignTable[]; extern const FormatArg::Sign formatSignTable[]; -} // namespace detail +} // namespace detail using namespace folly::detail; @@ -48,12 +51,14 @@ void FormatValue::formatHelper( } // 2+: for null terminator and optional sign shenanigans. - char buf[2 + std::max( - 2 + DoubleToStringConverter::kMaxFixedDigitsBeforePoint + - DoubleToStringConverter::kMaxFixedDigitsAfterPoint, - std::max(8 + DoubleToStringConverter::kMaxExponentialDigits, - 7 + DoubleToStringConverter::kMaxPrecisionDigits))]; - StringBuilder builder(buf + 1, static_cast (sizeof(buf) - 1)); + constexpr int bufLen = + 2 + constexpr_max( + 2 + DoubleToStringConverter::kMaxFixedDigitsBeforePoint + + DoubleToStringConverter::kMaxFixedDigitsAfterPoint, + constexpr_max(8 + DoubleToStringConverter::kMaxExponentialDigits, + 7 + DoubleToStringConverter::kMaxPrecisionDigits)); + char buf[bufLen]; + StringBuilder builder(buf + 1, bufLen - 1); char plusSign; switch (arg.sign) { @@ -77,6 +82,7 @@ void FormatValue::formatHelper( switch (arg.presentation) { case '%': val *= 100; + FOLLY_FALLTHROUGH; case 'f': case 'F': { @@ -155,7 +161,7 @@ void FormatValue::formatHelper( prefixLen = 1; } - piece = fbstring(p, len); + piece = fbstring(p, size_t(len)); } @@ -164,7 +170,7 @@ void FormatArg::initSlow() { auto end = fullArgString.end(); // Parse key - auto p = static_cast(memchr(b, ':', end - b)); + auto p = static_cast(memchr(b, ':', size_t(end - b))); if (!p) { key_ = StringPiece(b, end); return; @@ -173,7 +179,9 @@ void FormatArg::initSlow() { if (*p == ':') { // parse format spec - if (++p == end) return; + if (++p == end) { + return; + } // fill/align, or just align Align a; @@ -183,67 +191,87 @@ void FormatArg::initSlow() { fill = *p; align = a; p += 2; - if (p == end) return; + if (p == end) { + return; + } } else if ((a = formatAlignTable[static_cast(*p)]) != Align::INVALID) { align = a; - if (++p == end) return; + if (++p == end) { + return; + } } Sign s; unsigned char uSign = static_cast(*p); if ((s = formatSignTable[uSign]) != Sign::INVALID) { sign = s; - if (++p == end) return; + if (++p == end) { + return; + } } if (*p == '#') { basePrefix = true; - if (++p == end) return; + if (++p == end) { + return; + } } if (*p == '0') { enforce(align == Align::DEFAULT, "alignment specified twice"); fill = '0'; align = Align::PAD_AFTER_SIGN; - if (++p == end) return; + if (++p == end) { + return; + } } auto readInt = [&] { - auto const b = p; + auto const c = p; do { ++p; } while (p != end && *p >= '0' && *p <= '9'); - return to(StringPiece(b, p)); + return to(StringPiece(c, p)); }; if (*p == '*') { width = kDynamicWidth; ++p; - if (p == end) return; + if (p == end) { + return; + } - if (*p >= '0' && *p <= '9') widthIndex = readInt(); + if (*p >= '0' && *p <= '9') { + widthIndex = readInt(); + } - if (p == end) return; + if (p == end) { + return; + } } else if (*p >= '0' && *p <= '9') { width = readInt(); - if (p == end) return; + if (p == end) { + return; + } } if (*p == ',') { thousandsSeparator = true; - if (++p == end) return; + if (++p == end) { + return; + } } if (*p == '.') { - auto b = ++p; + auto d = ++p; while (p != end && *p >= '0' && *p <= '9') { ++p; } - if (p != b) { - precision = to(StringPiece(b, p)); + if (p != d) { + precision = to(StringPiece(d, p)); if (p != end && *p == '.') { trailingDot = true; ++p; @@ -252,11 +280,15 @@ void FormatArg::initSlow() { trailingDot = true; } - if (p == end) return; + if (p == end) { + return; + } } presentation = *p; - if (++p == end) return; + if (++p == end) { + return; + } } error("extra characters in format string"); @@ -290,7 +322,7 @@ void FormatArg::validate(Type type) const { namespace detail { void insertThousandsGroupingUnsafe(char* start_buffer, char** end_buffer) { - uint32_t remaining_digits = *end_buffer - start_buffer; + uint32_t remaining_digits = uint32_t(*end_buffer - start_buffer); uint32_t separator_size = (remaining_digits - 1) / 3; uint32_t result_size = remaining_digits + separator_size; *end_buffer = *end_buffer + separator_size; @@ -322,6 +354,17 @@ void insertThousandsGroupingUnsafe(char* start_buffer, char** end_buffer) { remaining_digits -= current_group_size; } } -} // detail +} // namespace detail + +FormatKeyNotFoundException::FormatKeyNotFoundException(StringPiece key) + : std::out_of_range(kMessagePrefix.str() + key.str()) {} + +constexpr StringPiece const FormatKeyNotFoundException::kMessagePrefix; + +namespace detail { +[[noreturn]] void throwFormatKeyNotFoundException(StringPiece key) { + throw FormatKeyNotFoundException(key); +} +} // namespace detail -} // namespace folly +} // namespace folly