12#include "../Split.hpp"
24#include "../Error.hpp"
25#include "../StringTools.hpp"
32CLI11_INLINE
bool split_short(
const std::string ¤t, std::string &name, std::string &rest) {
33 if(current.size() > 1 && current[0] ==
'-' && valid_first_char(current[1])) {
34 name = current.substr(1, 1);
35 rest = current.substr(2);
41CLI11_INLINE
bool split_long(
const std::string ¤t, std::string &name, std::string &value) {
42 if(current.size() > 2 && current.compare(0, 2,
"--") == 0 && valid_first_char(current[2])) {
43 auto loc = current.find_first_of(
'=');
44 if(loc != std::string::npos) {
45 name = current.substr(2, loc - 2);
46 value = current.substr(loc + 1);
48 name = current.substr(2);
56CLI11_INLINE
bool split_windows_style(
const std::string ¤t, std::string &name, std::string &value) {
57 if(current.size() > 1 && current[0] ==
'/' && valid_first_char(current[1])) {
58 auto loc = current.find_first_of(
':');
59 if(loc != std::string::npos) {
60 name = current.substr(1, loc - 1);
61 value = current.substr(loc + 1);
63 name = current.substr(1);
71CLI11_INLINE std::vector<std::string> split_names(std::string current) {
72 std::vector<std::string> output;
74 while((val = current.find(
',')) != std::string::npos) {
75 output.push_back(trim_copy(current.substr(0, val)));
76 current = current.substr(val + 1);
78 output.push_back(trim_copy(current));
82CLI11_INLINE std::vector<std::pair<std::string, std::string>> get_default_flag_values(
const std::string &str) {
83 std::vector<std::string> flags = split_names(str);
84 flags.erase(std::remove_if(flags.begin(),
86 [](
const std::string &name) {
87 return ((name.empty()) || (!(((name.find_first_of(
'{') != std::string::npos) &&
88 (name.back() ==
'}')) ||
92 std::vector<std::pair<std::string, std::string>> output;
93 output.reserve(flags.size());
94 for(
auto &flag : flags) {
95 auto def_start = flag.find_first_of(
'{');
96 std::string defval =
"false";
97 if((def_start != std::string::npos) && (flag.back() ==
'}')) {
98 defval = flag.substr(def_start + 1);
100 flag.erase(def_start, std::string::npos);
102 flag.erase(0, flag.find_first_not_of(
"-!"));
103 output.emplace_back(flag, defval);
108CLI11_INLINE std::tuple<std::vector<std::string>, std::vector<std::string>, std::string>
109get_names(
const std::vector<std::string> &input,
bool allow_non_standard) {
111 std::vector<std::string> short_names;
112 std::vector<std::string> long_names;
113 std::string pos_name;
114 for(std::string name : input) {
118 if(name.length() > 1 && name[0] ==
'-' && name[1] !=
'-') {
119 if(name.length() == 2 && valid_first_char(name[1])) {
120 short_names.emplace_back(1, name[1]);
121 }
else if(name.length() > 2) {
122 if(allow_non_standard) {
123 name = name.substr(1);
124 if(valid_name_string(name)) {
125 short_names.push_back(name);
127 throw BadNameString::BadLongName(name);
130 throw BadNameString::MissingDash(name);
133 throw BadNameString::OneCharName(name);
135 }
else if(name.length() > 2 && name.substr(0, 2) ==
"--") {
136 name = name.substr(2);
137 if(valid_name_string(name)) {
138 long_names.push_back(name);
140 throw BadNameString::BadLongName(name);
142 }
else if(name ==
"-" || name ==
"--" || name ==
"++") {
143 throw BadNameString::ReservedName(name);
145 if(!pos_name.empty()) {
146 throw BadNameString::MultiPositionalNames(name);
148 if(valid_name_string(name)) {
151 throw BadNameString::BadPositionalName(name);
155 return std::make_tuple(short_names, long_names, pos_name);