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