2 * Copyright (C) 2005-2008 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
25 #include "StdString.h"
30 CRegExp::CRegExp(bool caseless
)
33 m_iOptions
= PCRE_DOTALL
;
35 m_iOptions
|= PCRE_CASELESS
;
41 CRegExp::CRegExp(const CRegExp
& re
)
44 m_iOptions
= re
.m_iOptions
;
48 const CRegExp
& CRegExp::operator=(const CRegExp
& re
)
52 m_pattern
= re
.m_pattern
;
55 if (pcre_fullinfo(re
.m_re
, NULL
, PCRE_INFO_SIZE
, &size
) >= 0)
57 if ((m_re
= (pcre
*)malloc(size
)))
59 memcpy(m_re
, re
.m_re
, size
);
60 memcpy(m_iOvector
, re
.m_iOvector
, OVECCOUNT
*sizeof(int));
61 m_iMatchCount
= re
.m_iMatchCount
;
62 m_bMatched
= re
.m_bMatched
;
63 m_subject
= re
.m_subject
;
64 m_iOptions
= re
.m_iOptions
;
76 CRegExp
* CRegExp::RegComp(const char *re
)
83 const char *errMsg
= NULL
;
88 m_re
= pcre_compile(re
, m_iOptions
, &errMsg
, &errOffset
, NULL
);
92 CLog::Log(LOGERROR
, "PCRE: %s. Compilation failed at offset %d in expression '%s'",
93 errMsg
, errOffset
, re
);
102 int CRegExp::RegFind(const char* str
, int startoffset
)
109 CLog::Log(LOGERROR
, "PCRE: Called before compilation");
115 CLog::Log(LOGERROR
, "PCRE: Called without a string to match");
120 int rc
= pcre_exec(m_re
, NULL
, str
, strlen(str
), startoffset
, 0, m_iOvector
, OVECCOUNT
);
126 case PCRE_ERROR_NOMATCH
:
129 case PCRE_ERROR_MATCHLIMIT
:
130 CLog::Log(LOGERROR
, "PCRE: Match limit reached");
134 CLog::Log(LOGERROR
, "PCRE: Unknown error: %d", rc
);
140 return m_iOvector
[0];
143 int CRegExp::GetCaptureTotal()
147 pcre_fullinfo(m_re
, NULL
, PCRE_INFO_CAPTURECOUNT
, &c
);
151 char* CRegExp::GetReplaceString( const char* sReplaceExp
)
153 char *src
= (char *)sReplaceExp
;
159 if( sReplaceExp
== NULL
|| !m_bMatched
)
163 // First compute the length of the string
165 while ((c
= *src
++) != '\0')
169 else if (c
== '\\' && isdigit(*src
))
176 // Ordinary character.
177 if (c
== '\\' && (*src
== '\\' || *src
== '&'))
181 else if (no
< m_iMatchCount
&& (m_iOvector
[no
*2]>=0))
183 // Get tagged expression
184 len
= m_iOvector
[no
*2+1] - m_iOvector
[no
*2];
190 buf
= (char *)malloc((replacelen
+ 1)*sizeof(char));
194 char* sReplaceStr
= buf
;
196 // Add null termination
197 buf
[replacelen
] = '\0';
199 // Now we can create the string
200 src
= (char *)sReplaceExp
;
201 while ((c
= *src
++) != '\0')
205 else if (c
== '\\' && isdigit(*src
))
212 // Ordinary character.
213 if (c
== '\\' && (*src
== '\\' || *src
== '&'))
217 else if (no
< m_iMatchCount
&& (m_iOvector
[no
*2]>=0))
219 // Get tagged expression
220 len
= m_iOvector
[no
*2+1] - m_iOvector
[no
*2];
221 strncpy(buf
, m_subject
.c_str()+m_iOvector
[no
*2], len
);
229 std::string
CRegExp::GetMatch(int iSub
/* = 0 */)
231 if (iSub
< 0 || iSub
> m_iMatchCount
)
234 int pos
= m_iOvector
[(iSub
*2)];
235 int len
= m_iOvector
[(iSub
*2)+1] - pos
;
236 return m_subject
.substr(pos
, len
);
239 bool CRegExp::GetNamedSubPattern(const char* strName
, std::string
& strMatch
)
242 int iSub
= pcre_get_stringnumber(m_re
, strName
);
245 strMatch
= GetMatch(iSub
);
249 void CRegExp::DumpOvector(int iLog
/* = LOGDEBUG */)
251 if (iLog
< LOGDEBUG
|| iLog
> LOGNONE
)
254 CStdString str
= "{";
255 int size
= GetSubCount(); // past the subpatterns is junk
256 for (int i
= 0; i
<= size
; i
++)
259 t
.Format("[%i,%i]", m_iOvector
[(i
*2)], m_iOvector
[(i
*2)+1]);
265 CLog::Log(iLog
, "regexp ovector=%s", str
.c_str());