forked from akrennmair/newsbeuter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFilterParser.cpp
128 lines (112 loc) · 2.83 KB
/
FilterParser.cpp
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "logger.h"
#include "FilterParser.h"
#include "Parser.h"
#include <utils.h>
using namespace newsbeuter;
FilterParser::FilterParser() : root(0), curpos(0), next_must_descend_right(false) { }
FilterParser::~FilterParser() {
cleanup();
}
FilterParser::FilterParser(const FilterParser& p) {
LOG(LOG_DEBUG,"FilterParser: copy constructor called!");
parse_string(p.strexpr);
}
FilterParser& FilterParser::operator=(FilterParser& p) {
LOG(LOG_DEBUG,"FilterParser: operator= called!");
if (this != &p) {
cleanup();
parse_string(p.strexpr);
}
return *this;
}
void FilterParser::add_logop(int op) {
//fprintf(stderr,"add_logop: op = %d\n", op);
expression * expr = new expression(op);
if (!root) {
printf("error: there can't be a logical expression w/o a prior expression!");
// TODO: add proper error handling
} else {
if (curpos != root) {
expr->l = curpos;
curpos->parent->r = expr;
expr->parent = curpos->parent;
curpos = expr;
} else {
expr->l = root;
curpos = root = expr;
}
}
// printf("logop: %d\n", op);
}
void FilterParser::add_matchexpr(char * name, int op, char * lit) {
//fprintf(stderr,"add_matchexpr: name = %s op = %d lit = %s\n", name, op, lit);
expression * expr = new expression(name, lit, op);
if (next_must_descend_right) {
next_must_descend_right = false;
if (!curpos) {
curpos = root = expr;
} else {
expr->parent = curpos;
curpos->r = expr;
curpos = expr;
}
} else {
if (!curpos) {
curpos = root = expr;
} else {
expr->parent = curpos;
curpos->r = expr;
}
}
coco_string_delete(name);
coco_string_delete(lit);
// printf("matchexpr: %ls lit = %ls op = %d\n", name, lit, op);
}
void FilterParser::open_block() {
//fprintf(stderr,"open_block\n");
next_must_descend_right = true;
}
void FilterParser::close_block() {
//fprintf(stderr,"close_block\n");
if (curpos != root) {
curpos = curpos->parent;
}
}
bool FilterParser::parse_string(const std::string& str) {
cleanup();
strexpr = str;
Scanner s((const unsigned char *)str.c_str(), str.length());
Parser p(&s);
p.gen = this;
p.Parse();
if (0 == p.errors->count) {
return true;
}
errmsg = p.errors->errors[0];
cleanup();
return false;
}
void FilterParser::cleanup() {
cleanup_r(root);
root = curpos = NULL;
}
void FilterParser::cleanup_r(expression * e) {
if (e) {
LOG(LOG_DEBUG,"cleanup_r: e = %p", e);
cleanup_r(e->l);
cleanup_r(e->r);
delete e;
}
}
expression::expression(const std::string& n, const std::string& lit, int o) : name(n), literal(lit), op(o), l(NULL), r(NULL), parent(NULL), regex(NULL) {
if (literal[0] == '"' && literal[literal.length()-1] == '"') {
literal = literal.substr(1,literal.length()-2);
}
}
expression::expression(int o) : op(o), l(NULL), r(NULL), parent(NULL), regex(NULL) {
}
expression::~expression() {
if (regex)
regfree(regex);
delete regex;
}