From 4f35b2ac2088f7a2775912b23cef18195b6218d2 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Thu, 1 Aug 2024 14:05:07 +0000 Subject: [PATCH] Filter: 'contains' for string keys to mimic strstr/strcasestr --- src/grib_expression_class_functor.cc | 28 +++++++++++++++++++++++ tests/CMakeLists.txt | 1 + tests/filter_contains.sh | 34 ++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100755 tests/filter_contains.sh diff --git a/src/grib_expression_class_functor.cc b/src/grib_expression_class_functor.cc index f335966a0..1185338e7 100644 --- a/src/grib_expression_class_functor.cc +++ b/src/grib_expression_class_functor.cc @@ -168,6 +168,34 @@ static int evaluate_long(grib_expression* g, grib_handle* h, long* lres) return GRIB_SUCCESS; } + if (STR_EQUAL(e->name, "contains")) { + *lres = 0; + const int n = grib_arguments_get_count(e->args); + if (n != 3) return GRIB_INVALID_ARGUMENT; + const char* keyName = grib_arguments_get_name(h, e->args, 0); + if (!keyName) return GRIB_INVALID_ARGUMENT; + int type = 0; + int err = grib_get_native_type(h, keyName, &type); + if (err) return err; + if (type == GRIB_TYPE_STRING) { + char keyValue[254] = {0,}; + size_t len = sizeof(keyValue); + err = grib_get_string(h, keyName, keyValue, &len); + if (err) return err; + const char* sValue = grib_arguments_get_string(h, e->args, 1); + const bool case_sens = grib_arguments_get_long(h, e->args, 2) != 0; + const bool contains = case_sens? strcasestr(keyValue, sValue) : strstr(keyValue, sValue); + if (sValue && contains) { + *lres = 1; + return GRIB_SUCCESS; + } + } else { + // For now only keys of type string supported + return GRIB_INVALID_ARGUMENT; + } + return GRIB_SUCCESS; + } + if (STR_EQUAL(e->name, "is_one_of")) { *lres = 0; const char* keyName = grib_arguments_get_name(h, e->args, 0); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 755a84654..b6194fc61 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -104,6 +104,7 @@ if( HAVE_BUILD_TOOLS ) grib_ifsParam grib_packing_order filter_substr + filter_contains filter_size filter_is_one_of filter_is_in_list diff --git a/tests/filter_contains.sh b/tests/filter_contains.sh new file mode 100755 index 000000000..681bc3906 --- /dev/null +++ b/tests/filter_contains.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# (C) Copyright 2005- 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.ctest.sh + +label="filter_contains_test" +tempFilt=temp.$label.txt +sample=$ECCODES_SAMPLES_PATH/GRIB2.tmpl + +# The contains functor: +# 1st argument: Key name (haystack) +# 2nd argument: string (needle) +# 3rd argument 0=case-sensitive, 1=case-insensitive +# +cat > $tempFilt <