Skip to content

Commit 6609357

Browse files
author
thk123
committed
Allowed split_string to be used on whitespace if not also trying to strip
Also improved comments (and moved to doxygen) as I assumed strip would remove whitespace from throughout the string but actually only does the final string Replace asserts in string utils Adding tests for behaviour with whitespace delimiter
1 parent 145f474 commit 6609357

File tree

3 files changed

+111
-7
lines changed

3 files changed

+111
-7
lines changed

src/util/string_utils.cpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,16 @@ Author: Daniel Poetzl
77
\*******************************************************************/
88

99
#include "string_utils.h"
10+
#include "invariant.h"
1011

1112
#include <cassert>
1213
#include <cctype>
1314
#include <algorithm>
1415

16+
/// Remove all whitespace characters from either end of a string. Whitespace
17+
/// in the middle of the string is left unchanged
18+
/// \param s: the string to strip
19+
/// \return The stripped string
1520
std::string strip_string(const std::string &s)
1621
{
1722
auto pred=[](char c){ return std::isspace(c); };
@@ -30,15 +35,31 @@ std::string strip_string(const std::string &s)
3035
return s.substr(i, (j-i+1));
3136
}
3237

38+
/// Given a string s, split into a sequence of substrings when separated by
39+
/// specified delimiter.
40+
/// \param s: The string to split up
41+
/// \param delim: The character to use as the delimiter
42+
/// \param [out] result: The sub strings
43+
/// \param strip: If true, strip_string will be used on each element, removing
44+
/// whitespace from the beginning and end of each element
45+
/// \param remove_empty: If true, all empty-string elements will be removed.
46+
/// This is applied after strip so whitespace only elements will be removed if
47+
/// both are set to true
3348
void split_string(
3449
const std::string &s,
3550
char delim,
3651
std::vector<std::string> &result,
3752
bool strip,
3853
bool remove_empty)
3954
{
40-
assert(result.empty());
41-
assert(!std::isspace(delim));
55+
if(!result.empty())
56+
throw std::invalid_argument("result: vector must be empty");
57+
58+
if(strip && std::isspace(delim))
59+
{
60+
throw std::invalid_argument(
61+
"delim can't be a space character if using strip");
62+
}
4263

4364
if(s.empty())
4465
{
@@ -47,7 +68,7 @@ void split_string(
4768
}
4869

4970
std::string::size_type n=s.length();
50-
assert(n>0);
71+
INVARIANT(n > 0, "Empty string case should already be handled");
5172

5273
std::string::size_type start=0;
5374
std::string::size_type i;
@@ -87,7 +108,11 @@ void split_string(
87108
std::string &right,
88109
bool strip)
89110
{
90-
assert(!std::isspace(delim));
111+
if(strip && std::isspace(delim))
112+
{
113+
throw std::invalid_argument(
114+
"delim can't be a space character if using strip");
115+
}
91116

92117
std::vector<std::string> result;
93118

src/util/string_utils.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ std::string strip_string(const std::string &s);
1818

1919
void split_string(
2020
const std::string &s,
21-
char delim, // must not be a whitespace character
21+
char delim,
2222
std::vector<std::string> &result,
23-
bool strip=false, // strip whitespace from elements
24-
bool remove_empty=false); // remove empty elements
23+
bool strip = false,
24+
bool remove_empty = false);
2525

2626
void split_string(
2727
const std::string &s,

unit/util/string_utils/split_string.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,58 @@ SCENARIO("split_string", "[core][utils][string_utils][split_string]")
134134
run_on_all_variants(string, ',', expected_results);
135135
}
136136
}
137+
GIVEN("A whitespace delimter")
138+
{
139+
std::string string = "a\nb\nc";
140+
const char delimiter = '\n';
141+
142+
WHEN("Not stripping, not removing empty")
143+
{
144+
std::vector<std::string> result;
145+
split_string(string, delimiter, result, false, false);
146+
147+
THEN("Should get expected vector")
148+
{
149+
std::vector<std::string> expected_result = {"a", "b", "c"};
150+
REQUIRE_THAT(
151+
result,
152+
Catch::Matchers::Vector::EqualsMatcher<std::string>{expected_result});
153+
}
154+
}
155+
WHEN("Not stripping, removing empty")
156+
{
157+
std::vector<std::string> result;
158+
split_string(string, delimiter, result, false, true);
159+
160+
THEN("Should get expected vector")
161+
{
162+
std::vector<std::string> expected_result = {"a", "b", "c"};
163+
REQUIRE_THAT(
164+
result,
165+
Catch::Matchers::Vector::EqualsMatcher<std::string>{expected_result});
166+
}
167+
}
168+
WHEN("Stripping, not removing empty")
169+
{
170+
std::vector<std::string> result;
171+
THEN("Should throw an exception")
172+
{
173+
REQUIRE_THROWS_AS(
174+
split_string(string, delimiter, result, true, false),
175+
std::invalid_argument);
176+
}
177+
}
178+
WHEN("Stripping and removing empty")
179+
{
180+
std::vector<std::string> result;
181+
THEN("Should throw an exception")
182+
{
183+
REQUIRE_THROWS_AS(
184+
split_string(string, delimiter, result, true, true),
185+
std::invalid_argument);
186+
}
187+
}
188+
}
137189
}
138190

139191
SCENARIO("split_string into two", "[core][utils][string_utils][split_string]")
@@ -155,4 +207,31 @@ SCENARIO("split_string into two", "[core][utils][string_utils][split_string]")
155207
}
156208
}
157209
}
210+
GIVEN("A string and a whitespace delimiter")
211+
{
212+
std::string string = "a\nb";
213+
const char delimiter = '\n';
214+
215+
WHEN("Splitting in two and not stripping")
216+
{
217+
std::string s1;
218+
std::string s2;
219+
split_string(string, delimiter, s1, s2, false);
220+
THEN("The string should be split")
221+
{
222+
REQUIRE(s1 == "a");
223+
REQUIRE(s2 == "b");
224+
}
225+
}
226+
WHEN("Splitting in two and stripping")
227+
{
228+
THEN("An invalid argument exception should be raised")
229+
{
230+
std::string s1;
231+
std::string s2;
232+
REQUIRE_THROWS_AS(
233+
split_string(string, delimiter, s1, s2, true), std::invalid_argument);
234+
}
235+
}
236+
}
158237
}

0 commit comments

Comments
 (0)