From a774089f1f0578edda28f43ebd44a6ac0aebacc7 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Thu, 22 Nov 2018 18:11:58 +0000 Subject: [PATCH] Improve the grib_check_gaussian_grid tool error reporting --- tests/check_gaussian_grids.sh | 16 ++++++ tools/grib_check_gaussian_grid.c | 94 +++++++++++++++++++++----------- 2 files changed, 77 insertions(+), 33 deletions(-) diff --git a/tests/check_gaussian_grids.sh b/tests/check_gaussian_grids.sh index 61b11c826..4f2c5b075 100755 --- a/tests/check_gaussian_grids.sh +++ b/tests/check_gaussian_grids.sh @@ -9,9 +9,25 @@ . ./include.sh +label="grib_check_gaussian_grids" +temp=temp.$label.grib + + # Check all sample GRIBs with a Gaussian grid samples_dir=$ECCODES_SAMPLES_PATH for gg in ${samples_dir}/reduced_gg_* ${samples_dir}/regular_gg_*; do ${tools_dir}/grib_check_gaussian_grid $gg >/dev/null grib_check_key_equals $gg "global" 1 done + +# Set wrong angle and re-test. Should fail +input=$samples_dir/reduced_gg_pl_1280_grib2.tmpl +${tools_dir}/grib_set -s longitudeOfLastGridPoint=359929680 $input $temp +set +e +${tools_dir}/grib_check_gaussian_grid -v $temp +status=$? +set -e +[ $status -eq 1 ] + + +rm -f $temp diff --git a/tools/grib_check_gaussian_grid.c b/tools/grib_check_gaussian_grid.c index d7d066788..d4f23e739 100644 --- a/tools/grib_check_gaussian_grid.c +++ b/tools/grib_check_gaussian_grid.c @@ -18,11 +18,13 @@ #include #include #include +#include #include "eccodes.h" #define STR_EQUAL(s1, s2) (strcmp((s1), (s2)) == 0) int exit_on_error = 1; /* By default exit if any check fails */ +int verbose = 0; /* By default quiet unless errors */ int error_count = 0; int DBL_EQUAL(double d1, double d2, double tolerance) @@ -32,22 +34,26 @@ int DBL_EQUAL(double d1, double d2, double tolerance) void usage(const char* prog) { - printf("Usage: %s [-f] grib_file grib_file ...\n\n",prog); + printf("Usage: %s [-f] [-v] grib_file grib_file ...\n\n",prog); printf("Check geometry of GRIB fields with a Gaussian Grid.\n"); printf("(The grid is assumed to be GLOBAL)\n\n"); printf("Options:\n"); - printf("-f Do not exit on first error\n"); + printf(" -f Do not exit on first error\n"); + printf(" -v Verbose\n"); printf("\n"); exit(1); } -/* Print an error message and die */ -void error(const char* fmt, ...) +/* Print an error message and optionally die */ +void error(const char* filename, int msg_num, const char* fmt, ...) { char buf[1024] = {0,}; va_list list; va_start(list,fmt); - sprintf(buf, " %s", fmt); /* indent a bit */ + if(verbose) + sprintf(buf, " Error: %s", fmt); /* indent a bit */ + else + sprintf(buf, "Error: %s #%d: %s", filename, msg_num, fmt); vfprintf(stderr, buf, list); va_end(list); @@ -65,17 +71,32 @@ double get_precision(long edition) return 0.0; } +static int is_regular_file(const char* path) +{ + struct stat s; + int stat_val = stat(path,&s); + if (stat_val != 0) return 0; /*error doing stat*/ + return S_ISREG( s.st_mode ); +} + int process_file(const char* filename) { int err = 0, msg_num = 0; codes_handle *h = NULL; - - FILE* in = fopen(filename, "r"); - if(!in) { - error("ERROR: unable to open input file %s\n",filename); + FILE* in = NULL; + + if (!is_regular_file(filename)) { + if(verbose) printf(" WARNING: '%s' not a regular file! Ignoring\n", filename); + return GRIB_IO_PROBLEM; } - printf("Checking file %s\n", filename); + in = fopen(filename, "r"); + if(!in) { + fprintf(stderr, "ERROR: unable to open input file %s\n",filename); + exit(1); + } + + if(verbose) printf("Checking file %s\n", filename); while ((h = codes_handle_new_from_file(0, in, PRODUCT_GRIB, &err)) != NULL ) { @@ -91,7 +112,7 @@ int process_file(const char* filename) if (err != CODES_SUCCESS) CODES_CHECK(err,0); ++msg_num; CODES_CHECK(codes_get_long(h,"edition",&edition),0); - printf(" Processing GRIB message #%d (edition=%ld)\n", msg_num, edition); + if(verbose) printf(" Processing GRIB message #%d (edition=%ld)\n", msg_num, edition); len = 32; CODES_CHECK(codes_get_string(h,"gridType",gridType,&len),0); @@ -100,7 +121,7 @@ int process_file(const char* filename) grid_ok = is_regular || is_reduced; if( !grid_ok ) { /*error("ERROR: gridType should be Reduced or Regular Gaussian Grid!\n");*/ - printf(" WARNING: gridType should be Reduced or Regular Gaussian Grid! Ignoring\n"); + if(verbose) printf(" WARNING: gridType should be Reduced or Regular Gaussian Grid! Ignoring\n"); codes_handle_delete(h); continue; } @@ -117,20 +138,20 @@ int process_file(const char* filename) angular_tolerance = get_precision(edition); if (N <= 0) { - error("ERROR: N should be > 0\n", N); + error(filename, msg_num, "N should be > 0\n", N); } if ( Nj != 2*N ) { - error("ERROR: Nj is %ld but should be 2*N (%ld)\n", Nj, 2*N); + error(filename, msg_num, "Nj is %ld but should be 2*N (%ld)\n", Nj, 2*N); } if (lon1 != 0) { - error("ERROR: latitudeOfFirstGridPointInDegrees=%f but should be 0\n", lon1); + error(filename, msg_num, "latitudeOfFirstGridPointInDegrees=%f but should be 0\n", lon1); } expected_lon2 = 360.0 - 360.0/(4*N); /* Check first and last latitudes */ if (lat1 != -lat2) { - error("ERROR: First latitude must be = last latitude but opposite in sign: lat1=%f, lat2=%f\n", + error(filename, msg_num, "First latitude must be = last latitude but opposite in sign: lat1=%f, lat2=%f\n", lat1, lat2); } /* Note: grib_get_gaussian_latitudes() assumes the 'lats' array has 2N elements! */ @@ -139,10 +160,10 @@ int process_file(const char* filename) CODES_CHECK(codes_get_gaussian_latitudes(N,lats), 0); if (!DBL_EQUAL(lats[0], lat1, angular_tolerance)) { - error("ERROR: latitudeOfFirstGridPointInDegrees=%f but should be %f\n", lat1, lats[0]); + error(filename, msg_num, "latitudeOfFirstGridPointInDegrees=%f but should be %f\n", lat1, lats[0]); } if (!DBL_EQUAL(lats[Nj-1], lat2, angular_tolerance)) { - error("ERROR: latitudeOfLastGridPointInDegrees=%f but should be %f\n", lat2, lats[Nj-1]); + error(filename, msg_num, "latitudeOfLastGridPointInDegrees=%f but should be %f\n", lat2, lats[Nj-1]); } if (is_reduced) { @@ -154,16 +175,16 @@ int process_file(const char* filename) is_missing_Di = codes_is_missing(h, "iDirectionIncrement", &err); assert(err == CODES_SUCCESS); if (!is_missing_Ni) { - error("ERROR: For a reduced gaussian grid Ni should be missing\n"); + error(filename, msg_num, "For a reduced gaussian grid Ni should be missing\n"); } if (!is_missing_Di) { - error("ERROR: For a reduced gaussian grid iDirectionIncrement should be missing\n"); + error(filename, msg_num, "For a reduced gaussian grid iDirectionIncrement should be missing\n"); } CODES_CHECK(codes_get_size(h, "pl", &pl_len),0); assert(pl_len>0); if (pl_len != 2*N) { - error("ERROR: Length of pl array is %ld but should be 2*N (%ld)\n", pl_len, 2*N); + error(filename, msg_num, "Length of pl array is %ld but should be 2*N (%ld)\n", pl_len, 2*N); } pl = (long*)malloc(pl_len*sizeof(long)); assert(pl); @@ -175,8 +196,8 @@ int process_file(const char* filename) const long pl_start = pl[i]; const long pl_end = pl[pl_len-1-i]; if ( pl_start != pl_end ) { - error("ERROR: pl array is not symmetric: pl[%ld]=%ld, pl[%ld]=%ld\n", - i, pl_start, pl_len-1-i, pl_end); + error(filename, msg_num, "pl array is not symmetric: pl[%ld]=%ld, pl[%ld]=%ld\n", + i, pl_start, pl_len-1-i, pl_end); } } @@ -186,23 +207,23 @@ int process_file(const char* filename) if (pl[i] > max_pl) max_pl = pl[i]; } if (pl_sum != numberOfDataPoints) { - error("ERROR: Sum of pl array %ld does not match numberOfDataPoints %ld\n", pl_sum, numberOfDataPoints); + error(filename, msg_num, "Sum of pl array %ld does not match numberOfDataPoints %ld\n", pl_sum, numberOfDataPoints); } CODES_CHECK(codes_get_long(h,"isOctahedral",&is_octahedral),0); if (is_octahedral) { - printf(" This is an Octahedral Gaussian grid\n"); + if(verbose) printf(" This is an Octahedral Gaussian grid\n"); expected_lon2 = 360.0 - 360.0/max_pl; } free(pl); } if (fabs(lon2 - expected_lon2) > angular_tolerance) { - error("ERROR: longitudeOfLastGridPointInDegrees=%f but should be %f\n", lon2, expected_lon2); + error(filename, msg_num, "longitudeOfLastGridPointInDegrees=%f but should be %f\n", lon2, expected_lon2); } CODES_CHECK(codes_get_size(h, "values", &sizeOfValuesArray),0); if (sizeOfValuesArray != numberOfDataPoints) { - error("ERROR: Number of data points %d different from size of values array %d\n", + error(filename, msg_num, "Number of data points %d different from size of values array %d\n", numberOfDataPoints, sizeOfValuesArray); } @@ -210,8 +231,8 @@ int process_file(const char* filename) codes_handle_delete(h); } fclose(in); - printf("\n"); - return 0; + if(verbose) printf("\n"); + return GRIB_SUCCESS; } int main(int argc, char** argv) @@ -233,20 +254,27 @@ int main(int argc, char** argv) usage(argv[0]); return 1; } - /* Process switches */ exit_on_error = 0; } + else if (STR_EQUAL(arg, "-v")) + { + if (argc < 3) { + usage(argv[0]); + return 1; + } + verbose = 1; + } else { - /* We have a grib file */ + /* We have a GRIB file */ process_file(arg); } } - printf("###############\n"); + if(verbose) printf("###############\n"); if (error_count == 0) { - printf("ALL OK\n"); + if(verbose) printf("ALL OK\n"); } else {