RegularExpression.cpp [plain text]
#include "macros.hpp"
#include "common.hpp"
#include <regex.h>
const int RegularExpression::NOMATCH = -1;
RegularExpression::~RegularExpression()
{
if (this->m_preg) {
regex_t * preg = (regex_t *)(this->m_preg);
regfree(preg);
delete preg;
}
if (this->m_errstr) {
std::free(this->m_errstr);
}
}
int RegularExpression::compile(const char * pattern)
{
regex_t * preg = (regex_t *)(this->m_preg);
int err;
if (preg) {
regfree(preg);
delete preg;
this->m_preg = NULL;
}
preg = new regex_t;
if (preg == NULL) {
throw std::runtime_error("out of memory");
}
err = regcomp(preg, pattern, REG_EXTENDED | REG_NEWLINE);
if (err != 0) {
delete preg;
return err;
}
this->m_preg = preg;
ASSERT(this->m_preg != NULL);
return 0;
}
int
RegularExpression::match(const std::string& strval, unsigned count)
{
int err;
regex_t * preg = (regex_t *)(this->m_preg);
regmatch_t * matches = NULL;
if (count) {
matches = new regmatch_t[count];
if (matches == NULL) {
throw std::runtime_error("out of memory");
}
}
this->m_matchlist.clear();
err = regexec(preg, strval.c_str(), count, matches, 0 );
switch(err) {
case 0:
for (unsigned i = 0; i < count; ++i) {
std::string::size_type len;
if (matches[i].rm_so == -1 || matches[i].rm_eo == -1) {
continue;
}
DEBUGMSG("matched rm_eo=%d rm_so=%d\n",
(int)matches[i].rm_eo, (int)matches[i].rm_so);
len = matches[i].rm_eo - matches[i].rm_so;
this->m_matchlist.push_back(
std::string(strval.c_str() + matches[i].rm_so, len));
}
DEBUGMSG("made %zd matches\n", this->m_matchlist.size());
delete[] matches;
return err;
case REG_NOMATCH:
delete[] matches;
return RegularExpression::NOMATCH;
default:
delete[] matches;
return err;
}
}
const char * RegularExpression::errstring(int errcode)
{
size_t errsz;
if (this->m_errstr) {
delete[] this->m_errstr;
}
ASSERT(this->m_preg != NULL);
errsz = regerror(errcode, (const regex_t *)(this->m_preg), NULL, 0);
if (errsz <= 0) {
return "no error";
}
this->m_errstr = new char[errsz];
if (this->m_errstr == NULL) {
throw std::runtime_error("out of memory");
}
regerror(errcode, (const regex_t *)(this->m_preg), this->m_errstr, errsz);
return this->m_errstr;
}