OpenMEEG
Toggle main menu visibility
Loading...
Searching...
No Matches
OpenMEEG
include
commandline.h
Go to the documentation of this file.
1
// Project Name: OpenMEEG (http://openmeeg.github.io)
2
// © INRIA and ENPC under the French open source license CeCILL-B.
3
// See full copyright notice in the file LICENSE.txt
4
// If you make a copy of this file, you must either:
5
// - provide also LICENSE.txt and modify this header to refer to it.
6
// - replace this header by the LICENSE.txt content.
7
8
#pragma once
9
10
#include <iostream>
11
#include <filesystem>
12
#include <iomanip>
13
#include <string>
14
#include <vector>
15
#include <sstream>
16
#include <initializer_list>
17
18
#ifndef WIN32
19
#define use_color_terminal
20
#endif
21
22
#include "OpenMEEGConfigure.h"
23
24
#ifdef USE_OMP
25
#include <omp.h>
26
#endif
27
28
#include <
filenames.h
>
29
30
namespace
OpenMEEG
{
31
32
class
CommandLine
{
33
34
typedef
std::vector<const char*> Strings;
35
36
// Workaround a bug in old gcc compilers which does not allow the conversion of
37
// const std::initializer_list<const char* const> to const Strings.
38
39
typedef
std::initializer_list<const char* const> List;
40
41
static
Strings build_strings(
const
List& list) {
42
Strings strs;
43
strs.reserve(list.size());
44
for
(
const
auto
& item : list)
45
strs.push_back(item);
46
return
strs;
47
}
48
49
public
:
50
51
CommandLine
(
const
int
argc,
char
* argv[],
const
std::string& usage=
""
): n(argc),args(argv) {
52
help = find_argument(
"-h"
)!=end() || find_argument(
"--help"
)!=end();
53
if
(help) {
54
std::cerr << red << std::filesystem::path(args[0]).filename() << normal;
55
if
(usage!=
""
)
56
std::cerr <<
": "
<< usage;
57
std::cerr << std::endl << std::endl;
58
}
59
}
60
61
bool
help_mode
()
const
{
return
help; }
62
63
template
<
typename
T>
64
T
option
(
const
std::string& name,
const
T defaultvalue,
const
std::string usage)
const
{
65
char
** arg = find_argument(name);
66
const
T result = (arg==end()) ? defaultvalue : parse_value(arg+1,defaultvalue);
67
if
(help)
68
std::cerr <<
" "
<< bold << std::left << std::setw(8) << name << normal
69
<<
" = "
<< std::left << std::setw(12) << value(result) << purple << usage << normal << std::endl;
70
return
result;
71
}
72
73
bool
option
(
const
std::string& name,
const
bool
defaultvalue,
const
std::string usage)
const
{
74
char
** arg = find_argument(name);
75
const
bool
result = (arg==end()) ? defaultvalue : !defaultvalue;
76
if
(help)
77
std::cerr <<
" "
<< bold << std::left << std::setw(8) << name << normal
78
<<
" = "
<< std::left << std::setw(12) << value(result) << purple << usage << normal << std::endl;
79
return
result;
80
}
81
82
char
**
option
(
const
std::string&
option
,
const
Strings& parms,
const
std::size_t num_mandatory_parms)
const
{
83
char
** arg = find_argument(
option
);
84
if
(arg==end())
85
return
nullptr
;
86
87
const
std::size_t num_parms =
num_args
(arg);
88
if
(num_parms<num_mandatory_parms) {
89
std::cerr <<
"\'"
<< args[0] <<
"\' option \'"
<<
option
<<
"\' expects at least "
90
<< num_mandatory_parms <<
" arguments ("
;
91
if
(parms.size()!=0) {
92
std::cerr << parms[0];
93
for
(
unsigned
i=1; i<parms.size(); ++i)
94
std::cerr <<
", "
<< parms[i];
95
}
96
std::cerr <<
") and you gave only "
<< num_parms <<
" arguments."
<< std::endl;
97
exit(1);
98
}
99
return
arg;
100
}
101
102
char
**
option
(
const
std::string& name,
const
Strings& parms)
const
{
return
option
(name,parms,parms.size()); }
103
104
char
**
option
(
const
Strings& options,
const
Strings& parms)
const
{
105
std::size_t num_mandatory_parms = parms.size();
106
for
(
const
auto
& parm : parms)
107
if
(parm[0]==
'['
)
108
--num_mandatory_parms;
109
110
char
** mandatory_args =
nullptr
;
111
for
(
const
char
* opt : options) {
112
char
** arg =
option
(opt,parms,num_mandatory_parms);
113
if
(arg!=
nullptr
) {
114
if
(mandatory_args!=
nullptr
) {
115
std::cerr <<
"Warning: option "
<< *(options.begin()) <<
" provided multiple times!"
<< std::endl;
116
exit(1);
117
}
118
mandatory_args = arg;
119
}
120
}
121
return
mandatory_args;
122
}
123
124
// Workaround a bug in old gcc compilers which does not allow the conversion of
125
// const std::initializer_list<const char* const> to const Strings.
126
127
char
**
option
(
const
std::string& name,
const
List& parms)
const
{
return
option
(name,build_strings(parms)); }
128
char
**
option
(
const
List& options,
const
List& parms)
const
{
return
option
(build_strings(options),build_strings(parms)); }
129
130
// End of workaround.
131
132
unsigned
num_args
(
char
** argument)
const
{
133
unsigned
res = 0;
134
for
(
char
** arg=argument+1; arg!=end(); ++arg,++res)
135
if
((*arg)[0]==
'-'
)
136
break
;
137
return
res;
138
}
139
140
void
print
()
const
{
141
std::cout << std::endl <<
"| ------ "
<< args[0] << std::endl;
142
for
(
unsigned
i=1; i<n; ++i)
143
std::cout <<
"| "
<< args[i] << std::endl;
144
std::cout <<
"| -----------------------"
<< std::endl;
145
}
146
147
private
:
148
149
template
<
typename
T>
150
static
T value(
const
T val) {
return
val; }
151
152
static
std::string value(
const
bool
val) {
return
(val) ?
"true"
:
"false"
; }
153
154
static
std::string value(
const
std::string& val) {
return
'"'
+val+
'"'
; }
155
156
char
** end()
const
{
return
args+n; }
157
158
char
** find_argument(
const
std::string& name)
const
{
159
for
(
auto
arg = args; arg!=end(); ++arg)
160
if
(name==*arg)
161
return
arg;
162
return
end();
163
}
164
165
template
<
typename
T>
166
T parse_value(
char
* arg[],
const
T defaultvalue)
const
{
167
if
(arg==end())
168
return
defaultvalue;
169
std::istringstream iss(*arg);
170
T value = defaultvalue;
171
iss >> value;
172
return
value;
173
}
174
175
#ifndef WIN32
176
static
constexpr
char
normal[9] = { 0x1b,
'['
,
'0'
,
';'
,
'0'
,
';'
,
'0'
,
'm'
,
'\0'
};
177
static
constexpr
char
red[11] = { 0x1b,
'['
,
'4'
,
';'
,
'3'
,
'1'
,
';'
,
'5'
,
'9'
,
'm'
,
'\0'
};
178
static
constexpr
char
bold[5] = { 0x1b,
'['
,
'1'
,
'm'
,
'\0'
};
179
static
constexpr
char
purple[11] = { 0x1b,
'['
,
'0'
,
';'
,
'3'
,
'5'
,
';'
,
'5'
,
'9'
,
'm'
,
'\0'
};
180
static
constexpr
char
path_delimiter =
'/'
;
181
#else
182
static
constexpr
char
normal[1] = {
'\0'
};
183
static
constexpr
char
red[1] = {
'\0'
};
184
static
constexpr
char
bold[1] = {
'\0'
};
185
static
constexpr
char
purple[1] = {
'\0'
};
186
static
constexpr
char
path_delimiter =
'\\'
;
187
#endif
188
189
unsigned
n;
190
char
** args;
191
bool
help;
192
};
193
194
inline
void
print_version
(
const
char
* cmd) {
195
#ifdef USE_OMP
196
std::string omp_support =
" using OpenMP\n Executing using "
+ std::to_string(omp_get_max_threads()) +
" threads."
;
197
#else
198
std::string omp_support =
""
;
199
#endif
200
201
std::ostringstream display_info;
202
display_info << cmd;
203
display_info <<
" version "
<< version;
204
display_info <<
" compiled at "
<< __DATE__ <<
" "
<< __TIME__;
205
display_info << omp_support;
206
std::cout << display_info.str() << std::endl << std::endl;
207
}
208
209
// Some command have mutually exclusive options.
210
// This helper function ensures that.
211
// The counter num_options is counting options in each exclusive group.
212
213
inline
void
assert_non_conflicting_options
(
const
char
* command,
const
unsigned
num_options) {
214
if
(num_options!=1) {
215
std::cerr <<
"Error: providing mutually exclusive options to "
<< command <<
"!"
<< std::endl;
216
exit(1);
217
}
218
}
219
}
OpenMEEG::CommandLine::option
char ** option(const List &options, const List &parms) const
Definition
commandline.h:128
OpenMEEG::CommandLine::option
char ** option(const Strings &options, const Strings &parms) const
Definition
commandline.h:104
OpenMEEG::CommandLine::num_args
unsigned num_args(char **argument) const
Definition
commandline.h:132
OpenMEEG::CommandLine::option
T option(const std::string &name, const T defaultvalue, const std::string usage) const
Definition
commandline.h:64
OpenMEEG::CommandLine::CommandLine
CommandLine(const int argc, char *argv[], const std::string &usage="")
Definition
commandline.h:51
OpenMEEG::CommandLine::help_mode
bool help_mode() const
Definition
commandline.h:61
OpenMEEG::CommandLine::option
bool option(const std::string &name, const bool defaultvalue, const std::string usage) const
Definition
commandline.h:73
OpenMEEG::CommandLine::option
char ** option(const std::string &option, const Strings &parms, const std::size_t num_mandatory_parms) const
Definition
commandline.h:82
OpenMEEG::CommandLine::option
char ** option(const std::string &name, const List &parms) const
Definition
commandline.h:127
OpenMEEG::CommandLine::print
void print() const
Definition
commandline.h:140
OpenMEEG::CommandLine::option
char ** option(const std::string &name, const Strings &parms) const
Definition
commandline.h:102
filenames.h
OpenMEEG
Definition
analytics.h:14
OpenMEEG::assert_non_conflicting_options
void assert_non_conflicting_options(const char *command, const unsigned num_options)
Definition
commandline.h:213
OpenMEEG::print_version
void print_version(const char *cmd)
Definition
commandline.h:194
Generated by
1.17.0