From ffda07db1afb9ad728829143ad9dbd5ff97553b4 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Fri, 27 Oct 2023 13:31:13 +0100 Subject: [PATCH 01/11] Add abs functor (integer absolute value function) --- src/grib_expression_class_functor.cc | 22 +++++++++++++++------- tests/grib_filter.sh | 8 ++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/grib_expression_class_functor.cc b/src/grib_expression_class_functor.cc index c7ffc072e..89c4d8a6a 100644 --- a/src/grib_expression_class_functor.cc +++ b/src/grib_expression_class_functor.cc @@ -86,16 +86,24 @@ static int evaluate_long(grib_expression* g, grib_handle* h, long* lres) { grib_expression_functor* e = (grib_expression_functor*)g; - if (strcmp(e->name, "lookup") == 0) { + if (STR_EQUAL(e->name, "lookup")) { return GRIB_SUCCESS; } - if (strcmp(e->name, "new") == 0) { + if (STR_EQUAL(e->name, "new")) { *lres = h->loader != NULL; return GRIB_SUCCESS; } - if (strcmp(e->name, "missing") == 0) { + if (STR_EQUAL(e->name, "abs")) { + grib_expression* exp = grib_arguments_get_expression(h, e->args, 0); + long lval = 0; + int ret = grib_expression_evaluate_long(h, exp, &lval); + *lres = abs(lval); + return ret; + } + + if (STR_EQUAL(e->name, "missing")) { const char* p = grib_arguments_get_name(h, e->args, 0); if (p) { long val = 0; @@ -122,7 +130,7 @@ static int evaluate_long(grib_expression* g, grib_handle* h, long* lres) return GRIB_SUCCESS; } - if (strcmp(e->name, "defined") == 0) { + if (STR_EQUAL(e->name, "defined")) { const char* p = grib_arguments_get_name(h, e->args, 0); if (p) { @@ -134,7 +142,7 @@ static int evaluate_long(grib_expression* g, grib_handle* h, long* lres) return GRIB_SUCCESS; } - if (strcmp(e->name, "environment_variable") == 0) { + if (STR_EQUAL(e->name, "environment_variable")) { // ECC-1520: This implementation has some limitations: // 1. Cannot distinguish between environment variable NOT SET // and SET but equal to 0 @@ -154,12 +162,12 @@ static int evaluate_long(grib_expression* g, grib_handle* h, long* lres) return GRIB_SUCCESS; } - if (strcmp(e->name, "changed") == 0) { + if (STR_EQUAL(e->name, "changed")) { *lres = 1; return GRIB_SUCCESS; } - if (strcmp(e->name, "gribex_mode_on") == 0) { + if (STR_EQUAL(e->name, "gribex_mode_on")) { *lres = h->context->gribex_mode_on ? 1 : 0; return GRIB_SUCCESS; } diff --git a/tests/grib_filter.sh b/tests/grib_filter.sh index 22a0158ac..c114c5e4e 100755 --- a/tests/grib_filter.sh +++ b/tests/grib_filter.sh @@ -398,6 +398,14 @@ grep "unable to get rubbish as string" $tempOut grep "unable to get garbage as string" $tempOut +# Use of "abs" +cat >$tempFilt < Date: Fri, 27 Oct 2023 17:58:34 +0100 Subject: [PATCH 02/11] Cleanup --- src/grib_accessor_class_data_g22order_packing.cc | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/grib_accessor_class_data_g22order_packing.cc b/src/grib_accessor_class_data_g22order_packing.cc index af462d667..f45d9f722 100644 --- a/src/grib_accessor_class_data_g22order_packing.cc +++ b/src/grib_accessor_class_data_g22order_packing.cc @@ -267,11 +267,9 @@ static void add_bitstream(bitstream_context *ctx, grib_accessor* a, int t, int n return; } -/* - * find min/max of an integer array - * return 0: if min max found - * return 1: if min max not found, min = max = 0 - */ +// find min/max of an integer array +// return 0: if min max found +// return 1: if min max not found, min = max = 0 static int int_min_max_array(int* data, unsigned int n, int* min, int* max) { unsigned int first; @@ -1325,8 +1323,8 @@ static int pack_double(grib_accessor* a, const double* val, size_t* len) grib_context_log(a->context, GRIB_LOG_ERROR, "%s packing: failed to get min max of data", cclass_name); return GRIB_ENCODING_ERROR; } - min_val = static_cast(mn); - max_val = static_cast(mx); + min_val = mn; + max_val = mx; binary_scale = bin_scale; From a2628b6dac53727b5663f8093472e1588c93c7ed Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Fri, 27 Oct 2023 17:58:48 +0100 Subject: [PATCH 03/11] Testing: metar group keys --- tests/metar_get.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/metar_get.sh b/tests/metar_get.sh index 181461526..25613ce04 100755 --- a/tests/metar_get.sh +++ b/tests/metar_get.sh @@ -35,4 +35,9 @@ export METAR_MONTH=4 ${tools_dir}/metar_get -n ls $metar_file >/dev/null ${tools_dir}/metar_get -w count=1/2/3 -p CCCC,latitude,longitude,dateTime,elevation,temperature,dewPointTemperature,qnh $metar_file +# Decode a 'group' key as int and double +result=$( ${tools_dir}/metar_get -p visibilityInMetres:i,visibilityInMetres:d -w count=1 $metar_file ) +[ "$result" = "6000 6000" ] + +# Clean up rm -f $fLog From 51f6dcf5690a3809f6dd542663d885838598cb8d Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Mon, 30 Oct 2023 14:45:15 +0000 Subject: [PATCH 04/11] ECC-1709: GRIB2: Rename indicatorOfUnitOfTimeRange to indicatorOfUnitForForecastTime --- definitions/grib2/template.4.20.def | 8 +++----- definitions/grib2/template.4.forecast_time.def | 4 +++- definitions/grib2/template.4.forecast_time_44.def | 4 +++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/definitions/grib2/template.4.20.def b/definitions/grib2/template.4.20.def index 9ba5668eb..83db46bc5 100644 --- a/definitions/grib2/template.4.20.def +++ b/definitions/grib2/template.4.20.def @@ -1,7 +1,6 @@ # (C) Copyright 2005- ECMWF. # TEMPLATE 4.20, Radar product -# Parameter category codetable[1] parameterCategory ('4.1.[discipline:l].table',masterDir,localDir) : dump; # Parameter number @@ -9,22 +8,21 @@ codetable[1] parameterNumber ('4.2.[discipline:l].[parameterCategory:l].table',m meta parameterUnits codetable_units(parameterNumber) : dump; meta parameterName codetable_title(parameterNumber) : dump; -# Type of generating process codetable[1] typeOfGeneratingProcess ('4.3.table',masterDir,localDir) : dump; # Number of radar sites used unsigned[1] numberOfRadarSitesUsed : dump; -# Indicator of unit of time range codetable[1] indicatorOfUnitOfTimeRange ('4.4.table',masterDir,localDir) : dump; +alias indicatorOfUnitForForecastTime = indicatorOfUnitOfTimeRange; alias defaultStepUnits = one; # 1 means Hour. See code table 4.4 template_nofail default_step_units "grib2/localConcepts/[centre:s]/default_step_units.def"; codetable[1] stepUnits 'stepUnits.table' = defaultStepUnits : transient,dump,no_copy; -# Site latitude (in 10-6 degree) +# Site latitude (in microdegrees) unsigned[4] siteLatitude : dump; -# Site longitude (in 10-6 degree) +# Site longitude (in microdegrees) unsigned[4] siteLongitude : dump; # Site elevation (meters) diff --git a/definitions/grib2/template.4.forecast_time.def b/definitions/grib2/template.4.forecast_time.def index 662310fc6..d4999d24f 100644 --- a/definitions/grib2/template.4.forecast_time.def +++ b/definitions/grib2/template.4.forecast_time.def @@ -8,8 +8,10 @@ alias hoursAfterReferenceTimeOfDataCutoff=hoursAfterDataCutoff; unsigned[1] minutesAfterDataCutoff = missing() : edition_specific,can_be_missing; alias minutesAfterReferenceTimeOfDataCutoff=minutesAfterDataCutoff; -# Indicator of unit of time range +# Indicator of unit for forecastTime (ECC-1709) codetable[1] indicatorOfUnitOfTimeRange ('4.4.table',masterDir,localDir) : dump; +alias indicatorOfUnitForForecastTime = indicatorOfUnitOfTimeRange; + alias defaultStepUnits = one; # 1 means Hour. See code table 4.4 template_nofail default_step_units "grib2/localConcepts/[centre:s]/default_step_units.def"; codetable[1] stepUnits 'stepUnits.table' = defaultStepUnits : transient,dump,no_copy; diff --git a/definitions/grib2/template.4.forecast_time_44.def b/definitions/grib2/template.4.forecast_time_44.def index 494921b35..0ad48c53b 100644 --- a/definitions/grib2/template.4.forecast_time_44.def +++ b/definitions/grib2/template.4.forecast_time_44.def @@ -10,8 +10,10 @@ alias hoursAfterReferenceTimeOfDataCutoff=hoursAfterDataCutoff; unsigned[1] minutesAfterDataCutoff = missing() : edition_specific,can_be_missing; alias minutesAfterReferenceTimeOfDataCutoff=minutesAfterDataCutoff; -# Indicator of unit of time range +# Indicator of unit for forecastTime (ECC-1709) codetable[1] indicatorOfUnitOfTimeRange ('4.4.table',masterDir,localDir) : dump; +alias indicatorOfUnitForForecastTime = indicatorOfUnitOfTimeRange; + alias defaultStepUnits = one; # 1 means Hour. See code table 4.4 template_nofail default_step_units "grib2/localConcepts/[centre:s]/default_step_units.def"; codetable[1] stepUnits 'stepUnits.table' = defaultStepUnits : transient,dump,no_copy; From f991bdbd60feb672f7552c8016df75d504dbc10f Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Mon, 30 Oct 2023 14:59:45 +0000 Subject: [PATCH 05/11] ECC-1709: Test --- tests/grib_lam_gp.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/grib_lam_gp.cc b/tests/grib_lam_gp.cc index 38b2178ed..29b94a96c 100644 --- a/tests/grib_lam_gp.cc +++ b/tests/grib_lam_gp.cc @@ -908,7 +908,7 @@ int main(int argc, char* argv[]) GRIB_CHECK(grib_set_long(h, "minute", 0), 0); GRIB_CHECK(grib_set_long(h, "second", 0), 0); len = strlen("s"); - GRIB_CHECK(grib_set_string(h, "indicatorOfUnitOfTimeRange", "s", &len), 0); + GRIB_CHECK(grib_set_string(h, "indicatorOfUnitForForecastTime", "s", &len), 0); len = strlen("s"); GRIB_CHECK(grib_set_string(h, "stepUnits", "s", &len), 0); GRIB_CHECK(grib_set_long(h, "endStep", 3600), 0); From 5463da29a45017b6396b55966e9710ccd043b42f Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Mon, 30 Oct 2023 15:02:13 +0000 Subject: [PATCH 06/11] ECC-1709: Test --- tests/grib_step.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/grib_step.sh b/tests/grib_step.sh index 741da1867..ca101b3d5 100755 --- a/tests/grib_step.sh +++ b/tests/grib_step.sh @@ -101,7 +101,7 @@ ${tools_dir}/grib_set -s indicatorOfUnitOfTimeRange=m $grib1_sample $temp unit=`${tools_dir}/grib_get -p unitOfTimeRange $temp` [ "$unit" = "0" ] ${tools_dir}/grib_set -s indicatorOfUnitOfTimeRange=m $grib2_sample $temp -unit=`${tools_dir}/grib_get -p indicatorOfUnitOfTimeRange $temp` +unit=`${tools_dir}/grib_get -p indicatorOfUnitForForecastTime $temp` [ "$unit" = "0" ] # ECC-457 From 6e4caaa0b1f3434a9d77a7a2567243f58351d452 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Mon, 30 Oct 2023 16:35:13 +0000 Subject: [PATCH 07/11] Testing: invalid grid input --- tests/grib_copy_message.cc | 2 ++ tests/grib_to_netcdf.sh | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/tests/grib_copy_message.cc b/tests/grib_copy_message.cc index 0fd6bb021..b3ea95cdc 100644 --- a/tests/grib_copy_message.cc +++ b/tests/grib_copy_message.cc @@ -23,6 +23,8 @@ int main(int argc, char* argv[]) assert (argc == 3); + printf("%ld\n", codes_get_api_version()); + in = fopen(argv[1], "rb"); assert(in); diff --git a/tests/grib_to_netcdf.sh b/tests/grib_to_netcdf.sh index e83f9a620..c07dc89e9 100755 --- a/tests/grib_to_netcdf.sh +++ b/tests/grib_to_netcdf.sh @@ -148,6 +148,16 @@ set -e [ $status -ne 0 ] grep -q "Wrong number of fields" $tempText +# Not regular grid +input=${data_dir}/reduced_gaussian_pressure_level.grib2 +set +e +${tools_dir}/grib_to_netcdf -o $tempNetcdf $input > $tempText 2>&1 +status=$? +set -e +[ $status -ne 0 ] +grep -q "not on a regular lat/lon grid or on a regular Gaussian grid" $tempText + + export GRIB_TO_NETCDF_CHECKVALIDTIME=0 ${tools_dir}/grib_to_netcdf -o $tempNetcdf $tempGrib [ -f "$tempNetcdf" ] From 575c7d7316b49b74847ad189755e0ed25f823857 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Mon, 30 Oct 2023 16:35:53 +0000 Subject: [PATCH 08/11] Tools: More readable string compare function --- tools/grib_to_netcdf.cc | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/tools/grib_to_netcdf.cc b/tools/grib_to_netcdf.cc index fec300970..e62b69a7d 100644 --- a/tools/grib_to_netcdf.cc +++ b/tools/grib_to_netcdf.cc @@ -1317,8 +1317,9 @@ static int axisindex(const char* name) { size_t i = 0; for (i = 0; i < NUMBER(global_axis); i++) { - if (strcmp(name, global_axis[i].name) == 0) - return i; + if (STR_EQUAL(name, global_axis[i].name)){ + return (int)i; + } } return -1; } @@ -1335,7 +1336,7 @@ static namecmp comparator(const char* name) } if (dontcompare != NULL) { - if (strcmp(dontcompare, name) == 0) + if (STR_EQUAL(dontcompare, name)) return eq_null; } @@ -1434,7 +1435,7 @@ static void unset_value(request* r, const char* parname) p = r->params; while (p) { - if (strcmp(parname, p->name) == 0) { + if (STR_EQUAL(parname, p->name)) { if (q) q->next = p->next; else @@ -1624,7 +1625,7 @@ static void cube_indexes( int k = 0; int count = count_values(cube, axis); int last = h->index_cache[i]; - const bool is_time_axis = (strcmp(axis, "time") == 0); + const bool is_time_axis = (STR_EQUAL(axis, "time")); if (is_time_axis) { Assert(times_array); Assert(times_array_size == count); @@ -1956,9 +1957,9 @@ static long monthnumber(const char* m) static int check_stepUnits(const char* step_units_str) { /* Only hours, minutes and seconds supported */ - if (strcmp(step_units_str, "h") == 0 || - strcmp(step_units_str, "m") == 0 || - strcmp(step_units_str, "s") == 0) { + if (STR_EQUAL(step_units_str, "h") || + STR_EQUAL(step_units_str, "m") || + STR_EQUAL(step_units_str, "s")) { return GRIB_SUCCESS; } return GRIB_WRONG_STEP_UNIT; @@ -2051,10 +2052,10 @@ static void validation_time(request* r) grib_context_log(ctx, GRIB_LOG_ERROR, "Cannot convert stepUnits of '%s'. Only hours, minutes and seconds supported.", step_units); } - if (strcmp("m", step_units) == 0) { + if (STR_EQUAL("m", step_units)) { step /= 60; } - else if (strcmp("s", step_units) == 0) { + else if (STR_EQUAL("s", step_units)) { step /= 3600; } } @@ -2121,19 +2122,19 @@ static nc_type translate_nctype(const char* name) if (!name) return NC_SHORT; - if (strcmp(name, "NC_BYTE") == 0) + if (STR_EQUAL(name, "NC_BYTE")) return NC_BYTE; - if (strcmp(name, "NC_SHORT") == 0) + if (STR_EQUAL(name, "NC_SHORT")) return NC_SHORT; - if (strcmp(name, "NC_INT") == 0) + if (STR_EQUAL(name, "NC_INT")) return NC_INT; - if (strcmp(name, "NC_FLOAT") == 0) + if (STR_EQUAL(name, "NC_FLOAT")) return NC_FLOAT; - if (strcmp(name, "NC_DOUBLE") == 0) + if (STR_EQUAL(name, "NC_DOUBLE")) return NC_DOUBLE; grib_context_log(ctx, GRIB_LOG_ERROR, "Unknown netCDF type '%s'. Using NC_SHORT", name); @@ -2163,7 +2164,7 @@ static int set_dimension(int ncid, const char* name, int n, int xtype, const cha int dim_id = DIM_ID; int dim_vec[DIM_ID]; - if (setup.unlimited && (strcmp(name, setup.unlimited) == 0)) + if ( setup.unlimited && (STR_EQUAL(name, setup.unlimited)) ) n = NC_UNLIMITED; stat = nc_def_dim(ncid, name, n, &dim_id); @@ -2197,7 +2198,7 @@ static int check_grid(field* f) return e; } - if (strcmp(grid_type, "regular_ll") != 0 && (strcmp(grid_type, "regular_gg") != 0)) { + if ( !STR_EQUAL(grid_type, "regular_ll") && !STR_EQUAL(grid_type, "regular_gg") ) { grib_context_log(ctx, GRIB_LOG_ERROR, "Grid type = %s", grid_type); grib_context_log(ctx, GRIB_LOG_ERROR, "First GRIB is not on a regular lat/lon grid or on a regular Gaussian grid. Exiting.\n"); return GRIB_GEOCALCULUS_PROBLEM; From 6ed70d7c3999b199f72c57799b40310721c86f49 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Wed, 1 Nov 2023 11:49:39 +0000 Subject: [PATCH 09/11] Provide get_native_type (See SUP-3871) --- src/grib_accessor_class_when.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/grib_accessor_class_when.cc b/src/grib_accessor_class_when.cc index 6717c2c4a..1bf0d999e 100644 --- a/src/grib_accessor_class_when.cc +++ b/src/grib_accessor_class_when.cc @@ -8,11 +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 @@ -21,6 +16,7 @@ CLASS = accessor SUPER = grib_accessor_class_gen IMPLEMENTS = init;dump; + IMPLEMENTS = get_native_type IMPLEMENTS = notify_change END_CLASS_DEF @@ -36,6 +32,7 @@ or edit "accessor.class" and rerun ./make_class.pl */ +static int get_native_type(grib_accessor*); static void dump(grib_accessor*, grib_dumper*); static void init(grib_accessor*, const long, grib_arguments*); static int notify_change(grib_accessor*, grib_accessor*); @@ -64,7 +61,7 @@ static grib_accessor_class _grib_accessor_class_when = { 0, /* get number of values */ 0, /* get number of bytes */ 0, /* get offset to bytes */ - 0, /* get native type */ + &get_native_type, /* get native type */ 0, /* get sub_section */ 0, /* pack_missing */ 0, /* is_missing */ @@ -109,7 +106,6 @@ static void init(grib_accessor* a, const long len, grib_arguments* arg) a->flags |= GRIB_ACCESSOR_FLAG_READ_ONLY; } - static void dump(grib_accessor* a, grib_dumper* dumper) { /* grib_dump_when(dumper,a,NULL); */ @@ -119,3 +115,8 @@ static int notify_change(grib_accessor* a, grib_accessor* changed) { return grib_action_notify_change(a->creator, a, changed); } + +static int get_native_type(grib_accessor* a) +{ + return GRIB_TYPE_UNDEFINED; +} From e2470a8c60653442b5fc78890f02e437d1391fc4 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Wed, 1 Nov 2023 15:46:57 +0000 Subject: [PATCH 10/11] ECC-1710: GRIB2: Replace 'highres' with 'high' in DestinE resolution table --- definitions/grib2/destine_resolution.table | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/definitions/grib2/destine_resolution.table b/definitions/grib2/destine_resolution.table index 48d816018..1df78ebbc 100644 --- a/definitions/grib2/destine_resolution.table +++ b/definitions/grib2/destine_resolution.table @@ -1,4 +1,4 @@ 0 unknown unknown 1 standard Standard resolution model output with longer availability -2 highres High resolution model output with limited availability -65535 65535 Missing \ No newline at end of file +2 high High resolution model output with limited availability +65535 65535 Missing From 082b721c4fd712f12bf9b72697fac49fb3abc25c Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Thu, 2 Nov 2023 19:52:42 +0000 Subject: [PATCH 11/11] Tools: Add -h option --- tools/bufr_compare.cc | 3 ++- tools/bufr_copy.cc | 3 ++- tools/bufr_dump.cc | 3 ++- tools/bufr_filter.cc | 3 ++- tools/bufr_get.cc | 3 ++- tools/bufr_index_build.cc | 3 ++- tools/bufr_ls.cc | 3 ++- tools/bufr_set.cc | 3 ++- tools/grib_compare.cc | 3 ++- tools/grib_copy.cc | 3 ++- tools/grib_dump.cc | 3 ++- tools/grib_filter.cc | 3 ++- tools/grib_get.cc | 3 ++- tools/grib_get_data.cc | 3 ++- tools/grib_histogram.cc | 3 ++- tools/grib_index_build.cc | 3 ++- tools/grib_ls.cc | 3 ++- tools/grib_merge.cc | 3 ++- tools/grib_options.cc | 8 ++++++-- tools/grib_set.cc | 3 ++- tools/grib_to_netcdf.cc | 3 ++- 21 files changed, 46 insertions(+), 22 deletions(-) diff --git a/tools/bufr_compare.cc b/tools/bufr_compare.cc index 94da7ba2a..268d7ac8e 100644 --- a/tools/bufr_compare.cc +++ b/tools/bufr_compare.cc @@ -34,7 +34,8 @@ grib_option grib_options[] = { { "I", 0, 0, 1, 0, 0 }, { "V", 0, 0, 0, 1, 0 }, { "7", 0, 0, 0, 1, 0 }, - { "v", 0, 0, 0, 1, 0 } + { "v", 0, 0, 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; int grib_options_count = sizeof(grib_options) / sizeof(grib_option); diff --git a/tools/bufr_copy.cc b/tools/bufr_copy.cc index af1bc712c..c4c8cbf8d 100644 --- a/tools/bufr_copy.cc +++ b/tools/bufr_copy.cc @@ -44,7 +44,8 @@ grib_option grib_options[] = { { "g", 0, 0, 0, 1, 0 }, { "7", 0, 0, 0, 1, 0 }, { "X:", 0, 0, 0, 1, 0 }, - { "v", 0, 0, 0, 1, 0 } + { "v", 0, 0, 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; int grib_options_count = sizeof(grib_options) / sizeof(grib_option); diff --git a/tools/bufr_dump.cc b/tools/bufr_dump.cc index 60265b085..ed5fe88b8 100644 --- a/tools/bufr_dump.cc +++ b/tools/bufr_dump.cc @@ -53,7 +53,8 @@ grib_option grib_options[] = { { "V", 0, 0, 0, 1, 0 }, { "q", 0, 0, 1, 0, 0 }, { "S:", "subset_number", "\n\t\tDump the given subset\n", 0, 1, 0 }, - { "X:", 0, 0, 0, 1, 0 } + { "X:", 0, 0, 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, /* {"x",0,0,0,1,0} */ }; diff --git a/tools/bufr_filter.cc b/tools/bufr_filter.cc index bee0fe2da..fbabc7a76 100644 --- a/tools/bufr_filter.cc +++ b/tools/bufr_filter.cc @@ -23,7 +23,8 @@ grib_option grib_options[] = { /* {"G",0,0,0,1,0}, */ { "T:", 0, 0, 1, 0, "B" }, { "7", 0, 0, 0, 1, 0 }, - { "v", 0, 0, 0, 1, 0 } + { "v", 0, 0, 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; const char* tool_description = "Apply the rules defined in rules_file to each BUFR " diff --git a/tools/bufr_get.cc b/tools/bufr_get.cc index 57664a7ce..ba76afca7 100644 --- a/tools/bufr_get.cc +++ b/tools/bufr_get.cc @@ -27,7 +27,8 @@ grib_option grib_options[] = { /* {"G",0,0,0,1,0}, */ { "T:", 0, 0, 1, 0, "B" }, { "7", 0, 0, 0, 1, 0 }, - { "v", 0, 0, 1, 0, 0 } + { "v", 0, 0, 1, 0, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; const char* tool_description = diff --git a/tools/bufr_index_build.cc b/tools/bufr_index_build.cc index 12dcf7bf5..ac29bd6b7 100644 --- a/tools/bufr_index_build.cc +++ b/tools/bufr_index_build.cc @@ -34,7 +34,8 @@ grib_option grib_options[] = { { "N", 0, "Do not compress index." "\n\t\tBy default the index is compressed to remove keys with only one value.\n", - 0, 1, 0 } + 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; static int compress_index; diff --git a/tools/bufr_ls.cc b/tools/bufr_ls.cc index f86319e22..4537cc666 100644 --- a/tools/bufr_ls.cc +++ b/tools/bufr_ls.cc @@ -30,7 +30,8 @@ grib_option grib_options[] = { { "P", 0, 0, 1, 0, 0 }, { "T:", 0, 0, 1, 0, "B" }, { "7", 0, 0, 0, 1, 0 }, - { "v", 0, 0, 1, 0, 0 } + { "v", 0, 0, 1, 0, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; const char* tool_description = diff --git a/tools/bufr_set.cc b/tools/bufr_set.cc index 38c41dd1b..40c51547b 100644 --- a/tools/bufr_set.cc +++ b/tools/bufr_set.cc @@ -35,7 +35,8 @@ grib_option grib_options[] = { /* {"G",0,0,0,1,0}, */ { "T:", 0, 0, 1, 0, "B" }, { "f", 0, 0, 0, 1, 0 }, - { "v", 0, 0, 0, 1, 0 } + { "v", 0, 0, 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; const char* tool_description = diff --git a/tools/grib_compare.cc b/tools/grib_compare.cc index 800c3eca6..a538f2a8c 100644 --- a/tools/grib_compare.cc +++ b/tools/grib_compare.cc @@ -34,7 +34,8 @@ grib_option grib_options[] = { { "I", 0, 0, 1, 0, 0 }, { "V", 0, 0, 0, 1, 0 }, { "7", 0, 0, 0, 1, 0 }, - { "v", 0, 0, 0, 1, 0 } + { "v", 0, 0, 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; int grib_options_count = sizeof(grib_options) / sizeof(grib_option); diff --git a/tools/grib_copy.cc b/tools/grib_copy.cc index ccc4c690a..349a32259 100644 --- a/tools/grib_copy.cc +++ b/tools/grib_copy.cc @@ -48,7 +48,8 @@ grib_option grib_options[] = { { "G", 0, 0, 0, 1, 0 }, { "7", 0, 0, 0, 1, 0 }, { "X:", 0, 0, 0, 1, 0 }, - { "v", 0, 0, 0, 1, 0 } + { "v", 0, 0, 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; int grib_options_count = sizeof(grib_options) / sizeof(grib_option); diff --git a/tools/grib_dump.cc b/tools/grib_dump.cc index f61c6597e..c7e0c02d9 100644 --- a/tools/grib_dump.cc +++ b/tools/grib_dump.cc @@ -31,7 +31,8 @@ grib_option grib_options[] = { { "p:", "key1,key2,...", "\n\t\tDeclaration of keys to dump. Only those keys are dumped (not the whole message).\n", 0, 1, 0 }, { "X:", 0, 0, 0, 1, 0 }, - { "x", 0, 0, 0, 1, 0 } + { "x", 0, 0, 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; const char* tool_description = "Dump the content of a GRIB file in different formats."; diff --git a/tools/grib_filter.cc b/tools/grib_filter.cc index 8ed7ff296..019fc48c8 100644 --- a/tools/grib_filter.cc +++ b/tools/grib_filter.cc @@ -24,7 +24,8 @@ grib_option grib_options[] = { { "G", 0, 0, 0, 1, 0 }, { "T:", 0, 0, 0, 1, 0 }, { "7", 0, 0, 0, 1, 0 }, - { "v", 0, 0, 0, 1, 0 } + { "v", 0, 0, 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; const char* tool_description = "Apply the rules defined in rules_file to each GRIB " diff --git a/tools/grib_get.cc b/tools/grib_get.cc index 12acb78da..6251c436f 100644 --- a/tools/grib_get.cc +++ b/tools/grib_get.cc @@ -32,7 +32,8 @@ grib_option grib_options[] = { { "7", 0, 0, 0, 1, 0 }, { "v", 0, 0, 1, 0, 0 }, { "X:", 0, 0, 0, 1, 0 }, - { "i:", 0, 0, 0, 1, 0 } + { "i:", 0, 0, 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; const char* tool_description = diff --git a/tools/grib_get_data.cc b/tools/grib_get_data.cc index 83b87421d..54185ac61 100644 --- a/tools/grib_get_data.cc +++ b/tools/grib_get_data.cc @@ -31,7 +31,8 @@ grib_option grib_options[] = { { "G", 0, 0, 0, 1, 0 }, { "7", 0, 0, 0, 1, 0 }, { "X:", 0, 0, 0, 1, 0 }, - { "V", 0, 0, 0, 1, 0 } + { "V", 0, 0, 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; const char* tool_description = diff --git a/tools/grib_histogram.cc b/tools/grib_histogram.cc index a41105c74..789cdcc26 100644 --- a/tools/grib_histogram.cc +++ b/tools/grib_histogram.cc @@ -15,7 +15,8 @@ grib_option grib_options[] = { { "V", 0, 0, 0, 1, 0 }, { "p:", 0, 0, 0, 1, 0 }, /* print keys */ { "S", 0, 0, 1, 0, 0 }, /* needed for skip */ - { "w:", 0, 0, 0, 1, 0 } /* 'where' clause */ + { "w:", 0, 0, 0, 1, 0 }, /* 'where' clause */ + { "h", 0, 0, 0, 1, 0 }, }; int grib_options_count = sizeof(grib_options) / sizeof(grib_option); diff --git a/tools/grib_index_build.cc b/tools/grib_index_build.cc index 5d1d16915..6e933da2b 100644 --- a/tools/grib_index_build.cc +++ b/tools/grib_index_build.cc @@ -33,7 +33,8 @@ grib_option grib_options[] = { { "N", 0, "Do not compress index." "\n\t\tBy default the index is compressed to remove keys with only one value.\n", - 0, 1, 0 } + 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; static int compress_index; diff --git a/tools/grib_ls.cc b/tools/grib_ls.cc index 0193b3e17..2be9333e4 100644 --- a/tools/grib_ls.cc +++ b/tools/grib_ls.cc @@ -35,7 +35,8 @@ grib_option grib_options[] = { { "7", 0, 0, 0, 1, 0 }, { "v", 0, 0, 1, 0, 0 }, { "X:", 0, 0, 0, 1, 0 }, - { "x", 0, 0, 0, 1, 0 } + { "x", 0, 0, 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; const char* tool_description = diff --git a/tools/grib_merge.cc b/tools/grib_merge.cc index 8e18e54ea..7848935ff 100644 --- a/tools/grib_merge.cc +++ b/tools/grib_merge.cc @@ -56,7 +56,8 @@ grib_option grib_options[] = { { "g", 0, 0, 0, 1, 0 }, { "G", 0, 0, 0, 1, 0 }, { "7", 0, 0, 0, 1, 0 }, - { "v", 0, 0, 0, 1, 0 } + { "v", 0, 0, 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; int grib_options_count = sizeof(grib_options) / sizeof(grib_option); diff --git a/tools/grib_options.cc b/tools/grib_options.cc index 475f22fdf..3d792ca4e 100644 --- a/tools/grib_options.cc +++ b/tools/grib_options.cc @@ -106,8 +106,8 @@ static grib_options_help grib_options_help_list[] = { { "k:", "key1,key2,...", "\n\t\tSpecify a list of keys to index on. By default the input files are indexed on the MARS keys." "\n\t\tFor each key a string (key:s) or a double (key:d) or an integer (key:i)" - "\n\t\ttype can be requested.\n" } - + "\n\t\ttype can be requested.\n" }, + { "h", 0, "Display this help text and exit.\n" } }; static int grib_options_help_count = sizeof(grib_options_help_list) / sizeof(grib_options_help); @@ -198,6 +198,10 @@ int grib_process_runtime_options(grib_context* context, int argc, char** argv, g int has_input_extra = 0, nfiles = 0; char *karg = NULL, *warg = NULL, *sarg = NULL, *barg = NULL; + if (grib_options_on("h")) { + usage(); + } + if (grib_options_on("V")) { printf("\necCodes Version "); grib_print_api_version(stdout); diff --git a/tools/grib_set.cc b/tools/grib_set.cc index 13adcde65..537eb8a9f 100644 --- a/tools/grib_set.cc +++ b/tools/grib_set.cc @@ -39,7 +39,8 @@ grib_option grib_options[] = { { "G", 0, 0, 0, 1, 0 }, { "T:", 0, 0, 0, 1, 0 }, { "f", 0, 0, 0, 1, 0 }, - { "v", 0, 0, 0, 1, 0 } + { "v", 0, 0, 0, 1, 0 }, + { "h", 0, 0, 0, 1, 0 }, }; const char* tool_description = diff --git a/tools/grib_to_netcdf.cc b/tools/grib_to_netcdf.cc index e62b69a7d..b46145123 100644 --- a/tools/grib_to_netcdf.cc +++ b/tools/grib_to_netcdf.cc @@ -3936,7 +3936,8 @@ grib_option grib_options[] = { "\n\t\tChunking strategy based on GRIB message.\n", 0, 1, "6" }, { "s", 0, "Shuffle data before deflation compression.\n", 0, 1, 0 }, - { "u:", "dimension", "\n\t\tSet dimension to be an unlimited dimension.\n", 0, 1, "time" } + { "u:", "dimension", "\n\t\tSet dimension to be an unlimited dimension.\n", 0, 1, "time" }, + { "h", 0, 0, 0, 1, 0 }, }; int grib_options_count = sizeof(grib_options) / sizeof(grib_option);