#include "FilterParser.h" #include "logger.h" #include "Parser.h" #include "utils.h" using namespace newsboat; FilterParser::FilterParser() : root(0), curpos(0), next_must_descend_right(false) { } FilterParser::~FilterParser() { cleanup(); } FilterParser::FilterParser(const FilterParser& p) { LOG(Level::DEBUG,"FilterParser: copy constructor called!"); parse_string(p.strexpr); } FilterParser& FilterParser::operator=(FilterParser& p) { LOG(Level::DEBUG,"FilterParser: operator= called!"); if (this != &p) { cleanup(); parse_string(p.strexpr); } return *this; } void FilterParser::add_logop(int op) { expression * expr = new expression(op); if (!root) { printf("error: there can't be a logical expression w/o a prior expression!"); delete expr; // 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; } } } void FilterParser::add_matchexpr(char * name, int op, char * 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); } void FilterParser::open_block() { next_must_descend_right = true; } void FilterParser::close_block() { 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(Level::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; }