CLI11
C++11 Command Line Interface Parser
Loading...
Searching...
No Matches
Split_inl.hpp
1// Copyright (c) 2017-2024, 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 <string>
16#include <tuple>
17#include <utility>
18#include <vector>
19// [CLI11:public_includes:end]
20
21#include "../Error.hpp"
22#include "../StringTools.hpp"
23
24namespace CLI {
25// [CLI11:split_inl_hpp:verbatim]
26
27namespace detail {
28
29CLI11_INLINE bool split_short(const std::string &current, std::string &name, std::string &rest) {
30 if(current.size() > 1 && current[0] == '-' && valid_first_char(current[1])) {
31 name = current.substr(1, 1);
32 rest = current.substr(2);
33 return true;
34 }
35 return false;
36}
37
38CLI11_INLINE bool split_long(const std::string &current, std::string &name, std::string &value) {
39 if(current.size() > 2 && current.compare(0, 2, "--") == 0 && valid_first_char(current[2])) {
40 auto loc = current.find_first_of('=');
41 if(loc != std::string::npos) {
42 name = current.substr(2, loc - 2);
43 value = current.substr(loc + 1);
44 } else {
45 name = current.substr(2);
46 value = "";
47 }
48 return true;
49 }
50 return false;
51}
52
53CLI11_INLINE bool split_windows_style(const std::string &current, std::string &name, std::string &value) {
54 if(current.size() > 1 && current[0] == '/' && valid_first_char(current[1])) {
55 auto loc = current.find_first_of(':');
56 if(loc != std::string::npos) {
57 name = current.substr(1, loc - 1);
58 value = current.substr(loc + 1);
59 } else {
60 name = current.substr(1);
61 value = "";
62 }
63 return true;
64 }
65 return false;
66}
67
68CLI11_INLINE std::vector<std::string> split_names(std::string current) {
69 std::vector<std::string> output;
70 std::size_t val = 0;
71 while((val = current.find(',')) != std::string::npos) {
72 output.push_back(trim_copy(current.substr(0, val)));
73 current = current.substr(val + 1);
74 }
75 output.push_back(trim_copy(current));
76 return output;
77}
78
79CLI11_INLINE std::vector<std::pair<std::string, std::string>> get_default_flag_values(const std::string &str) {
80 std::vector<std::string> flags = split_names(str);
81 flags.erase(std::remove_if(flags.begin(),
82 flags.end(),
83 [](const std::string &name) {
84 return ((name.empty()) || (!(((name.find_first_of('{') != std::string::npos) &&
85 (name.back() == '}')) ||
86 (name[0] == '!'))));
87 }),
88 flags.end());
89 std::vector<std::pair<std::string, std::string>> output;
90 output.reserve(flags.size());
91 for(auto &flag : flags) {
92 auto def_start = flag.find_first_of('{');
93 std::string defval = "false";
94 if((def_start != std::string::npos) && (flag.back() == '}')) {
95 defval = flag.substr(def_start + 1);
96 defval.pop_back();
97 flag.erase(def_start, std::string::npos); // NOLINT(readability-suspicious-call-argument)
98 }
99 flag.erase(0, flag.find_first_not_of("-!"));
100 output.emplace_back(flag, defval);
101 }
102 return output;
103}
104
105CLI11_INLINE std::tuple<std::vector<std::string>, std::vector<std::string>, std::string>
106get_names(const std::vector<std::string> &input, bool allow_non_standard) {
107
108 std::vector<std::string> short_names;
109 std::vector<std::string> long_names;
110 std::string pos_name;
111 for(std::string name : input) {
112 if(name.length() == 0) {
113 continue;
114 }
115 if(name.length() > 1 && name[0] == '-' && name[1] != '-') {
116 if(name.length() == 2 && valid_first_char(name[1])) {
117 short_names.emplace_back(1, name[1]);
118 } else if(name.length() > 2) {
119 if(allow_non_standard) {
120 name = name.substr(1);
121 if(valid_name_string(name)) {
122 short_names.push_back(name);
123 } else {
124 throw BadNameString::BadLongName(name);
125 }
126 } else {
127 throw BadNameString::MissingDash(name);
128 }
129 } else {
130 throw BadNameString::OneCharName(name);
131 }
132 } else if(name.length() > 2 && name.substr(0, 2) == "--") {
133 name = name.substr(2);
134 if(valid_name_string(name)) {
135 long_names.push_back(name);
136 } else {
137 throw BadNameString::BadLongName(name);
138 }
139 } else if(name == "-" || name == "--" || name == "++") {
140 throw BadNameString::ReservedName(name);
141 } else {
142 if(!pos_name.empty()) {
143 throw BadNameString::MultiPositionalNames(name);
144 }
145 if(valid_name_string(name)) {
146 pos_name = name;
147 } else {
148 throw BadNameString::BadPositionalName(name);
149 }
150 }
151 }
152 return std::make_tuple(short_names, long_names, pos_name);
153}
154
155} // namespace detail
156// [CLI11:split_inl_hpp:end]
157} // namespace CLI