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 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') {
99 precision = to<int>(StringPiece(b, p));
101 if (p == end) return;
105 if (++p == end) return;
108 error("extra characters in format string");
111 void FormatArg::validate(Type type) const {
112 enforce(keyEmpty(), "index not allowed");
115 enforce(precision == kDefaultPrecision,
116 "precision not allowed on integers");
120 "base prefix ('#') specifier only allowed on integers");
121 enforce(!thousandsSeparator,
122 "thousands separator (',') only allowed on integers");
125 enforce(align != Align::PAD_AFTER_SIGN,
126 "'='alignment only allowed on numbers");
127 enforce(sign == Sign::DEFAULT,
128 "sign specifier only allowed on numbers");
130 "base prefix ('#') specifier only allowed on integers");
131 enforce(!thousandsSeparator,
132 "thousands separator (',') only allowed on integers");