1/* @title: Command Line Macro Internals */
2#pragma once
3#include <compiler/core.h>
4#include <compiler/diagnostic.h>
5#include <math/bit.h>
6#include <types/type_enum.h>
7
8struct cmdline_entry;
9struct cmdline_value;
10struct cmdline_list;
11struct cmdline_range;
12struct cpu_mask;
13
14/* ========== Type Offset + Bits ========== */
15
16#define CMDLINE_TYPE_OFFSET 6
17
18#define CMDLINE_IMPL_TYPE_BIT_1(t1) BIT(t1)
19#define CMDLINE_IMPL_TYPE_BIT_2(t1, t2) (BIT(t1) | BIT(t2))
20#define CMDLINE_IMPL_TYPE_BIT_3(t1, t2, t3) \
21 (CMDLINE_IMPL_TYPE_BIT_2(t1, t2) | BIT(t3))
22#define CMDLINE_IMPL_TYPE_BIT_4(t1, t2, t3, t4) \
23 (CMDLINE_IMPL_TYPE_BIT_3(t1, t2, t3) | BIT(t4))
24#define CMDLINE_IMPL_TYPE_BIT_5(t1, t2, t3, t4, t5) \
25 (CMDLINE_IMPL_TYPE_BIT_4(t1, t2, t3, t4) | BIT(t5))
26
27/* ========== Type Enum ========== */
28
29#define CMDLINE_STRICT_TYPE_ENUM(var) \
30 cc_generic( \
31 (var), bool : TYPE_BOOL, int8_t : TYPE_INT8, uint8_t : TYPE_UINT8, \
32 int16_t : TYPE_INT16, uint16_t : TYPE_UINT16, int32_t : TYPE_INT32, \
33 uint32_t : TYPE_UINT32, int64_t : TYPE_INT64, uint64_t : TYPE_UINT64)
34
35/* ========== Child Tuple Encodings ========== */
36
37#define _CMDLINE_CHILD_KIND_POLY 1
38#define _CMDLINE_CHILD_KIND_VAR 2
39
40#define _CMDLINE_UNPACK(...) __VA_ARGS__
41#define _CMDLINE_CHILD_SYM(parent_n, n) \
42 PP_CONCAT(__cmdline_, PP_CONCAT(parent_n, _##n))
43
44#define _CMDLINE_CHILD_DECL_1(parent_n, n, _var, ...) \
45 cc_wno_override_init_start LINKER_SECTION_OBJECT(struct cmdline_entry, \
46 cmdline_entries) \
47 _CMDLINE_CHILD_SYM(parent_n, \
48 n) = {.name = #n, \
49 .status = CMDLINE_ENTRY_NOT_FOUND, \
50 .parent = CMDLINE(parent_n), \
51 .types = 0, \
52 .range = RANGE(1, 0), \
53 .choices = NULL, \
54 .mappings = NULL, \
55 .flags_table = NULL, \
56 .value.mode = CMDLINE_MODE_POLYMORPHIC, \
57 .value.type = CMDLINE_TYPE_NONE, \
58 .flags = CMDLINE_ENTRY_FLAGS_NONE, \
59 ##__VA_ARGS__}; \
60 cc_wno_override_init_end
61
62#define _CMDLINE_CHILD_DECL_2(parent_n, n, var, ...) \
63 cc_wno_override_init_start LINKER_SECTION_OBJECT(struct cmdline_entry, \
64 cmdline_entries) \
65 _CMDLINE_CHILD_SYM(parent_n, \
66 n) = {.name = #n, \
67 .status = CMDLINE_ENTRY_NOT_FOUND, \
68 .parent = CMDLINE(parent_n), \
69 .types = 0, \
70 .range = RANGE(1, 0), \
71 .choices = NULL, \
72 .mappings = NULL, \
73 .flags_table = NULL, \
74 .value.mode = CMDLINE_MODE_VAR, \
75 .value.write_to = &(var), \
76 .value.c_type = TYPE_TO_ENUM((var)), \
77 .value.parse = NULL, \
78 .flags = CMDLINE_ENTRY_FLAGS_NONE, \
79 ##__VA_ARGS__}; \
80 cc_wno_override_init_end
81
82#define _CMDLINE_CHILD_DECL_DISPATCH(parent_n, kind, n, var, ...) \
83 _CMDLINE_CHILD_DECL_##kind(parent_n, n, var, ##__VA_ARGS__)
84
85#define _CMDLINE_CHILD_DECL_EXPAND(parent_n, ...) \
86 _CMDLINE_CHILD_DECL_DISPATCH(parent_n, __VA_ARGS__)
87
88#define _CMDLINE_CHILD_DECL_APPLY(parent_n, tuple) \
89 _CMDLINE_CHILD_DECL_EXPAND(parent_n, _CMDLINE_UNPACK tuple)
90
91/* ========== Variadic Children Map Expanders ========== */
92
93#define _CMDLINE_CHILDREN_MAP_1(p, c1) _CMDLINE_CHILD_DECL_APPLY(p, c1)
94#define _CMDLINE_CHILDREN_MAP_2(p, c1, c2) \
95 _CMDLINE_CHILD_DECL_APPLY(p, c1) _CMDLINE_CHILD_DECL_APPLY(p, c2)
96#define _CMDLINE_CHILDREN_MAP_3(p, c1, c2, c3) \
97 _CMDLINE_CHILDREN_MAP_2(p, c1, c2) _CMDLINE_CHILD_DECL_APPLY(p, c3)
98#define _CMDLINE_CHILDREN_MAP_4(p, c1, c2, c3, c4) \
99 _CMDLINE_CHILDREN_MAP_3(p, c1, c2, c3) _CMDLINE_CHILD_DECL_APPLY(p, c4)
100#define _CMDLINE_CHILDREN_MAP_5(p, c1, c2, c3, c4, c5) \
101 _CMDLINE_CHILDREN_MAP_4(p, c1, c2, c3, c4) _CMDLINE_CHILD_DECL_APPLY(p, c5)
102#define _CMDLINE_CHILDREN_MAP_6(p, c1, c2, c3, c4, c5, c6) \
103 _CMDLINE_CHILDREN_MAP_5(p, c1, c2, c3, c4, c5) \
104 _CMDLINE_CHILD_DECL_APPLY(p, c6)
105#define _CMDLINE_CHILDREN_MAP_7(p, c1, c2, c3, c4, c5, c6, c7) \
106 _CMDLINE_CHILDREN_MAP_6(p, c1, c2, c3, c4, c5, c6) \
107 _CMDLINE_CHILD_DECL_APPLY(p, c7)
108#define _CMDLINE_CHILDREN_MAP_8(p, c1, c2, c3, c4, c5, c6, c7, c8) \
109 _CMDLINE_CHILDREN_MAP_7(p, c1, c2, c3, c4, c5, c6, c7) \
110 _CMDLINE_CHILD_DECL_APPLY(p, c8)
111#define _CMDLINE_CHILDREN_MAP_9(p, c1, c2, c3, c4, c5, c6, c7, c8, c9) \
112 _CMDLINE_CHILDREN_MAP_8(p, c1, c2, c3, c4, c5, c6, c7, c8) \
113 _CMDLINE_CHILD_DECL_APPLY(p, c9)
114#define _CMDLINE_CHILDREN_MAP_10(p, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10) \
115 _CMDLINE_CHILDREN_MAP_9(p, c1, c2, c3, c4, c5, c6, c7, c8, c9) \
116 _CMDLINE_CHILD_DECL_APPLY(p, c10)
117#define _CMDLINE_CHILDREN_MAP_11(p, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, \
118 c11) \
119 _CMDLINE_CHILDREN_MAP_10(p, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10) \
120 _CMDLINE_CHILD_DECL_APPLY(p, c11)
121#define _CMDLINE_CHILDREN_MAP_12(p, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, \
122 c11, c12) \
123 _CMDLINE_CHILDREN_MAP_11(p, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11) \
124 _CMDLINE_CHILD_DECL_APPLY(p, c12)
125#define _CMDLINE_CHILDREN_MAP_13(p, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, \
126 c11, c12, c13) \
127 _CMDLINE_CHILDREN_MAP_12(p, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, \
128 c12) \
129 _CMDLINE_CHILD_DECL_APPLY(p, c13)
130#define _CMDLINE_CHILDREN_MAP_14(p, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, \
131 c11, c12, c13, c14) \
132 _CMDLINE_CHILDREN_MAP_13(p, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, \
133 c12, c13) \
134 _CMDLINE_CHILD_DECL_APPLY(p, c14)
135#define _CMDLINE_CHILDREN_MAP_15(p, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, \
136 c11, c12, c13, c14, c15) \
137 _CMDLINE_CHILDREN_MAP_14(p, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, \
138 c12, c13, c14) \
139 _CMDLINE_CHILD_DECL_APPLY(p, c15)
140#define _CMDLINE_CHILDREN_MAP_16(p, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, \
141 c11, c12, c13, c14, c15, c16) \
142 _CMDLINE_CHILDREN_MAP_15(p, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, \
143 c12, c13, c14, c15) \
144 _CMDLINE_CHILD_DECL_APPLY(p, c16)
145
146/* ========== Wrappers ========== */
147
148#define CMDLINE_DEFINE_FX(n, var, ...) \
149 CMDLINE_DEFINE_VAR(n, var, .types = CMDLINE_TYPES(CMDLINE_TYPE_FX), \
150 ##__VA_ARGS__)
151#define CMDLINE_DEFINE_DURATION(n, var, ...) \
152 CMDLINE_DEFINE_VAR(n, var, .types = CMDLINE_TYPES(CMDLINE_TYPE_DURATION), \
153 ##__VA_ARGS__)
154#define CMDLINE_DEFINE_SIZE(n, var, ...) \
155 CMDLINE_DEFINE_VAR(n, var, .types = CMDLINE_TYPES(CMDLINE_TYPE_DATA_SIZE), \
156 ##__VA_ARGS__)
157#define CMDLINE_DEFINE_CPUS(n, var, ...) \
158 CMDLINE_DEFINE_VAR(n, var, .types = CMDLINE_TYPES(CMDLINE_TYPE_CPU_MASK), \
159 ##__VA_ARGS__)
160#define CMDLINE_DEFINE_STRING(n, var, ...) \
161 CMDLINE_DEFINE_VAR(n, var, .types = CMDLINE_TYPES(CMDLINE_TYPE_STRING), \
162 ##__VA_ARGS__)
163
164#define CMDLINE_CHILD_DEFINE_FX(parent_n, n, var, ...) \
165 CMDLINE_CHILD_DEFINE_VAR(parent_n, n, var, \
166 .types = CMDLINE_TYPES(CMDLINE_TYPE_FX), \
167 ##__VA_ARGS__)
168#define CMDLINE_CHILD_DEFINE_DURATION(parent_n, n, var, ...) \
169 CMDLINE_CHILD_DEFINE_VAR(parent_n, n, var, \
170 .types = CMDLINE_TYPES(CMDLINE_TYPE_DURATION), \
171 ##__VA_ARGS__)
172#define CMDLINE_CHILD_DEFINE_SIZE(parent_n, n, var, ...) \
173 CMDLINE_CHILD_DEFINE_VAR(parent_n, n, var, \
174 .types = CMDLINE_TYPES(CMDLINE_TYPE_DATA_SIZE), \
175 ##__VA_ARGS__)
176#define CMDLINE_CHILD_DEFINE_CPUS(parent_n, n, var, ...) \
177 CMDLINE_CHILD_DEFINE_VAR(parent_n, n, var, \
178 .types = CMDLINE_TYPES(CMDLINE_TYPE_CPU_MASK), \
179 ##__VA_ARGS__)
180#define CMDLINE_CHILD_DEFINE_STRING(parent_n, n, var, ...) \
181 CMDLINE_CHILD_DEFINE_VAR(parent_n, n, var, \
182 .types = CMDLINE_TYPES(CMDLINE_TYPE_STRING), \
183 ##__VA_ARGS__)
184
185#define CMDLINE_INNER_FX(n, var, ...) \
186 CMDLINE_INNER_VAR(n, var, .types = CMDLINE_TYPES(CMDLINE_TYPE_FX), \
187 ##__VA_ARGS__)
188#define CMDLINE_INNER_DURATION(n, var, ...) \
189 CMDLINE_INNER_VAR(n, var, .types = CMDLINE_TYPES(CMDLINE_TYPE_DURATION), \
190 ##__VA_ARGS__)
191#define CMDLINE_INNER_SIZE(n, var, ...) \
192 CMDLINE_INNER_VAR(n, var, .types = CMDLINE_TYPES(CMDLINE_TYPE_DATA_SIZE), \
193 ##__VA_ARGS__)
194#define CMDLINE_INNER_CPUS(n, var, ...) \
195 CMDLINE_INNER_VAR(n, var, .types = CMDLINE_TYPES(CMDLINE_TYPE_CPU_MASK), \
196 ##__VA_ARGS__)
197#define CMDLINE_INNER_STRING(n, var, ...) \
198 CMDLINE_INNER_VAR(n, var, .types = CMDLINE_TYPES(CMDLINE_TYPE_STRING), \
199 ##__VA_ARGS__)
200
201#define CMDLINE_SCHEMA_PROP_FX(struct_type, member, ...) \
202 CMDLINE_SCHEMA_PROP(struct_type, member, \
203 .types = CMDLINE_TYPES(CMDLINE_TYPE_FX), \
204 ##__VA_ARGS__)
205#define CMDLINE_SCHEMA_PROP_DURATION(struct_type, member, ...) \
206 CMDLINE_SCHEMA_PROP(struct_type, member, \
207 .types = CMDLINE_TYPES(CMDLINE_TYPE_DURATION), \
208 ##__VA_ARGS__)
209#define CMDLINE_SCHEMA_PROP_SIZE(struct_type, member, ...) \
210 CMDLINE_SCHEMA_PROP(struct_type, member, \
211 .types = CMDLINE_TYPES(CMDLINE_TYPE_DATA_SIZE), \
212 ##__VA_ARGS__)
213#define CMDLINE_SCHEMA_PROP_CPUS(struct_type, member, ...) \
214 CMDLINE_SCHEMA_PROP(struct_type, member, \
215 .types = CMDLINE_TYPES(CMDLINE_TYPE_CPU_MASK), \
216 ##__VA_ARGS__)
217#define CMDLINE_SCHEMA_PROP_STRING(struct_type, member, ...) \
218 CMDLINE_SCHEMA_PROP(struct_type, member, \
219 .types = CMDLINE_TYPES(CMDLINE_TYPE_STRING), \
220 ##__VA_ARGS__)
221
222enum err cmdline_parse_bool(void *write_to, const char *text);
223enum err cmdline_parse_fx(void *write_to, const char *text);
224enum err cmdline_parse_duration(void *write_to, const char *text);
225enum err cmdline_parse_data_size(void *write_to, const char *text);
226enum err cmdline_parse_cpu_mask(void *write_to, const char *text);
227enum err cmdline_parse_mac(void *write_to, const char *text);
228enum err cmdline_parse_string(void *write_to, const char *text);
229
230enum err cmdline_extract_bool(struct cmdline_value *val, bool *out);
231enum err cmdline_extract_u64(struct cmdline_value *val, uint64_t *out);
232enum err cmdline_extract_i64(struct cmdline_value *val, int64_t *out);
233enum err cmdline_extract_u32(struct cmdline_value *val, uint32_t *out);
234enum err cmdline_extract_i32(struct cmdline_value *val, int32_t *out);
235enum err cmdline_extract_u16(struct cmdline_value *val, uint16_t *out);
236enum err cmdline_extract_i16(struct cmdline_value *val, int16_t *out);
237enum err cmdline_extract_u8(struct cmdline_value *val, uint8_t *out);
238enum err cmdline_extract_i8(struct cmdline_value *val, int8_t *out);
239enum err cmdline_extract_fx(struct cmdline_value *val, fx32_32_t *out);
240enum err cmdline_extract_duration(struct cmdline_value *val, time_ns_t *out);
241enum err cmdline_extract_mac(struct cmdline_value *val, uint64_t *out);
242enum err cmdline_extract_range(struct cmdline_value *val,
243 struct cmdline_range *out);
244enum err cmdline_extract_cpu_mask(struct cmdline_value *val,
245 struct cpu_mask *out);
246enum err cmdline_extract_string(struct cmdline_value *val, char **out);
247enum err cmdline_extract_const_string(struct cmdline_value *val,
248 const char **out);
249enum err cmdline_extract_list(struct cmdline_value *val,
250 struct cmdline_list *out);
251