16#include <initializer_list>
19#define use_color_terminal
22#include "OpenMEEGConfigure.h"
34 typedef std::vector<const char*> Strings;
39 typedef std::initializer_list<const char* const> List;
41 static Strings build_strings(
const List& list) {
43 strs.reserve(list.size());
44 for (
const auto& item : list)
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();
54 std::cerr << red << std::filesystem::path(args[0]).filename() << normal;
56 std::cerr <<
": " << usage;
57 std::cerr << std::endl << std::endl;
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);
68 std::cerr <<
" " << bold << std::left << std::setw(8) << name << normal
69 <<
" = " << std::left << std::setw(12) << value(result) << purple << usage << normal << std::endl;
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;
77 std::cerr <<
" " << bold << std::left << std::setw(8) << name << normal
78 <<
" = " << std::left << std::setw(12) << value(result) << purple << usage << normal << std::endl;
82 char**
option(
const std::string&
option,
const Strings& parms,
const std::size_t num_mandatory_parms)
const {
83 char** arg = find_argument(
option);
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];
96 std::cerr <<
") and you gave only " << num_parms <<
" arguments." << std::endl;
102 char**
option(
const std::string& name,
const Strings& parms)
const {
return option(name,parms,parms.size()); }
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)
108 --num_mandatory_parms;
110 char** mandatory_args =
nullptr;
111 for (
const char* opt : options) {
112 char** arg =
option(opt,parms,num_mandatory_parms);
114 if (mandatory_args!=
nullptr) {
115 std::cerr <<
"Warning: option " << *(options.begin()) <<
" provided multiple times!" << std::endl;
118 mandatory_args = arg;
121 return mandatory_args;
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)); }
134 for (
char** arg=argument+1; arg!=end(); ++arg,++res)
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;
149 template <
typename T>
150 static T value(
const T val) {
return val; }
152 static std::string value(
const bool val) {
return (val) ?
"true" :
"false"; }
154 static std::string value(
const std::string& val) {
return '"'+val+
'"'; }
156 char** end()
const {
return args+n; }
158 char** find_argument(
const std::string& name)
const {
159 for (
auto arg = args; arg!=end(); ++arg)
165 template <
typename T>
166 T parse_value(
char* arg[],
const T defaultvalue)
const {
169 std::istringstream iss(*arg);
170 T value = defaultvalue;
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 =
'/';
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 =
'\\';
196 std::string omp_support =
" using OpenMP\n Executing using " + std::to_string(omp_get_max_threads()) +
" threads.";
198 std::string omp_support =
"";
201 std::ostringstream display_info;
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;
214 if (num_options!=1) {
215 std::cerr <<
"Error: providing mutually exclusive options to " << command <<
"!" << std::endl;
char ** option(const List &options, const List &parms) const
char ** option(const Strings &options, const Strings &parms) const
unsigned num_args(char **argument) const
T option(const std::string &name, const T defaultvalue, const std::string usage) const
CommandLine(const int argc, char *argv[], const std::string &usage="")
bool option(const std::string &name, const bool defaultvalue, const std::string usage) const
char ** option(const std::string &option, const Strings &parms, const std::size_t num_mandatory_parms) const
char ** option(const std::string &name, const List &parms) const
char ** option(const std::string &name, const Strings &parms) const
void assert_non_conflicting_options(const char *command, const unsigned num_options)
void print_version(const char *cmd)