2 * Copyright 2013 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "folly/Format.h"
22 extern const FormatArg::Align formatAlignTable[];
23 extern const FormatArg::Sign formatSignTable[];
27 using namespace folly::detail;
29 void FormatArg::initSlow() {
30 auto b = fullArgString.begin();
31 auto end = fullArgString.end();
34 auto p = static_cast<const char*>(memchr(b, ':', end - b));
36 key_ = StringPiece(b, end);
39 key_ = StringPiece(b, p);
43 if (++p == end) return;
45 // fill/align, or just align
48 (a = formatAlignTable[static_cast<unsigned char>(p[1])]) !=
54 } else if ((a = formatAlignTable[static_cast<unsigned char>(*p)]) !=
57 if (++p == end) return;
61 unsigned char uSign = static_cast<unsigned char>(*p);
62 if ((s = formatSignTable[uSign]) != Sign::INVALID) {
64 if (++p == end) return;
69 if (++p == end) return;
73 CHECK(align == Align::DEFAULT) << errorStr("alignment specified twice");
75 align = Align::PAD_AFTER_SIGN;
76 if (++p == end) return;
79 if (*p >= '0' && *p <= '9') {
83 } while (p != end && *p >= '0' && *p <= '9');
84 width = to<int>(StringPiece(b, p));
90 thousandsSeparator = true;
91 if (++p == end) return;
96 while (p != end && *p >= '0' && *p <= '9') {
99 precision = to<int>(StringPiece(b, p));
101 if (p == end) return;
105 if (++p == end) return;
108 LOG(FATAL) << "extra characters in format string";
111 void FormatArg::validate(Type type) const {
112 CHECK(keyEmpty()) << "index not allowed";
115 CHECK(precision == kDefaultPrecision)
116 << errorStr("precision not allowed on integers");
120 << errorStr("base prefix ('#') specifier only allowed on integers");
121 CHECK(!thousandsSeparator)
122 << errorStr("thousands separator (',') only allowed on integers");
125 CHECK(align != Align::PAD_AFTER_SIGN)
126 << errorStr("'='alignment only allowed on numbers");
127 CHECK(sign == Sign::DEFAULT)
128 << errorStr("sign specifier only allowed on numbers");
130 << errorStr("base prefix ('#') specifier only allowed on integers");
131 CHECK(!thousandsSeparator)
132 << errorStr("thousands separator (',') only allowed on integers");