Commit d2f15f8d authored by Tristan Matthews's avatar Tristan Matthews
Browse files

* #7131: remove prefix from pattern

parent 2f15047c
......@@ -34,36 +34,35 @@
namespace sfl {
Pattern::Pattern(const std::string& pattern, const std::string& options) :
_pattern(pattern),
_re(NULL),
_ovector(NULL),
_ovectorSize(0),
_count(0),
_options(0)
pattern_(pattern),
re_(NULL),
ovector_(NULL),
ovectorSize_(0),
count_(0),
options_(0)
{
// Set offsets
_offset[0] = _offset[1] = 0;
offset_[0] = offset_[1] = 0;
// Set options.
_optionsDescription = options;
optionsDescription_ = options;
for (unsigned int i = 0; i < options.length(); i++) {
switch (options.at(i)) {
case 'i':
_options |= PCRE_CASELESS;
options_ |= PCRE_CASELESS;
break;
case 'm':
_options |= PCRE_MULTILINE;
options_ |= PCRE_MULTILINE;
break;
case 's':
_options |= PCRE_DOTALL;
options_ |= PCRE_DOTALL;
break;
case 'x':
_options |= PCRE_EXTENDED;
options_ |= PCRE_EXTENDED;
break;
}
}
......@@ -74,22 +73,21 @@ Pattern::Pattern(const std::string& pattern, const std::string& options) :
Pattern::~Pattern()
{
if (_re != NULL) {
pcre_free(_re);
}
if (re_ != NULL)
pcre_free(re_);
delete[] _ovector;
delete[] ovector_;
}
void Pattern::compile(void)
void Pattern::compile()
{
// Compile the pattern
int offset;
const char * error;
_re = pcre_compile(_pattern.c_str(), 0, &error, &offset, NULL);
re_ = pcre_compile(pattern_.c_str(), 0, &error, &offset, NULL);
if (_re == NULL) {
if (re_ == NULL) {
std::string offsetStr;
std::stringstream ss;
ss << offset;
......@@ -104,29 +102,29 @@ void Pattern::compile(void)
// of memory for the output vector.
int captureCount;
pcre_fullinfo(_re, NULL, PCRE_INFO_CAPTURECOUNT, &captureCount);
pcre_fullinfo(re_, NULL, PCRE_INFO_CAPTURECOUNT, &captureCount);
delete[] _ovector;
delete[] ovector_;
_ovector = new int[(captureCount + 1) *3];
ovector_ = new int[(captureCount + 1) * 3];
_ovectorSize = (captureCount + 1) * 3;
ovectorSize_ = (captureCount + 1) * 3;
}
unsigned int Pattern::getCaptureGroupCount(void)
unsigned int Pattern::getCaptureGroupCount()
{
int captureCount;
pcre_fullinfo(_re, NULL, PCRE_INFO_CAPTURECOUNT, &captureCount);
pcre_fullinfo(re_, NULL, PCRE_INFO_CAPTURECOUNT, &captureCount);
return captureCount;
}
std::vector<std::string> Pattern::groups(void)
std::vector<std::string> Pattern::groups()
{
const char ** stringList;
pcre_get_substring_list(_subject.c_str(),
_ovector,
_count,
pcre_get_substring_list(subject_.c_str(),
ovector_,
count_,
&stringList);
std::vector<std::string> matchedSubstrings;
......@@ -143,16 +141,11 @@ std::string Pattern::group(int groupNumber)
{
const char * stringPtr;
int rc = pcre_get_substring(
_subject.substr(_offset[0]).c_str(),
_ovector,
_count,
groupNumber,
&stringPtr);
int rc = pcre_get_substring(subject_.substr(offset_[0]).c_str(), ovector_,
count_, groupNumber, &stringPtr);
if (rc < 0) {
switch (rc) {
case PCRE_ERROR_NOSUBSTRING:
throw std::out_of_range("Invalid group reference.");
......@@ -174,20 +167,13 @@ std::string Pattern::group(int groupNumber)
std::string Pattern::group(const std::string& groupName)
{
const char * stringPtr = NULL;
int rc = pcre_get_named_substring(
_re,
_subject.substr(_offset[0]).c_str(),
_ovector,
_count,
groupName.c_str(),
&stringPtr);
int rc = pcre_get_named_substring(re_, subject_.substr(offset_[0]).c_str(),
ovector_, count_, groupName.c_str(),
&stringPtr);
if (rc < 0) {
switch (rc) {
case PCRE_ERROR_NOSUBSTRING:
break;
case PCRE_ERROR_NOMEMORY:
......@@ -201,106 +187,89 @@ std::string Pattern::group(const std::string& groupName)
std::string matchedStr;
if (stringPtr) {
matchedStr = stringPtr;
pcre_free_substring(stringPtr);
} else {
matchedStr = "";
}
return matchedStr;
}
void Pattern::start(const std::string& groupName) const
{
int index = pcre_get_stringnumber(_re, groupName.c_str());
int index = pcre_get_stringnumber(re_, groupName.c_str());
start(index);
}
size_t Pattern::start(unsigned int groupNumber) const
{
if (groupNumber <= (unsigned int) _count) {
return _ovector[(groupNumber + 1) * 2];
} else {
if (groupNumber <= (unsigned int) count_)
return ovector_[(groupNumber + 1) * 2];
else
throw std::out_of_range("Invalid group reference.");
}
}
size_t Pattern::start(void) const
size_t Pattern::start() const
{
return _ovector[0] + _offset[0];
return ovector_[0] + offset_[0];
}
void Pattern::end(const std::string& groupName) const
{
int index = pcre_get_stringnumber(_re, groupName.c_str());
int index = pcre_get_stringnumber(re_, groupName.c_str());
end(index);
}
size_t Pattern::end(unsigned int groupNumber) const
{
if (groupNumber <= (unsigned int) _count) {
return _ovector[((groupNumber + 1) * 2) + 1 ] - 1;
} else {
if (groupNumber <= (unsigned int) count_)
return ovector_[((groupNumber + 1) * 2) + 1 ] - 1;
else
throw std::out_of_range("Invalid group reference.");
}
}
size_t Pattern::end(void) const
size_t Pattern::end() const
{
return (_ovector[1] - 1) + _offset[0];
return (ovector_[1] - 1) + offset_[0];
}
bool Pattern::matches(void) throw(match_error)
bool Pattern::matches()
{
return matches(_subject);
return matches(subject_);
}
bool Pattern::matches(const std::string& subject) throw(match_error)
bool Pattern::matches(const std::string& subject)
{
// Try to find a match for this pattern
int rc = pcre_exec(
_re,
NULL,
subject.substr(_offset[1]).c_str(),
subject.length() - _offset[1],
0,
_options,
_ovector,
_ovectorSize);
int rc = pcre_exec(re_, NULL, subject.substr(offset_[1]).c_str(),
subject.length() - offset_[1], 0, options_, ovector_,
ovectorSize_);
// Matching failed.
if (rc < 0) {
_offset[0] = _offset[1] = 0;
offset_[0] = offset_[1] = 0;
return false;
}
// Handle the case if matching should be done globally
if (_optionsDescription.find("g") != std::string::npos) {
_offset[0] = _offset[1];
if (optionsDescription_.find("g") != std::string::npos) {
offset_[0] = offset_[1];
// New offset is old offset + end of relative offset
_offset[1] = _ovector[1] + _offset[0];
offset_[1] = ovector_[1] + offset_[0];
}
// Matching succeded but not enough space.
if (rc == 0) {
// @TODO figure out something more clever to do in this case.
if (rc == 0)
throw match_error("No space to store all substrings.");
// @TODO figure out something more clever to do in that case.
}
// Matching succeeded. Keep the number of substrings for
// subsequent calls to group().
_count = rc;
count_ = rc;
return true;
}
std::vector<std::string> Pattern::split(void)
std::vector<std::string> Pattern::split()
{
size_t tokenEnd = -1;
size_t tokenStart = 0;
......@@ -309,15 +278,13 @@ std::vector<std::string> Pattern::split(void)
while (matches()) {
tokenStart = start();
substringSplitted.push_back(_subject.substr(tokenEnd + 1,
substringSplitted.push_back(subject_.substr(tokenEnd + 1,
tokenStart - tokenEnd - 1));
tokenEnd = end();
}
substringSplitted.push_back(_subject.substr(tokenEnd + 1, tokenStart - tokenEnd - 1));
substringSplitted.push_back(subject_.substr(tokenEnd + 1,
tokenStart - tokenEnd - 1));
return substringSplitted;
}
}
......@@ -95,12 +95,12 @@ class Pattern {
* @param pattern The new pattern
*/
void operator= (const std::string& pattern) {
_pattern = pattern;
pattern_ = pattern;
compile();
}
void operator= (const char * pattern) {
_pattern = pattern;
pattern_ = pattern;
compile();
}
......@@ -109,7 +109,7 @@ class Pattern {
* from the pattern that was set for
* this object.
*/
void compile(void);
void compile();
/**
* Get the currently set regular expression
......@@ -117,8 +117,8 @@ class Pattern {
*
* @return The currently set pattern
*/
std::string getPattern(void) const {
return _pattern;
std::string getPattern() const {
return pattern_;
}
/**
......@@ -131,7 +131,7 @@ class Pattern {
*
*/
void operator<< (const std::string& subject) {
_subject = subject;
subject_ = subject;
}
/**
......@@ -139,7 +139,7 @@ class Pattern {
*
* @return the start position of the overall match.
*/
size_t start(void) const;
size_t start() const;
/**
* Get the start position of the specified match.
......@@ -162,7 +162,7 @@ class Pattern {
*
* @return the end position of the overall match.
*/
size_t end(void) const;
size_t end() const;
/**
* Get the end position of the specified match.
......@@ -191,7 +191,7 @@ class Pattern {
* @pre The regular expression should have been
* compiled prior to the execution of this method.
*/
unsigned int getCaptureGroupCount(void);
unsigned int getCaptureGroupCount();
/**
* Get the substring matched in a capturing
......@@ -241,7 +241,7 @@ class Pattern {
* @pre The regular expression should have been
* compiled prior to the execution of this method.
*/
std::vector<std::string> groups(void);
std::vector<std::string> groups();
/**
* Try to match the compiled pattern with a
......@@ -260,7 +260,7 @@ class Pattern {
* with the new matches. Therefore, subsequent
* calls to group may return different results.
*/
bool matches(const std::string& subject) throw(match_error);
bool matches(const std::string& subject);
/**
* Try to match the compiled pattern with the implicit
......@@ -276,7 +276,7 @@ class Pattern {
* with the new matches. Therefore, subsequent
* calls to group may return different results.
*/
bool matches(void) throw(match_error);
bool matches();
/**
* Split the subject into a list of substrings.
......@@ -290,59 +290,41 @@ class Pattern {
* by this operation. In other words: subject_before =
* subject_after.
*/
std::vector<std::string> split(void); // throw(match_error);
std::vector<std::string> split();
private:
/**
* The regular expression that represents that pattern.
*/
std::string _pattern;
// The regular expression that represents that pattern.
std::string pattern_;
/**
* The optional subject string.
*/
std::string _subject;
// The optional subject string.
std::string subject_;
/**
* PCRE struct that
* contains the compiled regular
* expression
*/
pcre * _re;
pcre * re_;
/**
* The internal output vector used by PCRE.
*/
int * _ovector;
// The internal output vector used by PCRE.
int * ovector_;
/**
* The size of the _ovector
*/
int _ovectorSize;
// The size of the ovector_
int ovectorSize_;
/**
* Current offset in the _ovector;
*/
int _offset[2];
// Current offset in the ovector_;
int offset_[2];
/**
* The number of substrings matched after calling
* pcre_exec.
*/
int _count;
// The number of substrings matched after calling pcre_exec.
int count_;
/**
* PCRE options for this pattern.
*/
int _options;
// PCRE options for this pattern.
int options_;
/**
* String representation of the options.
*/
std::string _optionsDescription;
// String representation of the options.
std::string optionsDescription_;
};
}
#endif // __PATTERN_H__
#endif // __PATTERN_H__ // __PATTERN_H__ // __PATTERN_H__ // __PATTERN_H__
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment