libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
printf_frontend_binding_field.hpp
1#pragma once
2
7namespace SourceSyntax
8{
9namespace FieldSelection
10{
20[[nodiscard]] consteval FormatType SelectFormatType(const Conversion& conversion,
21 FormatArgumentRule rule)
22{
23 if (conversion.length == Length::LongDouble)
24 {
25 if (conversion.type == ValueKind::FloatFixed)
26 {
27 return FormatType::LongDoubleFixed;
28 }
29 if (conversion.type == ValueKind::FloatScientific)
30 {
31 return FormatType::LongDoubleScientific;
32 }
33 if (conversion.type == ValueKind::FloatGeneral)
34 {
35 return FormatType::LongDoubleGeneral;
36 }
37 }
38
39 if (conversion.type == ValueKind::Signed)
40 {
41 return RuleUses64BitStorage(rule) ? FormatType::Signed64 : FormatType::Signed32;
42 }
43 if (conversion.type == ValueKind::Unsigned)
44 {
45 return RuleUses64BitStorage(rule) ? FormatType::Unsigned64 : FormatType::Unsigned32;
46 }
47 if (conversion.type == ValueKind::Binary)
48 {
49 return RuleUses64BitStorage(rule) ? FormatType::Binary64 : FormatType::Binary32;
50 }
51 if (conversion.type == ValueKind::Octal)
52 {
53 return RuleUses64BitStorage(rule) ? FormatType::Octal64 : FormatType::Octal32;
54 }
55 if (conversion.type == ValueKind::HexLower)
56 {
57 return RuleUses64BitStorage(rule) ? FormatType::HexLower64 : FormatType::HexLower32;
58 }
59 if (conversion.type == ValueKind::HexUpper)
60 {
61 return RuleUses64BitStorage(rule) ? FormatType::HexUpper64 : FormatType::HexUpper32;
62 }
63
64 switch (conversion.type)
65 {
66 case ValueKind::Pointer:
67 return FormatType::Pointer;
68 case ValueKind::Character:
69 return FormatType::Character;
70 case ValueKind::String:
71 return FormatType::String;
72 case ValueKind::FloatFixed:
73 return UsesDoubleFloatStorage() ? FormatType::DoubleFixed : FormatType::FloatFixed;
74 case ValueKind::FloatScientific:
75 return UsesDoubleFloatStorage() ? FormatType::DoubleScientific
76 : FormatType::FloatScientific;
77 case ValueKind::FloatGeneral:
78 return UsesDoubleFloatStorage() ? FormatType::DoubleGeneral
79 : FormatType::FloatGeneral;
80 case ValueKind::None:
81 case ValueKind::Signed:
82 case ValueKind::Unsigned:
83 case ValueKind::Binary:
84 case ValueKind::Octal:
85 case ValueKind::HexLower:
86 case ValueKind::HexUpper:
87 return FormatType::End;
88 }
89
90 return FormatType::End;
91}
92
98inline void InvalidPackKindType() noexcept {}
99
107[[nodiscard]] consteval FormatPackKind SelectPackKind(FormatType type)
108{
109 switch (type)
110 {
111 case FormatType::Signed32:
112 return FormatPackKind::I32;
113 case FormatType::Signed64:
114 return FormatPackKind::I64;
115 case FormatType::Unsigned32:
116 case FormatType::Binary32:
117 case FormatType::Octal32:
118 case FormatType::HexLower32:
119 case FormatType::HexUpper32:
120 return FormatPackKind::U32;
121 case FormatType::Unsigned64:
122 case FormatType::Binary64:
123 case FormatType::Octal64:
124 case FormatType::HexLower64:
125 case FormatType::HexUpper64:
126 return FormatPackKind::U64;
127 case FormatType::Pointer:
128 return FormatPackKind::Pointer;
129 case FormatType::Character:
130 return FormatPackKind::Character;
131 case FormatType::String:
132 return FormatPackKind::StringView;
133 case FormatType::FloatFixed:
134 case FormatType::FloatScientific:
135 case FormatType::FloatGeneral:
136 return FormatPackKind::F32;
137 case FormatType::DoubleFixed:
138 case FormatType::DoubleScientific:
139 case FormatType::DoubleGeneral:
140 return FormatPackKind::F64;
141 case FormatType::LongDoubleFixed:
142 case FormatType::LongDoubleScientific:
143 case FormatType::LongDoubleGeneral:
144 return FormatPackKind::LongDouble;
145 case FormatType::End:
146 case FormatType::TextInline:
147 case FormatType::TextRef:
148 case FormatType::TextSpace:
149 InvalidPackKindType();
150 return FormatPackKind::U32;
151 }
152
153 InvalidPackKindType();
154 return FormatPackKind::U32;
155}
156
164[[nodiscard]] consteval FormatArgumentRule SelectArgumentRule(
165 const Conversion& conversion)
166{
167 if (conversion.type == ValueKind::Signed)
168 {
169 return RuleFromTable(signed_rules, conversion.length);
170 }
171
172 if (IsUnsignedType(conversion.type))
173 {
174 return RuleFromTable(unsigned_rules, conversion.length);
175 }
176
177 switch (conversion.type)
178 {
179 case ValueKind::Pointer:
180 return FormatArgumentRule::Pointer;
181 case ValueKind::Character:
182 return FormatArgumentRule::Character;
183 case ValueKind::String:
184 return FormatArgumentRule::String;
185 case ValueKind::FloatFixed:
186 case ValueKind::FloatScientific:
187 case ValueKind::FloatGeneral:
188 return (conversion.length == Length::LongDouble) ? FormatArgumentRule::LongDouble
189 : FormatArgumentRule::Float;
190 case ValueKind::None:
191 case ValueKind::Signed:
192 case ValueKind::Unsigned:
193 case ValueKind::Binary:
194 case ValueKind::Octal:
195 case ValueKind::HexLower:
196 case ValueKind::HexUpper:
197 break;
198 }
199
200 return FormatArgumentRule::None;
201}
202
211[[nodiscard]] consteval Error ValidateConversion(const Conversion& conversion)
212{
213 if ((conversion.type == ValueKind::FloatFixed ||
214 conversion.type == ValueKind::FloatScientific ||
215 conversion.type == ValueKind::FloatGeneral) &&
216 conversion.has_precision && conversion.precision > Config::max_float_precision)
217 {
218 return Error::FloatPrecisionLimitExceeded;
219 }
220
221 if ((conversion.type == ValueKind::Signed || IsUnsignedType(conversion.type)) &&
222 RuleUses64BitStorage(SelectArgumentRule(conversion)) &&
223 !Config::enable_integer_64bit)
224 {
225 return Error::InvalidLength;
226 }
227
228 return Error::None;
229}
230
238[[nodiscard]] consteval FormatField BuildFormatField(const Conversion& conversion)
239{
240 auto rule = SelectArgumentRule(conversion);
241 auto type = SelectFormatType(conversion, rule);
242 return FormatField{
243 .type = type,
244 .pack = SelectPackKind(type),
245 .rule = rule,
246 .flags = conversion.FlagsByte(),
247 .width = conversion.width,
248 .precision = conversion.PrecisionByte(),
249 };
250}
251} // namespace FieldSelection
252} // namespace SourceSyntax
Error
brace 风格 format 前端的编译期失败类别 / Compile-time failure categories for the brace-style format frontend.
printf 降级阶段共享的描述表与策略辅助函数 / Shared descriptor-table and policy helpers for printf lowering
单个 printf 转换在降为共享格式前的解析结果 / One parsed printf conversion before lowering into the shared format
ValueKind type
转换项归一化后的语义类别 / semantic conversion category
constexpr uint8_t FlagsByte() const
将前端解析出的标志位打包成共享的 FormatFlag 字节 / Pack the parsed frontend flags into the shared FormatFlag byte
Length length
已解析的长度修饰符 / parsed length modifier
uint8_t width
已解析的字段宽度 / parsed field width
constexpr uint8_t PrecisionByte() const
返回共享精度字节;若未显式指定精度则为 0xFF / Return the shared precision byte, or 0xFF when precision is absent
uint8_t precision
已解析的精度值 / parsed precision value
bool has_precision
是否显式提供了精度 / whether precision was explicitly provided