libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
format_frontend_source.hpp
1#pragma once
2
3namespace SourceSyntax
4{
9template <size_t FieldCount>
10struct SourceAnalysis
11{
12 std::array<size_t, FieldCount> argument_order{};
14 Error error = Error::None;
15};
16
21template <size_t MaxFieldCount>
23{
24 std::array<size_t, MaxFieldCount> order{};
25 size_t field_count = 0;
27 Error error = Error::None;
28
29 [[nodiscard]] consteval Error Text(size_t, size_t) const { return Error::None; }
30
31 [[nodiscard]] consteval Error Field(const ParsedField& field)
32 {
33 order[field_count++] = field.arg_index;
34 size_t used_argument_count = field.arg_index + 1;
35 if (used_argument_count > required_argument_count)
36 {
37 required_argument_count = used_argument_count;
38 }
39 return Error::None;
40 }
41};
42
43#include "format_frontend_parser.hpp"
44
51[[nodiscard]] consteval Error WalkSource(std::string_view source, auto& visitor)
53 if (HasEmbeddedNul(source))
54 {
55 return Error::EmbeddedNul;
56 }
57
58 size_t pos = 0;
59 size_t text_begin = 0;
60 IndexingState indexing{};
61
62 while (pos < source.size())
63 {
64 if (source[pos] == '{')
65 {
66 if (pos + 1 < source.size() && source[pos + 1] == '{')
67 {
68 auto error = visitor.Text(text_begin, pos - text_begin);
69 if (error != Error::None)
70 {
71 return error;
72 }
73 error = visitor.Text(pos, 1);
74 if (error != Error::None)
75 {
76 return error;
77 }
78 pos += 2;
79 text_begin = pos;
80 continue;
81 }
82
83 auto error = visitor.Text(text_begin, pos - text_begin);
84 if (error != Error::None)
85 {
86 return error;
87 }
88
89 ParsedField field{};
90 error = ParseField(source, pos, indexing, field);
91 if (error != Error::None)
92 {
93 return error;
94 }
95
96 error = visitor.Field(field);
97 if (error != Error::None)
98 {
99 return error;
100 }
101
102 text_begin = pos;
103 continue;
105
106 if (source[pos] == '}')
107 {
108 if (pos + 1 < source.size() && source[pos + 1] == '}')
109 {
110 auto error = visitor.Text(text_begin, pos - text_begin);
111 if (error != Error::None)
112 {
113 return error;
114 }
115 error = visitor.Text(pos, 1);
116 if (error != Error::None)
117 {
118 return error;
119 }
120 pos += 2;
121 text_begin = pos;
122 continue;
123 }
124
125 return Error::UnmatchedBrace;
126 }
127
128 ++pos;
129 }
130
131 return visitor.Text(text_begin, source.size() - text_begin);
132}
133
139template <Text Source>
140[[nodiscard]] consteval auto Analyze()
141{
142 constexpr auto scratch = []() consteval {
143 SourceAnalysisScratch<Source.Size()> visitor{};
144 visitor.error = WalkSource(std::string_view(Source.Data(), Source.Size()), visitor);
145 return visitor;
146 }();
148 SourceAnalysis<scratch.field_count> result{};
149 result.required_argument_count = scratch.required_argument_count;
150 result.error = scratch.error;
151 for (size_t i = 0; i < scratch.field_count; ++i)
152 {
153 result.argument_order[i] = scratch.order[i];
154 }
155 return result;
156}
157} // 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 Error ParseField(std::string_view source, size_t &pos, IndexingState &indexing, ParsedField &field)
解析一个完整 brace 字段,从 { 一直到匹配的 } / Parse one complete brace field from { through the matching }
consteval auto Analyze()
对一个 brace 字面量执行仅源串分析,并返回按顺序整理的参数索引摘要 / Run source-only analysis for one brace literal and return the ...
consteval Error WalkSource(std::string_view source, auto &visitor)
遍历一个 brace 源字符串,并发射字面文本片段与已解析字段 / Walk one brace source string and emit literal-text spans plus parse...
brace 字段自动索引与手动索引的源级状态 / Source-level indexing mode for automatic versus manual brace fields
单条 brace 风格格式字面量的仅源串分析数据 / Source-only analysis data for one brace-style format literal
size_t required_argument_count
minimum call-site argument count / 调用点至少需要的参数个数
std::array< size_t, FieldCount > argument_order
source-ordered argument references / 按源串顺序引用的参数索引
Error error
first source-only parse error / 首个仅源串解析错误
仅源串分析阶段使用的保守临时累加器 / Conservative temporary accumulator used during source-only analysis
std::array< size_t, MaxFieldCount > order
conservative field-order scratch buffer / 按字段顺序记录参数索引的临时缓冲区
Error error
first parse error / 首个解析错误
size_t required_argument_count
minimum call-site argument count / 调用点至少需要的参数个数
size_t field_count
parsed replacement-field count / 已解析的替换字段数量