12#ifndef MCRL2_UTILITIES_COMMAND_LINE_INTERFACE_H
13#define MCRL2_UTILITIES_COMMAND_LINE_INTERFACE_H
29class interface_description;
30class command_line_parser;
33inline std::string copyright_period()
124class interface_description
126 friend class command_line_parser;
150 void set_name(std::string
const& n)
156 void set_type(std::string
const& t)
163 class argument_description
168 std::string m_description;
171 argument_description(
const std::string& long_,
const std::string& short_,
const std::string& description)
172 : m_long(long_), m_short(short_), m_description(
description)
175 argument_description(
const std::string& long_,
const std::string& description)
179 const std::string& get_long()
const
184 const std::string& get_short()
const
189 const std::string& get_description()
const
191 return m_description;
196 virtual basic_argument* clone()
const = 0;
199 std::string get_name()
const
205 std::string get_type()
const
211 virtual bool has_description()
const = 0;
214 virtual std::vector< argument_description >
const& get_description()
const = 0;
217 virtual std::string
const& get_default()
const = 0;
220 virtual bool validate(std::string
const&)
const = 0;
223 virtual bool is_optional()
const = 0;
226 virtual bool has_default()
const = 0;
229 virtual ~basic_argument()
235 template <
typename T >
236 class typed_argument;
239 template <
typename T = std::
string >
240 class optional_argument;
243 template <
typename T = std::
string >
244 class mandatory_argument;
246 template <
typename T = std::
string >
265 class option_descriptor
267 friend class command_line_parser;
268 friend class interface_description;
276 std::string m_description;
279 std::shared_ptr< basic_argument > m_argument;
290 std::string textual_description(
const std::size_t left_width,
const std::size_t right_width)
const;
293 std::string man_page_description()
const;
296 std::ostream& xml_page_description(std::ostream& s,
const bool is_standard =
false,
unsigned int indentation = 0)
const;
307 option_descriptor(std::string
const& l, std::string
const& d,
const char s) :
308 m_long(l), m_description(d), m_short(s), m_show(true)
312 assert(l.find_first_not_of(
"_-0123456789abcdefghijklmnopqrstuvwxyz") == std::string::npos);
316 option_descriptor(option_descriptor
const& o) : m_long(o.m_long),
317 m_description(o.m_description), m_argument(o.m_argument), m_short(o.m_short), m_show(true)
321 option_descriptor operator=(option_descriptor
const& o)
323 return option_descriptor(o);
326 basic_argument
const& argument()
const
335 template <
typename T >
336 void set_argument(T* a)
344 inline const std::string& get_long()
const
352 inline std::string
const& get_default()
const
354 return m_argument->get_default();
360 inline std::string get_description()
const
362 return m_description;
368 inline bool needs_argument()
const
370 return !(m_argument.get() ==
nullptr || m_argument->is_optional());
376 inline bool accepts_argument()
const
378 return m_argument.get() !=
nullptr;
385 struct option_identifier_less
387 bool operator()(
char const& c1,
char const& c2)
const
389 char c1u = toupper(c1);
390 char c2u = toupper(c2);
392 return c1u < c2u || (c1u == c2u && c2 <
c1);
395 template <
typename S >
396 bool operator()(S
const& s1, S
const& s2)
const
398 std::string s1u = s1;
399 std::string s2u = s2;
400 std::transform(s1u.begin(), s1u.end(), s1u.begin(), ::toupper);
401 std::transform(s2u.begin(), s2u.end(), s2u.begin(), ::toupper);
403 return s1u < s2u || (s1u == s2u && s2 < s1);
408 typedef std::map< std::string, option_descriptor > option_map;
410 typedef std::map< const char, std::string, option_identifier_less > short_to_long_map;
413 option_map m_options;
424 std::string m_authors;
427 std::string m_what_is;
433 std::string m_description;
436 std::string m_known_issues;
441 short_to_long_map m_short_to_long;
450 char long_to_short(std::string
const& n)
const
454 for (short_to_long_map::const_iterator i = m_short_to_long.begin(); result ==
'\0' && i != m_short_to_long.end(); ++i)
465 option_descriptor
const& find_option(std::string
const& long_identifier)
const;
468 static interface_description& get_standard_description();
471 template <
typename T >
472 inline static void register_initialiser()
474 T::add_options(get_standard_description());
478 inline interface_description()
495 interface_description(std::string
const& path, std::string
const& name, std::string
const& authors,
496 std::string
const& what_is, std::string
const& synopsis, std::string
const& description,
497 std::string
const& known_issues =
"");
503 static std::string copyright_message();
529 std::string version_information()
const;
589 template <
typename T >
590 interface_description& add_option(std::string
const& long_identifier,
591 typed_argument< T >
const& argument_specification,
592 std::string
const& description,
593 char const short_identifier =
'\0')
596 add_option(long_identifier, description, short_identifier);
598 m_options.find(long_identifier)->second.set_argument(argument_specification.clone());
634 interface_description& add_option(std::string
const& long_identifier,
635 std::string
const& description,
636 char const short_identifier =
'\0')
639 if (m_options.find(long_identifier) != m_options.end())
641 throw std::logic_error(
"Duplicate long option (--" + long_identifier +
"); this is a serious program error!");
644 if (short_identifier !=
'\0')
646 if (m_short_to_long.find(short_identifier) != m_short_to_long.end())
648 throw std::logic_error(
"Duplicate short option (-" + std::string(1, short_identifier) +
"); this is a serious program error!");
651 m_short_to_long[short_identifier] = long_identifier;
654 m_options.insert(std::make_pair(long_identifier, option_descriptor(long_identifier, description, short_identifier)));
668 template <
typename T >
669 void add_hidden_option(
670 std::string
const& long_identifier,
671 typed_argument< T >
const& argument_specification,
672 std::string
const& description,
673 char const short_identifier =
'\0')
676 add_option(long_identifier, argument_specification, description, short_identifier);
678 m_options.find(long_identifier)->second.m_show =
false;
686 void add_hidden_option(std::string
const& long_identifier,
687 std::string
const& description,
688 char const short_identifier =
'\0')
691 add_option(long_identifier, description, short_identifier);
693 m_options.find(long_identifier)->second.m_show =
false;
700 std::string textual_description(
bool show_hidden)
const;
706 std::string man_page()
const;
712 std::ostream& xml_page(std::ostream&)
const;
718 std::map<std::string, std::string> get_long_argument_with_description();
724 std::string get_toolname()
790class command_line_parser
795 typedef std::multimap< std::string, std::string > option_map;
798 typedef std::vector< std::string > argument_list;
803 option_map m_options;
806 argument_list m_arguments;
809 interface_description& m_interface;
817 option_map
const& options;
820 argument_list
const& arguments;
823 bool has_option(
const std::string& option)
const
825 return options.find(option) != options.end();
831 static std::vector< std::string > parse_command_line(
char const*
const arguments);
834 static std::vector< std::string > convert(
const int count,
char const*
const*
const arguments);
837 static std::vector< std::string > convert(
const int count,
wchar_t const*
const*
const arguments);
840 void collect(interface_description& d, std::vector< std::string >
const& arguments);
843 void process_default_options(interface_description& d);
846 static std::vector< bool (*)(command_line_parser&) >& get_registered_actions()
848 static std::vector< bool (*)(command_line_parser&) > actions;
854 static void register_action(
bool (*action)(command_line_parser&))
856 get_registered_actions().push_back(action);
866 option_argument_as_impl(std::string
const& long_identifier, std::string& res)
const
868 res = option_argument(long_identifier);
879 template <
typename T >
881 option_argument_as_impl(std::string
const& long_identifier, T& result)
const
883 std::istringstream
in(option_argument(long_identifier));
891 const char short_option(m_interface.long_to_short(long_identifier));
893 error(
"argument `" + option_argument(long_identifier) +
"' to option --" + long_identifier +
894 ((short_option ==
'\0') ?
" " :
" or -" +
std::string(1, short_option)) +
" is invalid");
907 inline command_line_parser(interface_description& interface_specification,
char const*
const command_line) :
908 m_interface(interface_specification), m_continue(true), options(m_options), arguments(m_arguments)
910 collect(interface_specification, parse_command_line(command_line));
912 process_default_options(interface_specification);
924 template <
typename CharacterType >
925 command_line_parser(interface_description& interface_specification,
926 const int argument_count, CharacterType
const*
const*
const arguments);
949 void error(std::string
const& message)
const
957 void check_no_duplicate_arguments()
const
959 for (option_map::const_iterator i = m_options.begin(); i != m_options.end(); ++i)
961 if (1 < m_options.count(i->first))
963 error(
"option -" + (m_interface.long_to_short(i->first) !=
'\0' ?
964 std::string(1, m_interface.long_to_short(i->first)).append(
", --") :
"-") + i->
first +
" specified more than once");
985 std::string
const& option_argument(std::string
const& long_identifier)
const;
990 inline bool continue_execution()
const
1003 template <
typename T >
1004 inline T option_argument_as(std::string
const& long_identifier)
const
1007 option_argument_as_impl(long_identifier, result);
1014template <
typename ArgumentType >
1015interface_description::optional_argument< ArgumentType >
make_optional_argument(std::string
const& name, std::string
const& default_value)
1017 return interface_description::optional_argument< ArgumentType >(name, default_value);
1043interface_description::optional_argument< std::string >
make_optional_argument(std::string
const& name, std::string
const& default_value);
1046template <
typename ArgumentType >
1049 return interface_description::mandatory_argument< ArgumentType >(name);
1073interface_description::mandatory_argument< std::string >
1080template <
typename ArgumentType >
1081interface_description::mandatory_argument< ArgumentType >
1084 return interface_description::mandatory_argument< ArgumentType >(name, standard_value);
1111interface_description::mandatory_argument< std::string >
1116template <
typename ArgumentType >
1117interface_description::enum_argument< ArgumentType > make_enum_argument(std::string
const& name)
1119 return interface_description::enum_argument< ArgumentType >(name);
1130template <
typename T >
1131class interface_description::typed_argument :
public basic_argument
1141 inline bool validate(std::string
const& s)
const
1143 std::istringstream test(s);
1149 return !test.fail();
1161inline bool interface_description::typed_argument< std::string >::validate(std::string
const&)
const
1170template <
typename T >
1171class interface_description::enum_argument :
public typed_argument< T >
1175 std::vector< basic_argument::argument_description > m_enum;
1177 std::string m_default;
1181 enum_argument& add_value_with_short(
const std::string& long_arg,
const std::string& short_arg,
const std::string& description,
const bool is_default =
false)
1183 m_enum.push_back(basic_argument::argument_description(long_arg, short_arg, description));
1189 throw std::runtime_error(
"cannot define duplicate default value to enum argument");
1191 m_default = long_arg;
1192 m_has_default =
true;
1201 enum_argument(std::string
const& name) :
1202 m_has_default(false)
1204 basic_argument::set_type(
"enum");
1205 basic_argument::set_name(name);
1210 enum_argument* clone()
const
1212 return new enum_argument< T >(*
this);
1217 bool has_default()
const
1219 return m_has_default;
1224 const std::string& get_default()
const
1231 bool is_optional()
const
1237 inline bool validate(std::string
const& s)
const
1239 for(
typename std::vector< basic_argument::argument_description >::const_iterator i = m_enum.begin(); i != m_enum.end(); ++i)
1241 if(i->get_long() == s || i->get_short() == s)
1243 std::istringstream test(s);
1247 return !test.fail();
1264 enum_argument& add_value(
const T& arg,
const bool is_default =
false)
1281 enum_argument& add_value_desc(
const T& arg,
const std::string& description,
const bool is_default =
false)
1283 return add_value_with_short(
to_string(arg), std::string(), description, is_default);
1298 enum_argument& add_value_short(
const T& arg,
const std::string& short_argument,
const bool is_default =
false)
1306 virtual bool has_description()
const
1312 virtual const std::vector< basic_argument::argument_description >& get_description()
const
1320template <
typename T >
1321class interface_description::optional_argument :
public typed_argument< T >
1323 friend class interface_description;
1324 friend class interface_description::option_descriptor;
1325 friend class command_line_parser;
1330 std::string m_default;
1333 std::vector< basic_argument::argument_description > m_description;
1337 virtual basic_argument* clone()
const
1339 return new optional_argument< T >(*
this);
1347 inline optional_argument(std::string
const& name, std::string
const& d) : m_default(d)
1349 basic_argument::set_type(
"optional");
1350 basic_argument::set_name(name);
1356 inline bool has_default()
const
1364 inline std::string
const& get_default()
const
1370 inline bool is_optional()
const
1375 inline bool has_description()
const
1380 inline const std::vector< basic_argument::argument_description >& get_description()
const
1382 return m_description;
1387template <
typename T >
1388class interface_description::mandatory_argument :
public typed_argument< T >
1394 std::string m_default;
1400 std::vector< basic_argument::argument_description > m_description;
1404 virtual basic_argument* clone()
const
1406 return new mandatory_argument< T >(*
this);
1413 inline mandatory_argument(std::string
const& name) : m_has_default(false)
1415 basic_argument::set_type(
"mandatory");
1416 basic_argument::set_name(name);
1423 inline mandatory_argument(std::string
const& name, std::string
const& d) : m_default(d), m_has_default(true)
1425 basic_argument::set_type(
"mandatory");
1426 basic_argument::set_name(name);
1432 inline std::string
const& get_default()
const
1440 inline bool has_default()
const
1442 return m_has_default;
1446 inline bool is_optional()
const
1451 inline bool has_description()
const
1456 inline const std::vector< basic_argument::argument_description >& get_description()
const
1458 return m_description;
1463class interface_description::file_argument :
public typed_argument<std::string>
1469 std::string m_default;
1475 std::vector< basic_argument::argument_description > m_description;
1479 virtual basic_argument* clone()
const
1481 return new file_argument(*
this);
1486 inline bool validate(std::string
const& )
const
1495 inline file_argument(std::string
const& name) : m_has_default(false)
1497 basic_argument::set_type(
"file");
1498 basic_argument::set_name(name);
1504 inline std::string
const& get_default()
const
1512 inline bool has_default()
const
1514 return m_has_default;
1518 inline bool is_optional()
const
1523 inline bool has_description()
const
1528 inline const std::vector< basic_argument::argument_description >& get_description()
const
1530 return m_description;
1536interface_description::file_argument make_file_argument(std::string
const& name)
1538 return interface_description::file_argument(name);
1541#if !defined(__COMMAND_LINE_INTERFACE__)
1544inline command_line_parser::command_line_parser(interface_description& d,
const int c,
char const*
const*
const a) :
1545 m_interface(d), m_continue(true), options(m_options), arguments(m_arguments)
1548 collect(d, convert(c, a));
1550 process_default_options(d);
1554inline command_line_parser::command_line_parser(interface_description& d,
const int c,
wchar_t const*
const*
const a) :
1555 m_interface(d), m_continue(true), options(m_options), arguments(m_arguments)
1558 collect(d, convert(c, a));
1560 process_default_options(d);
Exception class for errors raised by the command-line parser.
Exception classes for use in libraries and tools.
std::string description(const smt_solver_type s)
description of solver type
function_symbol in(const sort_expression &, const sort_expression &s0, const sort_expression &s1)
const function_symbol & first()
Constructor for function symbol @first.
const function_symbol & c1()
Constructor for function symbol @c1.
std::string to_string(const cs_game_node &n)
interface_description::optional_argument< std::string > make_optional_argument(std::string const &name, std::string const &default_value)
interface_description::mandatory_argument< std::string > make_mandatory_argument(std::string const &name, std::string const &default_value)
std::string get_toolset_version()
Get the toolset revision.
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
String manipulation functions.