diff --git a/definitions/boot.def b/definitions/boot.def index 22edf96e1..61a7b7be0 100644 --- a/definitions/boot.def +++ b/definitions/boot.def @@ -52,6 +52,9 @@ transient unitsFactor=1 : hidden; transient unitsBias=0 : hidden; constant globalDomain = "g"; transient timeRangeIndicatorFromStepRange=-1 : hidden; +# Format specifiers for converting a number (float or int) into a string +transient formatForDoubles = "%g" : no_copy,hidden; +transient formatForLongs = "%ld" : no_copy,hidden; # ECC-868 transient produceLargeConstantFields = 0 : hidden; diff --git a/src/grib_accessor_class_double.cc b/src/grib_accessor_class_double.cc index e1888ed0c..3f635720c 100644 --- a/src/grib_accessor_class_double.cc +++ b/src/grib_accessor_class_double.cc @@ -8,10 +8,6 @@ * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. */ -/************************************************ - * Enrico Fucile - ***********************************************/ - #include "grib_api_internal.h" /* This is used by make_class.pl @@ -115,13 +111,18 @@ static int unpack_string(grib_accessor* a, char* v, size_t* len) double val = 0; size_t l = 1; char repres[1024]; + char format[32] = "%g"; + grib_handle* h = grib_handle_of_accessor(a); grib_unpack_double(a, &val, &l); - if ((val == GRIB_MISSING_DOUBLE) && ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0)) + if ((val == GRIB_MISSING_DOUBLE) && ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0)) { snprintf(repres, sizeof(repres), "MISSING"); - else - snprintf(repres, sizeof(repres), "%g", val); + } else { + size_t size = sizeof(format); + grib_get_string(h, "formatForDoubles", format, &size); + snprintf(repres, sizeof(repres), format, val); + } l = strlen(repres) + 1; diff --git a/src/grib_accessor_class_long.cc b/src/grib_accessor_class_long.cc index c939189a5..1f97a539e 100644 --- a/src/grib_accessor_class_long.cc +++ b/src/grib_accessor_class_long.cc @@ -120,6 +120,8 @@ static int unpack_string(grib_accessor* a, char* v, size_t* len) long val = 0; size_t l = 1; char repres[1024]; + char format[32] = "%ld"; + grib_handle* h = grib_handle_of_accessor(a); err = grib_unpack_long(a, &val, &l); /* TODO: We should catch all errors but in this case the test ERA_Gen.sh will fail @@ -127,10 +129,13 @@ static int unpack_string(grib_accessor* a, char* v, size_t* len) /* if (err) return err; */ (void)err; - if ((val == GRIB_MISSING_LONG) && ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0)) + if ((val == GRIB_MISSING_LONG) && ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0)) { snprintf(repres, sizeof(repres), "MISSING"); - else - snprintf(repres, sizeof(repres), "%ld", val); + } else { + size_t size = sizeof(format); + grib_get_string(h, "formatForLongs", format, &size); + snprintf(repres, sizeof(repres), format, val); + } l = strlen(repres) + 1; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ad9f7c408..172101ad9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -236,6 +236,7 @@ if( HAVE_BUILD_TOOLS ) grib_set_bytes grib_set_force bufr_ecc-556 + codes_ecc-1698 gts_get gts_ls gts_count diff --git a/tests/codes_ecc-1698.sh b/tests/codes_ecc-1698.sh new file mode 100755 index 000000000..d7e0d49ec --- /dev/null +++ b/tests/codes_ecc-1698.sh @@ -0,0 +1,45 @@ +#!/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 + +REDIRECT=/dev/null + +label="codes_ecc-1698_test" +tempGrib=temp.$label.grib +tempBufr=temp.$label.bufr +tempFilt=temp.$label.filt +tempLog=temp.$label.log +tempRef=temp.$label.ref + +sample_grib2=$ECCODES_SAMPLES_PATH/GRIB2.tmpl +sample_bufr4=$ECCODES_SAMPLES_PATH/BUFR4.tmpl + +# Double to string +# ------------------ +infile=$sample_grib2 +result=$(${tools_dir}/grib_get -p maximum:s $infile) +[ "$result" = "1" ] +result=$(${tools_dir}/grib_get -s formatForDoubles=%e -p maximum:s $infile) +[ "$result" = "1.000000e+00" ] + +infile=${data_dir}/sample.grib2 +result=$(${tools_dir}/grib_get -s formatForDoubles=%e -p minimum:s $infile) +[ "$result" = "2.704668e+02" ] + + +# Integer to string +# ------------------ +infile=${data_dir}/sample.grib2 +result=$(${tools_dir}/grib_get -s formatForLongs=%lX -p year:s $infile) +[ "$result" = "7D8" ] + + +rm -f $tempGrib $tempBufr $tempFilt $tempLog $tempRef