Project
Loading...
Searching...
No Matches
qconfig_internal.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15// For internal use by qconfig.cxx
16// External usage is possible, but not fully supported
17
18#include "qconfig_general.h"
19#include "qconfig_helpers.h"
20
21#ifdef QCONFIG_PARSE
22
23#define QCONFIG_COMPARE(name, optname, optnameshort) \
24 (thisoption[0] == '-' && ((thisoption[1] == '-' && optname[0] != 0 && strcmp(&thisoption[2], optname) == 0) || \
25 (preoptshort == 0 && thisoption[1] == optnameshort && thisoption[2] == 0) || (thisoption[1] == '-' && strlen(preopt) == 0 && strcmp(&thisoption[2], name) == 0) || \
26 (preoptshort != 0 && thisoption[1] == preoptshort && thisoption[2] == optnameshort && thisoption[3] == 0) || (thisoption[1] == '-' && strlen(preopt) && strncmp(&thisoption[2], preopt, strlen(preopt)) == 0 && strcmp(&thisoption[2 + strlen(preopt)], name) == 0)))
27
28#define AddOption(name, type, default, optname, optnameshort, ...) \
29 else if (QCONFIG_COMPARE(#name, optname, optnameshort)) \
30 { \
31 int32_t retVal = qConfigType<type>::qAddOption(tmp.name, i, argv, argc, default, __VA_ARGS__); \
32 if (retVal) { \
33 return (retVal); \
34 } \
35 }
36
37#define AddOptionSet(name, type, value, optname, optnameshort, ...) \
38 else if (QCONFIG_COMPARE(optname, "", optnameshort)) \
39 { \
40 int32_t retVal = qConfigType<type>::qAddOption(tmp.name, i, nullptr, 0, value, __VA_ARGS__, set(value)); \
41 if (retVal) { \
42 return (retVal); \
43 } \
44 }
45
46#define AddOptionVec(name, type, optname, optnameshort, ...) \
47 else if (QCONFIG_COMPARE(#name, optname, optnameshort)) \
48 { \
49 int32_t retVal = qConfigType<type>::qAddOptionVec(tmp.name, i, argv, argc, __VA_ARGS__); \
50 if (retVal) { \
51 return (retVal); \
52 } \
53 }
54
55#define AddOptionArray(name, type, count, default, optname, optnameshort, ...) \
56 else if (QCONFIG_COMPARE(#name, optname, optnameshort)) \
57 { \
58 int32_t retVal = qConfigType<type>::qAddOptionArray(tmp.name, count, i, argv, argc, __VA_ARGS__); \
59 if (retVal) { \
60 return (retVal); \
61 } \
62 }
63
64#define AddSubConfig(name, instance)
65
66#define BeginConfig(name, instance) \
67 { \
68 constexpr const char* preopt = ""; \
69 constexpr const char preoptshort = 0; \
70 name& tmp = instance; \
71 bool tmpfound = true; \
72 if (found) { \
73 }
74
75#define BeginSubConfig(name, instance, parent, preoptname, preoptnameshort, descr, ...) \
76 { \
77 [[maybe_unused]] constexpr const char* preopt = preoptname; \
78 [[maybe_unused]] constexpr const char preoptshort = preoptnameshort; \
79 [[maybe_unused]] name& tmp = parent.instance; \
80 bool tmpfound = true; \
81 if (found) { \
82 }
83
84#define BeginHiddenConfig(name, instance) \
85 { \
86 bool tmpfound; \
87 if (0) { \
88 }
89
90// clang-format off
91#define EndConfig() \
92 else { tmpfound = false; } \
93 if (tmpfound) { \
94 found = true; \
95 } \
96 }
97// clang-format on
98
99#define AddHelp(cmd, cmdshort) \
100 else if (QCONFIG_COMPARE(cmd, "", cmdshort)) \
101 { \
102 const char* arg = getArg(i, argv, argc); \
103 qConfigHelp(arg ? arg : preopt); \
104 return (qcrHelp); \
105 }
106
107#define AddHelpAll(cmd, cmdshort) \
108 else if (QCONFIG_COMPARE(cmd, "", cmdshort)) \
109 { \
110 const char* arg = getArg(i, argv, argc); \
111 qConfigHelp(arg ? arg : "", true); \
112 return (qcrHelp); \
113 }
114
115#define AddCommand(cmd, cmdshort, command, help) \
116 else if (QCONFIG_COMPARE(cmd, "", cmdshort)) \
117 { \
118 if (command) { \
119 return (qcrCmd); \
120 } \
121 }
122
123#define AddShortcut(cmd, cmdshort, forward, help, ...) \
124 else if (QCONFIG_COMPARE(cmd, "", cmdshort)) \
125 { \
126 const char* options[] = {"", __VA_ARGS__, nullptr}; \
127 const int32_t nOptions = sizeof(options) / sizeof(options[0]) - 1; \
128 qConfigParse(nOptions, options, nullptr); \
129 thisoption = forward; \
130 goto repeat; \
131 }
132
133// End QCONFIG_PARSE
134#elif defined(QCONFIG_HELP)
135#define AddOption(name, type, default, optname, optnameshort, ...) qConfigType<type>::qConfigHelpOption(qon_mxstr(name), qon_mxstr(type), qon_mxstr(default), optname, optnameshort, preopt, preoptshort, 0, __VA_ARGS__);
136#define AddOptionSet(name, type, value, optname, optnameshort, ...) qConfigType<type>::qConfigHelpOption(qon_mxstr(name), qon_mxstr(type), qon_mxstr(value), optname, optnameshort, preopt, preoptshort, 1, __VA_ARGS__);
137#define AddOptionVec(name, type, optname, optnameshort, ...) qConfigType<type>::qConfigHelpOption(qon_mxstr(name), qon_mxstr(type), nullptr, optname, optnameshort, preopt, preoptshort, 2, __VA_ARGS__);
138#define AddOptionArray(name, type, count, default, optname, optnameshort, ...) qConfigType<type>::qConfigHelpOption(qon_mxstr(name), qon_mxstr(type) "[" qon_mxstr(count) "]", nullptr, optname, optnameshort, preopt, preoptshort, 2, __VA_ARGS__);
139#define AddSubConfig(name, instance) \
140 printf("\t%s\n\n", qon_mxcat(qConfig_subconfig_, name)); \
141 if (followSub) { \
142 qConfigHelp(qon_mxstr(name), 2); \
143 }
144#define BeginConfig(name, instance) \
145 if (subConfig == nullptr || *subConfig == 0) { \
146 constexpr const char* preopt = ""; \
147 constexpr const char preoptshort = 0; \
148 printf("\n");
149#define BeginSubConfig(name, instance, parent, preoptname, preoptnameshort, descr, ...) \
150 const char* qon_mxcat(qConfig_subconfig_, name) = preoptnameshort == 0 ? (qon_mxstr(name) ": --" preoptname "\n\t\t" descr) : (qon_mxstr(name) ": -" qon_mxstr('a') " (--" preoptname ")\n\t\t" descr); \
151 (void)qon_mxcat(qConfig_subconfig_, name); \
152 if (subConfig == nullptr || strcmp(subConfig, followSub == 2 ? qon_mxstr(name) : preoptname) == 0) { \
153 [[maybe_unused]] constexpr const char* preopt = preoptname; \
154 [[maybe_unused]] constexpr const char preoptshort = preoptnameshort; \
155 char argBuffer[2] = {preoptnameshort, 0}; \
156 printf("\n %s: (--%s%s%s)\n", descr, preoptname, preoptnameshort == 0 ? "" : " or -", argBuffer);
157#define BeginHiddenConfig(name, instance) {
158#define EndConfig() }
159#define AddHelp(cmd, cmdshort) qConfigType<void*>::qConfigHelpOption("help", "help", nullptr, cmd, cmdshort, preopt, preoptshort, 3, "Show usage information");
160#define AddHelpAll(cmd, cmdshort) qConfigType<void*>::qConfigHelpOption("help all", "help all", nullptr, cmd, cmdshort, preopt, preoptshort, 3, "Show usage info including all subparameters");
161#define AddCommand(cmd, cmdshort, command, help) qConfigType<void*>::qConfigHelpOption("command", "command", nullptr, cmd, cmdshort, preopt, preoptshort, 4, help);
162#define AddShortcut(cmd, cmdshort, forward, help, ...) qConfigType<void*>::qConfigHelpOption("shortcut", "shortcut", nullptr, cmd, cmdshort, preopt, preoptshort, 4, help);
163#define AddHelpText(text) printf("\n " text ":\n");
164
165// End QCONFIG_HELP
166#elif defined(QCONFIG_PRINT)
167template <class T>
168void qConfigPrint(const T& qconfig_tmp_object, const std::string& blockName); // (Re)declare in the namespace of the include for the specializations below, default argument only in qconfig_general.h
169#define AddOption(name, type, default, optname, optnameshort, ...) std::cout << "\t" << blockName << qon_mxstr(name) << ": " << ::qConfig::print_type(qconfig_tmp_object.name) << "\n";
170#define AddVariable(name, type, default) std::cout << "\t" << blockName << qon_mxstr(name) << ": " << ::qConfig::print_type(qconfig_tmp_object.name) << "\n";
171#define AddOptionSet(name, type, value, optname, optnameshort, ...)
172#define AddOptionVec(name, type, optname, optnameshort, ...) \
173 { \
174 std::cout << "\t" << blockName << qon_mxstr(name) << "[]: "; \
175 for (uint32_t i = 0; i < qconfig_tmp_object.name.size(); i++) { \
176 if (i) { \
177 std::cout << ", "; \
178 } \
179 std::cout << ::qConfig::print_type(qconfig_tmp_object.name[i]); \
180 } \
181 std::cout << "\n"; \
182 }
183#define AddOptionArray(name, type, count, default, optname, optnameshort, ...) \
184 { \
185 std::cout << "\t" << blockName << qon_mxstr(name) << "[" << count << "]: " << ::qConfig::print_type(qconfig_tmp_object.name[0]); \
186 for (int32_t i = 1; i < count; i++) { \
187 std::cout << ", " << ::qConfig::print_type(qconfig_tmp_object.name[i]); \
188 } \
189 std::cout << "\n"; \
190 }
191#define AddSubConfig(name, instance) qConfigPrint(qconfig_tmp_object.instance, blockName + qon_mxstr(instance.));
192#define AddHelpText(text) printf(" " text ":\n");
193#define BeginConfig(name, instance) \
194 void qConfigPrint(const name& qconfig_tmp_object); \
195 bool qon_mxcat(qprint_global_, instance) = []() { qprint_global.emplace_back([]() { qConfigPrint(instance); }); return true; }(); \
196 void qConfigPrint(const name& qconfig_tmp_object) \
197 { \
198 std::string blockName = "";
199#define BeginSubConfig(name, instance, parent, preoptname, preoptnameshort, descr, ...) \
200 template <> \
201 void qConfigPrint<name>(const name& qconfig_tmp_object, const std::string& blockName) \
202 { \
203 std::cout << "\n\t" << qon_mxstr(name) << ":\n";
204#define BeginHiddenConfig(name, instance) BeginSubConfig(name, instance, x, x, x, x)
205
206#define EndConfig() }
207
208// End QCONFIG_PRINT
209#elif defined(QCONFIG_INSTANCE)
210#define BeginNamespace(name) \
211 using namespace name; \
212 namespace name \
213 {
214#define EndNamespace() }
215#define AddOption(name, type, default, optname, optnameshort, help, ...)
216#define AddVariable(name, type, default)
217#define AddOptionSet(name, type, value, optname, optnameshort, help, ...)
218#define AddOptionVec(name, type, optname, optnameshort, help, ...)
219#define AddOptionArray(name, type, count, default, optname, optnameshort, help, ...)
220#define AddSubConfig(name, instance)
221#define BeginConfig(name, instance) name instance;
222#define BeginSubConfig(name, instance, parent, preoptname, preoptnameshort, descr, ...)
223#define EndConfig()
224
225// End QCONFIG_INSTANCE
226#elif defined(QCONFIG_PRINT_RTC)
227#define AddOption(name, type, default, optname, optnameshort, help, ...) out << qon_mxstr(type) << " " << qon_mxstr(name) << ";\n";
228#define AddVariable(name, type, default) out << qon_mxstr(type) << " " << qon_mxstr(name) << ";\n";
229#define AddOptionArray(name, type, count, default, optname, optnameshort, help, ...) out << qon_mxstr(type) << " " << qon_mxstr(name) << "[" << qon_mxstr(count) << "];\n";
230#define AddOptionVec(name, type, optname, optnameshort, help, ...) out << "std::vector<" << qon_mxstr(type) << "> " << qon_mxstr(name) << ";\n";
231#define AddVariableRTC(name, type, default) \
232 if (useConstexpr) { \
233 out << "static constexpr " << qon_mxstr(type) << " " << qon_mxstr(name) << " = " << ::qConfig::print_type(std::get<const qConfigCurrentType*>(tSrc)->name, true) << ";\n"; \
234 out << qon_mxstr(type) << " " << qon_mxstr(qon_mxcat(_dummy_, name)) << ";\n"; \
235 } else { \
236 AddOption(name, type, default, optname, optnameshort, help); \
237 }
238#define AddOptionRTC(name, type, default, optname, optnameshort, help, ...) AddVariableRTC(name, type, default)
239#define AddOptionArrayRTC(name, type, count, default, optname, optnameshort, help, ...) \
240 if (useConstexpr) { \
241 out << "static constexpr " << qon_mxstr(type) << " " << qon_mxstr(name) << "[" << count << "] = {" << ::qConfig::print_type(std::get<const qConfigCurrentType*>(tSrc)->name[0]); \
242 for (int32_t i = 1; i < count; i++) { \
243 out << ", " << qConfig::print_type(std::get<const qConfigCurrentType*>(tSrc)->name[i]); \
244 } \
245 out << "};\n"; \
246 out << qon_mxstr(type) << " " << qon_mxstr(qon_mxcat(_dummy_, name)) << ";\n"; \
247 } else { \
248 AddOptionArray(name, type, count, default, optname, optnameshort, help); \
249 }
250#define BeginConfig(name, instance) \
251 { \
252 using qConfigCurrentType = name; \
253 out << "struct " << qon_mxstr(name) << " {\n";
254#define BeginSubConfig(name, instance, parent, preoptname, preoptnameshort, descr, ...) BeginConfig(name, instance)
255#define EndConfig() \
256 out << "};\n"; \
257 }
258#define BeginNamespace(name) out << "namespace " << qon_mxstr(name) << " {\n";
259#define EndNamespace() out << "}\n";
260#define AddSubConfig(name, instance) out << qon_mxstr(name) << " " << qon_mxstr(instance) << ";";
261#define AddOptionSet(...)
262
263// End QCONFIG_PRINT_RTC
264#elif defined(QCONFIG_GEN_RTTI)
265#define QCONFIG_RTTI(vName, vType, rtc, variable, vector, count, defaultValue, ...) \
266 qConfigRTTIEntry<vType>(retVal, \
267 T{::qConfig::qConfigRTTIentry{.name = qon_mxstr(vName), .type = qon_mxstr(vType), .isRTC = rtc, .isVariable = variable, .isVector = vector, .offset = static_cast<size_t>(reinterpret_cast<const char*>(&qConfigObject.vName) - reinterpret_cast<const char*>(&qConfigObject)), .configStruct = qConfigStruct}}, \
268 count, *qConfigStructIndex, defaultValue, __VA_ARGS__);
269#define AddOption(name, type, default, optname, optnameshort, ...) QCONFIG_RTTI(name, type, false, false, false, 0, print_type(static_cast<type>(default)), __VA_ARGS__)
270#define AddOptionRTC(name, type, default, optname, optnameshort, ...) QCONFIG_RTTI(name, type, true, false, false, 0, print_type(static_cast<type>(default)), __VA_ARGS__)
271#define AddVariable(name, type, default) QCONFIG_RTTI(name, type, false, true, false, 0, print_type(static_cast<type>(default)), "")
272#define AddVariableRTC(name, type, default) QCONFIG_RTTI(name, type, true, true, false, 0, print_type(static_cast<type>(default)), "")
273#define AddOptionVec(name, type, optname, optnameshort, ...) QCONFIG_RTTI(name, type, false, false, true, 0, "", __VA_ARGS__)
274#define AddOptionArray(name, type, count, default, optname, optnameshort, ...) QCONFIG_RTTI(name, type, false, false, false, count, qon_mxstr(default), __VA_ARGS__)
275#define AddOptionArrayRTC(name, type, count, default, optname, optnameshort, ...) QCONFIG_RTTI(name, type, true, false, false, count, qon_mxstr(default), __VA_ARGS__)
276#define AddOptionSet(...)
277#define AddSubConfig(name, instance)
278#define BeginConfig(name, instance) \
279 if constexpr (qConfigRTTISelected<name, Structs...>) { \
280 if (const auto qConfigStructIndex = qConfigRTTIStructIndex<name, Structs...>(retStructs, qon_mxstr(name), configStructs != nullptr)) { \
281 [[maybe_unused]] constexpr const char* qConfigStruct = qon_mxstr(name); \
282 [[maybe_unused]] const name qConfigObject{}; // Default-constructed instance to compute the member offsets
283#define BeginSubConfig(name, instance, parent, preoptname, preoptnameshort, descr, ...) BeginConfig(name, instance)
284#define EndConfig() \
285 } \
286 }
287
288// End QCONFIG_GEN_RTTI
289#else // Define structures
290
291#error Internal error, qconfig_internal called with action type
292
293#endif
294
295#define QCONFIG_INTERNAL
296#include "qconfig_wrapinclude.h"
297#undef QCONFIG_INTERNAL
void qConfigPrint()
Definition qconfig.cxx:430