Source file: src/filter_eval.h
/* Copyright (C) 2011 Daniel Verite
This file is part of Manitou-Mail (see http://www.manitou-mail.org)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef INC_FILTER_EVAL_H
#define INC_FILTER_EVAL_H
#include <QStack>
#include <QString>
#include <QVariant>
#include <QMap>
#include <time.h>
#include "dbtypes.h"
#include "db.h"
#include "message.h"
#include "filter_rules.h"
class filter_eval_value {
public:
filter_eval_value();
typedef enum {
type_null,
type_func,
type_string,
type_number,
type_bool
} val_type_t;
val_type_t vtype;
QVariant val;
};
class filter_eval_context {
public:
filter_eval_context() : execute(true) {}
QString expr;
int evp; // current position in expression string
// int len; // expression length
int npar;
QStack<filter_eval_value> evstack;
QString errstr;
int mail_id;
QString header_cache;
QString body_cache;
QString identity_cache;
bool execute;
QMap<QString,filter_eval_value> expr_cache;
QStack<QString> call_stack;
const expr_list* filter_list; // other expressions in the filtering system
mail_msg message;
time_t start_time;
};
class filter_eval_result {
public:
int evp;
QString errstr;
bool result;
};
/*
class filter_eval_error {
public:
QString message;
int char_index;
};
*/
typedef filter_eval_value (*eval_binop_ptr)(const filter_eval_value,
const filter_eval_value,
filter_eval_context*);
typedef filter_eval_value (*eval_unop_ptr)(const filter_eval_value,
filter_eval_context*);
typedef filter_eval_value (*eval_func_ptr)(const filter_eval_value,
filter_eval_context*);
struct filter_eval_func {
const char* name;
eval_func_ptr func;
int nb_args;
filter_eval_value::val_type_t return_type;
};
typedef struct {
const char* name;
int prio;
eval_binop_ptr func;
} binary_op_t;
typedef struct {
const char* name;
int prio;
eval_unop_ptr func;
} unary_op_t;
class filter_evaluator {
public:
filter_eval_result evaluate(const filter_expr fe,
const expr_list& elist,
mail_id_t mail_id);
static bool inner_eval(int current_prio, filter_eval_context* ctxt);
static const int PRI_DOT=10;
static const int PRI_AND=24;
static const int PRI_OR=22;
static const int PRI_UNARY_NOT=30;
static const int PRI_CMP=40;
static const int PRI_CONTAINS=40;
static const int PRI_REGEXP=40;
static void skip_blanks(filter_eval_context*);
static QString getsym(filter_eval_context*);
static QString get_op_name(filter_eval_context*);
static bool eval_string(filter_eval_context*,QChar,bool);
static bool eval_number(filter_eval_context*);
// static bool is_function(const QString);
static bool is_unary_op(const QString);
static bool process_binary_op(filter_eval_context* ctxt, QString op, int prio);
static QChar nxchar(filter_eval_context*);
static QChar nxchar1(filter_eval_context*);
static filter_eval_func* get_func(const QString funcname);
static unary_op_t* get_unary_op(const QString);
static binary_op_t* get_binary_op(const QString);
static filter_eval_value eval_subexpr(filter_eval_context* ctxt, const QString sym);
// binary operators
static filter_eval_value contains_operator(const filter_eval_value v1,
const filter_eval_value v2,
filter_eval_context* ctxt);
static filter_eval_value and_operator(const filter_eval_value v1,
const filter_eval_value v2,
filter_eval_context* ctxt);
static filter_eval_value or_operator(const filter_eval_value v1,
const filter_eval_value v2,
filter_eval_context* ctxt);
static filter_eval_value is_operator(const filter_eval_value v1,
const filter_eval_value v2,
filter_eval_context* ctxt);
static filter_eval_value isnot_operator(const filter_eval_value v1,
const filter_eval_value v2,
filter_eval_context* ctxt);
static filter_eval_value equals_operator(const filter_eval_value v1,
const filter_eval_value v2,
filter_eval_context* ctxt);
static filter_eval_value not_equals_operator(const filter_eval_value v1,
const filter_eval_value v2,
filter_eval_context* ctxt);
static filter_eval_value regmatches_operator(const filter_eval_value v1,
const filter_eval_value v2,
filter_eval_context* ctxt);
// unary operators
static filter_eval_value not_operator(const filter_eval_value v,
filter_eval_context* ctxt);
// functions
static filter_eval_value func_age(const filter_eval_value,
filter_eval_context*);
static filter_eval_value func_condition(const filter_eval_value,
filter_eval_context*);
static filter_eval_value func_date(const filter_eval_value,
filter_eval_context*);
static filter_eval_value func_date_utc(const filter_eval_value,
filter_eval_context*);
static filter_eval_value func_header(const filter_eval_value,
filter_eval_context*);
static filter_eval_value func_body(const filter_eval_value,
filter_eval_context*);
static filter_eval_value func_headers(const filter_eval_value,
filter_eval_context*);
static filter_eval_value func_identity(const filter_eval_value,
filter_eval_context*);
static filter_eval_value func_rawsize(const filter_eval_value,
filter_eval_context*);
static filter_eval_value func_subject(const filter_eval_value,
filter_eval_context*);
static filter_eval_value func_from(const filter_eval_value,
filter_eval_context*);
static filter_eval_value func_to(const filter_eval_value,
filter_eval_context*);
static filter_eval_value func_cc(const filter_eval_value,
filter_eval_context*);
static filter_eval_value func_recipients(const filter_eval_value,
filter_eval_context*);
static filter_eval_value func_now(const filter_eval_value,
filter_eval_context*);
static filter_eval_value func_now_utc(const filter_eval_value,
filter_eval_context*);
private:
static binary_op_t binary_ops[];
static unary_op_t unary_ops[];
static filter_eval_func eval_funcs[];
static filter_eval_value eval_date(const filter_eval_value,
filter_eval_context* ctxt, time_t, int);
static filter_eval_value func_list_header_addresses(const QString field,
filter_eval_context*);
// interface with database
static const QString& db_get_header(filter_eval_context*);
static QString db_lookup_header(const QString, filter_eval_context*);
static QString db_get_body(filter_eval_context*);
static QString db_get_identity(filter_eval_context*);
static time_t db_get_sender_timestamp(filter_eval_context*);
static int db_get_age(filter_eval_context*, const QString unit);
static int db_get_rawsize(filter_eval_context*);
};
#endif
HTML source code generated by GNU Source-Highlight plus some custom post-processing
List of all available source files