Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef __CLIFW_ARGUMENTS_H__
- #define __CLIFW_ARGUMENTS_H__
- #include <string>
- #include <list>
- #include <regex>
- namespace clifw {
- template <typename UserApp>
- struct app;
- template <typename UserApp>
- struct arguments {
- typedef typename app<UserApp>::argument_type argument_type;
- typedef typename app<UserApp>::option_type option_type;
- typedef app<UserApp> app_type;
- arguments (app<UserApp> &app, int const argc,
- char const * const * const argv,
- char const * const * const envp);
- argument_type const & operator [] (std::string const &key) const;
- argument_type & operator [] (std::string const &key) ;
- private:
- app<UserApp> &_app;
- std::map<std::string, argument_type> _option_list;
- };
- template <typename UserApp>
- arguments<UserApp>::arguments (
- app<UserApp> &app, int const argc,
- char const * const * const argv,
- char const * const * const envp) :
- _app (app)
- {
- static const std::string _help_option = "help";
- static const std::string _help_alias = "?";
- struct helper {
- static bool match_option (std::string const &_haystack, std::string &_name, std::string &_value, bool &_is_alias, bool &_has_value) {
- logger &l = logger::clog ();
- static const std::regex _long_option_needle ("^--([a-zA-Z0-9][a-zA-Z0-9_\\-]*)([:=](.+))?$");
- static const std::regex _short_option_needle ("^-([\\?a-zA-Z0-9]+)$");
- bool _is_option;
- std::smatch _needles_found;
- _is_alias = std::regex_match ( _haystack, _needles_found, _short_option_needle);
- _is_option = _is_alias || std::regex_match (_haystack, _needles_found, _long_option_needle);
- _has_value = _needles_found [2].str () != "" ;
- // l.info ("Checking '%s' is_option:%d, is_alias:%d, has_value:%d\n", _haystack.c_str (), _is_option, _is_alias, _has_value);
- _name = _needles_found [1].str ();
- _value = _has_value ? _needles_found [3].str () : _haystack;
- return _is_option;
- }
- };
- if (argc < 2) {
- _app.option (_help_option).value ("", true);
- return;
- }
- bool _is_alias = false;
- bool _has_value = false;
- int _takes_value = 0;
- int _needs_value = 0;
- std::string _name, _value;
- std::string _was_name;
- bool _was_alias = false;
- int index = 0 ;
- int check = 0 ;
- for (int i = 1; i < argc; ++i) {
- if (helper::match_option (argv [i], _name, _value, _is_alias, _has_value)) {
- if (_needs_value > 0) {
- throw value_expected_exception (::clifw::helper::sprintf_format_string (
- "Option '%s' expected value.", _was_name.c_str ()));
- }
- auto &_option = _app.option (_name, _is_alias);
- _takes_value = _option.takes_value () ;
- _needs_value = _option.needs_value () ;
- if (!_takes_value) {
- _option.value ("", true);
- continue;
- }
- if (_has_value) {
- if (!_takes_value) {
- throw value_unexpected_exception (::clifw::helper::sprintf_format_string (
- "Option '%s' doesn't take a value", _name.c_str ()));
- }
- _option.value (_value, true);
- if (_name == _help_option || (_name == _help_alias && _is_alias))
- return ;
- _takes_value = _takes_value > 0 ? _takes_value - 1 : 0;
- _needs_value = _needs_value > 0 ? _needs_value - 1 : 0;
- }
- _was_name = _name;
- _was_alias = _is_alias;
- continue;
- }
- else {
- ++check;
- if (_takes_value) {
- auto &_option = _app.option (_was_name, _was_alias);
- _option.value (_value, true);
- if (_was_name == "help" || (_was_name == "?" && _was_alias))
- return ;
- _takes_value = _takes_value > 0 ? _takes_value - 1 : 0;
- _needs_value = _needs_value > 0 ? _needs_value - 1 : 0;
- continue;
- }
- _app.argument (index++).value (_value, true);
- continue;
- }
- }
- if (_takes_value) {
- auto &_option = _app.option (_was_name, _was_alias);
- if (_needs_value) {
- throw value_expected_exception (::clifw::helper::sprintf_format_string (
- "Option '%s' expected value.", _was_name.c_str ()));
- }
- _option.value ("", true);
- if (_was_name == _help_option || (_was_name == _help_alias && _was_alias))
- return;
- }
- if (check)
- _app.check_arguments (true);
- }
- template <typename UserApp>
- typename arguments<UserApp>::argument_type & arguments<UserApp>::operator [] (std::string const &key) {
- return _app.option (key).value ();
- }
- template <typename UserApp>
- typename arguments<UserApp>::argument_type const & arguments<UserApp>::operator [] (std::string const &key) const {
- return _app.option (key).value ();
- }
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement