Commit 653d8b70fd2f102eff0f1620e4cc83c350b857e4
1 parent
e0ca21f4
Clean up, move more to detail
Showing
3 changed files
with
296 additions
and
327 deletions
include/CLI.hpp
| ... | ... | @@ -18,6 +18,7 @@ |
| 18 | 18 | #include <iomanip> |
| 19 | 19 | #include <numeric> |
| 20 | 20 | #include <vector> |
| 21 | +#include <locale> | |
| 21 | 22 | |
| 22 | 23 | // C standard library |
| 23 | 24 | // Only needed for existence checking |
| ... | ... | @@ -25,118 +26,11 @@ |
| 25 | 26 | #include <sys/types.h> |
| 26 | 27 | #include <sys/stat.h> |
| 27 | 28 | |
| 28 | -#include <locale> | |
| 29 | - | |
| 30 | - | |
| 31 | -//#define CLI_LOG 1 | |
| 32 | 29 | |
| 33 | 30 | namespace CLI { |
| 34 | 31 | |
| 35 | -/// Log a message, can be enabled with CLI_LOG | |
| 36 | -void logit(std::string) { | |
| 37 | -#ifdef CLI_LOG | |
| 38 | - std::cout << "\033[1;31m" << output << "\033[0m" << std::endl; | |
| 39 | -#endif | |
| 40 | -} | |
| 41 | - | |
| 42 | -/// Simple fucntion to join a string | |
| 43 | -template <typename T> | |
| 44 | -std::string join(const T& v, std::string delim = ",") { | |
| 45 | - std::ostringstream s; | |
| 46 | - for (const auto& i : v) { | |
| 47 | - if (&i != &v[0]) { | |
| 48 | - s << delim; | |
| 49 | - } | |
| 50 | - s << i; | |
| 51 | - } | |
| 52 | - return s.str(); | |
| 53 | -} | |
| 54 | - | |
| 55 | -// Based generally on https://rmf.io/cxx11/almost-static-if | |
| 56 | -namespace detail { | |
| 57 | - /// Simple empty scoped class | |
| 58 | - enum class enabler {}; | |
| 59 | -} | |
| 60 | - | |
| 61 | -/// An instance to use in EnableIf | |
| 62 | -constexpr detail::enabler dummy = {}; | |
| 63 | - | |
| 64 | -// Copied from C++14 | |
| 65 | -#if __cplusplus < 201402L | |
| 66 | -template< bool B, class T = void > | |
| 67 | -using enable_if_t = typename std::enable_if<B,T>::type; | |
| 68 | -#else | |
| 69 | -using std::enable_if_t; | |
| 70 | -#endif | |
| 71 | -// If your compiler supports C++14, you can use that definition instead | |
| 72 | - | |
| 73 | -template <typename T> | |
| 74 | -struct is_vector { | |
| 75 | - static const bool value = false; | |
| 76 | -}; | |
| 77 | - | |
| 78 | - | |
| 79 | -template<class T, class A> | |
| 80 | -struct is_vector<std::vector<T, A> > { | |
| 81 | - static bool const value = true; | |
| 82 | -}; | |
| 83 | - | |
| 84 | -struct Combiner { | |
| 85 | - int num; | |
| 86 | - bool positional; | |
| 87 | - bool required; | |
| 88 | - bool defaulted; | |
| 89 | - std::vector<std::function<bool(std::string)>> validators; | |
| 90 | - | |
| 91 | - /// Can be or-ed together | |
| 92 | - Combiner operator | (Combiner b) const { | |
| 93 | - Combiner self; | |
| 94 | - self.num = std::min(num, b.num) == -1 ? -1 : std::max(num, b.num); | |
| 95 | - self.positional = positional || b.positional; | |
| 96 | - self.required = required || b.required; | |
| 97 | - self.defaulted = defaulted || b.defaulted; | |
| 98 | - self.validators.reserve(validators.size() + b.validators.size()); | |
| 99 | - self.validators.insert(self.validators.end(), validators.begin(), validators.end()); | |
| 100 | - self.validators.insert(self.validators.end(), b.validators.begin(), b.validators.end()); | |
| 101 | - return self; | |
| 102 | - } | |
| 103 | - | |
| 104 | - /// Call to give the number of arguments expected on cli | |
| 105 | - Combiner operator() (int n) const { | |
| 106 | - Combiner self = *this; | |
| 107 | - self.num = n; | |
| 108 | - return self; | |
| 109 | - } | |
| 110 | - /// Call to give a validator | |
| 111 | - Combiner operator() (std::function<bool(std::string)> func) const { | |
| 112 | - Combiner self = *this; | |
| 113 | - self.validators.push_back(func); | |
| 114 | - return self; | |
| 115 | - } | |
| 116 | - Combiner operator, (Combiner b) const { | |
| 117 | - return *this | b; | |
| 118 | - } | |
| 119 | -}; | |
| 120 | - | |
| 121 | -bool _ExistingFile(std::string filename) { | |
| 122 | -// std::fstream f(name.c_str()); | |
| 123 | -// return f.good(); | |
| 124 | -// Fastest way according to http://stackoverflow.com/questions/12774207/fastest-way-to-check-if-a-file-exist-using-standard-c-c11-c | |
| 125 | - struct stat buffer; | |
| 126 | - return (stat(filename.c_str(), &buffer) == 0); | |
| 127 | -} | |
| 128 | 32 | |
| 129 | -bool _ExistingDirectory(std::string filename) { | |
| 130 | - struct stat buffer; | |
| 131 | - if(stat(filename.c_str(), &buffer) == 0 && (buffer.st_mode & S_IFDIR) ) | |
| 132 | - return true; | |
| 133 | - return false; | |
| 134 | -} | |
| 135 | - | |
| 136 | -bool _NonexistentPath(std::string filename) { | |
| 137 | - struct stat buffer; | |
| 138 | - return stat(filename.c_str(), &buffer) != 0; | |
| 139 | -} | |
| 33 | +// Error definitions | |
| 140 | 34 | |
| 141 | 35 | struct Error : public std::runtime_error { |
| 142 | 36 | int exit_code; |
| ... | ... | @@ -183,125 +77,262 @@ struct EmptyError : public Error { |
| 183 | 77 | }; |
| 184 | 78 | |
| 185 | 79 | |
| 186 | -template<typename T> | |
| 187 | -bool valid_first_char(T c) { | |
| 188 | - return std::isalpha(c) || c=='_'; | |
| 189 | -} | |
| 80 | +// Type tools | |
| 81 | +// | |
| 82 | +// Copied from C++14 | |
| 83 | +#if __cplusplus < 201402L | |
| 84 | +template< bool B, class T = void > | |
| 85 | +using enable_if_t = typename std::enable_if<B,T>::type; | |
| 86 | +#else | |
| 87 | +using std::enable_if_t; | |
| 88 | +#endif | |
| 89 | +// If your compiler supports C++14, you can use that definition instead | |
| 190 | 90 | |
| 191 | -template<typename T> | |
| 192 | -bool valid_later_char(T c) { | |
| 193 | - return std::isalnum(c) || c=='_' || c=='.' || c=='-'; | |
| 194 | -} | |
| 91 | +template <typename T> | |
| 92 | +struct is_vector { | |
| 93 | + static const bool value = false; | |
| 94 | +}; | |
| 195 | 95 | |
| 196 | -inline bool valid_name_string(const std::string &str) { | |
| 197 | - if(str.size()<1 || !valid_first_char(str[0])) | |
| 198 | - return false; | |
| 199 | - for(auto c : str.substr(1)) | |
| 200 | - if(!valid_later_char(c)) | |
| 201 | - return false; | |
| 202 | - return true; | |
| 203 | -} | |
| 204 | 96 | |
| 205 | -// Returns false if not a short option. Otherwise, sets opt name and rest and returns true | |
| 206 | -inline bool split_short(const std::string ¤t, std::string &name, std::string &rest) { | |
| 207 | - if(current.size()>1 && current[0] == '-' && valid_first_char(current[1])) { | |
| 208 | - name = current.substr(1,1); | |
| 209 | - rest = current.substr(2); | |
| 210 | - return true; | |
| 211 | - } else | |
| 212 | - return false; | |
| 213 | -} | |
| 97 | +template<class T, class A> | |
| 98 | +struct is_vector<std::vector<T, A> > { | |
| 99 | + static bool const value = true; | |
| 100 | +}; | |
| 214 | 101 | |
| 215 | -// Returns false if not a long option. Otherwise, sets opt name and other side of = and returns true | |
| 216 | -inline bool split_long(const std::string ¤t, std::string &name, std::string &value) { | |
| 217 | - if(current.size()>2 && current.substr(0,2) == "--" && valid_first_char(current[2])) { | |
| 218 | - auto loc = current.find("="); | |
| 219 | - if(loc != std::string::npos) { | |
| 220 | - name = current.substr(2,loc-2); | |
| 221 | - value = current.substr(loc+1); | |
| 222 | - } else { | |
| 223 | - name = current.substr(2); | |
| 224 | - value = ""; | |
| 102 | +namespace detail { | |
| 103 | + // Based generally on https://rmf.io/cxx11/almost-static-if | |
| 104 | + /// Simple empty scoped class | |
| 105 | + enum class enabler {}; | |
| 106 | + | |
| 107 | + /// An instance to use in EnableIf | |
| 108 | + constexpr enabler dummy = {}; | |
| 109 | + | |
| 110 | + /// Simple function to join a string | |
| 111 | + template <typename T> | |
| 112 | + std::string join(const T& v, std::string delim = ",") { | |
| 113 | + std::ostringstream s; | |
| 114 | + for (const auto& i : v) { | |
| 115 | + if (&i != &v[0]) { | |
| 116 | + s << delim; | |
| 117 | + } | |
| 118 | + s << i; | |
| 225 | 119 | } |
| 226 | - return true; | |
| 227 | - } else | |
| 120 | + return s.str(); | |
| 121 | + } | |
| 122 | + | |
| 123 | + struct Combiner { | |
| 124 | + int num; | |
| 125 | + bool positional; | |
| 126 | + bool required; | |
| 127 | + bool defaulted; | |
| 128 | + std::vector<std::function<bool(std::string)>> validators; | |
| 129 | + | |
| 130 | + /// Can be or-ed together | |
| 131 | + Combiner operator | (Combiner b) const { | |
| 132 | + Combiner self; | |
| 133 | + self.num = std::min(num, b.num) == -1 ? -1 : std::max(num, b.num); | |
| 134 | + self.positional = positional || b.positional; | |
| 135 | + self.required = required || b.required; | |
| 136 | + self.defaulted = defaulted || b.defaulted; | |
| 137 | + self.validators.reserve(validators.size() + b.validators.size()); | |
| 138 | + self.validators.insert(self.validators.end(), validators.begin(), validators.end()); | |
| 139 | + self.validators.insert(self.validators.end(), b.validators.begin(), b.validators.end()); | |
| 140 | + return self; | |
| 141 | + } | |
| 142 | + | |
| 143 | + /// Call to give the number of arguments expected on cli | |
| 144 | + Combiner operator() (int n) const { | |
| 145 | + Combiner self = *this; | |
| 146 | + self.num = n; | |
| 147 | + return self; | |
| 148 | + } | |
| 149 | + /// Call to give a validator | |
| 150 | + Combiner operator() (std::function<bool(std::string)> func) const { | |
| 151 | + Combiner self = *this; | |
| 152 | + self.validators.push_back(func); | |
| 153 | + return self; | |
| 154 | + } | |
| 155 | + Combiner operator, (Combiner b) const { | |
| 156 | + return *this | b; | |
| 157 | + } | |
| 158 | + }; | |
| 159 | + | |
| 160 | + bool _ExistingFile(std::string filename) { | |
| 161 | + // std::fstream f(name.c_str()); | |
| 162 | + // return f.good(); | |
| 163 | + // Fastest way according to http://stackoverflow.com/questions/12774207/fastest-way-to-check-if-a-file-exist-using-standard-c-c11-c | |
| 164 | + struct stat buffer; | |
| 165 | + return (stat(filename.c_str(), &buffer) == 0); | |
| 166 | + } | |
| 167 | + | |
| 168 | + bool _ExistingDirectory(std::string filename) { | |
| 169 | + struct stat buffer; | |
| 170 | + if(stat(filename.c_str(), &buffer) == 0 && (buffer.st_mode & S_IFDIR) ) | |
| 171 | + return true; | |
| 228 | 172 | return false; |
| 229 | -} | |
| 173 | + } | |
| 230 | 174 | |
| 231 | -// Splits a string into multiple long and short names | |
| 232 | -inline std::vector<std::string> split_names(std::string current) { | |
| 233 | - std::vector<std::string> output; | |
| 234 | - size_t val; | |
| 235 | - while((val = current.find(",")) != std::string::npos) { | |
| 236 | - output.push_back(current.substr(0,val)); | |
| 237 | - current = current.substr(val+1); | |
| 175 | + bool _NonexistentPath(std::string filename) { | |
| 176 | + struct stat buffer; | |
| 177 | + return stat(filename.c_str(), &buffer) != 0; | |
| 238 | 178 | } |
| 239 | - output.push_back(current); | |
| 240 | - return output; | |
| 241 | 179 | |
| 242 | -} | |
| 243 | 180 | |
| 181 | + template<typename T> | |
| 182 | + bool valid_first_char(T c) { | |
| 183 | + return std::isalpha(c) || c=='_'; | |
| 184 | + } | |
| 244 | 185 | |
| 245 | -inline std::tuple<std::vector<std::string>,std::vector<std::string>> get_names(const std::vector<std::string> &input) { | |
| 246 | - std::vector<std::string> short_names; | |
| 247 | - std::vector<std::string> long_names; | |
| 248 | - | |
| 249 | - for(std::string name : input) { | |
| 250 | - if(name.length() == 0) | |
| 251 | - continue; | |
| 252 | - else if(name.length() == 1) | |
| 253 | - if(valid_first_char(name[0])) | |
| 254 | - short_names.push_back(name); | |
| 255 | - else | |
| 256 | - throw BadNameString("Invalid one char name: "+name); | |
| 257 | - else if(name.length() == 2 && name[0] == '-' && name[1] != '-') { | |
| 258 | - if(valid_first_char(name[1])) | |
| 259 | - short_names.push_back(std::string(1,name[1])); | |
| 260 | - else | |
| 261 | - throw BadNameString("Invalid one char name: "+name); | |
| 262 | - } else { | |
| 186 | + template<typename T> | |
| 187 | + bool valid_later_char(T c) { | |
| 188 | + return std::isalnum(c) || c=='_' || c=='.' || c=='-'; | |
| 189 | + } | |
| 263 | 190 | |
| 264 | - if(name.substr(0,2) == "--") | |
| 265 | - name = name.substr(2); | |
| 266 | - if(valid_name_string(name)) | |
| 267 | - long_names.push_back(name); | |
| 268 | - else | |
| 269 | - throw BadNameString("Bad long name"+name); | |
| 191 | + inline bool valid_name_string(const std::string &str) { | |
| 192 | + if(str.size()<1 || !valid_first_char(str[0])) | |
| 193 | + return false; | |
| 194 | + for(auto c : str.substr(1)) | |
| 195 | + if(!valid_later_char(c)) | |
| 196 | + return false; | |
| 197 | + return true; | |
| 198 | + } | |
| 199 | + | |
| 200 | + // Returns false if not a short option. Otherwise, sets opt name and rest and returns true | |
| 201 | + inline bool split_short(const std::string ¤t, std::string &name, std::string &rest) { | |
| 202 | + if(current.size()>1 && current[0] == '-' && valid_first_char(current[1])) { | |
| 203 | + name = current.substr(1,1); | |
| 204 | + rest = current.substr(2); | |
| 205 | + return true; | |
| 206 | + } else | |
| 207 | + return false; | |
| 208 | + } | |
| 209 | + | |
| 210 | + // Returns false if not a long option. Otherwise, sets opt name and other side of = and returns true | |
| 211 | + inline bool split_long(const std::string ¤t, std::string &name, std::string &value) { | |
| 212 | + if(current.size()>2 && current.substr(0,2) == "--" && valid_first_char(current[2])) { | |
| 213 | + auto loc = current.find("="); | |
| 214 | + if(loc != std::string::npos) { | |
| 215 | + name = current.substr(2,loc-2); | |
| 216 | + value = current.substr(loc+1); | |
| 217 | + } else { | |
| 218 | + name = current.substr(2); | |
| 219 | + value = ""; | |
| 220 | + } | |
| 221 | + return true; | |
| 222 | + } else | |
| 223 | + return false; | |
| 224 | + } | |
| 270 | 225 | |
| 226 | + // Splits a string into multiple long and short names | |
| 227 | + inline std::vector<std::string> split_names(std::string current) { | |
| 228 | + std::vector<std::string> output; | |
| 229 | + size_t val; | |
| 230 | + while((val = current.find(",")) != std::string::npos) { | |
| 231 | + output.push_back(current.substr(0,val)); | |
| 232 | + current = current.substr(val+1); | |
| 271 | 233 | } |
| 234 | + output.push_back(current); | |
| 235 | + return output; | |
| 236 | + | |
| 272 | 237 | } |
| 273 | - | |
| 274 | - return std::tuple<std::vector<std::string>,std::vector<std::string>>(short_names, long_names); | |
| 275 | 238 | |
| 276 | -} | |
| 277 | 239 | |
| 278 | -// Currently just throws an error if name is incorrect. May clean later. | |
| 279 | -inline void cleanup_names(const std::vector<std::string> &input) { | |
| 240 | + inline std::tuple<std::vector<std::string>,std::vector<std::string>> get_names(const std::vector<std::string> &input) { | |
| 241 | + std::vector<std::string> short_names; | |
| 242 | + std::vector<std::string> long_names; | |
| 243 | + | |
| 244 | + for(std::string name : input) { | |
| 245 | + if(name.length() == 0) | |
| 246 | + continue; | |
| 247 | + else if(name.length() == 1) | |
| 248 | + if(valid_first_char(name[0])) | |
| 249 | + short_names.push_back(name); | |
| 250 | + else | |
| 251 | + throw BadNameString("Invalid one char name: "+name); | |
| 252 | + else if(name.length() == 2 && name[0] == '-' && name[1] != '-') { | |
| 253 | + if(valid_first_char(name[1])) | |
| 254 | + short_names.push_back(std::string(1,name[1])); | |
| 255 | + else | |
| 256 | + throw BadNameString("Invalid one char name: "+name); | |
| 257 | + } else { | |
| 258 | + | |
| 259 | + if(name.substr(0,2) == "--") | |
| 260 | + name = name.substr(2); | |
| 261 | + if(valid_name_string(name)) | |
| 262 | + long_names.push_back(name); | |
| 263 | + else | |
| 264 | + throw BadNameString("Bad long name"+name); | |
| 265 | + | |
| 266 | + } | |
| 267 | + } | |
| 268 | + | |
| 269 | + return std::tuple<std::vector<std::string>,std::vector<std::string>>(short_names, long_names); | |
| 270 | + } | |
| 271 | + | |
| 272 | + | |
| 273 | + template<typename T, enable_if_t<std::is_integral<T>::value, detail::enabler> = detail::dummy> | |
| 274 | + bool lexical_cast(std::string input, T& output) { | |
| 275 | + try{ | |
| 276 | + output = (T) std::stoll(input); | |
| 277 | + return true; | |
| 278 | + } catch (std::invalid_argument) { | |
| 279 | + return false; | |
| 280 | + } catch (std::out_of_range) { | |
| 281 | + return false; | |
| 282 | + } | |
| 283 | + } | |
| 284 | + | |
| 285 | + template<typename T, enable_if_t<std::is_floating_point<T>::value, detail::enabler> = detail::dummy> | |
| 286 | + bool lexical_cast(std::string input, T& output) { | |
| 287 | + try{ | |
| 288 | + output = (T) std::stold(input); | |
| 289 | + return true; | |
| 290 | + } catch (std::invalid_argument) { | |
| 291 | + return false; | |
| 292 | + } catch (std::out_of_range) { | |
| 293 | + return false; | |
| 294 | + } | |
| 295 | + } | |
| 296 | + | |
| 297 | + // String and similar | |
| 298 | + template<typename T, | |
| 299 | + enable_if_t<is_vector<T>::value, detail::enabler> = detail::dummy> | |
| 300 | + bool lexical_cast(std::string input, T& output) { | |
| 301 | + if(output.size() == input.size()) | |
| 302 | + output.resize(input.size()); | |
| 303 | + for(size_t i=0; i<input.size(); i++) | |
| 304 | + output[i] = input[i]; | |
| 305 | + return true; | |
| 306 | + } | |
| 280 | 307 | |
| 281 | - for(const std::string &name : input) { | |
| 282 | - if(name.compare(0, 2, "--") == 0) | |
| 283 | - //output = output.substring(2); | |
| 284 | - throw BadNameString(name); | |
| 285 | - else if(name.compare(0, 1, std::string("-")) == 0) | |
| 286 | - throw BadNameString(name); | |
| 287 | - //output = output.substring(1); | |
| 308 | + // String and similar | |
| 309 | + template<typename T, | |
| 310 | + enable_if_t<!std::is_floating_point<T>::value && !std::is_integral<T>::value && !is_vector<T>::value | |
| 311 | + , detail::enabler> = detail::dummy> | |
| 312 | + bool lexical_cast(std::string input, T& output) { | |
| 313 | + output = input; | |
| 314 | + return true; | |
| 288 | 315 | } |
| 289 | 316 | } |
| 290 | 317 | |
| 291 | 318 | |
| 292 | -const Combiner NOTHING {0, false,false,false, {}}; | |
| 293 | -const Combiner REQUIRED {1, false,true, false, {}}; | |
| 294 | -const Combiner DEFAULT {1, false,false,true, {}}; | |
| 295 | -const Combiner POSITIONAL {1, true, false,false, {}}; | |
| 296 | -const Combiner ARGS {-1, false,false,false, {}}; | |
| 297 | -const Combiner VALIDATORS {1, false, false, false, {}}; | |
| 319 | + | |
| 320 | +// Defines for common Combiners (don't use combiners directly) | |
| 321 | + | |
| 322 | + | |
| 323 | +const detail::Combiner NOTHING {0, false,false,false, {}}; | |
| 324 | +const detail::Combiner REQUIRED {1, false,true, false, {}}; | |
| 325 | +const detail::Combiner DEFAULT {1, false,false,true, {}}; | |
| 326 | +const detail::Combiner POSITIONAL {1, true, false,false, {}}; | |
| 327 | +const detail::Combiner ARGS {-1, false,false,false, {}}; | |
| 328 | +const detail::Combiner VALIDATORS {1, false, false, false, {}}; | |
| 298 | 329 | |
| 299 | 330 | // Warning about using these validators: |
| 300 | 331 | // The files could be added/deleted after the validation. This is not common, |
| 301 | 332 | // but if this is a possibility, check the file you open afterwards |
| 302 | -const Combiner ExistingFile {1, false, false, false, {_ExistingFile}}; | |
| 303 | -const Combiner ExistingDirectory {1, false, false, false, {_ExistingDirectory}}; | |
| 304 | -const Combiner NonexistentPath {1, false, false, false, {_NonexistentPath}}; | |
| 333 | +const detail::Combiner ExistingFile {1, false, false, false, {detail::_ExistingFile}}; | |
| 334 | +const detail::Combiner ExistingDirectory {1, false, false, false, {detail::_ExistingDirectory}}; | |
| 335 | +const detail::Combiner NonexistentPath {1, false, false, false, {detail::_NonexistentPath}}; | |
| 305 | 336 | |
| 306 | 337 | typedef std::vector<std::vector<std::string>> results_t; |
| 307 | 338 | typedef std::function<bool(results_t)> callback_t; |
| ... | ... | @@ -314,7 +345,7 @@ protected: |
| 314 | 345 | // Config |
| 315 | 346 | std::vector<std::string> snames; |
| 316 | 347 | std::vector<std::string> lnames; |
| 317 | - Combiner opts; | |
| 348 | + detail::Combiner opts; | |
| 318 | 349 | std::string discription; |
| 319 | 350 | callback_t callback; |
| 320 | 351 | |
| ... | ... | @@ -323,9 +354,9 @@ protected: |
| 323 | 354 | |
| 324 | 355 | |
| 325 | 356 | public: |
| 326 | - Option(std::string name, std::string discription = "", Combiner opts=NOTHING, std::function<bool(results_t)> callback=[](results_t){return true;}) : | |
| 357 | + Option(std::string name, std::string discription = "", detail::Combiner opts=NOTHING, std::function<bool(results_t)> callback=[](results_t){return true;}) : | |
| 327 | 358 | opts(opts), discription(discription), callback(callback){ |
| 328 | - std::tie(snames, lnames) = get_names(split_names(name)); | |
| 359 | + std::tie(snames, lnames) = detail::get_names(detail::split_names(name)); | |
| 329 | 360 | } |
| 330 | 361 | |
| 331 | 362 | void clear() { |
| ... | ... | @@ -378,7 +409,7 @@ public: |
| 378 | 409 | name_list.push_back("-"+sname); |
| 379 | 410 | for(const std::string& lname : lnames) |
| 380 | 411 | name_list.push_back("--"+lname); |
| 381 | - return join(name_list); | |
| 412 | + return detail::join(name_list); | |
| 382 | 413 | } |
| 383 | 414 | |
| 384 | 415 | bool check_name(std::string name) const { |
| ... | ... | @@ -399,7 +430,6 @@ public: |
| 399 | 430 | |
| 400 | 431 | |
| 401 | 432 | void add_result(int r, std::string s) { |
| 402 | - logit("Adding result: " + s); | |
| 403 | 433 | results.at(r).push_back(s); |
| 404 | 434 | } |
| 405 | 435 | int get_new() { |
| ... | ... | @@ -420,7 +450,7 @@ public: |
| 420 | 450 | for(const auto& item : results) { |
| 421 | 451 | if(&item!=&results[0]) |
| 422 | 452 | val+="],["; |
| 423 | - val += join(item); | |
| 453 | + val += detail::join(item); | |
| 424 | 454 | } |
| 425 | 455 | val += "]"; |
| 426 | 456 | return val; |
| ... | ... | @@ -446,57 +476,9 @@ public: |
| 446 | 476 | }; |
| 447 | 477 | |
| 448 | 478 | |
| 449 | -template<typename T, enable_if_t<std::is_integral<T>::value, detail::enabler> = dummy> | |
| 450 | -bool lexical_cast(std::string input, T& output) { | |
| 451 | - logit("Int lexical cast " + input); | |
| 452 | - try{ | |
| 453 | - output = (T) std::stoll(input); | |
| 454 | - return true; | |
| 455 | - } catch (std::invalid_argument) { | |
| 456 | - return false; | |
| 457 | - } catch (std::out_of_range) { | |
| 458 | - return false; | |
| 459 | - } | |
| 460 | -} | |
| 461 | - | |
| 462 | -template<typename T, enable_if_t<std::is_floating_point<T>::value, detail::enabler> = dummy> | |
| 463 | -bool lexical_cast(std::string input, T& output) { | |
| 464 | - logit("Floating lexical cast " + input); | |
| 465 | - try{ | |
| 466 | - output = (T) std::stold(input); | |
| 467 | - return true; | |
| 468 | - } catch (std::invalid_argument) { | |
| 469 | - return false; | |
| 470 | - } catch (std::out_of_range) { | |
| 471 | - return false; | |
| 472 | - } | |
| 473 | -} | |
| 474 | - | |
| 475 | -// String and similar | |
| 476 | -template<typename T, | |
| 477 | -enable_if_t<is_vector<T>::value, detail::enabler> = dummy> | |
| 478 | -bool lexical_cast(std::string input, T& output) { | |
| 479 | - logit("vector lexical cast: " + input); | |
| 480 | - if(output.size() == input.size()) | |
| 481 | - output.resize(input.size()); | |
| 482 | - for(size_t i=0; i<input.size(); i++) | |
| 483 | - output[i] = input[i]; | |
| 484 | - return true; | |
| 485 | -} | |
| 486 | - | |
| 487 | -// String and similar | |
| 488 | -template<typename T, | |
| 489 | -enable_if_t<!std::is_floating_point<T>::value && !std::is_integral<T>::value && !is_vector<T>::value | |
| 490 | -, detail::enabler> = dummy> | |
| 491 | -bool lexical_cast(std::string input, T& output) { | |
| 492 | - logit("Direct lexical cast: " + input); | |
| 493 | - output = input; | |
| 494 | - return true; | |
| 495 | -} | |
| 496 | 479 | |
| 497 | 480 | enum class Classifer {NONE, POSITIONAL_MARK, SHORT, LONG, SUBCOMMAND}; |
| 498 | 481 | |
| 499 | - | |
| 500 | 482 | class App; |
| 501 | 483 | |
| 502 | 484 | // Prototype return value test |
| ... | ... | @@ -514,18 +496,16 @@ public: |
| 514 | 496 | /// explicit * notation. |
| 515 | 497 | T& operator *() const { |
| 516 | 498 | if(*value) { |
| 517 | - //std::cout << "Succ" << std::endl; | |
| 518 | 499 | return **value; |
| 519 | 500 | } |
| 520 | 501 | else { |
| 521 | - //std::cout << "Throwing!!!" << std::endl; | |
| 522 | 502 | throw EmptyError(name); |
| 523 | 503 | } |
| 524 | 504 | } |
| 525 | 505 | }; |
| 526 | 506 | |
| 527 | 507 | /// Creates a command line program, with very few defaults. |
| 528 | -/** To use, create a new Program() instance with argc, argv, and a help discription. The templated | |
| 508 | +/** To use, create a new Program() instance with argc, argv, and a help description. The templated | |
| 529 | 509 | * add_option methods make it easy to prepare options. Remember to call `.start` before starting your |
| 530 | 510 | * program, so that the options can be evaluated and the help option doesn't accidentally run your program. */ |
| 531 | 511 | class App { |
| ... | ... | @@ -568,7 +548,6 @@ public: |
| 568 | 548 | App* add_subcommand(std::string name, std::string discription="") { |
| 569 | 549 | subcommands.emplace_back(new App(discription)); |
| 570 | 550 | subcommands.back()->name = name; |
| 571 | - logit(subcommands.back()->name); | |
| 572 | 551 | return subcommands.back().get(); |
| 573 | 552 | } |
| 574 | 553 | |
| ... | ... | @@ -592,7 +571,7 @@ public: |
| 592 | 571 | std::string name, ///< The name, long,short |
| 593 | 572 | callback_t callback, ///< The callback |
| 594 | 573 | std::string discription="", ///< Discription string |
| 595 | - Combiner opts=VALIDATORS ///< The options (REQUIRED, DEFAULT, POSITIONAL, ARGS()) | |
| 574 | + detail::Combiner opts=VALIDATORS ///< The options (REQUIRED, DEFAULT, POSITIONAL, ARGS()) | |
| 596 | 575 | ) { |
| 597 | 576 | Option myopt{name, discription, opts, callback}; |
| 598 | 577 | if(std::find(std::begin(options), std::end(options), myopt) == std::end(options)) |
| ... | ... | @@ -604,12 +583,12 @@ public: |
| 604 | 583 | } |
| 605 | 584 | |
| 606 | 585 | /// Add option for string |
| 607 | - template<typename T, enable_if_t<!is_vector<T>::value, detail::enabler> = dummy> | |
| 586 | + template<typename T, enable_if_t<!is_vector<T>::value, detail::enabler> = detail::dummy> | |
| 608 | 587 | Option* add_option( |
| 609 | 588 | std::string name, ///< The name, long,short |
| 610 | 589 | T &variable, ///< The variable to set |
| 611 | 590 | std::string discription="", ///< Discription string |
| 612 | - Combiner opts=VALIDATORS ///< The options (REQUIRED, DEFAULT, POSITIONAL, ARGS()) | |
| 591 | + detail::Combiner opts=VALIDATORS ///< The options (REQUIRED, DEFAULT, POSITIONAL, ARGS()) | |
| 613 | 592 | ) { |
| 614 | 593 | |
| 615 | 594 | |
| ... | ... | @@ -622,7 +601,7 @@ public: |
| 622 | 601 | if(res[0].size()!=1) { |
| 623 | 602 | return false; |
| 624 | 603 | } |
| 625 | - return lexical_cast(res[0][0], variable); | |
| 604 | + return detail::lexical_cast(res[0][0], variable); | |
| 626 | 605 | }; |
| 627 | 606 | |
| 628 | 607 | return add_option(name, fun, discription, opts); |
| ... | ... | @@ -634,7 +613,7 @@ public: |
| 634 | 613 | std::string name, ///< The name, long,short |
| 635 | 614 | std::vector<T> &variable, ///< The variable to set |
| 636 | 615 | std::string discription="", ///< Discription string |
| 637 | - Combiner opts=ARGS ///< The options (REQUIRED, DEFAULT, POSITIONAL, ARGS()) | |
| 616 | + detail::Combiner opts=ARGS ///< The options (REQUIRED, DEFAULT, POSITIONAL, ARGS()) | |
| 638 | 617 | ) { |
| 639 | 618 | |
| 640 | 619 | if(opts.num==0) |
| ... | ... | @@ -645,7 +624,7 @@ public: |
| 645 | 624 | for(const auto &a : res) |
| 646 | 625 | for(const auto &b : a) { |
| 647 | 626 | variable.emplace_back(); |
| 648 | - retval &= lexical_cast(b, variable.back()); | |
| 627 | + retval &= detail::lexical_cast(b, variable.back()); | |
| 649 | 628 | } |
| 650 | 629 | return variable.size() > 0 && retval; |
| 651 | 630 | }; |
| ... | ... | @@ -667,7 +646,7 @@ public: |
| 667 | 646 | } |
| 668 | 647 | |
| 669 | 648 | /// Add option for flag |
| 670 | - template<typename T, enable_if_t<std::is_integral<T>::value, detail::enabler> = dummy> | |
| 649 | + template<typename T, enable_if_t<std::is_integral<T>::value, detail::enabler> = detail::dummy> | |
| 671 | 650 | Option* add_flag( |
| 672 | 651 | std::string name, ///< The name, short,long |
| 673 | 652 | T &count, ///< A varaible holding the count |
| ... | ... | @@ -690,7 +669,7 @@ public: |
| 690 | 669 | T &member, ///< The selected member of the set |
| 691 | 670 | std::set<T> options, ///< The set of posibilities |
| 692 | 671 | std::string discription="", ///< Discription string |
| 693 | - Combiner opts=VALIDATORS ///< The options (REQUIRED, DEFAULT, POSITIONAL, ARGS()) | |
| 672 | + detail::Combiner opts=VALIDATORS ///< The options (REQUIRED, DEFAULT, POSITIONAL, ARGS()) | |
| 694 | 673 | ) { |
| 695 | 674 | |
| 696 | 675 | if(opts.num!=1) |
| ... | ... | @@ -703,7 +682,7 @@ public: |
| 703 | 682 | if(res[0].size()!=1) { |
| 704 | 683 | return false; |
| 705 | 684 | } |
| 706 | - bool retval = lexical_cast(res[0][0], member); | |
| 685 | + bool retval = detail::lexical_cast(res[0][0], member); | |
| 707 | 686 | if(!retval) |
| 708 | 687 | return false; |
| 709 | 688 | return std::find(std::begin(options), std::end(options), member) != std::end(options); |
| ... | ... | @@ -719,11 +698,11 @@ public: |
| 719 | 698 | |
| 720 | 699 | /// Prototype for new output style |
| 721 | 700 | template<typename T = std::string, |
| 722 | - enable_if_t<!is_vector<T>::value, detail::enabler> = dummy> | |
| 701 | + enable_if_t<!is_vector<T>::value, detail::enabler> = detail::dummy> | |
| 723 | 702 | Value<T> make_option( |
| 724 | 703 | std::string name, ///< The name, short,long |
| 725 | 704 | std::string discription="", |
| 726 | - Combiner opts=VALIDATORS | |
| 705 | + detail::Combiner opts=VALIDATORS | |
| 727 | 706 | ) { |
| 728 | 707 | |
| 729 | 708 | if(opts.num!=1) |
| ... | ... | @@ -740,7 +719,7 @@ public: |
| 740 | 719 | return false; |
| 741 | 720 | } |
| 742 | 721 | ptr->reset(new T()); // resets the internal ptr |
| 743 | - return lexical_cast(res[0][0], **ptr); | |
| 722 | + return detail::lexical_cast(res[0][0], **ptr); | |
| 744 | 723 | }; |
| 745 | 724 | add_option(name, fun, discription, opts); |
| 746 | 725 | return out; |
| ... | ... | @@ -748,12 +727,12 @@ public: |
| 748 | 727 | |
| 749 | 728 | /// Prototype for new output style with default |
| 750 | 729 | template<typename T, |
| 751 | - enable_if_t<!is_vector<T>::value, detail::enabler> = dummy> | |
| 730 | + enable_if_t<!is_vector<T>::value, detail::enabler> = detail::dummy> | |
| 752 | 731 | Value<T> make_option( |
| 753 | 732 | std::string name, ///< The name, short,long |
| 754 | 733 | const T& default_value, |
| 755 | 734 | std::string discription="", |
| 756 | - Combiner opts=VALIDATORS | |
| 735 | + detail::Combiner opts=VALIDATORS | |
| 757 | 736 | ) { |
| 758 | 737 | |
| 759 | 738 | if(opts.num!=1) |
| ... | ... | @@ -771,7 +750,7 @@ public: |
| 771 | 750 | return false; |
| 772 | 751 | } |
| 773 | 752 | ptr->reset(new T()); // resets the internal ptr |
| 774 | - return lexical_cast(res[0][0], **ptr); | |
| 753 | + return detail::lexical_cast(res[0][0], **ptr); | |
| 775 | 754 | }; |
| 776 | 755 | add_option(name, fun, discription, opts); |
| 777 | 756 | return out; |
| ... | ... | @@ -779,11 +758,11 @@ public: |
| 779 | 758 | |
| 780 | 759 | /// Prototype for new output style, vector |
| 781 | 760 | template<typename T, |
| 782 | - enable_if_t<is_vector<T>::value, detail::enabler> = dummy> | |
| 761 | + enable_if_t<is_vector<T>::value, detail::enabler> = detail::dummy> | |
| 783 | 762 | Value<T> make_option( |
| 784 | 763 | std::string name, ///< The name, short,long |
| 785 | 764 | std::string discription="", |
| 786 | - Combiner opts=VALIDATORS | |
| 765 | + detail::Combiner opts=VALIDATORS | |
| 787 | 766 | ) { |
| 788 | 767 | |
| 789 | 768 | if(opts.num==0) |
| ... | ... | @@ -798,7 +777,7 @@ public: |
| 798 | 777 | for(const auto &a : res) |
| 799 | 778 | for(const auto &b : a) { |
| 800 | 779 | (*ptr)->emplace_back(); |
| 801 | - retval &= lexical_cast(b, (*ptr)->back()); | |
| 780 | + retval &= detail::lexical_cast(b, (*ptr)->back()); | |
| 802 | 781 | } |
| 803 | 782 | return (*ptr)->size() > 0 && retval; |
| 804 | 783 | }; |
| ... | ... | @@ -832,7 +811,7 @@ public: |
| 832 | 811 | std::string name, ///< The name, short,long |
| 833 | 812 | std::set<T> options, ///< The set of posibilities |
| 834 | 813 | std::string discription="", ///< Discription string |
| 835 | - Combiner opts=VALIDATORS ///< The options (REQUIRED, DEFAULT, POSITIONAL, ARGS()) | |
| 814 | + detail::Combiner opts=VALIDATORS ///< The options (REQUIRED, DEFAULT, POSITIONAL, ARGS()) | |
| 836 | 815 | ) { |
| 837 | 816 | |
| 838 | 817 | Value<T> out(name); |
| ... | ... | @@ -849,7 +828,7 @@ public: |
| 849 | 828 | return false; |
| 850 | 829 | } |
| 851 | 830 | ptr->reset(new T()); |
| 852 | - bool retval = lexical_cast(res[0][0], **ptr); | |
| 831 | + bool retval = detail::lexical_cast(res[0][0], **ptr); | |
| 853 | 832 | if(!retval) |
| 854 | 833 | return false; |
| 855 | 834 | return std::find(std::begin(options), std::end(options), **ptr) != std::end(options); |
| ... | ... | @@ -876,7 +855,6 @@ public: |
| 876 | 855 | |
| 877 | 856 | while(args.size()>0) { |
| 878 | 857 | |
| 879 | - logit("Parse: ["+join(args)+"]"); | |
| 880 | 858 | |
| 881 | 859 | Classifer classifer = positional_only ? Classifer::NONE : _recognize(args.back()); |
| 882 | 860 | switch(classifer) { |
| ... | ... | @@ -894,7 +872,6 @@ public: |
| 894 | 872 | _parse_short(args); |
| 895 | 873 | break; |
| 896 | 874 | case Classifer::NONE: |
| 897 | - logit("Positional: "+args.back()); | |
| 898 | 875 | positionals.push_back(args.back()); |
| 899 | 876 | args.pop_back(); |
| 900 | 877 | } |
| ... | ... | @@ -920,7 +897,7 @@ public: |
| 920 | 897 | |
| 921 | 898 | } |
| 922 | 899 | if(positionals.size()>0) |
| 923 | - throw PositionalError("[" + join(positionals) + "]"); | |
| 900 | + throw PositionalError("[" + detail::join(positionals) + "]"); | |
| 924 | 901 | } |
| 925 | 902 | |
| 926 | 903 | void _parse_subcommand(std::vector<std::string> &args) { |
| ... | ... | @@ -940,12 +917,10 @@ public: |
| 940 | 917 | |
| 941 | 918 | std::string name; |
| 942 | 919 | std::string rest; |
| 943 | - if(!split_short(current, name, rest)) | |
| 920 | + if(!detail::split_short(current, name, rest)) | |
| 944 | 921 | throw HorribleError("Short"); |
| 945 | 922 | args.pop_back(); |
| 946 | 923 | |
| 947 | - logit("Working on short: " + name + " (" + rest + ")"); | |
| 948 | - | |
| 949 | 924 | auto op = std::find_if(std::begin(options), std::end(options), [name](const Option &v){return v.check_sname(name);}); |
| 950 | 925 | |
| 951 | 926 | if(op == std::end(options)) { |
| ... | ... | @@ -975,7 +950,6 @@ public: |
| 975 | 950 | } else while(num>0 && args.size() > 0) { |
| 976 | 951 | num--; |
| 977 | 952 | std::string current = args.back(); |
| 978 | - logit("Adding: "+current); | |
| 979 | 953 | args.pop_back(); |
| 980 | 954 | op->add_result(vnum,current); |
| 981 | 955 | } |
| ... | ... | @@ -995,9 +969,9 @@ public: |
| 995 | 969 | if(com->name == current) |
| 996 | 970 | return Classifer::SUBCOMMAND; |
| 997 | 971 | } |
| 998 | - if(split_long(current, dummy1, dummy2)) | |
| 972 | + if(detail::split_long(current, dummy1, dummy2)) | |
| 999 | 973 | return Classifer::LONG; |
| 1000 | - if(split_short(current, dummy1, dummy2)) | |
| 974 | + if(detail::split_short(current, dummy1, dummy2)) | |
| 1001 | 975 | return Classifer::SHORT; |
| 1002 | 976 | return Classifer::NONE; |
| 1003 | 977 | } |
| ... | ... | @@ -1007,13 +981,10 @@ public: |
| 1007 | 981 | |
| 1008 | 982 | std::string name; |
| 1009 | 983 | std::string value; |
| 1010 | - if(!split_long(current, name, value)) | |
| 984 | + if(!detail::split_long(current, name, value)) | |
| 1011 | 985 | throw HorribleError("Long"); |
| 1012 | 986 | args.pop_back(); |
| 1013 | 987 | |
| 1014 | - | |
| 1015 | - logit("Working on long: " + name + " (" + value + ")"); | |
| 1016 | - | |
| 1017 | 988 | auto op = std::find_if(std::begin(options), std::end(options), [name](const Option &v){return v.check_lname(name);}); |
| 1018 | 989 | |
| 1019 | 990 | if(op == std::end(options)) { |
| ... | ... | @@ -1067,9 +1038,7 @@ public: |
| 1067 | 1038 | /// Counts the number of times the given option was passed. |
| 1068 | 1039 | int count(std::string name) const { |
| 1069 | 1040 | for(const Option &opt : options) { |
| 1070 | - logit("Computing: " + opt.get_name()); | |
| 1071 | 1041 | if(opt.check_name(name)) { |
| 1072 | - logit("Counting: " + opt.get_name() + std::to_string(opt.count())); | |
| 1073 | 1042 | return opt.count(); |
| 1074 | 1043 | } |
| 1075 | 1044 | } | ... | ... |
tests/CLITest.cpp
| ... | ... | @@ -222,7 +222,7 @@ TEST_F(TApp, Reset) { |
| 222 | 222 | |
| 223 | 223 | TEST_F(TApp, FileNotExists) { |
| 224 | 224 | std::string myfile{"TestNonFileNotUsed.txt"}; |
| 225 | - EXPECT_TRUE(CLI::_NonexistentPath(myfile)); | |
| 225 | + EXPECT_TRUE(CLI::detail::_NonexistentPath(myfile)); | |
| 226 | 226 | |
| 227 | 227 | std::string filename; |
| 228 | 228 | app.add_option("file", filename, "", CLI::NonexistentPath); |
| ... | ... | @@ -239,12 +239,12 @@ TEST_F(TApp, FileNotExists) { |
| 239 | 239 | EXPECT_THROW(run(), CLI::ParseError); |
| 240 | 240 | |
| 241 | 241 | std::remove(myfile.c_str()); |
| 242 | - EXPECT_FALSE(CLI::_ExistingFile(myfile)); | |
| 242 | + EXPECT_FALSE(CLI::detail::_ExistingFile(myfile)); | |
| 243 | 243 | } |
| 244 | 244 | |
| 245 | 245 | TEST_F(TApp, FileExists) { |
| 246 | 246 | std::string myfile{"TestNonFileNotUsed.txt"}; |
| 247 | - EXPECT_FALSE(CLI::_ExistingFile(myfile)); | |
| 247 | + EXPECT_FALSE(CLI::detail::_ExistingFile(myfile)); | |
| 248 | 248 | |
| 249 | 249 | std::string filename = "Failed"; |
| 250 | 250 | app.add_option("file", filename, "", CLI::ExistingFile); |
| ... | ... | @@ -261,7 +261,7 @@ TEST_F(TApp, FileExists) { |
| 261 | 261 | EXPECT_EQ(myfile, filename); |
| 262 | 262 | |
| 263 | 263 | std::remove(myfile.c_str()); |
| 264 | - EXPECT_FALSE(CLI::_ExistingFile(myfile)); | |
| 264 | + EXPECT_FALSE(CLI::detail::_ExistingFile(myfile)); | |
| 265 | 265 | } |
| 266 | 266 | |
| 267 | 267 | TEST_F(TApp, InSet) { | ... | ... |
tests/SmallTest.cpp
| ... | ... | @@ -7,79 +7,79 @@ |
| 7 | 7 | |
| 8 | 8 | TEST(Validators, FileExists) { |
| 9 | 9 | std::string myfile{"TestFileNotUsed.txt"}; |
| 10 | - EXPECT_FALSE(CLI::_ExistingFile(myfile)); | |
| 10 | + EXPECT_FALSE(CLI::detail::_ExistingFile(myfile)); | |
| 11 | 11 | bool ok = static_cast<bool>(std::ofstream(myfile.c_str()).put('a')); // create file |
| 12 | 12 | EXPECT_TRUE(ok); |
| 13 | - EXPECT_TRUE(CLI::_ExistingFile(myfile)); | |
| 13 | + EXPECT_TRUE(CLI::detail::_ExistingFile(myfile)); | |
| 14 | 14 | |
| 15 | 15 | std::remove(myfile.c_str()); |
| 16 | - EXPECT_FALSE(CLI::_ExistingFile(myfile)); | |
| 16 | + EXPECT_FALSE(CLI::detail::_ExistingFile(myfile)); | |
| 17 | 17 | } |
| 18 | 18 | |
| 19 | 19 | TEST(Validators, FileNotExists) { |
| 20 | 20 | std::string myfile{"TestFileNotUsed.txt"}; |
| 21 | - EXPECT_TRUE(CLI::_NonexistentPath(myfile)); | |
| 21 | + EXPECT_TRUE(CLI::detail::_NonexistentPath(myfile)); | |
| 22 | 22 | bool ok = static_cast<bool>(std::ofstream(myfile.c_str()).put('a')); // create file |
| 23 | 23 | EXPECT_TRUE(ok); |
| 24 | - EXPECT_FALSE(CLI::_NonexistentPath(myfile)); | |
| 24 | + EXPECT_FALSE(CLI::detail::_NonexistentPath(myfile)); | |
| 25 | 25 | |
| 26 | 26 | std::remove(myfile.c_str()); |
| 27 | - EXPECT_TRUE(CLI::_NonexistentPath(myfile)); | |
| 27 | + EXPECT_TRUE(CLI::detail::_NonexistentPath(myfile)); | |
| 28 | 28 | } |
| 29 | 29 | |
| 30 | 30 | TEST(Split, StringList) { |
| 31 | 31 | |
| 32 | 32 | std::vector<std::string> results {"a", "long", "--lone", "-q"}; |
| 33 | - EXPECT_EQ(results, CLI::split_names("a,long,--lone,-q")); | |
| 33 | + EXPECT_EQ(results, CLI::detail::split_names("a,long,--lone,-q")); | |
| 34 | 34 | |
| 35 | - EXPECT_EQ(std::vector<std::string>({"one"}), CLI::split_names("one")); | |
| 35 | + EXPECT_EQ(std::vector<std::string>({"one"}), CLI::detail::split_names("one")); | |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | 38 | TEST(RegEx, Shorts) { |
| 39 | 39 | std::string name, value; |
| 40 | 40 | |
| 41 | - EXPECT_TRUE(CLI::split_short("-a", name, value)); | |
| 41 | + EXPECT_TRUE(CLI::detail::split_short("-a", name, value)); | |
| 42 | 42 | EXPECT_EQ("a", name); |
| 43 | 43 | EXPECT_EQ("", value); |
| 44 | 44 | |
| 45 | - EXPECT_TRUE(CLI::split_short("-B", name, value)); | |
| 45 | + EXPECT_TRUE(CLI::detail::split_short("-B", name, value)); | |
| 46 | 46 | EXPECT_EQ("B", name); |
| 47 | 47 | EXPECT_EQ("", value); |
| 48 | 48 | |
| 49 | - EXPECT_TRUE(CLI::split_short("-cc", name, value)); | |
| 49 | + EXPECT_TRUE(CLI::detail::split_short("-cc", name, value)); | |
| 50 | 50 | EXPECT_EQ("c", name); |
| 51 | 51 | EXPECT_EQ("c", value); |
| 52 | 52 | |
| 53 | - EXPECT_TRUE(CLI::split_short("-simple", name, value)); | |
| 53 | + EXPECT_TRUE(CLI::detail::split_short("-simple", name, value)); | |
| 54 | 54 | EXPECT_EQ("s", name); |
| 55 | 55 | EXPECT_EQ("imple", value); |
| 56 | 56 | |
| 57 | - EXPECT_FALSE(CLI::split_short("--a", name, value)); | |
| 58 | - EXPECT_FALSE(CLI::split_short("--thing", name, value)); | |
| 59 | - EXPECT_FALSE(CLI::split_short("--", name, value)); | |
| 60 | - EXPECT_FALSE(CLI::split_short("something", name, value)); | |
| 61 | - EXPECT_FALSE(CLI::split_short("s", name, value)); | |
| 57 | + EXPECT_FALSE(CLI::detail::split_short("--a", name, value)); | |
| 58 | + EXPECT_FALSE(CLI::detail::split_short("--thing", name, value)); | |
| 59 | + EXPECT_FALSE(CLI::detail::split_short("--", name, value)); | |
| 60 | + EXPECT_FALSE(CLI::detail::split_short("something", name, value)); | |
| 61 | + EXPECT_FALSE(CLI::detail::split_short("s", name, value)); | |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | 64 | TEST(RegEx, Longs) { |
| 65 | 65 | std::string name, value; |
| 66 | 66 | |
| 67 | - EXPECT_TRUE(CLI::split_long("--a", name, value)); | |
| 67 | + EXPECT_TRUE(CLI::detail::split_long("--a", name, value)); | |
| 68 | 68 | EXPECT_EQ("a", name); |
| 69 | 69 | EXPECT_EQ("", value); |
| 70 | 70 | |
| 71 | - EXPECT_TRUE(CLI::split_long("--thing", name, value)); | |
| 71 | + EXPECT_TRUE(CLI::detail::split_long("--thing", name, value)); | |
| 72 | 72 | EXPECT_EQ("thing", name); |
| 73 | 73 | EXPECT_EQ("", value); |
| 74 | 74 | |
| 75 | - EXPECT_TRUE(CLI::split_long("--some=thing", name, value)); | |
| 75 | + EXPECT_TRUE(CLI::detail::split_long("--some=thing", name, value)); | |
| 76 | 76 | EXPECT_EQ("some", name); |
| 77 | 77 | EXPECT_EQ("thing", value); |
| 78 | 78 | |
| 79 | - EXPECT_FALSE(CLI::split_long("-a", name, value)); | |
| 80 | - EXPECT_FALSE(CLI::split_long("-things", name, value)); | |
| 81 | - EXPECT_FALSE(CLI::split_long("Q", name, value)); | |
| 82 | - EXPECT_FALSE(CLI::split_long("--", name, value)); | |
| 79 | + EXPECT_FALSE(CLI::detail::split_long("-a", name, value)); | |
| 80 | + EXPECT_FALSE(CLI::detail::split_long("-things", name, value)); | |
| 81 | + EXPECT_FALSE(CLI::detail::split_long("Q", name, value)); | |
| 82 | + EXPECT_FALSE(CLI::detail::split_long("--", name, value)); | |
| 83 | 83 | |
| 84 | 84 | } |
| 85 | 85 | |
| ... | ... | @@ -88,16 +88,16 @@ TEST(Regex, SplittingNew) { |
| 88 | 88 | std::vector<std::string> shorts; |
| 89 | 89 | std::vector<std::string> longs; |
| 90 | 90 | |
| 91 | - EXPECT_NO_THROW(std::tie(shorts, longs) = CLI::get_names({"--long", "s", "-q", "also-long"})); | |
| 91 | + EXPECT_NO_THROW(std::tie(shorts, longs) = CLI::detail::get_names({"--long", "s", "-q", "also-long"})); | |
| 92 | 92 | EXPECT_EQ(std::vector<std::string>({"long", "also-long"}), longs); |
| 93 | 93 | EXPECT_EQ(std::vector<std::string>({"s", "q"}), shorts); |
| 94 | 94 | |
| 95 | - EXPECT_NO_THROW(std::tie(shorts, longs) = CLI::get_names({"--long", "", "s", "-q", "", "also-long"})); | |
| 95 | + EXPECT_NO_THROW(std::tie(shorts, longs) = CLI::detail::get_names({"--long", "", "s", "-q", "", "also-long"})); | |
| 96 | 96 | EXPECT_EQ(std::vector<std::string>({"long", "also-long"}), longs); |
| 97 | 97 | EXPECT_EQ(std::vector<std::string>({"s", "q"}), shorts); |
| 98 | 98 | |
| 99 | - EXPECT_THROW(std::tie(shorts, longs) = CLI::get_names({"-"}), CLI::BadNameString); | |
| 100 | - EXPECT_THROW(std::tie(shorts, longs) = CLI::get_names({"--"}), CLI::BadNameString); | |
| 101 | - EXPECT_THROW(std::tie(shorts, longs) = CLI::get_names({"-hi"}), CLI::BadNameString); | |
| 99 | + EXPECT_THROW(std::tie(shorts, longs) = CLI::detail::get_names({"-"}), CLI::BadNameString); | |
| 100 | + EXPECT_THROW(std::tie(shorts, longs) = CLI::detail::get_names({"--"}), CLI::BadNameString); | |
| 101 | + EXPECT_THROW(std::tie(shorts, longs) = CLI::detail::get_names({"-hi"}), CLI::BadNameString); | |
| 102 | 102 | |
| 103 | 103 | } | ... | ... |