File indexing completed on 2026-01-08 10:09:17
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009
0010
0011
0012 #include "../Split.hpp"
0013
0014
0015 #include <string>
0016 #include <tuple>
0017 #include <utility>
0018 #include <vector>
0019
0020
0021 #include "../Error.hpp"
0022 #include "../StringTools.hpp"
0023
0024 namespace CLI {
0025
0026
0027 namespace detail {
0028
0029 CLI11_INLINE bool split_short(const std::string ¤t, std::string &name, std::string &rest) {
0030 if(current.size() > 1 && current[0] == '-' && valid_first_char(current[1])) {
0031 name = current.substr(1, 1);
0032 rest = current.substr(2);
0033 return true;
0034 }
0035 return false;
0036 }
0037
0038 CLI11_INLINE bool split_long(const std::string ¤t, std::string &name, std::string &value) {
0039 if(current.size() > 2 && current.compare(0, 2, "--") == 0 && valid_first_char(current[2])) {
0040 auto loc = current.find_first_of('=');
0041 if(loc != std::string::npos) {
0042 name = current.substr(2, loc - 2);
0043 value = current.substr(loc + 1);
0044 } else {
0045 name = current.substr(2);
0046 value = "";
0047 }
0048 return true;
0049 }
0050 return false;
0051 }
0052
0053 CLI11_INLINE bool split_windows_style(const std::string ¤t, std::string &name, std::string &value) {
0054 if(current.size() > 1 && current[0] == '/' && valid_first_char(current[1])) {
0055 auto loc = current.find_first_of(':');
0056 if(loc != std::string::npos) {
0057 name = current.substr(1, loc - 1);
0058 value = current.substr(loc + 1);
0059 } else {
0060 name = current.substr(1);
0061 value = "";
0062 }
0063 return true;
0064 }
0065 return false;
0066 }
0067
0068 CLI11_INLINE std::vector<std::string> split_names(std::string current) {
0069 std::vector<std::string> output;
0070 std::size_t val = 0;
0071 while((val = current.find(',')) != std::string::npos) {
0072 output.push_back(trim_copy(current.substr(0, val)));
0073 current = current.substr(val + 1);
0074 }
0075 output.push_back(trim_copy(current));
0076 return output;
0077 }
0078
0079 CLI11_INLINE std::vector<std::pair<std::string, std::string>> get_default_flag_values(const std::string &str) {
0080 std::vector<std::string> flags = split_names(str);
0081 flags.erase(std::remove_if(flags.begin(),
0082 flags.end(),
0083 [](const std::string &name) {
0084 return ((name.empty()) || (!(((name.find_first_of('{') != std::string::npos) &&
0085 (name.back() == '}')) ||
0086 (name[0] == '!'))));
0087 }),
0088 flags.end());
0089 std::vector<std::pair<std::string, std::string>> output;
0090 output.reserve(flags.size());
0091 for(auto &flag : flags) {
0092 auto def_start = flag.find_first_of('{');
0093 std::string defval = "false";
0094 if((def_start != std::string::npos) && (flag.back() == '}')) {
0095 defval = flag.substr(def_start + 1);
0096 defval.pop_back();
0097 flag.erase(def_start, std::string::npos);
0098 }
0099 flag.erase(0, flag.find_first_not_of("-!"));
0100 output.emplace_back(flag, defval);
0101 }
0102 return output;
0103 }
0104
0105 CLI11_INLINE std::tuple<std::vector<std::string>, std::vector<std::string>, std::string>
0106 get_names(const std::vector<std::string> &input, bool allow_non_standard) {
0107
0108 std::vector<std::string> short_names;
0109 std::vector<std::string> long_names;
0110 std::string pos_name;
0111 for(std::string name : input) {
0112 if(name.length() == 0) {
0113 continue;
0114 }
0115 if(name.length() > 1 && name[0] == '-' && name[1] != '-') {
0116 if(name.length() == 2 && valid_first_char(name[1])) {
0117 short_names.emplace_back(1, name[1]);
0118 } else if(name.length() > 2) {
0119 if(allow_non_standard) {
0120 name = name.substr(1);
0121 if(valid_name_string(name)) {
0122 short_names.push_back(name);
0123 } else {
0124 throw BadNameString::BadLongName(name);
0125 }
0126 } else {
0127 throw BadNameString::MissingDash(name);
0128 }
0129 } else {
0130 throw BadNameString::OneCharName(name);
0131 }
0132 } else if(name.length() > 2 && name.substr(0, 2) == "--") {
0133 name = name.substr(2);
0134 if(valid_name_string(name)) {
0135 long_names.push_back(name);
0136 } else {
0137 throw BadNameString::BadLongName(name);
0138 }
0139 } else if(name == "-" || name == "--" || name == "++") {
0140 throw BadNameString::ReservedName(name);
0141 } else {
0142 if(!pos_name.empty()) {
0143 throw BadNameString::MultiPositionalNames(name);
0144 }
0145 if(valid_name_string(name)) {
0146 pos_name = name;
0147 } else {
0148 throw BadNameString::BadPositionalName(name);
0149 }
0150 }
0151 }
0152 return std::make_tuple(short_names, long_names, pos_name);
0153 }
0154
0155 }
0156
0157 }