Commit a36e1ddfe64793256a9a2ad060022a61504f7679

Authored by Henry Fredrick Schreiner
1 parent 1df5d9db

Removed dependency on regex

Showing 1 changed file with 32 additions and 39 deletions
include/CLI.hpp
... ... @@ -16,6 +16,7 @@
16 16 #include <set>
17 17 #include <iomanip>
18 18 #include <numeric>
  19 +#include <vector>
19 20  
20 21 // C standard library
21 22 // Only needed for existence checking
... ... @@ -25,17 +26,6 @@
25 26  
26 27 #include <locale>
27 28  
28   -// GCC 4.7 and 4.8 have an non-working implementation of regex
29   -#include <regex>
30   -#if __cplusplus >= 201103L \
31   - && (!defined(__GLIBCXX__) \
32   - || (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE>4) \
33   - || (__cplusplus >= 201402L) \
34   - || (defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || defined(_GLIBCXX_REGEX_STATE_LIMIT)))
35   -#define HAVE_WORKING_REGEX 1
36   -#else
37   -#define HAVE_WORKING_REGEX 0
38   -#endif
39 29  
40 30 //#define CLI_LOG 1
41 31  
... ... @@ -191,15 +181,31 @@ struct EmptyError : public Error {
191 181 EmptyError(std::string name) : Error("EmptyError", name, 9) {}
192 182 };
193 183  
194   -const std::regex reg_short{R"regex(-([a-zA-Z_])(.*))regex"};
195   -const std::regex reg_long{R"regex(--([^-^=][^=]*)=?(.*))regex"};
  184 +
  185 +template<typename T>
  186 +bool valid_first_char(T c) {
  187 + return std::isalpha(c) || c=='_';
  188 +}
  189 +
  190 +template<typename T>
  191 +bool valid_later_char(T c) {
  192 + return std::isalnum(c) || c=='_' || c=='.' || c=='-';
  193 +}
  194 +
  195 +inline bool valid_name_string(const std::string &str) {
  196 + if(str.size()<1 || !valid_first_char(str[0]))
  197 + return false;
  198 + for(auto c : str.substr(1))
  199 + if(!valid_later_char(c))
  200 + return false;
  201 + return true;
  202 +}
196 203  
197 204 // Returns false if not a short option. Otherwise, sets opt name and rest and returns true
198 205 inline bool split_short(const std::string &current, std::string &name, std::string &rest) {
199   - std::smatch match;
200   - if(std::regex_match(current, match, reg_short)) {
201   - name = match[1];
202   - rest = match[2];
  206 + if(current.size()>1 && current[0] == '-' && valid_first_char(current[1])) {
  207 + name = current.substr(1,1);
  208 + rest = current.substr(2);
203 209 return true;
204 210 } else
205 211 return false;
... ... @@ -207,10 +213,15 @@ inline bool split_short(const std::string &amp;current, std::string &amp;name, std::stri
207 213  
208 214 // Returns false if not a long option. Otherwise, sets opt name and other side of = and returns true
209 215 inline bool split_long(const std::string &current, std::string &name, std::string &value) {
210   - std::smatch match;
211   - if(std::regex_match(current, match, reg_long)) {
212   - name = match[1];
213   - value = match[2];
  216 + if(current.size()>2 && current.substr(0,2) == "--" && valid_first_char(current[2])) {
  217 + auto loc = current.find("=");
  218 + if(loc != std::string::npos) {
  219 + name = current.substr(2,loc-2);
  220 + value = current.substr(loc+1);
  221 + } else {
  222 + name = current.substr(2);
  223 + value = "";
  224 + }
214 225 return true;
215 226 } else
216 227 return false;
... ... @@ -229,24 +240,6 @@ inline std::vector&lt;std::string&gt; split_names(std::string current) {
229 240  
230 241 }
231 242  
232   -template<typename T>
233   -bool valid_first_char(T c) {
234   - return std::isalpha(c) || c=='_';
235   -}
236   -
237   -template<typename T>
238   -bool valid_later_char(T c) {
239   - return std::isalnum(c) || c=='_' || c=='.' || c=='-';
240   -}
241   -
242   -inline bool valid_name_string(const std::string &str) {
243   - if(str.size()<1 || !valid_first_char(str[0]))
244   - return false;
245   - for(auto c : str.substr(1))
246   - if(!valid_later_char(c))
247   - return false;
248   - return true;
249   -}
250 243  
251 244 inline std::tuple<std::vector<std::string>,std::vector<std::string>> get_names(const std::vector<std::string> &input) {
252 245 std::vector<std::string> short_names;
... ...