Skip to content

Commit a7ff906

Browse files
committed
Regex: use iterators for match results
* Use `smatch` to match std::string instead of char pointer * Use iterators to walk the results instead of integer indices * Store position as ptrdiff_t to always have the correct size This prevents signed/unsigned and narrowing (64-bit to 32-bit) conversion warnings on MSVC.
1 parent 4dec371 commit a7ff906

File tree

5 files changed

+23
-21
lines changed

5 files changed

+23
-21
lines changed

include/cucumber-cpp/internal/CukeEngine.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef CUKE_CUKEENGINE_HPP_
22
#define CUKE_CUKEENGINE_HPP_
33

4+
#include <cstddef>
45
#include <string>
56
#include <vector>
67

@@ -12,7 +13,7 @@ namespace internal {
1213
class StepMatchArg {
1314
public:
1415
std::string value;
15-
int position;
16+
std::ptrdiff_t position;
1617
};
1718

1819
class StepMatch {

include/cucumber-cpp/internal/utils/Regex.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef CUKE_REGEX_HPP_
22
#define CUKE_REGEX_HPP_
33

4+
#include <cstddef>
45
#include <vector>
56

67
#include <boost/shared_ptr.hpp>
@@ -11,7 +12,7 @@ namespace internal {
1112

1213
struct RegexSubmatch {
1314
std::string value;
14-
int position;
15+
std::ptrdiff_t position;
1516
};
1617

1718

src/Regex.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,18 @@ boost::shared_ptr<RegexMatch> Regex::find(const std::string &expression) const {
2525
}
2626

2727
FindRegexMatch::FindRegexMatch(const boost::regex &regexImpl, const std::string &expression) {
28-
boost::cmatch matchResults;
29-
regexMatched = boost::regex_search(expression.c_str(), matchResults, regexImpl, boost::regex_constants::match_extra);
28+
boost::smatch matchResults;
29+
regexMatched = boost::regex_search(
30+
expression, matchResults, regexImpl, boost::regex_constants::match_extra);
3031
if (regexMatched) {
31-
for (boost::cmatch::size_type i = 1; i < matchResults.size(); ++i) {
32-
RegexSubmatch s;
33-
s.value = matchResults.str(i);
34-
s.position = matchResults.position(i);
35-
submatches.push_back(s);
32+
boost::smatch::const_iterator i = matchResults.begin();
33+
if (i != matchResults.end())
34+
++i;
35+
for (; i != matchResults.end(); ++i) {
36+
if (i->matched) {
37+
RegexSubmatch s = {*i, i->first - expression.begin()};
38+
submatches.push_back(s);
39+
}
3640
}
3741
}
3842
}
@@ -42,17 +46,13 @@ boost::shared_ptr<RegexMatch> Regex::findAll(const std::string &expression) cons
4246
}
4347

4448
FindAllRegexMatch::FindAllRegexMatch(const boost::regex &regexImpl, const std::string &expression) {
45-
regexMatched = false;
4649
boost::sregex_token_iterator i(expression.begin(), expression.end(), regexImpl, 1, boost::regex_constants::match_continuous);
47-
boost::sregex_token_iterator j;
48-
while (i != j) {
49-
regexMatched = true;
50-
RegexSubmatch s;
51-
s.value = *i;
52-
s.position = -1;
50+
const boost::sregex_token_iterator end;
51+
for (; i != end; ++i) {
52+
RegexSubmatch s = {*i, -1};
5353
submatches.push_back(s);
54-
++i;
5554
}
55+
regexMatched = !submatches.empty();
5656
}
5757

5858
}

src/connectors/wire/WireProtocol.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ namespace {
268268
BOOST_FOREACH(StepMatchArg ma, m.args) {
269269
mObject jsonMa;
270270
jsonMa["val"] = ma.value;
271-
jsonMa["pos"] = ma.position;
271+
jsonMa["pos"] = static_cast<boost::int64_t>(ma.position);
272272
jsonArgs.push_back(jsonMa);
273273
}
274274
jsonM["args"] = jsonArgs;

tests/unit/StepManagerTest.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class StepManagerTest : public ::testing::Test {
1919
const static char *another_matcher;
2020
const static char *no_match;
2121
const static char *a_third_matcher;
22-
const map<int, string> no_params;
22+
const map<std::ptrdiff_t, string> no_params;
2323

2424
int getUniqueMatchIdOrZeroFor(const string &stepMatch) {
2525
MatchResult::match_results_type resultSet = getResultSetFor(stepMatch);
@@ -30,7 +30,7 @@ class StepManagerTest : public ::testing::Test {
3030
}
3131
}
3232

33-
int countMatches(const string &stepMatch) {
33+
size_t countMatches(const string &stepMatch) {
3434
return getResultSetFor(stepMatch).size();
3535
}
3636

@@ -42,7 +42,7 @@ class StepManagerTest : public ::testing::Test {
4242
return (countMatches(stepMatch) > 0);
4343
}
4444

45-
bool extractedParamsAre(const string stepMatch, map<int, string> params) {
45+
bool extractedParamsAre(const string stepMatch, map<std::ptrdiff_t, string> params) {
4646
MatchResult::match_results_type resultSet = getResultSetFor(stepMatch);
4747
if (resultSet.size() != 1) {
4848
return false; // more than one match

0 commit comments

Comments
 (0)