Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 138 lines (116 sloc) 3.495 kB
27494a2 @jdelong Pull from FB rev 63ce89e2f2301e6bba44a111cc7d4218022156f6
jdelong authored
1 /*
2 * Copyright 2012 Facebook, Inc.
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17 #include "folly/Format.h"
18
19 namespace folly {
20 namespace detail {
21
22 extern const FormatArg::Align formatAlignTable[];
23 extern const FormatArg::Sign formatSignTable[];
24
25 } // namespace detail
26
27 using namespace folly::detail;
28
29 void FormatArg::initSlow() {
30 auto b = fullArgString.begin();
31 auto end = fullArgString.end();
32
33 // Parse key
34 auto p = static_cast<const char*>(memchr(b, ':', end - b));
35 if (!p) {
36 key_ = StringPiece(b, end);
37 return;
38 }
39 key_ = StringPiece(b, p);
40
41 if (*p == ':') {
42 // parse format spec
43 if (++p == end) return;
44
45 // fill/align, or just align
46 Align a;
47 if (p + 1 != end &&
48 (a = formatAlignTable[static_cast<unsigned char>(p[1])]) !=
49 Align::INVALID) {
50 fill = *p;
51 align = a;
52 p += 2;
53 if (p == end) return;
54 } else if ((a = formatAlignTable[static_cast<unsigned char>(*p)]) !=
55 Align::INVALID) {
56 align = a;
57 if (++p == end) return;
58 }
59
60 Sign s;
61 unsigned char uSign = static_cast<unsigned char>(*p);
62 if ((s = formatSignTable[uSign]) != Sign::INVALID) {
63 sign = s;
64 if (++p == end) return;
65 }
66
67 if (*p == '#') {
68 basePrefix = true;
69 if (++p == end) return;
70 }
71
72 if (*p == '0') {
73 enforce(align == Align::DEFAULT, "alignment specified twice");
74 fill = '0';
75 align = Align::PAD_AFTER_SIGN;
76 if (++p == end) return;
77 }
78
79 if (*p >= '0' && *p <= '9') {
80 auto b = p;
81 do {
82 ++p;
83 } while (p != end && *p >= '0' && *p <= '9');
84 width = to<int>(StringPiece(b, p));
85
86 if (p == end) return;
87 }
88
89 if (*p == ',') {
90 thousandsSeparator = true;
91 if (++p == end) return;
92 }
93
94 if (*p == '.') {
95 auto b = ++p;
96 while (p != end && *p >= '0' && *p <= '9') {
97 ++p;
98 }
99 precision = to<int>(StringPiece(b, p));
100
101 if (p == end) return;
102 }
103
104 presentation = *p;
105 if (++p == end) return;
106 }
107
108 error("extra characters in format string");
109 }
110
111 void FormatArg::validate(Type type) const {
112 enforce(keyEmpty(), "index not allowed");
113 switch (type) {
114 case Type::INTEGER:
115 enforce(precision == kDefaultPrecision,
116 "precision not allowed on integers");
117 break;
118 case Type::FLOAT:
119 enforce(!basePrefix,
120 "base prefix ('#') specifier only allowed on integers");
121 enforce(!thousandsSeparator,
122 "thousands separator (',') only allowed on integers");
123 break;
124 case Type::OTHER:
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");
129 enforce(!basePrefix,
130 "base prefix ('#') specifier only allowed on integers");
131 enforce(!thousandsSeparator,
132 "thousands separator (',') only allowed on integers");
133 break;
134 }
135 }
136
137 } // namespace folly
Something went wrong with that request. Please try again.