From dcf8c563fb37004aad071d511d1d0392aec5d432 Mon Sep 17 00:00:00 2001 From: Enrico Fucile Date: Tue, 30 May 2017 15:18:50 +0100 Subject: [PATCH] ECC-486 --- src/CMakeLists.txt | 1 + src/Makefile.am | 1 + src/grib_api_prototypes.h | 3 + src/grib_expression_class.h | 1 + src/grib_expression_class_logical_or.c | 186 +++++++++++++++++++++++++ src/grib_expression_factory.h | 1 + src/grib_yacc.c | 2 +- src/griby.y | 2 +- 8 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 src/grib_expression_class_logical_or.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 18616382d..d162de05e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -312,6 +312,7 @@ list( APPEND grib_api_srcs grib_errors.c grib_expression_class_binop.c grib_expression_class_logical_and.c + grib_expression_class_logical_or.c grib_expression_class_is_in_dict.c grib_expression_class_true.c grib_expression_class_string_compare.c diff --git a/src/Makefile.am b/src/Makefile.am index 266482b15..ad5f441d7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -327,6 +327,7 @@ libeccodes_la_prototypes= \ grib_errors.c \ grib_expression_class_binop.c \ grib_expression_class_logical_and.c \ + grib_expression_class_logical_or.c \ grib_expression_class_is_in_dict.c \ grib_expression_class_true.c \ grib_expression_class_string_compare.c \ diff --git a/src/grib_api_prototypes.h b/src/grib_api_prototypes.h index a57221f7f..15616bea9 100644 --- a/src/grib_api_prototypes.h +++ b/src/grib_api_prototypes.h @@ -1278,6 +1278,9 @@ grib_expression *new_binop_expression(grib_context *c, grib_binop_long_proc long /* grib_expression_class_logical_and.c */ grib_expression *new_logical_and_expression(grib_context *c, grib_expression *left, grib_expression *right); +/* grib_expression_class_logical_or.c */ +grib_expression *new_logical_or_expression(grib_context *c, grib_expression *left, grib_expression *right); + /* grib_expression_class_is_in_dict.c */ grib_expression *new_is_in_dict_expression(grib_context *c, const char *name, const char *list); diff --git a/src/grib_expression_class.h b/src/grib_expression_class.h index 8dc9ef5d8..6856b1b06 100644 --- a/src/grib_expression_class.h +++ b/src/grib_expression_class.h @@ -10,6 +10,7 @@ extern grib_expression_class* grib_expression_class_is_in_list; extern grib_expression_class* grib_expression_class_is_integer; extern grib_expression_class* grib_expression_class_length; extern grib_expression_class* grib_expression_class_logical_and; +extern grib_expression_class* grib_expression_class_logical_or; extern grib_expression_class* grib_expression_class_long; extern grib_expression_class* grib_expression_class_string; extern grib_expression_class* grib_expression_class_string_compare; diff --git a/src/grib_expression_class_logical_or.c b/src/grib_expression_class_logical_or.c new file mode 100644 index 000000000..2d492b19f --- /dev/null +++ b/src/grib_expression_class_logical_or.c @@ -0,0 +1,186 @@ +/* + * Copyright 2005-2017 ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#include "grib_api_internal.h" + +/* + This is used by make_class.pl + + START_CLASS_DEF + CLASS = expression + IMPLEMENTS = init_class + IMPLEMENTS = destroy + IMPLEMENTS = native_type + IMPLEMENTS = evaluate_long + IMPLEMENTS = evaluate_double + IMPLEMENTS = print + IMPLEMENTS = add_dependency + MEMBERS = grib_expression *left + MEMBERS = grib_expression *right + END_CLASS_DEF + + */ +/* START_CLASS_IMP */ + +/* + +Don't edit anything between START_CLASS_IMP and END_CLASS_IMP +Instead edit values between START_CLASS_DEF and END_CLASS_DEF +or edit "expression.class" and rerun ./make_class.pl + +*/ + +typedef const char* string; /* to keep make_class.pl happy */ + + +static void init_class (grib_expression_class*); + +static void destroy(grib_context*,grib_expression* e); + +static void print(grib_context*,grib_expression*,grib_handle*); +static void add_dependency(grib_expression* e, grib_accessor* observer); + +static int native_type(grib_expression*,grib_handle*); + +static int evaluate_long(grib_expression*,grib_handle*,long*); +static int evaluate_double(grib_expression*,grib_handle*,double*); + +typedef struct grib_expression_logical_or{ + grib_expression base; +/* Members defined in logical_or */ + grib_expression *left; + grib_expression *right; +} grib_expression_logical_or; + + +static grib_expression_class _grib_expression_class_logical_or = { + 0, /* super */ + "logical_or", /* name */ + sizeof(grib_expression_logical_or),/* size of instance */ + 0, /* inited */ + &init_class, /* init_class */ + 0, /* constructor */ + &destroy, /* destructor */ + &print, + &add_dependency, + + &native_type, + 0, + + &evaluate_long, + &evaluate_double, + 0, +}; + +grib_expression_class* grib_expression_class_logical_or = &_grib_expression_class_logical_or; + + +static void init_class(grib_expression_class* c) +{ +} +/* END_CLASS_IMP */ + +static int evaluate_long(grib_expression *g,grib_handle* h,long* lres) +{ + long v1=0; + long v2=0; + double dv1=0; + double dv2=0; + int ret; + grib_expression_logical_or* e = (grib_expression_logical_or*)g; + + + switch (grib_expression_native_type(h, e->left)) { + case GRIB_TYPE_LONG: + ret = grib_expression_evaluate_long(h,e->left,&v1); + if (ret != GRIB_SUCCESS) return ret; + if (v1 != 0) { + *lres=1; + return ret; + } + break; + case GRIB_TYPE_DOUBLE: + ret = grib_expression_evaluate_double(h,e->left,&dv1); + if (ret != GRIB_SUCCESS) return ret; + if (dv1 != 0) { + *lres=1; + return ret; + } + break; + default : + return GRIB_INVALID_TYPE; + } + + switch (grib_expression_native_type(h, e->right)) { + case GRIB_TYPE_LONG: + ret = grib_expression_evaluate_long(h,e->right,&v2); + if (ret != GRIB_SUCCESS) return ret; + *lres = v2 ? 1 : 0; + break; + case GRIB_TYPE_DOUBLE: + ret = grib_expression_evaluate_double(h,e->right,&dv2); + if (ret != GRIB_SUCCESS) return ret; + *lres = dv2 ? 1 : 0; + break; + default : + return GRIB_INVALID_TYPE; + } + + return GRIB_SUCCESS; +} + +static int evaluate_double(grib_expression *g,grib_handle* h,double* dres) +{ + long lres=0; + int ret=0; + + ret=evaluate_long(g,h,&lres); + *dres=(double)lres; + + return ret; +} + +static void print(grib_context* c,grib_expression* g,grib_handle* f) +{ + grib_expression_logical_or* e = (grib_expression_logical_or*)g; + printf("("); + grib_expression_print(c,e->left,f); + printf(" && "); + grib_expression_print(c,e->right,f); + printf(")"); +} + +static void destroy(grib_context* c,grib_expression* g) +{ + grib_expression_logical_or* e = (grib_expression_logical_or*)g; + grib_expression_free(c,e->left); + grib_expression_free(c,e->right); +} + +static void add_dependency(grib_expression* g, grib_accessor* observer) +{ + grib_expression_logical_or* e = (grib_expression_logical_or*)g; + grib_dependency_observe_expression(observer,e->left); + grib_dependency_observe_expression(observer,e->right); +} + +grib_expression* new_logical_or_expression(grib_context* c, grib_expression* left,grib_expression* right) +{ + grib_expression_logical_or* e = (grib_expression_logical_or*)grib_context_malloc_clear_persistent(c,sizeof(grib_expression_logical_or)); + e->base.cclass = grib_expression_class_logical_or; + e->left = left; + e->right = right; + return (grib_expression*)e; +} + +static int native_type(grib_expression* g,grib_handle *h) +{ + return GRIB_TYPE_LONG; +} diff --git a/src/grib_expression_factory.h b/src/grib_expression_factory.h index 1988b7e77..0f5cd83bb 100644 --- a/src/grib_expression_factory.h +++ b/src/grib_expression_factory.h @@ -10,6 +10,7 @@ { "is_integer", &grib_expression_class_is_integer, }, { "length", &grib_expression_class_length, }, { "logical_and", &grib_expression_class_logical_and, }, +{ "logical_or", &grib_expression_class_logical_or, }, { "long", &grib_expression_class_long, }, { "string", &grib_expression_class_string, }, { "string_compare", &grib_expression_class_string_compare, }, diff --git a/src/grib_yacc.c b/src/grib_yacc.c index bb9c00c9d..6bf85dce6 100644 --- a/src/grib_yacc.c +++ b/src/grib_yacc.c @@ -3917,7 +3917,7 @@ grib_yyreduce: case 254: /* Line 1792 of yacc.c */ #line 824 "griby.y" - { (grib_yyval.exp) = new_binop_expression(grib_parser_context,&grib_op_or,NULL,(grib_yyvsp[(1) - (3)].exp),(grib_yyvsp[(3) - (3)].exp));} + { (grib_yyval.exp) = new_logical_or_expression(grib_parser_context,(grib_yyvsp[(1) - (3)].exp),(grib_yyvsp[(3) - (3)].exp));} break; case 259: diff --git a/src/griby.y b/src/griby.y index 6132fb676..1be6f8523 100644 --- a/src/griby.y +++ b/src/griby.y @@ -821,7 +821,7 @@ conjonction : conjonction AND condition { $$ = new_logical_and_expression(grib_p | condition ; -disjonction : disjonction OR conjonction { $$ = new_binop_expression(grib_parser_context,&grib_op_or,NULL,$1,$3);} +disjonction : disjonction OR conjonction { $$ = new_logical_or_expression(grib_parser_context,$1,$3);} | conjonction ;