Skip to content
Snippets Groups Projects
Commit d2f15f8d authored by Tristan Matthews's avatar Tristan Matthews
Browse files

* #7131: remove prefix from pattern

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