2 * Copyright 2014 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 enforce(align == Align::DEFAULT, "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') {
100 precision = to<int>(StringPiece(b, p));
101 if (p != end && *p == '.') {
109 if (p == end) return;
113 if (++p == end) return;
116 error("extra characters in format string");
119 void FormatArg::validate(Type type) const {
120 enforce(keyEmpty(), "index not allowed");
123 enforce(precision == kDefaultPrecision,
124 "precision not allowed on integers");
128 "base prefix ('#') specifier only allowed on integers");
129 enforce(!thousandsSeparator,
130 "thousands separator (',') only allowed on integers");
133 enforce(align != Align::PAD_AFTER_SIGN,
134 "'='alignment only allowed on numbers");
135 enforce(sign == Sign::DEFAULT,
136 "sign specifier only allowed on numbers");
138 "base prefix ('#') specifier only allowed on integers");
139 enforce(!thousandsSeparator,
140 "thousands separator (',') only allowed on integers");