CLI11 2.7.2
C++11 Command Line Interface Parser
Loading...
Searching...
No Matches
Split_inl.hpp
1// Copyright (c) 2017-2026, University of Cincinnati, developed by Henry Schreiner
2// under NSF AWARD 1414736 and by the respective contributors.
3// All rights reserved.
4//
5// SPDX-License-Identifier: BSD-3-Clause
6
7#pragma once
8
9// IWYU pragma: private, include "CLI/CLI.hpp"
10
11// This include is only needed for IDEs to discover symbols
12#include "../Split.hpp"
13
14// [CLI11:public_includes:set]
15#include <algorithm>
16#include <cstddef>
17#include <iterator>
18#include <string>
19#include <tuple>
20#include <utility>
21#include <vector>
22// [CLI11:public_includes:end]
23
24#include "../Error.hpp"
25#include "../StringTools.hpp"
26
27namespace CLI {
28// [CLI11:split_inl_hpp:verbatim]
29
30namespace detail {
31
32CLI11_INLINE bool split_short(const std::string &current, 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);
36 return true;
37 }
38 return false;
39}
40
41CLI11_INLINE bool split_long(const std::string &current, 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);
47 } else {
48 name = current.substr(2);
49 value = "";
50 }
51 return true;
52 }
53 return false;
54}
55
56CLI11_INLINE bool split_windows_style(const std::string &current, 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);
62 } else {
63 name = current.substr(1);
64 value = "";
65 }
66 return true;
67 }
68 return false;
69}
70
71CLI11_INLINE std::vector<std::string> split_names(std::string current) {
72 std::vector<std::string> output;
73 std::size_t val = 0;
74 while((val = current.find(',')) != std::string::npos) {
75 output.push_back(trim_copy(current.substr(0, val)));
76 current = current.substr(val + 1);
77 }
78 output.push_back(trim_copy(current));
79 return output;
80}
81
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(),
85 flags.end(),
86 [](const std::string &name) {
87 return ((name.empty()) || (!(((name.find_first_of('{') != std::string::npos) &&
88 (name.back() == '}')) ||
89 (name[0] == '!'))));
90 }),
91 flags.end());
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);
99 defval.pop_back();
100 flag.erase(def_start, std::string::npos); // NOLINT(readability-suspicious-call-argument)
101 }
102 flag.erase(0, flag.find_first_not_of("-!"));
103 output.emplace_back(flag, defval);
104 }
105 return output;
106}
107
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) {
110
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) {
115 if(name.empty()) {
116 continue;
117 }
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);
126 } else {
127 throw BadNameString::BadLongName(name);
128 }
129 } else {
130 throw BadNameString::MissingDash(name);
131 }
132 } else {
133 throw BadNameString::OneCharName(name);
134 }
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);
139 } else {
140 throw BadNameString::BadLongName(name);
141 }
142 } else if(name == "-" || name == "--" || name == "++") {
143 throw BadNameString::ReservedName(name);
144 } else {
145 if(!pos_name.empty()) {
146 throw BadNameString::MultiPositionalNames(name);
147 }
148 if(valid_name_string(name)) {
149 pos_name = name;
150 } else {
151 throw BadNameString::BadPositionalName(name);
152 }
153 }
154 }
155 return std::make_tuple(short_names, long_names, pos_name);
156}
157
158} // namespace detail
159// [CLI11:split_inl_hpp:end]
160} // namespace CLI