summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatti Lehtimäki <matti.lehtimaki@gmail.com>2013-09-28 17:03:17 +0200
committerMatti Lehtimäki <matti.lehtimaki@gmail.com>2013-09-28 17:03:17 +0200
commit6e954ad800a4696b3818df08bf132a9535a5f03b (patch)
tree98927aff5a4fc843bfd95b0e74eb787ad139cf89
parent1bb571ae4d12b42863a8f85969439fa1dd2655ec (diff)
downloadvdr-plugin-epgfixer-6e954ad800a4696b3818df08bf132a9535a5f03b.tar.gz
vdr-plugin-epgfixer-6e954ad800a4696b3818df08bf132a9535a5f03b.tar.bz2
Support conditional regular expressions.
These are used only if the content of another EPG field matches to an additional regular expression.
-rw-r--r--HISTORY2
-rw-r--r--regexp.c78
-rw-r--r--regexp.h5
3 files changed, 84 insertions, 1 deletions
diff --git a/HISTORY b/HISTORY
index 48639a0..211d465 100644
--- a/HISTORY
+++ b/HISTORY
@@ -3,6 +3,8 @@ VDR Plugin 'epgfixer' Revision History
2013-xx-xx: Version x.x.x
+- Support regular expressions which are used only if the content of another EPG
+ field matches to an additional regular expression.
- Fix possible null pointer error.
- Fix header includes.
- Makefile fixes. Install example config files automatically.
diff --git a/regexp.c b/regexp.c
index c4c1243..7f9ad87 100644
--- a/regexp.c
+++ b/regexp.c
@@ -28,18 +28,24 @@ const char *strBackrefs[] = { "atitle", "ptitle", "title", "ashorttext", "pshort
cRegexp::cRegexp()
{
+ cmodifiers = 0;
modifiers = 0;
+ cregexp = NULL;
regexp = NULL;
replace = NONE;
replacement = NULL;
+ csource = REGEXP_UNDEFINED;
source = REGEXP_UNDEFINED;
+ cre = NULL;
re = NULL;
+ csd = NULL;
sd = NULL;
}
cRegexp::~cRegexp(void)
{
Free();
+ free(cregexp);
free(regexp);
free(replacement);
FreeCompiled();
@@ -57,8 +63,23 @@ void cRegexp::Compile()
}
else {
sd = pcre_study(re, PCRE_STUDY_JIT_COMPILE, (const char **)&error);
- if (error)
+ if (error) {
error("PCRE study error: %s", error);
+ }
+ else {
+ if (cregexp) {
+ cre = pcre_compile(cregexp, cmodifiers, &error, &erroffset, NULL);
+ if (error) {
+ error("PCRE compile error: %s at offset %i", error, erroffset);
+ enabled = false;
+ }
+ else {
+ csd = pcre_study(cre, PCRE_STUDY_JIT_COMPILE, (const char **)&error);
+ if (error)
+ error("PCRE study error: %s", error);
+ }
+ }
+ }
}
}
@@ -68,6 +89,10 @@ void cRegexp::FreeCompiled()
pcre_free(re);
re = NULL;
}
+ if (cre) {
+ pcre_free(cre);
+ cre = NULL;
+ }
if (sd) {
#ifdef PCRE_CONFIG_JIT
pcre_free_study(sd);
@@ -76,6 +101,14 @@ void cRegexp::FreeCompiled()
#endif
sd = NULL;
}
+ if (csd) {
+#ifdef PCRE_CONFIG_JIT
+ pcre_free_study(csd);
+#else
+ pcre_free(csd);
+#endif
+ csd = NULL;
+ }
}
int cRegexp::ParseModifiers(char *modstring, int substitution)
@@ -154,12 +187,15 @@ void cRegexp::ParseRegexp(char *restring)
void cRegexp::SetFromString(char *s, bool Enabled)
{
+ cmodifiers = 0;
modifiers = 0;
+ FREE(cregexp);
FREE(regexp);
replace = NONE;
FREE(replacement);
Free();
FreeCompiled();
+ csource = REGEXP_UNDEFINED;
source = REGEXP_UNDEFINED;
cListItem::SetFromString(s, Enabled);
if (enabled) {
@@ -176,6 +212,28 @@ void cRegexp::SetFromString(char *s, bool Enabled)
field = f + 1;
numchannels = LoadChannelsFromString(chanfield);
}
+ // parse field conditional
+ char *cond = strchr(field, '?');
+ if (cond) {
+ *cond = 0;
+ cond += 1;
+ char *m = strrchr(cond, '/');
+ if (m) {
+ *m = 0;
+ cmodifiers = ParseModifiers(m + 1);
+ }
+ char *cs = strchr(cond, '~');
+ if (cs) {
+ *cs = 0;
+ cregexp = strdup(cs + 3);
+ }
+ if (strcmp(cond, "title") == 0)
+ csource = REGEXP_TITLE;
+ if (strcmp(cond, "shorttext") == 0)
+ csource = REGEXP_SHORTTEXT;
+ if (strcmp(cond, "description") == 0)
+ csource = REGEXP_DESCRIPTION;
+ }
if (strcmp(field, "title") == 0)
source = REGEXP_TITLE;
if (strcmp(field, "shorttext") == 0)
@@ -210,6 +268,24 @@ bool cRegexp::Apply(cEvent *Event)
int tmpstringlen = strlen(*tmpstring);
int ovector[OVECCOUNT];
int rc = 0;
+ cString ctmpstring;
+ switch (csource) {
+ case REGEXP_TITLE:
+ ctmpstring = Event->Title();
+ break;
+ case REGEXP_SHORTTEXT:
+ ctmpstring = Event->ShortText();
+ break;
+ case REGEXP_DESCRIPTION:
+ ctmpstring = Event->Description();
+ break;
+ default:
+ ctmpstring = "";
+ break;
+ }
+ if (cre && ((rc = pcre_exec(cre, csd, *ctmpstring, strlen(*ctmpstring), 0, 0, ovector, OVECCOUNT)) != 1))
+ return false;
+
if (replace != NONE) {// find and replace
int last_match_end = -1;
int options = 0;
diff --git a/regexp.h b/regexp.h
index 25efae9..18fc08d 100644
--- a/regexp.h
+++ b/regexp.h
@@ -21,12 +21,17 @@ typedef enum { REGEXP_TITLE, REGEXP_SHORTTEXT, REGEXP_DESCRIPTION, REGEXP_UNDEFI
class cRegexp : public cListItem
{
private:
+ char *cregexp;
char *regexp;
char *replacement;
int replace;
+ int cmodifiers;
int modifiers;
+ int csource;
int source;
+ pcre *cre;
pcre *re;
+ pcre_extra *csd;
pcre_extra *sd;
void Compile();
void FreeCompiled();