Option++  2.0
C++ library for reading command-line options
utility.hpp
Go to the documentation of this file.
1 /* Option++ -- read command-line program options
2  * Copyright (C) 2017-2020 Greg Kikola.
3  *
4  * This file is part of Option++.
5  *
6  * Option++ is free software: you can redistribute it and/or modify
7  * it under the terms of the Boost Software License version 1.0.
8  *
9  * Option++ is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * Boost Software License for more details.
13  *
14  * You should have received a copy of the Boost Software License
15  * along with Option++. If not, see
16  * <https://www.boost.org/LICENSE_1_0.txt>.
17  */
18 /* Written by Greg Kikola <[email protected]>. */
19 
25 #ifndef OPTIONPP_UTILITY_HPP
26 #define OPTIONPP_UTILITY_HPP
27 
28 #include <stdexcept>
29 #include <string>
30 
31 namespace optionpp {
32 
36  namespace utility {
37 
60  template <typename OutputIt>
61  void split(const std::string& str, OutputIt dest,
62  const std::string& delims = " \t\n\r",
63  const std::string& quotes = "\"\'",
64  char escape_char = '\\',
65  bool allow_empty = false);
66 
85  std::string wrap_text(const std::string& str,
86  int line_len = 79,
87  int indent = 0);
88 
110  std::string wrap_text(const std::string& str,
111  int line_len,
112  int indent,
113  int first_line_indent);
114 
134  bool is_substr_at_pos(const std::string& str, const std::string& substr,
135  std::string::size_type pos = 0) noexcept;
136 
137  } // End namespace
138 
139 } // End namespace
140 
141 
142 /* Implementation */
143 
144 template <typename OutputIt>
145 void optionpp::utility::split(const std::string& str, OutputIt dest,
146  const std::string& delims,
147  const std::string& quotes,
148  char escape_char,
149  bool allow_empty) {
150  using size_type = decltype(str.size());
151  size_type pos{0};
152  bool escape_next{false};
153  bool in_quotes{false};
154  size_type quote_index{0};
155  std::string cur_token;
156  while (pos < str.size()) {
157  if (in_quotes) {
158  // Look for closing quote, unless we are escaping
159  if (escape_next || str[pos] != quotes[quote_index]) {
160  if (!escape_next && str[pos] == escape_char)
161  escape_next = true;
162  else {
163  cur_token.push_back(str[pos]);
164  escape_next = false;
165  }
166  } else { // Found closing quote
167  in_quotes = false;
168  }
169  } else {
170  // Look for delimiter
171  if (escape_next || delims.find(str[pos]) == std::string::npos) {
172  if (!escape_next && str[pos] == escape_char)
173  escape_next = true;
174  else if (escape_next) {
175  cur_token.push_back(str[pos]);
176  escape_next = false;
177  } else {
178  // Look for quote
179  quote_index = quotes.find(str[pos]);
180  if (quote_index != std::string::npos)
181  in_quotes = true;
182  else
183  cur_token.push_back(str[pos]);
184  }
185  } else { // We hit a delimiter
186  if (!cur_token.empty() || allow_empty)
187  *dest++ = cur_token;
188  cur_token.clear();
189  }
190  }
191 
192  ++pos;
193  }
194 
195  // Do we have any characters leftover?
196  if (!cur_token.empty() || allow_empty)
197  *dest++ = cur_token;
198 }
199 
200 #endif
optionpp::utility::split
void split(const std::string &str, OutputIt dest, const std::string &delims=" \t\n\r", const std::string &quotes="\"\'", char escape_char='\\', bool allow_empty=false)
Split a string over delimiters into substrings.
Definition: utility.hpp:145
optionpp::utility::wrap_text
std::string wrap_text(const std::string &str, int line_len=79, int indent=0)
Perform word-wrapping on a string.
Definition: utility.cpp:124
optionpp
Library namespace.
Definition: error.hpp:31
optionpp::utility::is_substr_at_pos
bool is_substr_at_pos(const std::string &str, const std::string &substr, std::string::size_type pos=0) noexcept
Determine if a string occurs within another string at a particular position.
Definition: utility.cpp:148