Filter: 'contains' for string keys to mimic strstr/strcasestr

This commit is contained in:
Shahram Najm 2024-08-01 14:05:07 +00:00
parent ec1a3a10f5
commit 4f35b2ac20
3 changed files with 63 additions and 0 deletions

View File

@ -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);

View File

@ -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

34
tests/filter_contains.sh Executable file
View File

@ -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 <<EOF
if (! contains(identifier, "GR", 0) ) { assert (false); }
if (! contains(identifier, "ib", 1) ) { assert (false); }
if (! contains(identifier, "", 1) ) { assert (false); }
if (contains(identifier, "grb", 1) ) { assert (false); }
if (contains(identifier, "ib", 0) ) { assert (false); }
EOF
cat $tempFilt
${tools_dir}/grib_filter $tempFilt $sample
# Clean up
rm -f $tempFilt