TTK
Loading...
Searching...
No Matches
CommandLineParser.h
Go to the documentation of this file.
1
7
8#pragma once
9
10#include <Debug.h>
11
12namespace ttk {
13
14 class CommandLineParser : public Debug {
15
16 public:
17 // 1) constructors, destructors, operators, etc.
18 class CommandLineArgument : public Debug {
19
20 public:
22 boolValue_ = nullptr;
23 intValue_ = nullptr;
24 intValueList_ = nullptr;
25 doubleValue_ = nullptr;
26 doubleValueList_ = nullptr;
27 stringValue_ = nullptr;
28 stringValueList_ = nullptr;
29 isSet_ = false;
30
31 setDebugMsgPrefix("CMD");
32 }
33
34 int print(std::ostream &stream) const {
35 std::string s;
36 s = " ";
37 if((isAnOption_) || (isOptional_)) {
38 s += "[";
39 }
40
41 s += "-";
42 s += key_;
43
44 if(isAnOption_)
45 s += ":";
46
47 s += " ";
48 if(!isAnOption_) {
49 s += "<";
51 s += "{";
52 }
53 }
54
55 if(description_.length()) {
56 s += description_;
57 } else {
58 s += "no description";
59 }
60
61 if((stringValue_) || (intValue_) || (doubleValue_)) {
62 s += " (default: ";
63 if(stringValue_) {
64 s += "`";
65 s += *stringValue_;
66 s += "'";
67 }
68 if(intValue_)
69 s += std::to_string(*intValue_);
70 if(doubleValue_)
71 s += std::to_string(*doubleValue_);
72 s += ")";
73 }
74
75 if(isAnOption_) {
76 s += " (default: ";
77 s += std::to_string(*boolValue_);
78 s += ")";
79 }
80
81 if(!isAnOption_) {
83 s += "}";
84 }
85 s += ">";
86 }
87
88 if((isAnOption_) || (isOptional_)) {
89 s += "]";
90 }
91
93
94 return 0;
95 }
96
101 std::string *stringValue_;
102 std::vector<int> *intValueList_;
103 std::vector<double> *doubleValueList_;
104 std::vector<std::string> *stringValueList_;
105
106 std::string key_;
107 std::string description_;
108 };
109
111 // running from the command line, add a default value.
113 setArgument("d", &(ttk::globalDebugLevel_), "Global debug level", true);
114 setArgument("t", &ttk::globalThreadNumber_, "Global thread number", true);
116
117 setDebugMsgPrefix("CMD");
118 }
119
120 ~CommandLineParser() override = default;
121
122 // 2) functions
123 int parse(int argc, char **argv) {
124
125 for(int i = 0; i < argc; i++) {
126
127 if((std::string(argv[i]) == "-h")
128 || (std::string(argv[i]) == "--help")) {
129 printUsage(argv[0]);
130 }
131
132 for(int j = 0; j < (int)arguments_.size(); j++) {
133
134 if(!arguments_[j].isAnOption_) {
135 if((std::string(argv[i]) == "-" + arguments_[j].key_)
136 && (i + 1 < argc)) {
137
138 if(arguments_[j].stringValue_) {
139 // let's process a std::string
140 (*arguments_[j].stringValue_) = argv[i + 1];
141 arguments_[j].isSet_ = true;
142 } else if(arguments_[j].stringValueList_) {
143 arguments_[j].stringValueList_->push_back(argv[i + 1]);
144 arguments_[j].isSet_ = true;
145 } else if(arguments_[j].intValue_) {
146 std::stringstream s(argv[i + 1]);
147 s >> *(arguments_[j].intValue_);
148 arguments_[j].isSet_ = true;
149 } else if(arguments_[j].intValueList_) {
150 std::stringstream s(argv[i + 1]);
151 arguments_[j].intValueList_->resize(
152 arguments_[j].intValueList_->size() + 1);
153 s >> arguments_[j].intValueList_->back();
154 arguments_[j].isSet_ = true;
155 } else if(arguments_[j].doubleValue_) {
156 std::stringstream s(argv[i + 1]);
157 s >> *(arguments_[j].doubleValue_);
158 arguments_[j].isSet_ = true;
159 } else if(arguments_[j].doubleValueList_) {
160 std::stringstream s(argv[i + 1]);
161 arguments_[j].doubleValueList_->resize(
162 arguments_[j].doubleValueList_->size() + 1);
163 s >> arguments_[j].doubleValueList_->back();
164 arguments_[j].isSet_ = true;
165 }
166 }
167 } else {
168 if(std::string(argv[i]) == "-" + arguments_[j].key_) {
169 *(arguments_[j].boolValue_) = !(*(arguments_[j].boolValue_));
170 }
171 }
172 }
173 }
174
175 // check all the necessary arguments have been provided
176 for(int i = 0; i < (int)arguments_.size(); i++) {
177 if(!arguments_[i].isOptional_) {
178 if(!arguments_[i].isSet_) {
179 printMsg(
181 printMsg("Missing mandatory argument:", debug::Priority::ERROR,
182 debug::LineMode::NEW, std::cerr);
183 arguments_[i].print(std::cerr);
184 printUsage(argv[0]);
185 }
186 }
187 }
188
190
191 return 0;
192 }
193
194 int printArgs(std::ostream &o = std::cout) const {
195
196 printMsg("Options and arguments:", debug::Priority::INFO,
198 for(int i = 0; i < (int)arguments_.size(); i++) {
199 std::string s;
200 s += " -";
201 s += arguments_[i].key_;
202 s += ": ";
203
204 if(arguments_[i].isAnOption_) {
205 if(arguments_[i].boolValue_) {
206 if(*(arguments_[i].boolValue_))
207 s += "true";
208 else
209 s += "false";
210 } else {
211 s += "(not set)";
212 }
213 } else if(arguments_[i].stringValue_) {
214 if(arguments_[i].isSet_) {
215 s += *(arguments_[i].stringValue_);
216 } else {
217 s += "(not set)";
218 }
219 } else if(arguments_[i].stringValueList_) {
220 if(!arguments_[i].isSet_) {
221 s += "(not set)";
222 } else {
223 for(int j = 0; j < (int)arguments_[i].stringValueList_->size();
224 j++) {
225 s += (*(arguments_[i].stringValueList_))[j];
226 s += " ";
227 }
228 }
229 } else if(arguments_[i].intValue_) {
230 if(!arguments_[i].isSet_) {
231 s += "(not set)";
232 } else {
233 s += std::to_string(*(arguments_[i].intValue_));
234 }
235 } else if(arguments_[i].intValueList_) {
236 if(!arguments_[i].isSet_) {
237 s += "(not set)";
238 } else {
239 for(int j = 0; j < (int)arguments_[i].intValueList_->size(); j++) {
240 s += std::to_string((*(arguments_[i].intValueList_))[j]);
241 s += " ";
242 }
243 }
244 } else if(arguments_[i].doubleValue_) {
245 if(!arguments_[i].isSet_) {
246 s += "(not set)";
247 } else {
248 s += std::to_string(*(arguments_[i].doubleValue_));
249 }
250 } else if(arguments_[i].doubleValueList_) {
251 if(!arguments_[i].isSet_) {
252 s += "(not set)";
253 } else {
254 for(int j = 0; j < (int)arguments_[i].doubleValueList_->size();
255 j++) {
256 s += std::to_string((*(arguments_[i].doubleValueList_))[j]);
257 s += " ";
258 }
259 }
260 }
261
263 }
264
265 return 0;
266 }
267
268 int printUsage(const std::string &binPath) const {
269
271 printMsg(
272 "Usage:", debug::Priority::ERROR, debug::LineMode::NEW, std::cerr);
274 std::cerr);
275
277 std::cerr);
278 for(int i = 0; i < (int)arguments_.size(); i++) {
279 if(!arguments_[i].isAnOption_) {
280 arguments_[i].print(std::cerr);
281 }
282 }
283
284 printMsg(
285 "Option(s):", debug::Priority::ERROR, debug::LineMode::NEW, std::cerr);
286 for(int i = 0; i < (int)arguments_.size(); i++) {
287 if(arguments_[i].isAnOption_) {
288 arguments_[i].print(std::cerr);
289 }
290 }
291
292 exit(0);
293 return 0;
294 }
295
296 int setOption(const std::string &key,
297 bool *value,
298 const std::string &description = "") {
299
300 if(!value)
301 return -1;
302
303 arguments_.resize(arguments_.size() + 1);
304 arguments_.back().isOptional_ = true;
305 arguments_.back().key_ = key;
306 arguments_.back().description_ = description;
307 arguments_.back().boolValue_ = value;
308 arguments_.back().isAnOption_ = true;
309
310 return 0;
311 }
312
313 int setArgument(const std::string &key,
314 double *value,
315 const std::string &description = "",
316 const bool &optional = false) {
317
318 if(!value)
319 return -1;
320
321 arguments_.resize(arguments_.size() + 1);
322 arguments_.back().isOptional_ = optional;
323 arguments_.back().key_ = key;
324 arguments_.back().description_ = description;
325 arguments_.back().doubleValue_ = value;
326 arguments_.back().isAnOption_ = false;
327
328 return 0;
329 }
330
331 int setArgument(const std::string &key,
332 std::vector<double> *value,
333 const std::string &description = "",
334 const bool &optional = false) {
335
336 if(!value)
337 return -1;
338
339 arguments_.resize(arguments_.size() + 1);
340 arguments_.back().isOptional_ = optional;
341 arguments_.back().key_ = key;
342 arguments_.back().description_ = description;
343 arguments_.back().doubleValueList_ = value;
344 arguments_.back().isAnOption_ = false;
345
346 return 0;
347 }
348
349 inline int setArgument(const std::string &key,
350 int *value,
351 const std::string &description = "",
352 const bool &optional = false) {
353
354 if(!value)
355 return -1;
356
357 arguments_.resize(arguments_.size() + 1);
358 arguments_.back().isOptional_ = optional;
359 arguments_.back().key_ = key;
360 arguments_.back().description_ = description;
361 arguments_.back().intValue_ = value;
362 arguments_.back().isAnOption_ = false;
363
364 return 0;
365 }
366
367 int setArgument(const std::string &key,
368 std::vector<int> *value,
369 const std::string &description = "",
370 const bool &optional = false) {
371
372 if(!value)
373 return -1;
374
375 arguments_.resize(arguments_.size() + 1);
376 arguments_.back().isOptional_ = optional;
377 arguments_.back().key_ = key;
378 arguments_.back().description_ = description;
379 arguments_.back().intValueList_ = value;
380 arguments_.back().isAnOption_ = false;
381
382 return 0;
383 }
384
385 int setArgument(const std::string &key,
386 std::string *value,
387 const std::string &description = "",
388 const bool &optional = false) {
389
390 if(!value)
391 return -1;
392
393 arguments_.resize(arguments_.size() + 1);
394 arguments_.back().isOptional_ = optional;
395 arguments_.back().key_ = key;
396 arguments_.back().description_ = description;
397 arguments_.back().stringValue_ = value;
398 arguments_.back().isAnOption_ = false;
399
400 return 0;
401 }
402
403 int setArgument(const std::string &key,
404 std::vector<std::string> *value,
405 const std::string &description = "",
406 const bool &optional = false) {
407
408 if(!value)
409 return -1;
410
411 arguments_.resize(arguments_.size() + 1);
412 arguments_.back().isOptional_ = optional;
413 arguments_.back().key_ = key;
414 arguments_.back().description_ = description;
415 arguments_.back().stringValueList_ = value;
416 arguments_.back().isAnOption_ = false;
417
418 return 0;
419 }
420
421 protected:
422 std::vector<CommandLineArgument> arguments_;
423 };
424} // namespace ttk
int print(std::ostream &stream) const
std::vector< std::string > * stringValueList_
Basic command line parsing.
int printArgs(std::ostream &o=std::cout) const
int setArgument(const std::string &key, std::string *value, const std::string &description="", const bool &optional=false)
int parse(int argc, char **argv)
std::vector< CommandLineArgument > arguments_
int printUsage(const std::string &binPath) const
int setArgument(const std::string &key, std::vector< double > *value, const std::string &description="", const bool &optional=false)
int setArgument(const std::string &key, std::vector< int > *value, const std::string &description="", const bool &optional=false)
int setArgument(const std::string &key, std::vector< std::string > *value, const std::string &description="", const bool &optional=false)
~CommandLineParser() override=default
int setArgument(const std::string &key, double *value, const std::string &description="", const bool &optional=false)
int setOption(const std::string &key, bool *value, const std::string &description="")
int setArgument(const std::string &key, int *value, const std::string &description="", const bool &optional=false)
Minimalist debugging class.
Definition Debug.h:88
int debugLevel_
Definition Debug.h:379
void setDebugMsgPrefix(const std::string &prefix)
Definition Debug.h:364
virtual int setDebugLevel(const int &debugLevel)
Definition Debug.cpp:147
The Topology ToolKit.
COMMON_EXPORTS int globalThreadNumber_
Definition BaseClass.cpp:6
COMMON_EXPORTS int globalDebugLevel_
Definition Debug.cpp:8
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)