diff --git a/include/CLI.hpp b/include/CLI.hpp index caf2db9..806a31a 100644 --- a/include/CLI.hpp +++ b/include/CLI.hpp @@ -16,6 +16,7 @@ #include #include #include +#include // C standard library // Only needed for existence checking @@ -25,17 +26,6 @@ #include -// GCC 4.7 and 4.8 have an non-working implementation of regex -#include -#if __cplusplus >= 201103L \ - && (!defined(__GLIBCXX__) \ - || (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE>4) \ - || (__cplusplus >= 201402L) \ - || (defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || defined(_GLIBCXX_REGEX_STATE_LIMIT))) -#define HAVE_WORKING_REGEX 1 -#else -#define HAVE_WORKING_REGEX 0 -#endif //#define CLI_LOG 1 @@ -191,15 +181,31 @@ struct EmptyError : public Error { EmptyError(std::string name) : Error("EmptyError", name, 9) {} }; -const std::regex reg_short{R"regex(-([a-zA-Z_])(.*))regex"}; -const std::regex reg_long{R"regex(--([^-^=][^=]*)=?(.*))regex"}; + +template +bool valid_first_char(T c) { + return std::isalpha(c) || c=='_'; +} + +template +bool valid_later_char(T c) { + return std::isalnum(c) || c=='_' || c=='.' || c=='-'; +} + +inline bool valid_name_string(const std::string &str) { + if(str.size()<1 || !valid_first_char(str[0])) + return false; + for(auto c : str.substr(1)) + if(!valid_later_char(c)) + return false; + return true; +} // Returns false if not a short option. Otherwise, sets opt name and rest and returns true inline bool split_short(const std::string ¤t, std::string &name, std::string &rest) { - std::smatch match; - if(std::regex_match(current, match, reg_short)) { - name = match[1]; - rest = match[2]; + if(current.size()>1 && current[0] == '-' && valid_first_char(current[1])) { + name = current.substr(1,1); + rest = current.substr(2); return true; } else return false; @@ -207,10 +213,15 @@ inline bool split_short(const std::string ¤t, std::string &name, std::stri // Returns false if not a long option. Otherwise, sets opt name and other side of = and returns true inline bool split_long(const std::string ¤t, std::string &name, std::string &value) { - std::smatch match; - if(std::regex_match(current, match, reg_long)) { - name = match[1]; - value = match[2]; + if(current.size()>2 && current.substr(0,2) == "--" && valid_first_char(current[2])) { + auto loc = current.find("="); + if(loc != std::string::npos) { + name = current.substr(2,loc-2); + value = current.substr(loc+1); + } else { + name = current.substr(2); + value = ""; + } return true; } else return false; @@ -229,24 +240,6 @@ inline std::vector split_names(std::string current) { } -template -bool valid_first_char(T c) { - return std::isalpha(c) || c=='_'; -} - -template -bool valid_later_char(T c) { - return std::isalnum(c) || c=='_' || c=='.' || c=='-'; -} - -inline bool valid_name_string(const std::string &str) { - if(str.size()<1 || !valid_first_char(str[0])) - return false; - for(auto c : str.substr(1)) - if(!valid_later_char(c)) - return false; - return true; -} inline std::tuple,std::vector> get_names(const std::vector &input) { std::vector short_names;