libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
printf_frontend_spec.hpp
1#pragma once
2
13enum class ValueKind : uint8_t
14{
15 None,
16 Signed,
17 Unsigned,
18 Binary,
19 Octal,
20 HexLower,
21 HexUpper,
22 Pointer,
23 Character,
24 String,
25 FloatFixed,
26 FloatScientific,
27 FloatGeneral,
28};
29
35{
36 size_t arg_index =
37 0;
38 ValueKind type =
39 ValueKind::None;
40 Length length = Length::Default;
41 bool left_align = false;
42 bool force_sign = false;
43 bool space_sign = false;
44 bool alternate = false;
45 bool zero_pad = false;
46 bool upper_case = false;
48 false;
49 uint8_t width = 0;
51 false;
52 uint8_t precision = 0;
53
60 [[nodiscard]] constexpr uint8_t FlagsByte() const
61 {
62 uint8_t flags = 0;
63 if (left_align)
64 {
65 flags |= static_cast<uint8_t>(FormatFlag::LeftAlign);
66 }
67 if (force_sign)
68 {
69 flags |= static_cast<uint8_t>(FormatFlag::ForceSign);
70 }
71 if (space_sign)
72 {
73 flags |= static_cast<uint8_t>(FormatFlag::SpaceSign);
74 }
75 if (alternate)
76 {
77 flags |= static_cast<uint8_t>(FormatFlag::Alternate);
78 }
79 if (zero_pad)
80 {
81 flags |= static_cast<uint8_t>(FormatFlag::ZeroPad);
82 }
83 if (upper_case)
84 {
85 flags |= static_cast<uint8_t>(FormatFlag::UpperCase);
86 }
87 return flags;
88 }
89
96 [[nodiscard]] constexpr uint8_t PrecisionByte() const
97 {
98 return has_precision ? precision : std::numeric_limits<uint8_t>::max();
99 }
100};
101
106enum class FeatureGate : uint8_t
107{
108 Integer,
109 IntegerBase8_16,
110 Pointer,
111 Text,
112 FloatFixed,
113 FloatScientific,
114 FloatGeneral,
115};
116
121enum class LengthPolicy : uint8_t
122{
123 Integer,
124 NoneOnly,
125 Float,
126};
127
132{
133 char token = 0;
134 ValueKind type =
135 ValueKind::None;
136 FeatureGate gate = FeatureGate::Integer;
138 LengthPolicy length_policy =
139 LengthPolicy::NoneOnly;
141 false;
142};
143
147inline constexpr size_t length_rule_count = static_cast<size_t>(Length::LongDouble) + 1;
148
152inline constexpr std::array<FormatArgumentRule, length_rule_count> signed_rules{
153 FormatArgumentRule::SignedAny, FormatArgumentRule::SignedChar,
154 FormatArgumentRule::SignedShort, FormatArgumentRule::SignedLong,
155 FormatArgumentRule::SignedLongLong, FormatArgumentRule::SignedIntMax,
156 FormatArgumentRule::SignedSize, FormatArgumentRule::SignedPtrDiff,
157 FormatArgumentRule::None,
158};
159
164inline constexpr std::array<FormatArgumentRule, length_rule_count> unsigned_rules{
165 FormatArgumentRule::UnsignedAny,
166 FormatArgumentRule::UnsignedChar,
167 FormatArgumentRule::UnsignedShort,
168 FormatArgumentRule::UnsignedLong,
169 FormatArgumentRule::UnsignedLongLong,
170 FormatArgumentRule::UnsignedIntMax,
171 FormatArgumentRule::UnsignedSize,
172 FormatArgumentRule::UnsignedPtrDiff,
173 FormatArgumentRule::None,
174};
175
179inline constexpr std::array<SpecifierDescriptor, 17> specifiers{{
180 {'d', ValueKind::Signed, FeatureGate::Integer, LengthPolicy::Integer, false},
181 {'i', ValueKind::Signed, FeatureGate::Integer, LengthPolicy::Integer, false},
182 {'u', ValueKind::Unsigned, FeatureGate::Integer, LengthPolicy::Integer, false},
183 {'b', ValueKind::Binary, FeatureGate::IntegerBase8_16, LengthPolicy::Integer, false},
184 {'B', ValueKind::Binary, FeatureGate::IntegerBase8_16, LengthPolicy::Integer, true},
185 {'o', ValueKind::Octal, FeatureGate::IntegerBase8_16, LengthPolicy::Integer, false},
186 {'x', ValueKind::HexLower, FeatureGate::IntegerBase8_16, LengthPolicy::Integer,
187 false},
188 {'X', ValueKind::HexUpper, FeatureGate::IntegerBase8_16, LengthPolicy::Integer,
189 false},
190 {'p', ValueKind::Pointer, FeatureGate::Pointer, LengthPolicy::NoneOnly, false},
191 {'c', ValueKind::Character, FeatureGate::Text, LengthPolicy::NoneOnly, false},
192 {'s', ValueKind::String, FeatureGate::Text, LengthPolicy::NoneOnly, false},
193 {'f', ValueKind::FloatFixed, FeatureGate::FloatFixed, LengthPolicy::Float, false},
194 {'F', ValueKind::FloatFixed, FeatureGate::FloatFixed, LengthPolicy::Float, true},
195 {'e', ValueKind::FloatScientific, FeatureGate::FloatScientific, LengthPolicy::Float,
196 false},
197 {'E', ValueKind::FloatScientific, FeatureGate::FloatScientific, LengthPolicy::Float,
198 true},
199 {'g', ValueKind::FloatGeneral, FeatureGate::FloatGeneral, LengthPolicy::Float, false},
200 {'G', ValueKind::FloatGeneral, FeatureGate::FloatGeneral, LengthPolicy::Float, true},
201}};
@ 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 / 允许的长度修饰类别
bool upper_case
whether the specifier implies uppercase output / 说明符是否隐含大写输出
char token
source conversion character / 源格式转换字符
ValueKind type
normalized semantic category / 归一化后的语义类别