summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2012-07-16 11:41:31 +0000
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2012-07-16 11:41:31 +0000
commit6f200d9f7ebe912ab6aa651293fd56f8cd95ce30 (patch)
tree3b9946dbc45f96dae604026893da51a2ec8dcbf4
parent1c8482f629a724b9b866370d4c5f69e94e2e51f3 (diff)
downloadnavit-6f200d9f7ebe912ab6aa651293fd56f8cd95ce30.tar.gz
navit-6f200d9f7ebe912ab6aa651293fd56f8cd95ce30.tar.bz2
navit-6f200d9f7ebe912ab6aa651293fd56f8cd95ce30.zip
Add:Core:Integrated obj_filter.c into command.c
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@5190 ffa7fe5e-494d-0410-b361-a75ebd5db220
-rw-r--r--navit/navit/CMakeLists.txt2
-rw-r--r--navit/navit/Makefile.am4
-rw-r--r--navit/navit/command.c77
-rw-r--r--navit/navit/command.h1
-rw-r--r--navit/navit/obj_filter.c867
-rw-r--r--navit/navit/obj_filter.h23
6 files changed, 62 insertions, 912 deletions
diff --git a/navit/navit/CMakeLists.txt b/navit/navit/CMakeLists.txt
index ba70e4f0..d19659ca 100644
--- a/navit/navit/CMakeLists.txt
+++ b/navit/navit/CMakeLists.txt
@@ -6,7 +6,7 @@ include_directories( "${CMAKE_CURRENT_SOURCE_DIR}/support")
# navit cre
set(NAVIT_SRC announcement.c atom.c attr.c cache.c callback.c command.c compass.c config_.c coord.c country.c data_window.c debug.c
- event.c file.c graphics.c gui.c item.c layout.c log.c main.c map.c maps.c obj_filter.c
+ event.c file.c graphics.c gui.c item.c layout.c log.c main.c map.c maps.c
linguistics.c mapset.c maptype.c menu.c messages.c bookmarks.c navit.c navigation.c osd.c param.c phrase.c plugin.c popup.c
profile.c projection.c roadprofile.c route.c routech.c search.c speech.c start_real.c sunriset.c transform.c track.c
util.c vehicle.c vehicleprofile.c xmlconfig.c )
diff --git a/navit/navit/Makefile.am b/navit/navit/Makefile.am
index a90f129f..8657fd94 100644
--- a/navit/navit/Makefile.am
+++ b/navit/navit/Makefile.am
@@ -48,11 +48,11 @@ pkgdata_DATA = navit.xml
EXTRA_DIST = navit_shipped.xml navit.dtd
-lib@LIBNAVIT@_la_SOURCES = announcement.c atom.c attr.c cache.c callback.c obj_filter.c command.c compass.c config_.c coord.c country.c data_window.c debug.c \
+lib@LIBNAVIT@_la_SOURCES = announcement.c atom.c attr.c cache.c callback.c command.c compass.c config_.c coord.c country.c data_window.c debug.c \
event.c event_glib.h file.c graphics.c gui.c item.c layout.c log.c main.c map.c maps.c \
linguistics.c mapset.c maptype.c menu.c messages.c bookmarks.c bookmarks.h navit.c navigation.c osd.c param.c phrase.c plugin.c popup.c \
profile.c projection.c roadprofile.c route.c routech.c search.c speech.c start_real.c transform.c track.c \
- util.c vehicle.c vehicleprofile.c xmlconfig.c announcement.h atom.h attr.h attr_def.h cache.h callback.h color.h obj_filter.h command.h compass.h config_.h coord.h country.h \
+ util.c vehicle.c vehicleprofile.c xmlconfig.c announcement.h atom.h attr.h attr_def.h cache.h callback.h color.h command.h compass.h config_.h coord.h country.h \
android.h data.h data_window.h data_window_int.h debug.h destination.h draw_info.h endianess.h event.h \
file.h graphics.h gtkext.h gui.h item.h item_def.h keys.h log.h layer.h layout.h linguistics.h main.h map-share.h map.h\
map_data.h mapset.h maptype.h menu.h messages.h navigation.h navit.h osd.h \
diff --git a/navit/navit/command.c b/navit/navit/command.c
index 84fb1f27..1ed24947 100644
--- a/navit/navit/command.c
+++ b/navit/navit/command.c
@@ -15,7 +15,6 @@
#include "command.h"
#include "event.h"
#include "navit_nls.h"
-#include "obj_filter.h"
/*
gui.fullscreen=!gui.fullscreen
@@ -195,7 +194,6 @@ command_get_attr(struct context *ctx, struct result *res)
static void
command_set_attr(struct context *ctx, struct result *res, struct result *newres)
{
- int result=0;
enum attr_type attr_type=command_attr_type(res);
struct object_func *func=object_func_lookup(res->attr.type);
if (!func || !func->set_attr)
@@ -210,7 +208,7 @@ command_set_attr(struct context *ctx, struct result *res, struct result *newres)
g_free(tmp);
}
newres->attr.type=attr_type;
- result=func->set_attr(res->attr.u.data, &newres->attr);
+ func->set_attr(res->attr.u.data, &newres->attr);
*res=*newres;
}
@@ -287,8 +285,6 @@ static void
eval_value(struct context *ctx, struct result *res) {
const char *op;
int len,dots=0;
- struct obj_filter_t out;
- int parsed_chars;
op=ctx->expr;
res->varlen=0;
@@ -299,18 +295,6 @@ eval_value(struct context *ctx, struct result *res) {
while (g_ascii_isspace(*op)) {
op++;
}
-
- parsed_chars = parse_obj_filter(op, &out);
- if (parsed_chars) {
- struct attr* res_attr = filter_object(ctx->attr, out.iterator_type, out.filter_expr, out.idx);
- if (res_attr) {
- res->attr = *res_attr;
- g_free(res_attr);
- ctx->expr = op+parsed_chars;
- return;
- }
- }
-
if ((op[0] >= 'a' && op[0] <= 'z') || op[0] == '_') {
res->attr.type=attr_none;
res->var=op;
@@ -486,6 +470,34 @@ eval_postfix(struct context *ctx, struct result *res)
res->attrnlen=tmp.varlen;
dump(res);
} else if (op[0] == '[') {
+ resolve_object(ctx, res);
+ if (ctx->error) return;
+ if (get_op(ctx,0,"@",NULL)) {
+ struct object_func *obj_func=object_func_lookup(res->attr.type);
+ struct attr_iter *iter;
+ struct attr attr;
+ enum attr_type attr_type=command_attr_type(res);
+ void *obj=res->attr.u.data;
+ if (!obj_func) {
+ dbg(0,"no object func\n");
+ return;
+ }
+ if (!obj_func->iter_new || !obj_func->iter_destroy) {
+ dbg(0,"no iter func\n");
+ return;
+ }
+ iter = obj_func->iter_new(NULL);
+ res->attr.type=attr_none;
+ res->attr.u.data=NULL;
+ res->varlen=0;
+ while (obj_func->get_attr(obj, attr_type, &attr, iter)) {
+ if (command_evaluate_to_boolean(&attr, ctx->expr, &ctx->error))
+ res->attr=attr;
+ }
+ obj_func->iter_destroy(iter);
+ if (ctx->error) return;
+ ctx->expr+=command_evaluate_to_length(ctx->expr, &ctx->error);
+ }
if (!get_op(ctx,0,"]",NULL)) {
ctx->error=missing_closing_bracket;
return;
@@ -587,12 +599,24 @@ eval_equality(struct context *ctx, struct result *res)
eval_additive(ctx, &tmp);
if (ctx->error) return;
+ resolve(ctx, res, NULL);
+ resolve(ctx, &tmp, NULL);
switch (op[0]) {
case '=':
- set_int(ctx, res, (get_int(ctx, res) == get_int(ctx, &tmp)));
+ if (res->attr.type == attr_none || tmp.attr.type == attr_none) {
+ set_int(ctx, res, 0);
+ } else if (ATTR_IS_STRING(res->attr.type) && ATTR_IS_STRING(tmp.attr.type))
+ set_int(ctx, res, (!strcmp(get_string(ctx, res),get_string(ctx, &tmp))));
+ else
+ set_int(ctx, res, (get_int(ctx, res) == get_int(ctx, &tmp)));
break;
case '!':
- set_int(ctx, res, (get_int(ctx, res) != get_int(ctx, &tmp)));
+ if (res->attr.type == attr_none || tmp.attr.type == attr_none) {
+ set_int(ctx, res, 1);
+ } else if (ATTR_IS_STRING(res->attr.type) && ATTR_IS_STRING(tmp.attr.type))
+ set_int(ctx, res, (!!strcmp(get_string(ctx, res),get_string(ctx, &tmp))));
+ else
+ set_int(ctx, res, (get_int(ctx, res) != get_int(ctx, &tmp)));
break;
case '<':
if (op[1] == '=') {
@@ -900,6 +924,21 @@ command_evaluate_to_boolean(struct attr *attr, const char *expr, int *error)
return ret;
}
+int
+command_evaluate_to_length(const char *expr, int *error)
+{
+ struct attr attr;
+ struct result res;
+ struct context ctx;
+
+ attr.type=attr_none;
+ attr.u.data=NULL;
+ command_evaluate_to(&attr, expr, &ctx, &res);
+ if (!ctx.error)
+ return ctx.expr-expr;
+ return 0;
+}
+
void
command_evaluate(struct attr *attr, const char *expr)
{
diff --git a/navit/navit/command.h b/navit/navit/command.h
index 3ab8d54c..f1382255 100644
--- a/navit/navit/command.h
+++ b/navit/navit/command.h
@@ -44,6 +44,7 @@ void command_evaluate_to_void(struct attr *attr, char *expr, int *error);
char *command_evaluate_to_string(struct attr *attr, char *expr, int *error);
int command_evaluate_to_int(struct attr *attr, char *expr, int *error);
int command_evaluate_to_boolean(struct attr *attr, const char *expr, int *error);
+int command_evaluate_to_length(const char *expr, int *error);
void command_evaluate(struct attr *attr, const char *expr);
void command_add_table_attr(struct command_table *table, int count, void *data, struct attr *attr);
void command_add_table(struct callback_list *cbl, struct command_table *table, int count, void *data);
diff --git a/navit/navit/obj_filter.c b/navit/navit/obj_filter.c
deleted file mode 100644
index 7166bcda..00000000
--- a/navit/navit/obj_filter.c
+++ /dev/null
@@ -1,867 +0,0 @@
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
-#include <glib.h>
-#include "obj_filter.h"
-#include "item.h"
-#include "attr.h"
-#include "xmlconfig.h"
-
-union result_t {
- int res_int;
- int res_bool;
- char* res_str;
-};
-
-enum error_t {ERR_NONE=0, ERR_SYNTAX, ERR_UNKNOWN_ATTRIBUTE, ERR_INTERNAL, ERR_NONTERMINATED_STRING };
-
-struct ctx {
- char*expr;
- union result_t res;
- enum error_t error;
- struct attr *navit_obj;
- struct object_func *obj_func;
-};
-
-//prototypes
-static int parse_numeric_expr(struct ctx*the_ctx);
-static int parse_cond_expr(struct ctx*the_ctx);
-static int parse_bool_expr(struct ctx*the_ctx);
-static enum operator_t get_operator_by_symbol(char*sym);
-static char* get_opstr_by_op(enum operator_t op);
-static int whitespace_num(char*str);
-
-static char*next_sym_ptr;
-
-/*
- * parses an input like osd[attr1==2 && attr2==3][2] or [attr1==2 && attr2==3]
- * returns 0 on failure , returns the number of parsed characters on success
- */
-int parse_obj_filter(const char*input, struct obj_filter_t* out)
-{
- char *curr_ch, *itt, *expr;
- out->idx = 0; //default idx
-
- //skip whitespaces
- curr_ch = (char*)input;
- while(isspace(*curr_ch)) {++curr_ch;}
-
- //parse attr type for the list(iterator)
- itt = out->iterator_type;
- if(isalpha(*curr_ch) || *curr_ch=='_') {
- while(isalnum(*curr_ch) || *curr_ch=='_' ) {
- *itt = *curr_ch;
- ++itt;
- ++curr_ch;
- }
- }
- *itt = 0;
- //skip whitespaces
- while(isspace(*curr_ch)) {++curr_ch;}
- //parse the filter expression (first section between[]), ignore [] chars between "" or ''
- expr = out->filter_expr;
- if(*curr_ch++ == '[') {
- while (*curr_ch && *curr_ch!=']') {
- *expr = *curr_ch;
- ++expr;
- ++curr_ch;
- }
- } else {
- return 0;
- }
- *expr = 0;
- if (*curr_ch==']') {
- char*end1;
- ++curr_ch;
- //skip whitespaces
- while(isspace(*curr_ch)) {++curr_ch;}
- end1 = curr_ch; //possible end of expression if no idx specified
- //parse the optional idx part (another part between [] contains numeric expreession(currently only constant numers are supported))
- if (*curr_ch=='[') {
- char numstr[64];
- char*numch;
- ++curr_ch;
- //skip whitespaces
- while(isspace(*curr_ch)) {++curr_ch;}
-
- numch = numstr;
- while ('0'<=*curr_ch && *curr_ch<='9') {
- *numch = *curr_ch;
- ++numch;
- ++curr_ch;
- }
-
- //skip whitespaces
- while(isspace(*curr_ch)) {++curr_ch;}
-
- if (*curr_ch==']') {
- ++curr_ch;
- *numch = 0;
- out->idx = atoi(numstr);
- return curr_ch-input;
- } else {
- return end1-input;
- }
- } else {
- return end1-input;
- }
- } else {
- return 0;
- }
-}
-
-struct attr* filter_object(struct attr* root,char*iter_type,char*expr, int idx)
-{
- struct attr_iter *iter;
- struct attr the_attr;
- int curr_idx = 0;
- struct object_func *obj_func_root;
- struct object_func *obj_func_iter;
-
- if (!root || !iter_type || !expr) {
- return NULL;
- }
-
- obj_func_root = object_func_lookup(((struct attr*)root)->type);
- obj_func_iter = object_func_lookup(attr_from_name(iter_type));
- if( !obj_func_root || !obj_func_root->get_attr || !obj_func_root->iter_new || !obj_func_root->iter_destroy ||
- !obj_func_iter || !obj_func_iter->get_attr ) {
- return NULL;
- }
-
- iter = obj_func_root->iter_new(NULL);
- while ( obj_func_root->get_attr(root->u.data, attr_from_name(iter_type), &the_attr, iter ) ) {
- struct ctx the_ctx;
- the_ctx.expr = expr;
- the_ctx.navit_obj = &the_attr;
- the_ctx.obj_func = obj_func_iter;
- if (parse_bool_expr(&the_ctx)) {
- if(the_ctx.res.res_bool) {
- if (curr_idx==idx) {
- return attr_dup(&the_attr);
- }
- ++curr_idx;
- }
- }
- }
- obj_func_root->iter_destroy(iter);
-
- return NULL;
-}
-
-enum operator_t {OP_NONE=0, OP_GT, OP_GE, OP_LT, OP_LE, OP_EQ, OP_NE, OP_LOGICAL_AND, OP_LOGICAL_OR, OP_LOGICAL_XOR, OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD};
-
-struct op_table_entry {
- char*name;
- enum operator_t op_type;
-};
-
-struct op_table_entry op_table[] = {
- {"<" , OP_GT},
- {"<=", OP_GE},
- {">" , OP_LT},
- {">=", OP_LE},
- {"!=", OP_NE},
- {"==", OP_EQ},
- {"&&", OP_LOGICAL_AND},
- {"||", OP_LOGICAL_OR},
- {"^" , OP_LOGICAL_XOR},
- {"+" , OP_ADD},
- {"-" , OP_SUB},
- {"*" , OP_MUL},
- {"/" , OP_DIV},
- {"%" , OP_MOD},
- {NULL, OP_NONE}
- };
-
-static enum operator_t get_operator_by_symbol(char*sym)
-{
- struct op_table_entry* ote = op_table;
- while(sym && ote->name) {
- if ( ! strcmp(ote->name, sym)) {
- return ote->op_type;
- }
- ++ote;
- }
- return OP_NONE;
-}
-
-static char* get_opstr_by_op(enum operator_t op)
-{
- struct op_table_entry* ote = op_table;
- while(ote->name) {
- if ( ote->op_type == op ) {
- return ote->name;
- }
- ++ote;
- }
- return NULL;
-}
-
-/*
-GRAMMAR
-
-ident = [ [A-Z,a-z][A-Z,a-z,0-9]+
- ] .
-
-number = [ [A-Z,a-z][A-Z,a-z,0-9]+
- ] .
-
-numeric_additive_expr = [
- | numeric_mul_operand numeric_mul_operator numeric_mul_expr
- | numeric_add_operand numeric_add_operator numeric_add_expr
- | "(" numeric_expr ")"
- | numeric_operand
- ]
-
-bool_expr = [ bool_expr bool_operator bool_operand
- | "!" bool_operand
- | bool_operand
- ]
-
-cond_expr = [
- cond_operand cond_operator cond_operand
- ]
-
-//TODO support precedence between additive and multiplicative operators (the order of +- and * / evaluation)
-
-numeric_multiplicative_operator = [ "*" "/" "%"
- ]
-
-numeric_additive_operator = [ "+" "-"
- ]
-
-bool_operator = [ "&&" "||" "^"
- ]
-
-cond_operator = [ "==" "!=" "< "> "<=" ">="
- ]
-
-cond_operand =
- [ ident
- | number
- | numeric_expr
- ] .
-
-numeric_operand =
- [ ident
- | number
- | "(" numeric_expr ")"
- ] .
-
-bool_operand =
- | "(" bool_expr ")"
- | cond_expr
- | "true"
- | "false"
- ] .
-*/
-
-static int whitespace_num(char*str)
-{
- int ret = 0;
- while(isspace(*str)) {
- ++str;
- ++ret;
- }
- return ret;
-}
-
-static char *
-get_op(char *expr, ...)
-{
- char *op;
- char *ret=NULL;
- va_list ap;
-
- while (isspace(*expr)) {
- expr++;
- }
-
- va_start(ap, expr);
- while ((op = va_arg(ap, char *))) {
- if (!strncmp(expr, op, strlen(op))) {
- ret = op;
- break;
- }
- }
- va_end(ap);
- return ret;
-}
-
-static int ident_length(char*input)
-{
- int ret = 0;
- if(input[0] != '@') {
- return 0;
- }
- if(isalpha((int)input[1])) {
- int ii;
- ++ret;
- for(ii=2 ; ii<strlen(input) ; ++ii) {
- if(!isalnum((int)input[ii])) {
- return ret;
- } else {
- ++ret;
- }
- }
- return ret;
- }
- return 0;
-}
-
-static enum operator_t parse_bool_operator(struct ctx*the_ctx)
-{
- char* input = the_ctx->expr;
- char *sym;
- enum operator_t op;
- sym = get_op(input,"&&","||","^",NULL);
-
- op = get_operator_by_symbol(sym);
- switch(op) {
- case OP_LOGICAL_AND:
- case OP_LOGICAL_OR:
- case OP_LOGICAL_XOR:
- return op;
- break;
- default:
- return OP_NONE;
- break;
- };
-}
-
-static enum operator_t parse_cond_operator(struct ctx*the_ctx)
-{
- char* input = the_ctx->expr;
- char *sym;
- enum operator_t op;
- sym = get_op(input, "==", "<", ">", "<=", ">=", "!=", NULL);
-
- op = get_operator_by_symbol(sym);
- switch(op) {
- case OP_EQ:
- case OP_GT:
- case OP_LT:
- case OP_GE:
- case OP_LE:
- case OP_NE:
- return op;
- break;
- default:
- return OP_NONE;
- break;
- };
-}
-
-static enum operator_t parse_numeric_multiplicative_operator(struct ctx*the_ctx)
-{
- char* input = the_ctx->expr;
- char *sym;
- enum operator_t op;
- sym = get_op(input, "*", "/", "%", NULL);
-
- op = get_operator_by_symbol(sym);
- switch(op) {
- case OP_MUL:
- case OP_DIV:
- case OP_MOD:
- return op;
- break;
- default:
- return OP_NONE;
- break;
- };
-}
-
-static enum operator_t parse_numeric_additive_operator(struct ctx*the_ctx)
-{
- char* input = the_ctx->expr;
- char *sym;
- enum operator_t op;
- sym = get_op(input, "+", "-", NULL);
-
- op = get_operator_by_symbol(sym);
- switch(op) {
- case OP_ADD:
- case OP_SUB:
- return op;
- break;
- default:
- return OP_NONE;
- break;
- };
-}
-
-static int parse_string_operand(struct ctx*the_ctx)
-{
- char* input = the_ctx->expr;
- char sym[256];
- struct ctx sub_ctx;
- int ilen;
- sub_ctx.navit_obj = the_ctx->navit_obj;
- sub_ctx.obj_func = the_ctx->obj_func;
-
- while(isspace(*input)) {++input;}
-
- if (*input == '"' || *input=='\'') {
- char delimiter = *input;
- char* psym = sym;
- ++input;
- while(*input != delimiter && *input!='\0') {
- *psym = *input;
- ++psym;
- ++input;
- }
- if(*input=='\0') {
- the_ctx->error = ERR_NONTERMINATED_STRING;
- return 0;
- } else { //terminating delimiter found
- *psym = '\0';
- the_ctx->res.res_str = g_strdup(sym);
- the_ctx->error = ERR_NONE;
- next_sym_ptr = input + 1;
- return 1;
- }
- }
-
- ilen = ident_length(input);
- if(ilen) {
- struct attr the_attr;
- strncpy(sym,input+1,ilen);
- sym[ilen] = '\0';
- if ( attr_from_name(sym)!=attr_none && the_ctx->obj_func->get_attr(the_ctx->navit_obj->u.data, attr_from_name(sym), &the_attr, NULL )
- && attr_type_string_begin<=the_attr.type && the_attr.type <= attr_type_string_end) {
- the_ctx->res.res_str = g_strdup(the_attr.u.str);
- the_ctx->error = ERR_NONE;
- next_sym_ptr = input+ilen+1;
- return 1;
- } else {
- the_ctx->error = ERR_UNKNOWN_ATTRIBUTE;
- return 0;
- }
- }
-
- //currently we are not supporting string expressions (eg: concatenation)
- /*
- if(get_op(input,"(",NULL)) {
- sub_ctx.expr = input + 1 + whitespace_num(input);
- if ( ! parse_string_expr(&sub_ctx)) {
- the_ctx->error = ERR_SYNTAX;
- return 0;
- } else {
- the_ctx->res.res_int = sub_ctx.res.res_int;
- the_ctx->error = ERR_NONE;
- }
- //expect ")"
- if ( get_op(next_sym_ptr,")",NULL)) {
- next_sym_ptr += 1 + whitespace_num(next_sym_ptr);
- return 1;
- } else {
- the_ctx->res.res_int = 0;
- the_ctx->error = ERR_SYNTAX;
- return 0;
- }
- }
- */
- return 0;
-}
-
-
-static int parse_numeric_operand(struct ctx*the_ctx)
-{
- char* input = the_ctx->expr;
- char sym[256];
- struct ctx sub_ctx;
- char* endptr = NULL;
- int res, ilen;
- sub_ctx.navit_obj = the_ctx->navit_obj;
- sub_ctx.obj_func = the_ctx->obj_func;
-
- res = strtol(input,&endptr,0);
- if( endptr!=input ) {
- the_ctx->res.res_int = res;
- the_ctx->error = ERR_NONE;
- next_sym_ptr = endptr;
- return 1;
- }
-
- while(isspace(*input)) {++input;}
- ilen = ident_length(input);
- if(ilen) {
- //get int value from context object and set result member of context argument
- struct attr the_attr;
- strncpy(sym,input+1,ilen);
- sym[ilen] = '\0';
- if ( attr_from_name(sym)!=attr_none && the_ctx->obj_func->get_attr(the_ctx->navit_obj->u.data, attr_from_name(sym), &the_attr, NULL )
- && attr_type_int_begin<=the_attr.type && the_attr.type <= attr_type_int_end) { //TODO support other numeric types
- the_ctx->res.res_int = the_attr.u.num;
- the_ctx->error = ERR_NONE;
- next_sym_ptr = input+ilen+1;
- return 1;
- } else {
- the_ctx->error = ERR_UNKNOWN_ATTRIBUTE;
- return 0;
- }
- }
- if(get_op(input,"(",NULL)) {
- sub_ctx.expr = input + 1 + whitespace_num(input);
- if ( ! parse_numeric_expr(&sub_ctx)) {
- the_ctx->error = ERR_SYNTAX;
- return 0;
- } else {
- the_ctx->res.res_int = sub_ctx.res.res_int;
- the_ctx->error = ERR_NONE;
- }
- //expect ")"
- if ( get_op(next_sym_ptr,")",NULL)) {
- next_sym_ptr += 1 + whitespace_num(next_sym_ptr);
- return 1;
- } else {
- the_ctx->res.res_int = 0;
- the_ctx->error = ERR_SYNTAX;
- return 0;
- }
- }
- return 0;
-}
-
-static int parse_cond_operand(struct ctx*the_ctx)
-{
- char* input = the_ctx->expr;
- char sym[256];
- char* endptr = NULL;
- int res, ilen;
- struct attr the_attr;
- struct ctx sub_ctx;
- sub_ctx.navit_obj = the_ctx->navit_obj;
- sub_ctx.obj_func = the_ctx->obj_func;
- sub_ctx.expr = input;
- if(parse_numeric_expr(&sub_ctx)) {
- the_ctx->res.res_int = sub_ctx.res.res_int;
- the_ctx->error = ERR_NONE;
- return 1;
- }
-
- res = strtol(input,&endptr,0);
- if( endptr!=input ) {
- the_ctx->res.res_int = res;
- the_ctx->error = ERR_NONE;
- next_sym_ptr = endptr;
- return 1;
- }
- while(isspace(*input)) {++input;}
- ilen = ident_length(input);
- strncpy(sym,input+1,ilen);
- sym[ilen] = '\0';
- if ( attr_from_name(sym)!=attr_none && the_ctx->obj_func->get_attr(the_ctx->navit_obj->u.data, attr_from_name(sym), &the_attr, NULL )
- && attr_type_int_begin<=the_attr.type && the_attr.type <= attr_type_int_end) { //TODO support other numeric types
- the_ctx->res.res_int = the_attr.u.num;
- the_ctx->error = ERR_NONE;
- next_sym_ptr = input+ilen+1;
- return 1;
- } else {
- the_ctx->error = ERR_UNKNOWN_ATTRIBUTE;
- return 0;
- }
- the_ctx->error = ERR_SYNTAX;
- return 0;
-}
-
-static int parse_bool_operand(struct ctx*the_ctx)
-{
- char* input = the_ctx->expr;
- struct ctx sub_ctx;
- sub_ctx.navit_obj = the_ctx->navit_obj;
- sub_ctx.obj_func = the_ctx->obj_func;
- if(get_op(input,"true",NULL)) {
- the_ctx->res.res_bool = 1;
- the_ctx->error = ERR_NONE;
- next_sym_ptr += whitespace_num(input)+strlen("true");
- return 1;
- }
- if(get_op(input,"false",NULL)) {
- the_ctx->res.res_bool = 0;
- the_ctx->error = ERR_NONE;
- next_sym_ptr += whitespace_num(input)+strlen("false");
- return 1;
- }
- if(get_op(input,"(",NULL)) {
- sub_ctx.expr = input + 1 + whitespace_num(input);
- if ( ! parse_bool_expr(&sub_ctx)) {
- the_ctx->error = ERR_SYNTAX;
- return 0;
- } else {
- the_ctx->res.res_bool = sub_ctx.res.res_bool;
- the_ctx->error = ERR_NONE;
- }
- //expect ")"
- if(get_op(next_sym_ptr,"(",NULL)) {
- next_sym_ptr += 1 + whitespace_num(next_sym_ptr);
- return 1;
- } else {
- the_ctx->error = ERR_SYNTAX;
- return 0;
- }
- }
- //cond_expr
- sub_ctx.expr = input;
- if (parse_cond_expr(&sub_ctx)) {
- the_ctx->res.res_bool = sub_ctx.res.res_bool;
- the_ctx->error = ERR_NONE;
- return 1;
- }
- the_ctx->error = ERR_SYNTAX;
- return 0;
-}
-
-static int parse_cond_expr(struct ctx*the_ctx)
-{
- char* input = the_ctx->expr;
- struct ctx sub_ctx;
- sub_ctx.navit_obj = the_ctx->navit_obj;
- sub_ctx.obj_func = the_ctx->obj_func;
- sub_ctx.expr = input;
-
-
- //expect cond operand
- if(parse_cond_operand(&sub_ctx)) {
- enum operator_t op;
- int op1 = sub_ctx.res.res_int;
- //expect cond operand
- sub_ctx.expr = next_sym_ptr;
- if( (op=parse_cond_operator(&sub_ctx)) ) {
- next_sym_ptr += whitespace_num(next_sym_ptr) + strlen(get_opstr_by_op(op));
- sub_ctx.expr = next_sym_ptr;
- if(parse_cond_operand(&sub_ctx)) {
- int op2 = sub_ctx.res.res_int;
- switch(op) {
- case OP_EQ:
- the_ctx->res.res_bool = op1==op2;
- break;
- case OP_GT:
- the_ctx->res.res_bool = op1<op2;
- break;
- case OP_LT:
- the_ctx->res.res_bool = op1>op2;
- break;
- case OP_GE:
- the_ctx->res.res_bool = op1<=op2;
- break;
- case OP_LE:
- the_ctx->res.res_bool = op1>=op2;
- break;
- case OP_NE:
- the_ctx->res.res_bool = op1!=op2;
- break;
- default:
- //unknown operator
- the_ctx->error = ERR_INTERNAL;
- return 0;
- break;
- };
- the_ctx->error = ERR_NONE;
- return 1;
- }
- }
- }
-
-
-
- //expect cond operand
- if(parse_string_operand(&sub_ctx)) {
- char* op1 = sub_ctx.res.res_str;
- enum operator_t op;
-
- //expect cond operand
- sub_ctx.expr = next_sym_ptr;
- if( (op=parse_cond_operator(&sub_ctx)) ) {
- next_sym_ptr += whitespace_num(next_sym_ptr) + strlen(get_opstr_by_op(op));
- sub_ctx.expr = next_sym_ptr;
- if(parse_string_operand(&sub_ctx)) {
- char* op2 = sub_ctx.res.res_str;
- switch(op) {
- case OP_EQ:
- the_ctx->res.res_bool = !strcmp(op1,op2);
- break;
- case OP_GT:
- the_ctx->res.res_bool = strcmp(op1,op2)<=0;
- break;
- case OP_LT:
- the_ctx->res.res_bool = strcmp(op1,op2)>=0;
- break;
- case OP_GE:
- the_ctx->res.res_bool = strcmp(op1,op2)<0;
- break;
- case OP_LE:
- the_ctx->res.res_bool = strcmp(op1,op2)>0;
- break;
- case OP_NE:
- the_ctx->res.res_bool = !!strcmp(op1,op2);
- break;
- default:
- //unknown operator
- the_ctx->error = ERR_INTERNAL;
- return 0;
- break;
- };
- the_ctx->error = ERR_NONE;
- return 1;
- }
- }
- }
- the_ctx->error = ERR_SYNTAX;
- return 0;
-}
-
-/*
-numeric_expr = [
- | numeric_operand numeric_multiplicative_operator numeric_expr
- | numeric_operand numeric_additive_operator numeric_expr
- | "(" numeric_expr ")"
- | numeric_operand
- ]
-*/
-static int parse_numeric_expr(struct ctx*the_ctx)
-{
-char* input = the_ctx->expr;
-struct ctx sub_ctx;
-sub_ctx.navit_obj = the_ctx->navit_obj;
-sub_ctx.obj_func = the_ctx->obj_func;
-sub_ctx.expr = input;
-if(parse_numeric_operand(&sub_ctx)) {
- enum operator_t op;
- int op1 = sub_ctx.res.res_int;
- //expect numeric_multiplicative operator
- sub_ctx.expr = next_sym_ptr;
- if( (op=parse_numeric_multiplicative_operator(&sub_ctx)) ) {
- next_sym_ptr += whitespace_num(next_sym_ptr) + strlen(get_opstr_by_op(op));
- sub_ctx.expr = next_sym_ptr;
- if(parse_numeric_expr(&sub_ctx)) {
- int op2 = sub_ctx.res.res_int;
- switch(op) {
- case OP_MUL:
- the_ctx->res.res_int = op1*op2;
- break;
- case OP_DIV:
- the_ctx->res.res_int = op1/op2;
- break;
- case OP_MOD:
- the_ctx->res.res_int = op1%op2;
- break;
- default:
- //unknown operator
- the_ctx->error = ERR_INTERNAL;
- return 0;
- break;
- };
- the_ctx->error = ERR_NONE;
- return 1;
- }
- }
-}
-
-sub_ctx.expr = input;
-if(parse_numeric_operand(&sub_ctx)) {
- //expect numeric_additive operator
- enum operator_t op;
- int op1 = sub_ctx.res.res_int;
- sub_ctx.expr = next_sym_ptr;
- if((op=parse_numeric_additive_operator(&sub_ctx))) {
- next_sym_ptr += whitespace_num(next_sym_ptr) + strlen(get_opstr_by_op(op));
- sub_ctx.expr = next_sym_ptr;
- if(parse_numeric_expr(&sub_ctx)) {
- int op2 = sub_ctx.res.res_int;
- switch(op) {
- case OP_ADD:
- the_ctx->res.res_int = op1+op2;
- break;
- case OP_SUB:
- the_ctx->res.res_int = op1-op2;
- break;
- default:
- //unknown operator
- the_ctx->error = ERR_INTERNAL;
- return 0;
- break;
- };
- the_ctx->error = ERR_NONE;
- return 1;
- }
- }
-}
-
-sub_ctx.expr = input;
-if(parse_numeric_operand(&sub_ctx) ) {
- the_ctx->res.res_int = sub_ctx.res.res_int;
- the_ctx->error = ERR_NONE;
- return 1;
-}
- the_ctx->error = ERR_SYNTAX;
- return 0;
-}
-
-/*
-bool_expr = [ bool_operand bool_operator bool_expr
- | bool_operand
- ]
-*/
-static int parse_bool_expr(struct ctx*the_ctx)
-{
- char* input = the_ctx->expr;
- struct ctx sub_ctx;
- sub_ctx.navit_obj = the_ctx->navit_obj;
- sub_ctx.obj_func = the_ctx->obj_func;
- sub_ctx.expr = input;
- if(parse_bool_operand(&sub_ctx)) {
- enum operator_t op;
- int op1 = sub_ctx.res.res_bool;
- //expect bool operator
- sub_ctx.expr = next_sym_ptr;
- if((op=parse_bool_operator(&sub_ctx))) {
- next_sym_ptr += whitespace_num(next_sym_ptr) + strlen(get_opstr_by_op(op));
- sub_ctx.expr = next_sym_ptr;
- if(parse_bool_expr(&sub_ctx)) {
- int op2 = sub_ctx.res.res_bool;
- switch(op) {
- case OP_LOGICAL_AND:
- the_ctx->res.res_bool = op1 && op2;
- break;
- case OP_LOGICAL_OR:
- the_ctx->res.res_bool = op1 || op2;
- break;
- case OP_LOGICAL_XOR:
- the_ctx->res.res_bool = op1 ^ op2;
- break;
- default:
- //unknown operator
- the_ctx->error = ERR_INTERNAL;
- return 0;
- break;
- };
- return 1;
- }
- }
- }
-
- if(get_op(input,"!",NULL)) {
- next_sym_ptr += 1 + whitespace_num(input);
- sub_ctx.expr = next_sym_ptr;
- if(parse_bool_expr(&sub_ctx)) {
- the_ctx->res.res_bool = ! sub_ctx.res.res_bool;
- the_ctx->error = ERR_NONE;
- return 1;
- }
- }
- sub_ctx.expr = input;
- if(parse_bool_operand(&sub_ctx) ) {
- the_ctx->res.res_bool = sub_ctx.res.res_bool;
- the_ctx->error = ERR_NONE;
- return 1;
- }
- the_ctx->error = ERR_SYNTAX;
- return 0;
-}
-
diff --git a/navit/navit/obj_filter.h b/navit/navit/obj_filter.h
deleted file mode 100644
index 9e8dcae1..00000000
--- a/navit/navit/obj_filter.h
+++ /dev/null
@@ -1,23 +0,0 @@
-
-#ifndef OBJ_FILTER
-#define OBJ_FILTER
-
-//forward declaration
-struct attr;
-
-struct obj_filter_t {
- char iterator_type[64];
- char filter_expr[256];
- int idx;
-};
-
-struct obj_list {
- struct navit_object* objs;
- int size;
-};
-
-int parse_obj_filter(const char*input, struct obj_filter_t* out);
-struct attr* filter_object(struct attr* root,char*iter_type,char*expr, int idx);
-
-#endif
-