aboutsummaryrefslogtreecommitdiff
path: root/src/regexp.cpp
blob: 4370667d404fd2d9a169191640865c754e3c5d61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include "regexp.h"
#include "build.h" // For BuildException
#include "bu/fstring.h"

RegExp::RegExp() :
	bCompiled( false ),
	aSubStr( NULL )
{
}

RegExp::RegExp( const char *sSrc ) :
	bCompiled( false ),
	aSubStr( NULL )
{
	compile( sSrc );
}

RegExp::~RegExp()
{
	if( bCompiled )
	{
		regfree( &re );
		delete[] aSubStr;
	}
}

void RegExp::compile( const char *sSrc )
{
	if( bCompiled )
	{
		regfree( &re );
		delete[] aSubStr;
		bCompiled = false;
	}

	int nErr = regcomp( &re, sSrc, REG_EXTENDED|REG_NEWLINE );
	if( nErr )
	{
		size_t length = regerror( nErr, &re, NULL, 0 );
		char *buffer = new char[length];
		(void) regerror( nErr, &re, buffer, length );
		Bu::FString s( buffer );
		delete[] buffer;
		throw BuildException( s.getStr() );
	}
	bCompiled = true;
	this->sSrc = sSrc;

	nSubStr = re.re_nsub+1;
	aSubStr = new regmatch_t[nSubStr];
}

int RegExp::getNumSubStrings()
{
	return nSubStr;
}

bool RegExp::execute( const char *sSrc )
{
	sTest = sSrc;
	if( regexec( &re, sSrc, nSubStr, aSubStr, 0 ) )
		return false;
	return true;
}

std::pair<int,int> RegExp::getSubStringRange( int nIndex )
{
	return std::pair<int,int>( aSubStr[nIndex].rm_so, aSubStr[nIndex].rm_eo );
}

std::string RegExp::getSubString( int nIndex )
{
	return std::string(
		sTest.getStr()+aSubStr[nIndex].rm_so,
		aSubStr[nIndex].rm_eo - aSubStr[nIndex].rm_so
		);
}