libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
printf_frontend_spec.hpp
1#pragma once
2
12enum class ValueKind : uint8_t
13{
14 None,
15 Signed,
16 Unsigned,
17 Binary,
18 Octal,
19 HexLower,
20 HexUpper,
21 Pointer,
22 Character,
23 String,
24 FloatFixed,
25 FloatScientific,
26 FloatGeneral,
27};
28
33{
34 size_t arg_index = 0;
35 ValueKind type = ValueKind::None;
36 Length length = Length::Default;
37 bool left_align = false;
38 bool force_sign = false;
39 bool space_sign = false;
40 bool alternate = false;
41 bool zero_pad = false;
42 bool upper_case = false;
43 bool positional = false;
44 uint8_t width = 0;
45 bool has_precision = false;
46 uint8_t precision = 0;
47
52 [[nodiscard]] constexpr uint8_t FlagsByte() const
53 {
54 uint8_t flags = 0;
55 if (left_align)
56 {
57 flags |= static_cast<uint8_t>(FormatFlag::LeftAlign);
58 }
59 if (force_sign)
60 {
61 flags |= static_cast<uint8_t>(FormatFlag::ForceSign);
62 }
63 if (space_sign)
64 {
65 flags |= static_cast<uint8_t>(FormatFlag::SpaceSign);
66 }
67 if (alternate)
68 {
69 flags |= static_cast<uint8_t>(FormatFlag::Alternate);
70 }
71 if (zero_pad)
72 {
73 flags |= static_cast<uint8_t>(FormatFlag::ZeroPad);
74 }
75 if (upper_case)
76 {
77 flags |= static_cast<uint8_t>(FormatFlag::UpperCase);
78 }
79 return flags;
80 }
81
86 [[nodiscard]] constexpr uint8_t PrecisionByte() const
87 {
88 return has_precision ? precision : std::numeric_limits<uint8_t>::max();
89 }
90};
91
95enum class FeatureGate : uint8_t
96{
97 Integer,
98 IntegerBase8_16,
99 Pointer,
100 Text,
101 FloatFixed,
102 FloatScientific,
103 FloatGeneral,
104};
105
109enum class LengthPolicy : uint8_t
110{
111 Integer,
112 NoneOnly,
113 Float,
114};
115
120{
121 char token = 0;
122 ValueKind type = ValueKind::None;
123 FeatureGate gate =
124 FeatureGate::Integer;
125 LengthPolicy length_policy =
126 LengthPolicy::NoneOnly;
127 bool upper_case = false;
128};
129
133inline constexpr size_t length_rule_count =
134 static_cast<size_t>(Length::LongDouble) + 1;
135
139inline constexpr std::array<FormatArgumentRule, length_rule_count> signed_rules{
140 FormatArgumentRule::SignedAny,
141 FormatArgumentRule::SignedChar,
142 FormatArgumentRule::SignedShort,
143 FormatArgumentRule::SignedLong,
144 FormatArgumentRule::SignedLongLong,
145 FormatArgumentRule::SignedIntMax,
146 FormatArgumentRule::SignedSize,
147 FormatArgumentRule::SignedPtrDiff,
148 FormatArgumentRule::None,
149};
150
154inline constexpr std::array<FormatArgumentRule, length_rule_count> unsigned_rules{
155 FormatArgumentRule::UnsignedAny,
156 FormatArgumentRule::UnsignedChar,
157 FormatArgumentRule::UnsignedShort,
158 FormatArgumentRule::UnsignedLong,
159 FormatArgumentRule::UnsignedLongLong,
160 FormatArgumentRule::UnsignedIntMax,
161 FormatArgumentRule::UnsignedSize,
162 FormatArgumentRule::UnsignedPtrDiff,
163 FormatArgumentRule::None,
164};
165
169inline constexpr std::array<SpecifierDescriptor, 17> specifiers{{
170 {'d', ValueKind::Signed, FeatureGate::Integer, LengthPolicy::Integer, false},
171 {'i', ValueKind::Signed, FeatureGate::Integer, LengthPolicy::Integer, false},
172 {'u', ValueKind::Unsigned, FeatureGate::Integer, LengthPolicy::Integer, false},
173 {'b', ValueKind::Binary, FeatureGate::IntegerBase8_16, LengthPolicy::Integer, false},
174 {'B', ValueKind::Binary, FeatureGate::IntegerBase8_16, LengthPolicy::Integer, true},
175 {'o', ValueKind::Octal, FeatureGate::IntegerBase8_16, LengthPolicy::Integer, false},
176 {'x', ValueKind::HexLower, FeatureGate::IntegerBase8_16, LengthPolicy::Integer,
177 false},
178 {'X', ValueKind::HexUpper, FeatureGate::IntegerBase8_16, LengthPolicy::Integer,
179 false},
180 {'p', ValueKind::Pointer, FeatureGate::Pointer, LengthPolicy::NoneOnly, false},
181 {'c', ValueKind::Character, FeatureGate::Text, LengthPolicy::NoneOnly, false},
182 {'s', ValueKind::String, FeatureGate::Text, LengthPolicy::NoneOnly, false},
183 {'f', ValueKind::FloatFixed, FeatureGate::FloatFixed, LengthPolicy::Float, false},
184 {'F', ValueKind::FloatFixed, FeatureGate::FloatFixed, LengthPolicy::Float, true},
185 {'e', ValueKind::FloatScientific, FeatureGate::FloatScientific,
186 LengthPolicy::Float, false},
187 {'E', ValueKind::FloatScientific, FeatureGate::FloatScientific,
188 LengthPolicy::Float, true},
189 {'g', ValueKind::FloatGeneral, FeatureGate::FloatGeneral, LengthPolicy::Float,
190 false},
191 {'G', ValueKind::FloatGeneral, FeatureGate::FloatGeneral, LengthPolicy::Float,
192 true},
193}};
@ Signed
signed integer / 有符号整数
@ Unsigned
unsigned integer / 无符号整数
单个 printf 转换在降为共享格式前的解析结果 / One parsed printf conversion before lowering into the shared format
ValueKind type
semantic conversion category / 转换项归一化后的语义类别
bool upper_case
implied uppercase output / 隐含的大写输出标志
constexpr uint8_t FlagsByte() const
将前端解析出的标志位打包成共享的 FormatFlag 字节 / Pack the parsed frontend flags into the shared FormatFlag byte
bool left_align
parsed - flag / 已解析的 - 标志
Length length
parsed length modifier / 已解析的长度修饰符
uint8_t width
parsed field width / 已解析的字段宽度
bool force_sign
parsed + flag / 已解析的 + 标志
bool positional
whether arg_index came from n$ syntax / arg_index 是否来自 n$ 语法
bool zero_pad
parsed 0 flag / 已解析的 0 标志
constexpr uint8_t PrecisionByte() const
返回共享精度字节;若未显式指定精度则为 0xFF / Return the shared precision byte, or 0xFF when precision is absent
bool space_sign
parsed space-sign flag / 已解析的空格正号标志
size_t arg_index
source argument index consumed by this field / 当前字段消耗的源参数索引
bool alternate
parsed # flag / 已解析的 # 标志
uint8_t precision
parsed precision value / 已解析的精度值
bool has_precision
whether precision was explicitly provided / 是否显式提供了精度
单个源级 printf 说明符描述项 / One source-level printf specifier descriptor
LengthPolicy length_policy
accepted length family / 允许的长度修饰类别
FeatureGate gate
feature gate controlling this specifier / 控制该说明符的功能开关
bool upper_case
whether the specifier implies uppercase output / 说明符是否隐含大写输出
char token
source conversion character / 源格式转换字符
ValueKind type
normalized semantic category / 归一化后的语义类别