Developer documentation
Version 3.0.3-105-gd3941f44
app.h
Go to the documentation of this file.
1/* Copyright (c) 2008-2022 the MRtrix3 contributors.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 *
7 * Covered Software is provided under this License on an "as is"
8 * basis, without warranty of any kind, either expressed, implied, or
9 * statutory, including, without limitation, warranties that the
10 * Covered Software is free of defects, merchantable, fit for a
11 * particular purpose or non-infringing.
12 * See the Mozilla Public License v. 2.0 for more details.
13 *
14 * For more details, see http://www.mrtrix.org/.
15 */
16
17#ifndef __app_h__
18#define __app_h__
19
20#include <cstring>
21#include <limits>
22#include <string>
23#include <thread>
24
25#ifdef None
26# undef None
27#endif
28
29#include "cmdline_option.h"
30#include "types.h"
31#include "file/path.h"
32
33
34extern void usage ();
35extern void run ();
36
37namespace MR
38{
39 namespace App
40 {
41
42
43 extern const char* mrtrix_version;
44 extern const char* build_date;
45 extern int log_level;
46 extern int exit_error_code;
47 extern std::string NAME;
48 extern std::string command_history_string;
49 extern bool overwrite_files;
50 extern void (*check_overwrite_files_func) (const std::string& name);
51 extern bool fail_on_warn;
52 extern bool terminal_use_colour;
53 extern const std::thread::id main_thread_ID;
54
55 extern int argc;
56 extern const char* const* argv;
57
58 extern const char* project_version;
59 extern const char* project_build_date;
60
61
62 const char* argtype_description (ArgType type);
63
64 std::string help_head (int format);
65 std::string help_synopsis (int format);
66 std::string help_tail (int format);
67 std::string usage_syntax (int format);
68
69
70
71
73 // @{
74
76 class Description : public vector<const char*> { NOMEMALIGN
77 public:
78 Description& operator+ (const char* text) {
79 push_back (text);
80 return *this;
81 }
82
83 Description& operator+ (const char* const text[]) {
84 for (const char* const* p = text; *p; ++p)
85 push_back (*p);
86 return *this;
87 }
88
89 std::string syntax (int format) const;
90 };
91
92
93
96 public:
97 Example (const std::string& title,
98 const std::string& code,
99 const std::string& description) :
100 title (title),
101 code (code),
103 const std::string title, code, description;
104
105 operator std::string () const;
106 std::string syntax (int format) const;
107 };
108
110 class ExampleList : public vector<Example> { NOMEMALIGN
111 public:
112 ExampleList& operator+ (const Example& example) {
113 push_back (example);
114 return *this;
115 }
116
117 std::string syntax (int format) const;
118 };
119
120
121
122
124 class ArgumentList : public vector<Argument> { NOMEMALIGN
125 public:
127 push_back (argument);
128 return *this;
129 }
130
131 std::string syntax (int format) const;
132 };
133
134
135
136
137
139 class OptionList : public vector<OptionGroup> { NOMEMALIGN
140 public:
141 OptionList& operator+ (const OptionGroup& option_group) {
142 push_back (option_group);
143 return *this;
144 }
145
147 back() + option;
148 return *this;
149 }
150
152 back() + argument;
153 return *this;
154 }
155
157 if (empty())
158 push_back (OptionGroup());
160 }
161
162 std::string syntax (int format) const;
163 };
164
165
166
167
168 inline void check_overwrite (const std::string& name)
169 {
173 else
174 throw Exception ("output file \"" + name + "\" already exists (use -force option to force overwrite)");
175 }
176 }
177
178
179
180
182
185 void init (int argc, const char* const* argv);
186
189
192
194 void parse ();
195
197 void sort_arguments (int argc, const char* const* argv);
198
200 const Option* match_option (const char* stub);
201
203 std::string full_usage ();
204
205
206
207
208
210 public:
211 operator std::string () const { return p; }
212
213 const char* as_text () const { return p; }
214 bool as_bool () const { return to<bool> (p); }
215 int64_t as_int () const;
216 uint64_t as_uint () const { return uint64_t (as_int()); }
218
220 assert (arg->type == IntSeq);
221 try { return parse_ints<int32_t> (p); }
222 catch (Exception& e) { error (e); }
223 return vector<int32_t>();
224 }
225
227 assert (arg->type == IntSeq);
228 try { return parse_ints<uint32_t> (p); }
229 catch (Exception& e) { error (e); }
230 return vector<uint32_t>();
231 }
232
234 assert (arg->type == FloatSeq);
235 try { return parse_floats (p); }
236 catch (Exception& e) { error (e); }
237 return vector<default_type>();
238 }
239
240 operator bool () const { return as_bool(); }
241 operator int () const { return as_int(); }
242 operator unsigned int () const { return as_uint(); }
243 operator long int () const { return as_int(); }
244 operator long unsigned int () const { return as_uint(); }
245 operator long long int () const { return as_int(); }
246 operator long long unsigned int () const { return as_uint(); }
247 operator float () const { return as_float(); }
248 operator double () const { return as_float(); }
249 operator vector<int32_t> () const { return as_sequence_int(); }
250 operator vector<uint32_t> () const { return as_sequence_uint(); }
251 operator vector<default_type> () const { return as_sequence_float(); }
252
253 const char* c_str () const { return p; }
254
255 private:
256 const Option* opt;
257 const Argument* arg;
258 const char* p;
259
260 ParsedArgument (const Option* option, const Argument* argument, const char* text) :
261 opt (option), arg (argument), p (text) {
262 assert (text);
263 }
264
265 void error (Exception& e) const {
266 std::string msg ("error parsing token \"");
267 msg += p;
268 if (opt) msg += std::string ("\" for option \"") + opt->id + "\"";
269 else msg += std::string ("\" for argument \"") + arg->id + "\"";
270 throw Exception (e, msg);
271 }
272
273 friend class ParsedOption;
274 friend class Options;
275 friend void MR::App::init (int argc, const char* const* argv);
276 friend void MR::App::parse ();
277 friend void MR::App::sort_arguments (int argc, const char* const* argv);
278 };
279
280
281
282
284
287 public:
288 ParsedOption (const Option* option, const char* const* arguments) :
289 opt (option), args (arguments)
290 {
291 for (size_t i = 0; i != option->size(); ++i) {
292 const char* p = arguments[i];
293 if (!consume_dash (p))
294 continue;
295 if (( (*option)[i].type == ImageIn || (*option)[i].type == ImageOut ) && is_dash (arguments[i]))
296 continue;
297 if ((*option)[i].type == Integer || (*option)[i].type == Float || (*option)[i].type == IntSeq ||
298 (*option)[i].type == FloatSeq || (*option)[i].type == Various)
299 continue;
300 WARN (std::string("Value \"") + arguments[i] + "\" is being used as " +
301 ((option->size() == 1) ?
302 "the expected argument " :
303 ("one of the " + str(option->size()) + " expected arguments ")) +
304 "for option \"-" + option->id + "\", yet this itself looks like a separate command-line option; " +
305 "the requisite input" +
306 ((option->size() == 1) ? " " : "s ") +
307 "to command-line option \"-" + option->id + "\" may have been erroneously omitted, which may cause " +
308 "other command-line parsing errors");
309 }
310 }
311
313 const Option* opt;
315 const char* const* args;
316
317 const ParsedArgument operator[] (size_t num) const {
318 assert (num < opt->size());
319 return ParsedArgument (opt, & (*opt) [num], args[num]);
320 }
321
323 bool operator== (const char* match) const {
324 std::string name = lowercase (match);
325 return name == opt->id;
326 }
327
328 };
329
330
335
337
350 extern Description DESCRIPTION;
351
353
369 extern ExampleList EXAMPLES;
370
372
386 extern ArgumentList ARGUMENTS;
387
389
405 extern OptionList OPTIONS;
406
407
409
412
414 extern const char* AUTHOR;
415
417 extern const char* COPYRIGHT;
418
420 extern const char* SYNOPSIS;
421
423
425 extern Description REFERENCES;
426
427
429 extern OptionGroup __standard_options;
430
431
432
434
451 const vector<ParsedOption> get_options (const std::string& name);
452
453
455
464 template <typename T>
465 inline T get_option_value (const std::string& name, const T default_value)
466 {
467 auto opt = get_options(name);
468 T r = (opt.size()) ? opt[0][0] : default_value;
469 return r;
470 }
471
472
474 inline std::string operator+ (const char* left, const App::ParsedArgument& right)
475 {
476 std::string retval (left);
477 retval += std::string (right);
478 return retval;
479 }
480
481
482 inline std::ostream& operator<< (std::ostream& stream, const App::ParsedArgument& arg)
483 {
484 stream << std::string (arg);
485 return stream;
486 }
487
488 }
489
491}
492
493#endif
void run()
void usage()
A class to specify a command-line argument.
ArgType type
the argument type
const char * id
the argument name
a class to hold the list of Argument's
Definition: app.h:124
ArgumentList & operator+(const Argument &argument)
Definition: app.h:126
std::string syntax(int format) const
vector of strings to hold more comprehensive command description
Definition: app.h:76
Description & operator+(const char *text)
Definition: app.h:78
std::string syntax(int format) const
object for storing a single example command usage
Definition: app.h:95
const std::string description
Definition: app.h:103
const std::string title
Definition: app.h:103
const std::string code
Definition: app.h:103
std::string syntax(int format) const
Example(const std::string &title, const std::string &code, const std::string &description)
Definition: app.h:97
a class to hold the list of Example's
Definition: app.h:110
ExampleList & operator+(const Example &example)
Definition: app.h:112
std::string syntax(int format) const
a class to hold a named list of Option's
A class to specify a command-line option.
const char * id
the option name
a class to hold the list of option groups
Definition: app.h:139
OptionGroup & back()
Definition: app.h:156
OptionList & operator+(const OptionGroup &option_group)
Definition: app.h:141
std::string syntax(int format) const
const char * c_str() const
Definition: app.h:253
vector< uint32_t > as_sequence_uint() const
Definition: app.h:226
default_type as_float() const
vector< default_type > as_sequence_float() const
Definition: app.h:233
bool as_bool() const
Definition: app.h:214
int64_t as_int() const
vector< int32_t > as_sequence_int() const
Definition: app.h:219
friend class Options
Definition: app.h:274
uint64_t as_uint() const
Definition: app.h:216
const char * as_text() const
Definition: app.h:213
object storing information about option parsed from command-line
Definition: app.h:286
const char *const * args
pointer into argv corresponding to the option's first argument
Definition: app.h:315
bool operator==(const char *match) const
check whether this option matches the name supplied
Definition: app.h:323
const ParsedArgument operator[](size_t num) const
Definition: app.h:317
const Option * opt
reference to the corresponding Option entry in the OPTIONS section
Definition: app.h:313
ParsedOption(const Option *option, const char *const *arguments)
Definition: app.h:288
#define WARN(msg)
Definition: exception.h:73
constexpr double e
Definition: math.h:39
#define NOMEMALIGN
Definition: memory.h:22
std::string full_usage()
dump formatted help page [used internally]
void verify_usage()
verify that command's usage() function has set requisite fields [used internally]
const vector< ParsedOption > get_options(const std::string &name)
return all command-line options matching name
int log_level
Definition: exception.h:34
void init(int argc, const char *const *argv)
initialise MRtrix and parse command-line arguments
std::ostream & operator<<(std::ostream &stream, const App::ParsedArgument &arg)
Definition: app.h:482
void check_overwrite(const std::string &name)
Definition: app.h:168
std::string operator+(const char *left, const App::ParsedArgument &right)
convenience function provided mostly to ease writing Exception strings
Definition: app.h:474
OptionList OPTIONS
the options accepted by the command
bool fail_on_warn
const char *const * argv
ExampleList EXAMPLES
example usages of the command
const char * mrtrix_version
vector< ParsedArgument > argument
the list of arguments parsed from the command-line
const char * AUTHOR
set the author of the command
std::string help_synopsis(int format)
const char * COPYRIGHT
set the copyright notice if different from that used in MRtrix
const char * argtype_description(ArgType type)
int exit_error_code
Definition: exception.h:35
void parse_special_options()
option parsing that should happen before GUI creation [used internally]
const char * SYNOPSIS
set a one-sentence synopsis for the command
std::string usage_syntax(int format)
T get_option_value(const std::string &name, const T default_value)
Returns the option value if set, and the default otherwise.
Definition: app.h:465
Description DESCRIPTION
additional description of the command over and above the synopsis
std::string help_head(int format)
void(* check_overwrite_files_func)(const std::string &name)
const char * project_version
Description REFERENCES
add references to command help page
std::string command_history_string
const std::thread::id main_thread_ID
const char * project_build_date
bool REQUIRES_AT_LEAST_ONE_ARGUMENT
set to false if command can operate with no arguments
const Option * match_option(const char *stub)
uniquely match option stub to Option
std::string NAME
Definition: debug.h:25
void sort_arguments(int argc, const char *const *argv)
sort command-line tokens into arguments and options [used internally]
bool terminal_use_colour
bool overwrite_files
std::string help_tail(int format)
ArgumentList ARGUMENTS
the arguments expected by the command
const char * build_date
void parse()
do the actual parsing of the command-line [used internally]
OptionGroup __standard_options
the group of standard options for all commands
vector< ParsedOption > option
the list of options parsed from the command-line
bool exists(const std::string &path)
Definition: path.h:88
Definition: base.h:24
bool consume_dash(const char *&arg)
match current character to a dash or any Unicode character that looks like one
Definition: mrtrix.h:236
vector< default_type > parse_floats(const std::string &spec)
double default_type
the default type used throughout MRtrix
Definition: types.h:228
bool match(const std::string &pattern, const std::string &text, bool ignore_case=false)
bool to< bool >(const std::string &string)
Definition: mrtrix.h:285
std::string str(const T &value, int precision=0)
Definition: mrtrix.h:247
std::string lowercase(const std::string &string)
return lowercase version of string
Definition: mrtrix.h:98
size_t is_dash(const std::string &arg)
match whole string to a dash or any Unicode character that looks like one
Definition: mrtrix.h:225
size_t num
Definition: thread.h:216
const std::string name
Definition: thread.h:108