libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
cmdlineparser.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <variant>
14#include <promeki/function.h>
15#include <promeki/namespace.h>
16#include <promeki/stringlist.h>
17#include <promeki/string.h>
18#include <promeki/list.h>
19#include <promeki/map.h>
20#include <promeki/logger.h>
21
22PROMEKI_NAMESPACE_BEGIN
23
54class CmdLineParser {
55 public:
57 using OptionCallback = Function<int()>;
58
60 using OptionBoolCallback = Function<int(bool)>;
61
63 using OptionStringCallback = Function<int(const String &)>;
64
66 using OptionIntCallback = Function<int(int)>;
67
69 using OptionDoubleCallback = Function<int(double)>;
70
77 using OptionCallbackVariant = std::variant<OptionCallback, OptionBoolCallback, OptionStringCallback,
78 OptionIntCallback, OptionDoubleCallback>;
79
86 class Option {
87 public:
89 enum ArgType {
90 ArgNone,
91 ArgBool,
92 ArgString,
93 ArgInt,
94 ArgDouble,
95 ArgUnknown
96 };
97
98 char shortName = 0;
99 String longName;
100 String desc;
101 OptionCallbackVariant callback;
102
104 Option() = default;
105
113 Option(char sn, const String &ln, const String &d, OptionCallbackVariant cb)
114 : shortName(sn), longName(ln), desc(d), callback(cb) {}
115
120 ArgType argType() const {
121 if (std::holds_alternative<OptionCallback>(callback)) return ArgNone;
122 if (std::holds_alternative<OptionBoolCallback>(callback)) return ArgBool;
123 if (std::holds_alternative<OptionIntCallback>(callback)) return ArgInt;
124 if (std::holds_alternative<OptionStringCallback>(callback)) return ArgString;
125 if (std::holds_alternative<OptionDoubleCallback>(callback)) return ArgDouble;
126 return ArgUnknown;
127 }
128 };
129
138 void registerOptions(const std::initializer_list<Option> &options) {
139 for (const auto &opt : options) {
140 if (opt.shortName != 0) {
141 _optionsMap[String(1, opt.shortName)] = opt;
142 }
143 if (!opt.longName.isEmpty()) {
144 _optionsMap[opt.longName] = opt;
145 }
146 _options.pushToBack(opt);
147 }
148 }
149
151 CmdLineParser() = default;
152
154 void clear() {
155 _optionsMap.clear();
156 _options.clear();
157 _args.clear();
158 return;
159 }
160
174 int parseMain(int argc, char **argv) {
175 StringList args;
176 if (argc > 1) args.reserve(static_cast<size_t>(argc - 1));
177 for (int i = 1; i < argc; ++i) {
178 const char *a = argv[i] ? argv[i] : "";
179 size_t len = 0;
180 while (a[len]) ++len;
181 args.pushToBack(String::fromUtf8(a, len));
182 }
183 return parse(args);
184 }
185
195 int parse(StringList args);
196
201 int argCount() const { return _args.size(); }
202
208 const String &arg(int index) const { return _args[index]; }
209
214 StringList generateUsage() const;
215
216 private:
217 Map<String, Option> _optionsMap;
218 List<Option> _options;
219 StringList _args;
220
227 static String optionFullName(bool optionName, const Option &option);
228};
229
230PROMEKI_NAMESPACE_END
231
232#endif // PROMEKI_ENABLE_CORE