libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
printf_frontend_source.hpp
1#pragma once
2
3#include "printf_frontend_binding_base.hpp"
4#include "printf_frontend_binding_field.hpp"
5
6namespace SourceSyntax
7{
14template <size_t MaxFieldCount>
16{
17 std::array<size_t, MaxFieldCount>
19 size_t field_count = 0;
21 0;
22 Error error = Error::None;
23
24 [[nodiscard]] consteval Error Text(size_t, size_t) const { return Error::None; }
25
26 [[nodiscard]] consteval Error Field(const Conversion& conversion)
27 {
28 order[field_count++] = conversion.arg_index;
29 size_t used_argument_count = conversion.arg_index + 1;
30 if (used_argument_count > argument_count)
31 {
32 argument_count = used_argument_count;
33 }
34 return Error::None;
35 }
36};
37
44template <size_t FieldCount, size_t ArgCount>
46{
47 std::array<size_t, FieldCount>
49 std::array<FormatArgumentInfo, ArgCount>
50 args{};
51 Error error = Error::None;
52};
53
60template <size_t FieldCount, size_t ArgCount>
64
65 [[nodiscard]] consteval Error Text(size_t, size_t) const { return Error::None; }
66
67 [[nodiscard]] consteval Error Field(const Conversion& conversion)
68 {
69 auto field = FieldSelection::BuildFormatField(conversion);
70 auto info = FormatArgumentInfo{
71 .pack = field.pack,
72 .rule = field.rule,
73 };
74 auto& slot = analysis.args[conversion.arg_index];
75 if (slot.rule != FormatArgumentRule::None &&
76 (slot.rule != info.rule || slot.pack != info.pack))
77 {
78 return Error::ConflictingArgument;
79 }
80
81 slot = info;
82 return Error::None;
83 }
84};
85
86#include "printf_frontend_parser.hpp"
97[[nodiscard]] consteval Error WalkSource(std::string_view source, auto& visitor)
98{
99 if (HasEmbeddedNul(source))
100 {
101 return Error::EmbeddedNul;
102 }
103
104 size_t pos = 0;
105 size_t text_begin = 0;
106 IndexingState indexing{};
107
108 while (pos < source.size())
109 {
110 if (source[pos] != '%')
111 {
112 ++pos;
113 continue;
114 }
115
116 auto error = visitor.Text(text_begin, pos - text_begin);
117 if (error != Error::None)
118 {
119 return error;
120 }
121
122 if (pos + 1 < source.size() && source[pos + 1] == '%')
123 {
124 error = visitor.Text(pos, 1);
125 if (error != Error::None)
127 return error;
128 }
129
130 pos += 2;
131 text_begin = pos;
132 continue;
133 }
134
135 auto parse_pos = pos;
136 Conversion conversion{};
137 error = Parse(source, parse_pos, indexing, conversion);
138 if (error != Error::None)
139 {
140 return error;
141 }
142
143 error = visitor.Field(conversion);
144 if (error != Error::None)
145 {
146 return error;
147 }
148
149 pos = parse_pos;
150 text_begin = pos;
151 }
152
153 return visitor.Text(text_begin, source.size() - text_begin);
154}
155
165template <Text Source>
166[[nodiscard]] consteval auto Analyze()
167{
168 constexpr auto scratch = []() consteval
169 {
170 SourceAnalysisScratch<Source.Size()> visitor{};
171 visitor.error = WalkSource(std::string_view(Source.Data(), Source.Size()), visitor);
172 return visitor;
173 }();
174
175 SourceAnalysis<scratch.field_count, scratch.argument_count> result{};
176 result.error = scratch.error;
177 for (size_t i = 0; i < scratch.field_count; ++i)
178 {
179 result.order[i] = scratch.order[i];
180 }
181
182 if constexpr (scratch.error != Error::None)
183 {
184 return result;
185 }
186 else
187 {
188 ResolvedArgumentVisitor<scratch.field_count, scratch.argument_count> visitor{result};
189 result.error = WalkSource(std::string_view(Source.Data(), Source.Size()), visitor);
190 return result;
191 }
192}
193} // namespace SourceSyntax
printf 降级阶段共享的描述表与策略辅助函数 / Shared descriptor-table and policy helpers for printf lowering
constexpr bool HasEmbeddedNul(std::string_view source)
判断源字符串在终止前是否包含嵌入式 NUL / Return whether the source contains an embedded NUL before the terminator
consteval auto Analyze()
对一个 brace 字面量执行仅源串分析,并返回按顺序整理的参数索引摘要 / Run source-only analysis for one brace literal and return the ...
consteval Error Parse(std::string_view source, size_t &pos, IndexingState &indexing, Conversion &conversion)
在前导 % 之后解析一个完整 printf 转换项 / Parse one complete printf conversion after the leading %
consteval Error WalkSource(std::string_view source, auto &visitor)
遍历一个 brace 源字符串,并发射字面文本片段与已解析字段 / Walk one brace source string and emit literal-text spans plus parse...
单个 printf 转换在降为共享格式前的解析结果 / One parsed printf conversion before lowering into the shared format
size_t arg_index
source argument index consumed by this field / 当前字段消耗的源参数索引
brace 字段自动索引与手动索引的源级状态 / Source-level indexing mode for automatic versus manual brace fields
将已解析转换解析成最终源顺序参数元信息摘要的 visitor / Visitor that resolves parsed conversions into the final source-order...
单条 brace 风格格式字面量的仅源串分析数据 / Source-only analysis data for one brace-style format literal
std::array< size_t, FieldCount > order
field-ordered source argument indexes / 按字段顺序排列的源参数索引
std::array< FormatArgumentInfo, ArgCount > args
source-ordered argument metadata / 按源参数顺序排列的参数元信息
Error error
first source-only parse error / 首个仅源串解析错误
仅源串分析阶段使用的保守临时累加器 / Conservative temporary accumulator used during source-only analysis
std::array< size_t, MaxFieldCount > order
field-ordered source argument indexes / 按字段顺序排列的源参数索引
Error error
first parse error / 首个解析错误
size_t argument_count
highest referenced argument count / 最高引用到的参数个数
size_t field_count
parsed replacement-field count / 已解析的替换字段数量