CLI11 2.2.0
Loading...
Searching...
No Matches
Split.hpp
Go to the documentation of this file.
1// Copyright (c) 2017-2022, 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// [CLI11:public_includes:set]
10#include <string>
11#include <tuple>
12#include <utility>
13#include <vector>
14// [CLI11:public_includes:end]
15
16#include "Error.hpp"
17#include "StringTools.hpp"
18
19namespace CLI {
20// [CLI11:split_hpp:verbatim]
21
22namespace detail {
23
24// Returns false if not a short option. Otherwise, sets opt name and rest and returns true
25inline bool split_short(const std::string &current, std::string &name, std::string &rest) {
26 if(current.size() > 1 && current[0] == '-' && valid_first_char(current[1])) {
27 name = current.substr(1, 1);
28 rest = current.substr(2);
29 return true;
30 }
31 return false;
32}
33
34// Returns false if not a long option. Otherwise, sets opt name and other side of = and returns true
35inline bool split_long(const std::string &current, std::string &name, std::string &value) {
36 if(current.size() > 2 && current.substr(0, 2) == "--" && valid_first_char(current[2])) {
37 auto loc = current.find_first_of('=');
38 if(loc != std::string::npos) {
39 name = current.substr(2, loc - 2);
40 value = current.substr(loc + 1);
41 } else {
42 name = current.substr(2);
43 value = "";
44 }
45 return true;
46 }
47 return false;
48}
49
50// Returns false if not a windows style option. Otherwise, sets opt name and value and returns true
51inline bool split_windows_style(const std::string &current, std::string &name, std::string &value) {
52 if(current.size() > 1 && current[0] == '/' && valid_first_char(current[1])) {
53 auto loc = current.find_first_of(':');
54 if(loc != std::string::npos) {
55 name = current.substr(1, loc - 1);
56 value = current.substr(loc + 1);
57 } else {
58 name = current.substr(1);
59 value = "";
60 }
61 return true;
62 }
63 return false;
64}
65
66// Splits a string into multiple long and short names
67inline std::vector<std::string> split_names(std::string current) {
68 std::vector<std::string> output;
69 std::size_t val;
70 while((val = current.find(",")) != std::string::npos) {
71 output.push_back(trim_copy(current.substr(0, val)));
72 current = current.substr(val + 1);
73 }
74 output.push_back(trim_copy(current));
75 return output;
76}
77
79inline 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);
98 }
99 flag.erase(0, flag.find_first_not_of("-!"));
100 output.emplace_back(flag, defval);
101 }
102 return output;
103}
104
106inline std::tuple<std::vector<std::string>, std::vector<std::string>, std::string>
107get_names(const std::vector<std::string> &input) {
108
109 std::vector<std::string> short_names;
110 std::vector<std::string> long_names;
111 std::string pos_name;
112
113 for(std::string name : input) {
114 if(name.length() == 0) {
115 continue;
116 }
117 if(name.length() > 1 && name[0] == '-' && name[1] != '-') {
118 if(name.length() == 2 && valid_first_char(name[1]))
119 short_names.emplace_back(1, name[1]);
120 else
121 throw BadNameString::OneCharName(name);
122 } else if(name.length() > 2 && name.substr(0, 2) == "--") {
123 name = name.substr(2);
124 if(valid_name_string(name))
125 long_names.push_back(name);
126 else
127 throw BadNameString::BadLongName(name);
128 } else if(name == "-" || name == "--") {
129 throw BadNameString::DashesOnly(name);
130 } else {
131 if(pos_name.length() > 0)
132 throw BadNameString::MultiPositionalNames(name);
133 pos_name = name;
134 }
135 }
136
137 return std::tuple<std::vector<std::string>, std::vector<std::string>, std::string>(
138 short_names, long_names, pos_name);
139}
140
141} // namespace detail
142// [CLI11:split_hpp:end]
143} // namespace CLI
std::vector< std::string > split_names(std::string current)
Definition Split.hpp:67
bool split_long(const std::string &current, std::string &name, std::string &value)
Definition Split.hpp:35
bool split_short(const std::string &current, std::string &name, std::string &rest)
Definition Split.hpp:25
std::vector< std::string > output
Definition StringTools.hpp:354
std::tuple< std::vector< std::string >, std::vector< std::string >, std::string > get_names(const std::vector< std::string > &input)
Get a vector of short names, one of long names, and a single name.
Definition Split.hpp:107
bool valid_first_char(T c)
Definition StringTools.hpp:219
bool valid_name_string(const std::string &str)
Verify an option/subcommand name.
Definition StringTools.hpp:230
std::string trim_copy(const std::string &str)
Make a copy of the string and then trim it.
Definition StringTools.hpp:144
bool split_windows_style(const std::string &current, std::string &name, std::string &value)
Definition Split.hpp:51
std::vector< std::pair< std::string, std::string > > get_default_flag_values(const std::string &str)
extract default flag values either {def} or starting with a !
Definition Split.hpp:79
Definition App.hpp:34