2013-03-25 12:04:10 +00:00
|
|
|
/*
|
2019-04-15 13:44:45 +00:00
|
|
|
* Copyright 2005-2019 ECMWF.
|
2013-03-25 12:04:10 +00:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* C Implementation: grib_tools
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "grib_tools.h"
|
|
|
|
#if HAVE_LIBJASPER
|
2014-10-23 14:02:08 +00:00
|
|
|
/* Remove compiler warnings re macros being redefined */
|
|
|
|
#undef PACKAGE_BUGREPORT
|
|
|
|
#undef PACKAGE_NAME
|
|
|
|
#undef PACKAGE_STRING
|
|
|
|
#undef PACKAGE_TARNAME
|
|
|
|
#undef PACKAGE_VERSION
|
2013-03-25 12:04:10 +00:00
|
|
|
#endif
|
|
|
|
|
2015-04-24 17:04:12 +00:00
|
|
|
#ifdef ENABLE_FLOATING_POINT_EXCEPTIONS
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#include <fenv.h>
|
|
|
|
int feenableexcept(int excepts);
|
|
|
|
#endif
|
|
|
|
|
2013-03-25 12:04:10 +00:00
|
|
|
GRIB_INLINE static int grib_inline_strcmp(const char* a,const char* b) {
|
2013-06-14 10:38:40 +00:00
|
|
|
if (*a != *b) return 1;
|
|
|
|
while((*a!=0 && *b!=0) && *(a) == *(b) ) {a++;b++;}
|
|
|
|
return (*a==0 && *b==0) ? 0 : 1;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void grib_print_header(grib_runtime_options* options,grib_handle* h);
|
|
|
|
static void grib_tools_set_print_keys(grib_runtime_options* options,grib_handle* h,const char* ns);
|
|
|
|
static int grib_tool_with_orderby(grib_runtime_options* options);
|
|
|
|
static int grib_tool_without_orderby(grib_runtime_options* options);
|
|
|
|
static int grib_tool_onlyfiles(grib_runtime_options* options);
|
|
|
|
static int grib_tool_index(grib_runtime_options* options);
|
|
|
|
static int process(grib_context* c,grib_runtime_options* options,const char* path);
|
|
|
|
static int scan(grib_context* c,grib_runtime_options* options,const char* dir);
|
|
|
|
|
|
|
|
FILE* dump_file;
|
|
|
|
|
2019-08-12 15:00:15 +00:00
|
|
|
static grib_runtime_options global_options={
|
2016-09-16 15:23:03 +00:00
|
|
|
0, /* verbose */
|
|
|
|
0, /* fail */
|
|
|
|
0, /* skip */
|
|
|
|
12, /* default_print_width */
|
|
|
|
0, /* print_header */
|
|
|
|
0, /* name_space */
|
|
|
|
0, /* print_number */
|
|
|
|
1, /* print_statistics */
|
2013-03-25 12:04:10 +00:00
|
|
|
{{0,},}, /* grib_values requested_print_keys[MAX_KEYS] */
|
2016-09-16 15:23:03 +00:00
|
|
|
0, /* requested_print_keys_count */
|
|
|
|
{{0,},}, /* grib_values print_keys[MAX_KEYS] */
|
|
|
|
0, /* print_keys_count */
|
|
|
|
0, /* strict */
|
|
|
|
0, /* multi_support */
|
|
|
|
0, /* set_values_count */
|
|
|
|
{{0,},}, /* grib_values set_values[MAX_KEYS] */
|
|
|
|
{{0,},}, /* grib_values constraints[MAX_KEYS] */
|
|
|
|
0, /* constraints_count */
|
|
|
|
{{0,},}, /* grib_values compare[MAX_KEYS] */
|
|
|
|
0, /* compare_count */
|
|
|
|
0, /* handle_count */
|
|
|
|
0, /* filter_handle_count */
|
|
|
|
0, /* file_count */
|
|
|
|
0, /* grib_tools_file* infile_extra */
|
|
|
|
0, /* grib_tools_file* current_infile */
|
|
|
|
0, /* grib_tools_file* infile */
|
|
|
|
0, /* grib_tools_file* outfile */
|
|
|
|
0, /* grib_action* action */
|
|
|
|
0, /* grib_rule* rules */
|
|
|
|
0, /* int dump_flags; */
|
|
|
|
0, /* char* dump_mode; */
|
|
|
|
0, /* repack */
|
|
|
|
0, /* error */
|
|
|
|
0, /* gts */
|
|
|
|
0, /* orderby */
|
|
|
|
0, /* latlon */
|
|
|
|
{0,}, /* double lats[4] */
|
|
|
|
{0,}, /* double lons[4] */
|
|
|
|
{0,}, /* double values[4] */
|
|
|
|
{0,}, /* double distances[4] */
|
|
|
|
{0,}, /* int indexes[4] */
|
|
|
|
4, /* int latlon_mode */
|
|
|
|
0, /* char* latlon_mask */
|
|
|
|
-1, /* int latlon_idx */
|
|
|
|
{0,}, /* double mask_values[4] */
|
|
|
|
0, /* index */
|
|
|
|
0, /* index_on */
|
|
|
|
0, /* constant */
|
|
|
|
0, /* dump_filename*/
|
|
|
|
0, /* grib_fieldset* idx */
|
|
|
|
0, /* random */
|
2013-03-25 12:04:10 +00:00
|
|
|
0, /* format */
|
|
|
|
0, /* onlyfiles */
|
|
|
|
0, /* tolerance_count */
|
2016-09-16 15:23:03 +00:00
|
|
|
0, /* through_index */
|
2013-03-25 12:04:10 +00:00
|
|
|
0, /* index1 */
|
|
|
|
0, /* index2 */
|
|
|
|
0, /* context */
|
|
|
|
0, /* stop */
|
|
|
|
0, /* mode */
|
2013-03-25 14:23:07 +00:00
|
|
|
0, /* headers_only */
|
2013-03-25 12:04:10 +00:00
|
|
|
0, /* skip_all */
|
2013-06-17 16:53:16 +00:00
|
|
|
{{0,},}, /* grib_values tolerance[MAX_KEYS] */
|
2016-12-20 10:43:36 +00:00
|
|
|
0, /* infile_offset */
|
|
|
|
0 /* JSON output */
|
2016-09-16 15:23:03 +00:00
|
|
|
};
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-12-10 18:19:57 +00:00
|
|
|
static grib_handle* grib_handle_new_from_file_x(grib_context* c,FILE* f,int mode,int headers_only,int *err)
|
|
|
|
{
|
2017-05-31 16:21:18 +00:00
|
|
|
if (mode==MODE_GRIB)
|
|
|
|
return grib_new_from_file(c,f,headers_only,err);
|
|
|
|
|
|
|
|
if (mode==MODE_BUFR)
|
|
|
|
return bufr_new_from_file(c,f,err);
|
|
|
|
|
2014-12-16 18:21:56 +00:00
|
|
|
if (mode==MODE_ANY)
|
2015-01-29 10:36:16 +00:00
|
|
|
return any_new_from_file(c,f,err);
|
2014-12-16 18:21:56 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (mode==MODE_GTS)
|
2015-01-29 10:36:16 +00:00
|
|
|
return gts_new_from_file(c,f,err);
|
2013-03-25 14:23:07 +00:00
|
|
|
|
2016-05-20 15:08:27 +00:00
|
|
|
if (mode==MODE_METAR)
|
|
|
|
return metar_new_from_file(c,f,err);
|
2014-07-07 20:55:19 +00:00
|
|
|
|
2016-05-20 15:08:27 +00:00
|
|
|
if (mode==MODE_TAF)
|
|
|
|
return taf_new_from_file(c,f,err);
|
2014-07-07 20:55:19 +00:00
|
|
|
|
2015-02-11 18:58:34 +00:00
|
|
|
Assert(!"grib_handle_new_from_file_x: unknown mode");
|
2016-05-20 15:08:27 +00:00
|
|
|
return NULL;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int grib_tool(int argc, char **argv)
|
|
|
|
{
|
2013-06-14 10:38:40 +00:00
|
|
|
int ret=0;
|
|
|
|
grib_context* c=grib_context_get_default();
|
2016-04-13 13:50:27 +00:00
|
|
|
global_options.context=c;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2015-04-24 17:04:12 +00:00
|
|
|
#ifdef ENABLE_FLOATING_POINT_EXCEPTIONS
|
|
|
|
feenableexcept(FE_ALL_EXCEPT & ~FE_INEXACT);
|
|
|
|
#endif
|
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (getenv("DOXYGEN_USAGE") && argc==1 ) usage_doxygen();
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2016-04-13 13:50:27 +00:00
|
|
|
grib_get_runtime_options(argc,argv,&global_options);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2016-04-13 13:50:27 +00:00
|
|
|
grib_tool_before_getopt(&global_options);
|
2013-06-14 10:38:40 +00:00
|
|
|
|
2016-04-13 13:50:27 +00:00
|
|
|
grib_process_runtime_options(c,argc,argv,&global_options);
|
2013-06-14 10:38:40 +00:00
|
|
|
|
2016-04-13 13:50:27 +00:00
|
|
|
grib_tool_init(&global_options);
|
|
|
|
if (global_options.dump_filename) {
|
|
|
|
dump_file= fopen(global_options.dump_filename,"w");
|
2013-06-14 10:38:40 +00:00
|
|
|
if(!dump_file) {
|
2016-04-13 13:50:27 +00:00
|
|
|
perror(global_options.dump_filename);
|
2013-06-14 10:38:40 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
dump_file=stdout;
|
|
|
|
}
|
|
|
|
|
2019-05-14 16:53:27 +00:00
|
|
|
/* ECC-926: Currently only GRIB indexing works. Disable the through_index if BUFR, GTS etc */
|
|
|
|
if (global_options.mode == MODE_GRIB &&
|
|
|
|
is_index_file(global_options.infile->name) &&
|
2016-04-13 13:50:27 +00:00
|
|
|
( global_options.infile_extra && is_index_file(global_options.infile_extra->name))) {
|
|
|
|
global_options.through_index=1;
|
|
|
|
return grib_tool_index(&global_options);
|
2013-06-14 10:38:40 +00:00
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2016-04-13 13:50:27 +00:00
|
|
|
if (global_options.onlyfiles)
|
|
|
|
ret=grib_tool_onlyfiles(&global_options);
|
2013-06-14 10:38:40 +00:00
|
|
|
else {
|
2016-04-13 13:50:27 +00:00
|
|
|
if (global_options.orderby)
|
|
|
|
ret=grib_tool_with_orderby(&global_options);
|
2013-06-14 10:38:40 +00:00
|
|
|
else
|
2016-04-13 13:50:27 +00:00
|
|
|
ret=grib_tool_without_orderby(&global_options);
|
2013-06-14 10:38:40 +00:00
|
|
|
}
|
|
|
|
|
2016-04-13 13:50:27 +00:00
|
|
|
if (global_options.dump_filename) fclose(dump_file);
|
2013-06-14 10:38:40 +00:00
|
|
|
return ret;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-12-10 18:19:57 +00:00
|
|
|
static int grib_tool_with_orderby(grib_runtime_options* options)
|
|
|
|
{
|
2013-06-14 10:38:40 +00:00
|
|
|
int err=0;
|
|
|
|
grib_failed *failed=NULL,*p=NULL;
|
|
|
|
grib_handle* h=NULL;
|
2017-10-18 17:23:43 +00:00
|
|
|
grib_tools_file* infile=options->infile;
|
2013-06-14 10:38:40 +00:00
|
|
|
char** filenames;
|
2019-08-12 15:00:15 +00:00
|
|
|
int files_count=0;
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_fieldset* set=NULL;
|
|
|
|
int i=0;
|
2017-10-18 17:23:43 +00:00
|
|
|
grib_context* c=grib_context_get_default();
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if(infile) infile->failed=NULL;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
files_count=0;
|
|
|
|
while(infile) {files_count++;infile=infile->next;}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
filenames=(char**)grib_context_malloc_clear(c,files_count*sizeof(char*));
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
infile=options->infile;
|
|
|
|
for (i=0;i<files_count;i++) {filenames[i]=infile->name;infile=infile->next;}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (grib_options_on("7")) c->no_fail_on_wrong_length=1;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
set=grib_fieldset_new_from_files(0,filenames,files_count,0,0,0,options->orderby,&err);
|
|
|
|
if (err) {
|
2018-02-27 11:42:16 +00:00
|
|
|
grib_context_log(c,GRIB_LOG_ERROR,"unable to create index for input file %s (%s)",
|
2018-02-27 15:35:59 +00:00
|
|
|
filenames[0],grib_get_error_message(err));
|
2013-06-14 10:38:40 +00:00
|
|
|
exit(err);
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
options->handle_count=0;
|
2019-01-23 17:02:35 +00:00
|
|
|
grib_context_set_handle_file_count(c, 0); /* ECC-873 */
|
|
|
|
grib_context_set_handle_total_count(c, 0); /* ECC-873 */
|
2013-06-14 10:38:40 +00:00
|
|
|
while(!options->skip_all && ((h = grib_fieldset_next_handle(set,&err))
|
|
|
|
!= NULL || err != GRIB_SUCCESS )) {
|
|
|
|
options->handle_count++;
|
2019-01-23 17:02:35 +00:00
|
|
|
grib_context_set_handle_file_count(c, options->handle_count);/* ECC-873 */
|
|
|
|
grib_context_set_handle_total_count(c, options->handle_count);/* ECC-873 */
|
2013-06-14 10:38:40 +00:00
|
|
|
options->error=err;
|
|
|
|
|
|
|
|
if (!h) {
|
2016-08-30 12:45:02 +00:00
|
|
|
grib_no_handle_action(options, err);
|
2013-06-14 10:38:40 +00:00
|
|
|
|
|
|
|
failed=(grib_failed*)grib_context_malloc_clear(c,sizeof(grib_failed));
|
|
|
|
failed->count=infile->handle_count;
|
|
|
|
failed->error=err;
|
|
|
|
failed->next=NULL;
|
|
|
|
|
|
|
|
if (!infile->failed) {
|
|
|
|
infile->failed=failed;
|
|
|
|
} else {
|
|
|
|
p=infile->failed;
|
|
|
|
while (p->next) p=p->next;
|
|
|
|
p->next=failed;
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
continue;
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_print_header(options,h);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_skip_check(options,h);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (options->skip && options->strict) {
|
|
|
|
grib_tool_skip_handle(options,h);
|
|
|
|
continue;
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_tool_new_handle_action(options,h);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_tool_print_key_values(options,h);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_handle_delete(h);
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_tool_finalise_action(options);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
return 0;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2019-08-12 15:00:15 +00:00
|
|
|
static char iobuf[1024*1024];
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-12-10 18:19:57 +00:00
|
|
|
static int grib_tool_without_orderby(grib_runtime_options* options)
|
|
|
|
{
|
2013-06-14 10:38:40 +00:00
|
|
|
int err=0;
|
2016-01-19 14:46:17 +00:00
|
|
|
/*int nofail=0;*/
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_failed *failed=NULL,*p=NULL;
|
|
|
|
grib_handle* h=NULL;
|
2017-10-18 17:23:43 +00:00
|
|
|
grib_tools_file* infile=options->infile;
|
2013-06-14 10:38:40 +00:00
|
|
|
|
2017-10-18 17:23:43 +00:00
|
|
|
grib_context* c=grib_context_get_default();
|
2013-06-14 10:38:40 +00:00
|
|
|
options->file_count=0;
|
|
|
|
options->handle_count=0;
|
|
|
|
options->filter_handle_count=0;
|
|
|
|
options->current_infile=options->infile;
|
2013-03-25 12:04:10 +00:00
|
|
|
infile->failed=NULL;
|
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (grib_options_on("7")) c->no_fail_on_wrong_length=1;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
while (infile!=NULL && infile->name!=NULL) {
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2019-02-15 16:20:44 +00:00
|
|
|
if (options->print_statistics && options->verbose && !options->json_output) fprintf(dump_file,"%s\n",infile->name);
|
2018-02-01 11:00:58 +00:00
|
|
|
if (strcmp(infile->name,"-")==0)
|
|
|
|
infile->file = stdin;
|
|
|
|
else
|
2019-05-31 18:00:24 +00:00
|
|
|
infile->file = fopen(infile->name,"rb");
|
2013-06-14 10:38:40 +00:00
|
|
|
if(!infile->file) {
|
|
|
|
perror(infile->name);
|
|
|
|
exit(1);
|
|
|
|
}
|
2013-06-17 16:53:16 +00:00
|
|
|
if (options->infile_offset) {
|
2015-02-18 17:42:02 +00:00
|
|
|
#ifndef ECCODES_ON_WINDOWS
|
2013-12-10 18:19:57 +00:00
|
|
|
/* Check at compile time to ensure our file offset is at least 64 bits */
|
|
|
|
COMPILE_TIME_ASSERT( sizeof(options->infile_offset) >= 8 );
|
2014-03-05 11:33:31 +00:00
|
|
|
#endif
|
2013-06-17 16:53:16 +00:00
|
|
|
err=fseeko(infile->file, options->infile_offset, SEEK_SET);
|
|
|
|
if (err) {
|
2013-12-10 18:19:57 +00:00
|
|
|
/*fprintf(stderr, "Invalid file offset: %ld\n", options->infile_offset);*/
|
|
|
|
perror("Invalid file offset");
|
2013-06-17 16:53:16 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
setvbuf(infile->file,iobuf,_IOFBF,sizeof(iobuf));
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
options->file_count++;
|
|
|
|
infile->handle_count=0;
|
|
|
|
infile->filter_handle_count=0;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_tool_new_file_action(options,infile);
|
2016-01-19 14:46:17 +00:00
|
|
|
/*nofail=grib_options_on("f");*/
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
while(!options->skip_all && ((h = grib_handle_new_from_file_x(c,infile->file,options->mode,
|
|
|
|
options->headers_only,&err))
|
2015-04-29 12:25:04 +00:00
|
|
|
!= NULL || err != GRIB_SUCCESS ) ) {
|
2013-06-14 10:38:40 +00:00
|
|
|
infile->handle_count++;
|
|
|
|
options->handle_count++;
|
|
|
|
options->error=err;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (!h) {
|
2015-05-01 09:04:58 +00:00
|
|
|
/* fprintf(dump_file,"\t\t\"ERROR: unreadable message\"\n"); */
|
2016-08-30 12:45:02 +00:00
|
|
|
grib_no_handle_action(options, err);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
failed=(grib_failed*)grib_context_malloc_clear(c,sizeof(grib_failed));
|
|
|
|
failed->count=infile->handle_count;
|
|
|
|
failed->error=err;
|
|
|
|
failed->next=NULL;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (!infile->failed) {
|
|
|
|
infile->failed=failed;
|
|
|
|
} else {
|
|
|
|
p=infile->failed;
|
|
|
|
while (p->next) p=p->next;
|
|
|
|
p->next=failed;
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
continue;
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2016-12-20 10:43:36 +00:00
|
|
|
if (options->json_output == 0)
|
|
|
|
grib_print_header(options,h);
|
|
|
|
else
|
|
|
|
grib_tools_set_print_keys(options,h,options->name_space);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_skip_check(options,h);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (options->skip && options->strict) {
|
|
|
|
grib_tool_skip_handle(options,h);
|
|
|
|
continue;
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_tool_new_handle_action(options,h);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_print_key_values(options,h);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_handle_delete(h);
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_print_file_statistics(options,infile);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (infile->file) fclose(infile->file);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (infile->handle_count==0) {
|
2015-01-30 18:30:48 +00:00
|
|
|
fprintf(dump_file,"no messages found in %s\n", infile->name);
|
2013-06-14 10:38:40 +00:00
|
|
|
if (options->fail) exit(1);
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
infile=infile->next;
|
|
|
|
options->current_infile=infile;
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_print_full_statistics(options);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_tool_finalise_action(options);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2015-04-30 15:21:17 +00:00
|
|
|
return options->error;
|
2013-06-14 10:38:40 +00:00
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-12-10 18:19:57 +00:00
|
|
|
static int navigate(grib_field_tree* fields,grib_runtime_options* options)
|
|
|
|
{
|
2013-06-14 10:38:40 +00:00
|
|
|
int err=0;
|
2016-09-16 15:23:03 +00:00
|
|
|
int message_type=0;
|
2014-07-07 20:55:19 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (!fields || options->stop) return 0;
|
|
|
|
|
2016-09-16 15:23:03 +00:00
|
|
|
switch (options->mode) {
|
2014-07-07 20:55:19 +00:00
|
|
|
case MODE_GRIB:
|
2016-09-16 15:23:03 +00:00
|
|
|
message_type=CODES_GRIB;
|
|
|
|
break;
|
2014-07-07 20:55:19 +00:00
|
|
|
case MODE_BUFR:
|
2016-09-16 15:23:03 +00:00
|
|
|
message_type=CODES_BUFR;
|
|
|
|
break;
|
2014-07-07 20:55:19 +00:00
|
|
|
default :
|
2016-09-16 15:23:03 +00:00
|
|
|
Assert(0);
|
|
|
|
}
|
2014-07-07 20:55:19 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (fields->field) {
|
2016-09-16 15:23:03 +00:00
|
|
|
grib_handle* h=codes_index_get_handle(fields->field,message_type,&err);
|
2013-06-14 10:38:40 +00:00
|
|
|
if (!options->index2->current)
|
2014-10-11 17:44:22 +00:00
|
|
|
options->index2->current=(grib_field_list*)grib_context_malloc_clear(options->context,sizeof(grib_field_list));
|
2013-06-14 10:38:40 +00:00
|
|
|
options->index2->current->field=fields->field;
|
|
|
|
if (!h) return err;
|
|
|
|
grib_skip_check(options,h);
|
|
|
|
if (options->skip && options->strict) {
|
|
|
|
grib_tool_skip_handle(options,h);
|
|
|
|
} else {
|
|
|
|
grib_tool_new_handle_action(options,h);
|
|
|
|
grib_handle_delete(h);
|
|
|
|
}
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
err=navigate(fields->next_level,options);
|
|
|
|
if (err) return err;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
err=navigate(fields->next,options);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
return err;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2013-12-10 18:19:57 +00:00
|
|
|
static int grib_tool_index(grib_runtime_options* options)
|
|
|
|
{
|
2013-06-14 10:38:40 +00:00
|
|
|
int err=0;
|
|
|
|
char* f1=options->infile->name;
|
|
|
|
char* f2=options->infile_extra->name;
|
|
|
|
grib_index_key *k1,*k2;
|
|
|
|
int found=0;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2017-10-18 17:23:43 +00:00
|
|
|
grib_context* c=grib_context_get_default();
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
options->index1=grib_index_read(c,f1,&err);
|
|
|
|
if (err)
|
|
|
|
grib_context_log(c,(GRIB_LOG_FATAL) | (GRIB_LOG_PERROR) ,
|
|
|
|
"unable to read index from %s",f1);
|
|
|
|
|
|
|
|
options->index2=grib_index_read(c,f2,&err);
|
|
|
|
if (err)
|
|
|
|
grib_context_log(c,(GRIB_LOG_FATAL) | (GRIB_LOG_PERROR) ,
|
|
|
|
"unable to read index from %s",f2);
|
|
|
|
|
|
|
|
k1=options->index1->keys;
|
|
|
|
while ( k1 ) {
|
|
|
|
k2=options->index2->keys;
|
|
|
|
found=0;
|
|
|
|
while (k2) {
|
|
|
|
if ( !strcmp(k1->name,k2->name) ) {
|
|
|
|
found=1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
k2=k2->next;
|
|
|
|
}
|
|
|
|
if (!found) {
|
|
|
|
printf("Indexes contained in the input files have different keys\n");
|
|
|
|
printf("keys in file %s:\n",f1);
|
|
|
|
k1=options->index1->keys;
|
|
|
|
while (k1) {
|
|
|
|
printf("\t%s\n",k1->name);
|
|
|
|
k1=k1->next;
|
|
|
|
}
|
|
|
|
printf("keys in file %s:\n",f2);
|
|
|
|
k2=options->index2->keys;
|
|
|
|
while (k2) {
|
|
|
|
printf("\t%s\n",k2->name);
|
|
|
|
k2=k2->next;
|
|
|
|
}
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
k1->value[0]=0;
|
|
|
|
k1=k1->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
k2=options->index2->keys;
|
|
|
|
while ( k2 ) {
|
|
|
|
k1=options->index1->keys;
|
|
|
|
found=0;
|
|
|
|
while (k1) {
|
|
|
|
if ( !strcmp(k1->name,k2->name) ) {
|
|
|
|
found=1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
k1=k1->next;
|
|
|
|
}
|
|
|
|
if (!found) {
|
|
|
|
printf("Indexes contained in the input files have different keys\n");
|
|
|
|
printf("keys in file %s:\n",f2);
|
|
|
|
k2=options->index2->keys;
|
|
|
|
while (k2) {
|
|
|
|
printf("\t%s\n",k2->name);
|
|
|
|
k2=k2->next;
|
|
|
|
}
|
|
|
|
printf("keys in file %s:\n",f1);
|
|
|
|
k1=options->index1->keys;
|
|
|
|
while (k1) {
|
|
|
|
printf("\t%s\n",k1->name);
|
|
|
|
k1=k1->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
exit(1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
k2=k2->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
navigate(options->index2->fields,options);
|
|
|
|
|
|
|
|
grib_tool_finalise_action(options);
|
|
|
|
|
|
|
|
return 0;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2015-02-18 17:42:02 +00:00
|
|
|
#ifndef ECCODES_ON_WINDOWS
|
2013-12-10 18:19:57 +00:00
|
|
|
static int scan(grib_context* c,grib_runtime_options* options,const char* dir)
|
|
|
|
{
|
2013-06-14 10:38:40 +00:00
|
|
|
struct dirent *s;
|
|
|
|
DIR *d;
|
|
|
|
int err=0;
|
|
|
|
|
|
|
|
d= opendir(dir);
|
|
|
|
if (!d) {
|
|
|
|
grib_context_log(c,(GRIB_LOG_ERROR) | (GRIB_LOG_PERROR) , "opendir %s",dir);
|
|
|
|
return GRIB_IO_PROBLEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ((s=readdir(d)) && (err==0)) {
|
|
|
|
if(strcmp(s->d_name,".") != 0 && strcmp(s->d_name,"..") != 0) {
|
|
|
|
char buf[1024];
|
|
|
|
sprintf(buf,"%s/%s",dir,s->d_name);
|
|
|
|
process(c,options,buf);
|
|
|
|
}
|
|
|
|
}
|
2019-01-11 12:49:31 +00:00
|
|
|
closedir(d);
|
2013-06-14 10:38:40 +00:00
|
|
|
return 0;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
2013-03-25 14:23:07 +00:00
|
|
|
#else
|
2019-01-11 12:49:31 +00:00
|
|
|
static int scan(grib_context* c,grib_runtime_options* options,const char* dir) {
|
|
|
|
struct _finddata_t fileinfo;
|
|
|
|
intptr_t handle;
|
|
|
|
char buffer[1024];
|
|
|
|
sprintf(buffer, "%s/*", dir);
|
|
|
|
if((handle = _findfirst(buffer, &fileinfo)) != -1)
|
2019-01-10 17:42:10 +00:00
|
|
|
{
|
2019-01-11 12:49:31 +00:00
|
|
|
do {
|
|
|
|
if(strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name,"..") != 0) {
|
2019-01-10 17:42:10 +00:00
|
|
|
char buf[1024];
|
2019-01-11 12:49:31 +00:00
|
|
|
sprintf(buf, "%s/%s", dir, fileinfo.name);
|
2019-01-10 17:42:10 +00:00
|
|
|
process(c, options, buf);
|
|
|
|
}
|
2019-01-11 12:49:31 +00:00
|
|
|
} while(!_findnext(handle, &fileinfo));
|
|
|
|
|
|
|
|
_findclose(handle);
|
2013-06-14 10:38:40 +00:00
|
|
|
}
|
|
|
|
else
|
2013-03-25 14:23:07 +00:00
|
|
|
{
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_context_log(c,(GRIB_LOG_ERROR) | (GRIB_LOG_PERROR) , "opendir %s",dir);
|
|
|
|
return GRIB_IO_PROBLEM;
|
|
|
|
}
|
2013-03-25 14:23:07 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
2013-03-25 12:04:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
static int process(grib_context* c,grib_runtime_options* options,const char* path) {
|
2013-06-14 10:38:40 +00:00
|
|
|
struct stat s;
|
|
|
|
int stat_val=0;
|
2013-03-25 14:23:07 +00:00
|
|
|
|
2015-02-18 17:42:02 +00:00
|
|
|
#ifndef ECCODES_ON_WINDOWS
|
2013-06-14 10:38:40 +00:00
|
|
|
stat_val = lstat(path,&s);
|
2013-03-25 14:23:07 +00:00
|
|
|
#else
|
2013-06-14 10:38:40 +00:00
|
|
|
stat_val = stat(path,&s);
|
2013-03-25 14:23:07 +00:00
|
|
|
#endif
|
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if ( stat_val != 0 ) {
|
|
|
|
grib_context_log(c,(GRIB_LOG_ERROR) | (GRIB_LOG_PERROR),"Cannot stat %s",path);
|
|
|
|
return GRIB_IO_PROBLEM;
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (S_ISDIR(s.st_mode) && !S_ISLNK(s.st_mode)) {
|
|
|
|
scan(c,options,path);
|
|
|
|
} else {
|
|
|
|
grib_tool_new_filename_action(options,path);
|
|
|
|
}
|
|
|
|
return 0;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2013-12-10 18:19:57 +00:00
|
|
|
static int grib_tool_onlyfiles(grib_runtime_options* options)
|
|
|
|
{
|
2017-10-18 17:23:43 +00:00
|
|
|
grib_context* c=grib_context_get_default();
|
|
|
|
grib_tools_file* infile=options->infile;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
while (infile!=NULL && infile->name!=NULL) {
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
process(c,options,infile->name);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
infile=infile->next;
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_tool_finalise_action(options);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
return 0;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2013-12-10 18:19:57 +00:00
|
|
|
static void grib_print_header(grib_runtime_options* options,grib_handle* h)
|
|
|
|
{
|
2013-06-14 10:38:40 +00:00
|
|
|
size_t strlenkey=0;
|
|
|
|
int width;
|
|
|
|
int written_to_dump = 0; /* boolean */
|
2016-12-20 10:43:36 +00:00
|
|
|
if (options->json_output)
|
|
|
|
return; /* For JSON output we do not print a single header for all msgs */
|
2015-12-18 18:01:56 +00:00
|
|
|
if (options->handle_count!=1)
|
2013-06-14 10:38:40 +00:00
|
|
|
return;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
|
|
|
grib_tools_set_print_keys(options,h,options->name_space);
|
|
|
|
|
2015-12-18 18:01:56 +00:00
|
|
|
if (options->verbose && options->print_header) {
|
2013-06-14 10:38:40 +00:00
|
|
|
int j=0;
|
|
|
|
for (j=0;j<options->print_keys_count;j++) {
|
|
|
|
strlenkey=strlen(options->print_keys[j].name);
|
|
|
|
width= strlenkey < options->default_print_width ?
|
|
|
|
options->default_print_width+2 : strlenkey+2;
|
2013-03-25 12:04:10 +00:00
|
|
|
if (options->default_print_width < 0)
|
2013-06-14 10:38:40 +00:00
|
|
|
width=strlenkey+1;
|
|
|
|
|
|
|
|
fprintf(dump_file,"%-*s",(int)width,options->print_keys[j].name);
|
|
|
|
written_to_dump = 1;
|
|
|
|
}
|
|
|
|
if (options->latlon) {
|
|
|
|
if (options->latlon_mode==4) {
|
|
|
|
fprintf(dump_file," value1 ");
|
|
|
|
fprintf(dump_file," value2 ");
|
|
|
|
fprintf(dump_file," value3 ");
|
|
|
|
fprintf(dump_file," value4 ");
|
|
|
|
} else {
|
|
|
|
fprintf(dump_file," value ");
|
|
|
|
}
|
|
|
|
written_to_dump = 1;
|
|
|
|
}
|
|
|
|
if (options->index_on) {
|
|
|
|
fprintf(dump_file," value(%d) ",(int)options->index);
|
|
|
|
written_to_dump = 1;
|
|
|
|
}
|
|
|
|
if (written_to_dump) {
|
|
|
|
fprintf(dump_file,"\n");
|
|
|
|
}
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2017-10-18 17:23:43 +00:00
|
|
|
static int cmpstringp(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
/* The actual arguments to this function are "pointers to
|
|
|
|
pointers to char", but strcmp(3) arguments are "pointers
|
|
|
|
to char", hence the following cast plus dereference */
|
|
|
|
return strcmp(* (char * const *) p1, * (char * const *) p2);
|
|
|
|
}
|
|
|
|
|
2013-12-10 18:19:57 +00:00
|
|
|
static void grib_tools_set_print_keys(grib_runtime_options* options, grib_handle* h, const char* ns)
|
|
|
|
{
|
2013-06-14 10:38:40 +00:00
|
|
|
int i=0;
|
|
|
|
grib_keys_iterator* kiter=NULL;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
|
|
|
options->print_keys_count=0;
|
2013-06-14 10:38:40 +00:00
|
|
|
|
2013-03-25 12:04:10 +00:00
|
|
|
for (i=0;i<options->requested_print_keys_count;i++) {
|
2013-06-14 10:38:40 +00:00
|
|
|
options->print_keys[options->print_keys_count].name=options->requested_print_keys[i].name;
|
2019-08-12 15:00:15 +00:00
|
|
|
if (strlen(options->requested_print_keys[i].name) > options->default_print_width)
|
|
|
|
options->default_print_width = (int)strlen(options->requested_print_keys[i].name);
|
2013-06-14 10:38:40 +00:00
|
|
|
options->print_keys[options->print_keys_count].type=options->requested_print_keys[i].type;
|
|
|
|
options->print_keys_count++;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
2013-06-14 10:38:40 +00:00
|
|
|
|
2013-03-25 12:04:10 +00:00
|
|
|
if (ns) {
|
2017-01-13 17:24:36 +00:00
|
|
|
kiter=grib_keys_iterator_new(h,0,ns);
|
2013-06-14 10:38:40 +00:00
|
|
|
if (!kiter) {
|
|
|
|
fprintf(dump_file,"ERROR: Unable to create keys iterator\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
while(grib_keys_iterator_next(kiter))
|
|
|
|
{
|
|
|
|
const char* name = grib_keys_iterator_get_name(kiter);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (options->print_keys_count >= MAX_KEYS ) {
|
|
|
|
fprintf(stderr,"ERROR: keys list too long (more than %d keys)\n",
|
|
|
|
options->print_keys_count);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
options->print_keys[options->print_keys_count].name=strdup(name);
|
|
|
|
if (strlen(name)>options->default_print_width)
|
2019-08-12 15:00:15 +00:00
|
|
|
options->default_print_width=(int)strlen(name);
|
2013-06-14 10:38:40 +00:00
|
|
|
options->print_keys[options->print_keys_count].type=GRIB_TYPE_STRING;
|
|
|
|
options->print_keys_count++;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_keys_iterator_delete(kiter);
|
|
|
|
if (options->print_keys_count==0 && options->latlon == 0 ) {
|
2018-01-03 16:41:06 +00:00
|
|
|
int j=0,k=0,ns_count=0;
|
2019-08-12 15:00:15 +00:00
|
|
|
const char* all_namespace_vals[1024] = {NULL,}; /* sorted array containing all namespaces */
|
2017-10-18 17:23:43 +00:00
|
|
|
printf("ERROR: namespace \"%s\" does not contain any key.\n",ns);
|
|
|
|
printf("Here are the available namespaces in this message:\n");
|
|
|
|
for (i=0; i<ACCESSORS_ARRAY_SIZE; i++) {
|
|
|
|
grib_accessor* anAccessor = h->accessors[i];
|
|
|
|
if (anAccessor) {
|
|
|
|
for (j=0; j<MAX_ACCESSOR_NAMES; j++) {
|
2019-08-12 15:00:15 +00:00
|
|
|
const char* a_namespace = anAccessor->all_name_spaces[j];
|
2017-10-18 17:23:43 +00:00
|
|
|
if (a_namespace) {
|
|
|
|
all_namespace_vals[k++] = a_namespace;
|
|
|
|
ns_count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
qsort(&all_namespace_vals, ns_count, sizeof(char*), cmpstringp);
|
|
|
|
for(i=0; i<ns_count; ++i) {
|
|
|
|
if (all_namespace_vals[i]) {
|
|
|
|
int print_it = 1;
|
|
|
|
if (i>0 && strcmp(all_namespace_vals[i], all_namespace_vals[i-1]) == 0) {
|
|
|
|
print_it = 0; /* skip duplicate entries */
|
|
|
|
}
|
|
|
|
if (print_it) printf("\t%s\n", all_namespace_vals[i]);
|
|
|
|
}
|
|
|
|
}
|
2013-06-14 10:38:40 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-10 18:19:57 +00:00
|
|
|
static int to_skip(grib_handle* h,grib_values* v,int *err)
|
|
|
|
{
|
2013-06-14 10:38:40 +00:00
|
|
|
double dvalue=0;
|
|
|
|
int ret=0;
|
|
|
|
long lvalue=0;
|
|
|
|
char value[MAX_STRING_LEN]={0,};
|
|
|
|
size_t len=MAX_STRING_LEN;
|
|
|
|
*err=0;
|
|
|
|
|
|
|
|
switch (v->type) {
|
2013-03-25 14:23:07 +00:00
|
|
|
case GRIB_TYPE_STRING:
|
2013-06-14 10:38:40 +00:00
|
|
|
*err=grib_get_string( h,v->name,value,&len);
|
|
|
|
ret = v->equal ? grib_inline_strcmp(value,v->string_value) : !grib_inline_strcmp(value,v->string_value);
|
|
|
|
break;
|
2013-03-25 14:23:07 +00:00
|
|
|
case GRIB_TYPE_DOUBLE:
|
2013-06-14 10:38:40 +00:00
|
|
|
*err=grib_get_double( h,v->name,&dvalue);
|
|
|
|
ret = v->equal ? (dvalue != v->double_value) : (dvalue == v->double_value);
|
|
|
|
break;
|
2013-03-25 14:23:07 +00:00
|
|
|
case GRIB_TYPE_LONG:
|
2013-06-14 10:38:40 +00:00
|
|
|
*err=grib_get_long( h,v->name,&lvalue);
|
|
|
|
ret = v->equal ? (lvalue != v->long_value) : (lvalue == v->long_value);
|
|
|
|
break;
|
2013-03-25 14:23:07 +00:00
|
|
|
case GRIB_TYPE_MISSING:
|
2013-06-14 10:38:40 +00:00
|
|
|
lvalue=grib_is_missing( h,v->name,err);
|
|
|
|
ret = (lvalue == v->equal) ? 0 : 1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fprintf(dump_file,"invalid type for %s\n",v->name);
|
|
|
|
exit(1);
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
return ret;
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2013-12-10 18:19:57 +00:00
|
|
|
void grib_skip_check(grib_runtime_options* options,grib_handle* h)
|
|
|
|
{
|
2013-06-14 10:38:40 +00:00
|
|
|
int i,ret=0;
|
2013-03-25 14:23:07 +00:00
|
|
|
grib_values* v=NULL;
|
|
|
|
for (i=0;i < options->constraints_count ;i++) {
|
|
|
|
v=&(options->constraints[i]);
|
|
|
|
if (v->equal) {
|
2013-06-14 10:38:40 +00:00
|
|
|
options->skip=1;
|
|
|
|
while (v) {
|
|
|
|
if (!to_skip(h,v,&ret)) {
|
|
|
|
if (!strcmp(v->name,"count") && !v->next)
|
|
|
|
options->skip_all=1;
|
|
|
|
options->skip=0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (ret != GRIB_SUCCESS && options->fail) {
|
|
|
|
grib_context_log(h->context,GRIB_LOG_ERROR,"unable to get \"%s\" (%s)",
|
|
|
|
v->name,grib_get_error_message(ret));
|
|
|
|
exit(ret);
|
|
|
|
}
|
|
|
|
v=v->next;
|
2013-03-25 14:23:07 +00:00
|
|
|
}
|
|
|
|
} else {
|
2013-06-14 10:38:40 +00:00
|
|
|
options->skip=0;
|
|
|
|
while (v) {
|
|
|
|
if (to_skip(h,v,&ret)) {
|
|
|
|
options->skip=1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (ret != GRIB_SUCCESS && options->fail) {
|
|
|
|
grib_context_log(h->context,GRIB_LOG_ERROR,"unable to get \"%s\" (%s)",
|
|
|
|
v->name,grib_get_error_message(ret));
|
|
|
|
exit(ret);
|
|
|
|
}
|
|
|
|
v=v->next;
|
2013-03-25 14:23:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (options->skip==1)
|
2013-06-14 10:38:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!options->skip) {
|
|
|
|
options->filter_handle_count++;
|
|
|
|
if (options->current_infile)
|
|
|
|
options->current_infile->filter_handle_count++;
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2019-08-28 15:44:07 +00:00
|
|
|
/* TODO: Does not work for 2.7e+01 */
|
|
|
|
static int is_value_a_number(const char* input)
|
|
|
|
{
|
|
|
|
const char *p = input;
|
|
|
|
if (p == 0 || *p == 0) return 0;
|
|
|
|
if (*p == '-') p++;
|
|
|
|
|
|
|
|
while (*p) {
|
|
|
|
if( *p != '.' && !isdigit(*p)) return 0;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
2019-08-28 14:42:36 +00:00
|
|
|
static void get_value_for_key(grib_handle* h, const char* key_name, int key_type, char* value_str, const char* format)
|
2016-12-20 10:43:36 +00:00
|
|
|
{
|
2019-08-28 14:42:36 +00:00
|
|
|
int ret = 0, type = key_type;
|
2016-12-20 10:43:36 +00:00
|
|
|
double dvalue = 0;
|
|
|
|
long lvalue = 0;
|
|
|
|
size_t len=MAX_STRING_LEN;
|
2019-08-28 17:04:44 +00:00
|
|
|
|
2019-08-28 14:42:36 +00:00
|
|
|
if (grib_is_missing(h, key_name, &ret) && ret==GRIB_SUCCESS) {
|
|
|
|
sprintf(value_str,"MISSING");
|
|
|
|
return;
|
|
|
|
}
|
2019-08-28 17:04:44 +00:00
|
|
|
if (ret == GRIB_NOT_FOUND) {
|
|
|
|
sprintf(value_str,"not_found");
|
|
|
|
return;
|
|
|
|
}
|
2019-08-28 14:42:36 +00:00
|
|
|
|
|
|
|
if (type == GRIB_TYPE_UNDEFINED) {
|
2019-08-28 17:04:44 +00:00
|
|
|
ret=grib_get_native_type(h, key_name, &type);
|
|
|
|
if(ret!=GRIB_SUCCESS) {
|
|
|
|
fprintf(dump_file,"Could not determine type for %s\n", key_name);
|
|
|
|
exit(1);
|
|
|
|
}
|
2019-08-28 14:42:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (type == GRIB_TYPE_STRING) {
|
2016-12-20 10:43:36 +00:00
|
|
|
ret=grib_get_string(h, key_name, value_str, &len);
|
|
|
|
}
|
2019-08-28 14:42:36 +00:00
|
|
|
else if (type == GRIB_TYPE_DOUBLE) {
|
2016-12-20 10:43:36 +00:00
|
|
|
ret=grib_get_double( h, key_name, &dvalue);
|
|
|
|
sprintf(value_str, format, dvalue);
|
|
|
|
}
|
2019-08-28 14:42:36 +00:00
|
|
|
else if (type == GRIB_TYPE_LONG) {
|
2016-12-20 10:43:36 +00:00
|
|
|
ret=grib_get_long( h, key_name, &lvalue);
|
|
|
|
sprintf(value_str,"%ld", lvalue);
|
|
|
|
}
|
2019-08-28 14:42:36 +00:00
|
|
|
else if (type == GRIB_TYPE_BYTES) {
|
2016-12-20 10:43:36 +00:00
|
|
|
ret=grib_get_string(h, key_name, value_str, &len);
|
|
|
|
}
|
2019-08-28 14:42:36 +00:00
|
|
|
else {
|
2016-12-20 10:43:36 +00:00
|
|
|
fprintf(dump_file,"invalid format option for %s\n", key_name);
|
|
|
|
exit(1);
|
|
|
|
}
|
2019-08-28 14:42:36 +00:00
|
|
|
|
2016-12-20 10:43:36 +00:00
|
|
|
if (ret != GRIB_SUCCESS) {
|
|
|
|
fprintf(dump_file,"Failed to get value for key %s\n", key_name);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
2019-08-28 14:42:36 +00:00
|
|
|
|
2018-06-25 16:01:42 +00:00
|
|
|
/* See ECC-707 */
|
|
|
|
static int fix_for_lsdate_needed(grib_handle* h)
|
|
|
|
{
|
|
|
|
long lsdate_bug = 0;
|
|
|
|
int err = grib_get_long(h, "lsdate_bug", &lsdate_bug);
|
|
|
|
if (!err && lsdate_bug == 1) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-11-07 17:20:56 +00:00
|
|
|
static int get_initial_element_of_array(grib_handle* h, const char* keyName, size_t num_vals, char* value)
|
|
|
|
{
|
|
|
|
int err = 0, type = 0;
|
|
|
|
size_t len = num_vals;
|
|
|
|
char* sval = NULL;
|
|
|
|
unsigned char *uval = NULL;
|
|
|
|
long *lval = NULL;
|
|
|
|
double* dval = NULL;
|
|
|
|
grib_context* c = h->context;
|
|
|
|
|
|
|
|
Assert(num_vals > 1); /* This is for array keys */
|
|
|
|
if ((err = grib_get_native_type(h,keyName,&type))!=GRIB_SUCCESS) return err;
|
|
|
|
switch(type) {
|
|
|
|
case GRIB_TYPE_STRING:
|
|
|
|
grib_get_string_length(h,keyName,&len);
|
|
|
|
sval = (char*)grib_context_malloc(c,len*sizeof(char));
|
|
|
|
if (!sval) return GRIB_OUT_OF_MEMORY;
|
|
|
|
if((err = grib_get_string(h,keyName,sval,&len)) != GRIB_SUCCESS) return err;
|
|
|
|
sprintf(value, "%s", sval);
|
|
|
|
free(sval);
|
|
|
|
break;
|
|
|
|
case GRIB_TYPE_LONG:
|
|
|
|
lval = (long*)grib_context_malloc(c,num_vals*sizeof(long));
|
|
|
|
if (!lval) return GRIB_OUT_OF_MEMORY;
|
|
|
|
if((err = grib_get_long_array(h,keyName,lval,&len)) != GRIB_SUCCESS) return err;
|
|
|
|
sprintf(value, "%ld...", lval[0]);
|
|
|
|
free(lval);
|
|
|
|
break;
|
|
|
|
case GRIB_TYPE_DOUBLE:
|
|
|
|
dval = (double*)grib_context_malloc(c,num_vals*sizeof(double));
|
|
|
|
if (!dval) return GRIB_OUT_OF_MEMORY;
|
|
|
|
if((err = grib_get_double_array(h,keyName,dval,&len)) != GRIB_SUCCESS) return err;
|
|
|
|
sprintf(value, "%g...", dval[0]);
|
|
|
|
free(dval);
|
|
|
|
break;
|
|
|
|
case GRIB_TYPE_BYTES:
|
|
|
|
uval = (unsigned char*)grib_context_malloc(c,num_vals*sizeof(unsigned char));
|
|
|
|
if (!uval) return GRIB_OUT_OF_MEMORY;
|
|
|
|
if((err = grib_get_bytes(h,keyName,uval,&len)) != GRIB_SUCCESS) return err;
|
|
|
|
sprintf(value, "%d...", (short)uval[0]);
|
|
|
|
free(uval);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
sprintf(value, "%s...", "");
|
|
|
|
}
|
|
|
|
return GRIB_SUCCESS;
|
|
|
|
}
|
2016-12-20 10:43:36 +00:00
|
|
|
|
2016-09-16 15:57:06 +00:00
|
|
|
void grib_print_key_values(grib_runtime_options* options, grib_handle* h)
|
2013-06-14 10:38:40 +00:00
|
|
|
{
|
|
|
|
int i=0;
|
|
|
|
int ret=0,width=0;
|
|
|
|
int strlenvalue=0;
|
|
|
|
double dvalue=0;
|
|
|
|
long lvalue=0;
|
|
|
|
char value[MAX_STRING_LEN];
|
2018-08-07 12:50:41 +00:00
|
|
|
const char* notfound="not_found";
|
2013-06-14 10:38:40 +00:00
|
|
|
int written_to_dump = 0; /* boolean */
|
2016-09-16 15:57:06 +00:00
|
|
|
grib_accessor* acc = NULL;
|
2018-11-07 17:20:56 +00:00
|
|
|
size_t num_vals = 0;
|
2019-07-26 12:12:59 +00:00
|
|
|
int fix_lsdate = 0;
|
2013-06-14 10:38:40 +00:00
|
|
|
|
|
|
|
if (!options->verbose) return;
|
|
|
|
|
2016-12-20 10:43:36 +00:00
|
|
|
if (options->json_output) {
|
2019-08-28 15:44:07 +00:00
|
|
|
/* fprintf(dump_file, "\"message %d\" : {\n", options->handle_count); */
|
2019-08-28 17:04:44 +00:00
|
|
|
fprintf(dump_file, " {\n");
|
2016-12-20 10:43:36 +00:00
|
|
|
for (i=0;i<options->print_keys_count;i++) {
|
|
|
|
fprintf(dump_file,"\t\"%s\": ", options->print_keys[i].name);
|
2019-08-28 14:42:36 +00:00
|
|
|
get_value_for_key(h, options->print_keys[i].name, options->print_keys[i].type, value, options->format);
|
2019-08-28 15:44:07 +00:00
|
|
|
if (is_value_a_number(value))
|
|
|
|
fprintf(dump_file,"%s", value);
|
|
|
|
else
|
|
|
|
fprintf(dump_file,"\"%s\"", value);
|
2016-12-20 10:43:36 +00:00
|
|
|
if (i != options->print_keys_count-1)
|
|
|
|
fprintf(dump_file,",\n");
|
|
|
|
else
|
|
|
|
fprintf(dump_file,"\n");
|
|
|
|
}
|
2019-08-28 17:04:44 +00:00
|
|
|
fprintf(dump_file, " }");
|
2016-12-20 10:43:36 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-07-26 12:12:59 +00:00
|
|
|
fix_lsdate = (fix_for_lsdate_needed(h) && options->name_space && strcmp(options->name_space,"ls")==0);
|
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
for (i=0;i<options->print_keys_count;i++) {
|
|
|
|
size_t len=MAX_STRING_LEN;
|
|
|
|
ret=GRIB_SUCCESS;
|
|
|
|
|
2016-09-16 15:23:03 +00:00
|
|
|
if (h->product_kind == PRODUCT_BUFR) {
|
|
|
|
/* ECC-236: Do not use grib_is_missing for BUFR */
|
|
|
|
if (!grib_is_defined(h, options->print_keys[i].name)) ret = GRIB_NOT_FOUND;
|
|
|
|
if (ret == GRIB_SUCCESS) {
|
|
|
|
if (options->print_keys[i].type == GRIB_TYPE_UNDEFINED)
|
|
|
|
grib_get_native_type(h, options->print_keys[i].name, &(options->print_keys[i].type));
|
|
|
|
switch (options->print_keys[i].type) {
|
|
|
|
case GRIB_TYPE_STRING:
|
2016-09-16 15:57:06 +00:00
|
|
|
acc = grib_find_accessor(h, options->print_keys[i].name);
|
2016-09-16 15:23:03 +00:00
|
|
|
ret=grib_get_string(h, options->print_keys[i].name, value, &len);
|
2016-09-16 15:57:06 +00:00
|
|
|
if (grib_is_missing_string(acc, (unsigned char *)value, len))
|
|
|
|
sprintf(value,"MISSING");
|
2016-09-16 15:23:03 +00:00
|
|
|
break;
|
|
|
|
case GRIB_TYPE_DOUBLE:
|
|
|
|
ret=grib_get_double(h, options->print_keys[i].name, &dvalue);
|
|
|
|
if (dvalue == GRIB_MISSING_DOUBLE) sprintf(value,"MISSING");
|
|
|
|
else sprintf(value,options->format,dvalue);
|
|
|
|
break;
|
|
|
|
case GRIB_TYPE_LONG:
|
|
|
|
ret=grib_get_long(h, options->print_keys[i].name, &lvalue);
|
|
|
|
if (lvalue == GRIB_MISSING_LONG) sprintf(value,"MISSING");
|
|
|
|
else sprintf(value,"%ld", lvalue);
|
|
|
|
break;
|
|
|
|
case GRIB_TYPE_BYTES:
|
|
|
|
ret=grib_get_string(h, options->print_keys[i].name, value, &len);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fprintf(dump_file,"Could not determine type for %s\n", options->print_keys[i].name);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2016-09-16 15:57:06 +00:00
|
|
|
/* Other products e.g. GRIB */
|
2016-09-16 15:23:03 +00:00
|
|
|
if (grib_is_missing(h,options->print_keys[i].name,&ret) && ret==GRIB_SUCCESS) {
|
|
|
|
sprintf(value,"MISSING");
|
|
|
|
}
|
|
|
|
else if ( ret == GRIB_SUCCESS ) {
|
2018-06-25 16:01:42 +00:00
|
|
|
const char* pName = NULL;
|
2016-09-16 15:23:03 +00:00
|
|
|
if (options->print_keys[i].type == GRIB_TYPE_UNDEFINED)
|
|
|
|
grib_get_native_type(h,options->print_keys[i].name,&(options->print_keys[i].type));
|
|
|
|
switch (options->print_keys[i].type) {
|
|
|
|
case GRIB_TYPE_STRING:
|
2018-06-25 16:01:42 +00:00
|
|
|
pName = options->print_keys[i].name;
|
|
|
|
if (fix_lsdate && strcmp(pName, "date")==0) { /* ECC-707 */
|
|
|
|
pName = "ls.date";
|
|
|
|
}
|
2018-11-07 17:20:56 +00:00
|
|
|
ret = grib_get_size(h, pName, &num_vals);
|
|
|
|
if(ret==GRIB_SUCCESS && num_vals>1) { /* See ECC-278 */
|
|
|
|
ret = get_initial_element_of_array(h, pName, num_vals, value);
|
|
|
|
} else {
|
|
|
|
ret=grib_get_string( h,pName,value,&len);
|
|
|
|
}
|
2016-09-16 15:23:03 +00:00
|
|
|
break;
|
|
|
|
case GRIB_TYPE_DOUBLE:
|
|
|
|
ret=grib_get_double( h,options->print_keys[i].name,&dvalue);
|
|
|
|
sprintf(value,options->format,dvalue);
|
|
|
|
break;
|
|
|
|
case GRIB_TYPE_LONG:
|
|
|
|
ret=grib_get_long( h,options->print_keys[i].name,&lvalue);
|
|
|
|
sprintf(value,"%ld", lvalue);
|
|
|
|
break;
|
|
|
|
case GRIB_TYPE_BYTES:
|
|
|
|
ret=grib_get_string( h,options->print_keys[i].name,value,&len);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fprintf(dump_file,"invalid format option for %s\n",options->print_keys[i].name);
|
|
|
|
exit(1);
|
|
|
|
}
|
2013-06-14 10:38:40 +00:00
|
|
|
}
|
|
|
|
}
|
2016-09-16 15:23:03 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (ret != GRIB_SUCCESS) {
|
|
|
|
if (options->fail) GRIB_CHECK_NOLINE(ret,options->print_keys[i].name);
|
|
|
|
if (ret == GRIB_NOT_FOUND) strcpy(value,notfound);
|
|
|
|
else {
|
|
|
|
fprintf(dump_file,"%s %s\n",grib_get_error_message(ret),options->print_keys[i].name);
|
|
|
|
exit(ret);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-12 15:00:15 +00:00
|
|
|
strlenvalue = (int)strlen(value);
|
2013-06-14 10:38:40 +00:00
|
|
|
|
|
|
|
width = strlenvalue < options->default_print_width ?
|
|
|
|
options->default_print_width + 2 :
|
|
|
|
strlenvalue + 2;
|
|
|
|
|
|
|
|
if (options->default_print_width < 0) width = strlenvalue + 1;
|
|
|
|
|
|
|
|
if (options->print_keys_count==i+1 && options->latlon==0) width--;
|
|
|
|
|
|
|
|
fprintf(dump_file,"%-*s",(int)width,value);
|
|
|
|
written_to_dump = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (options->latlon) {
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (options->latlon_mode==4){
|
2017-09-01 16:52:05 +00:00
|
|
|
int ii=0;
|
|
|
|
for (ii=0;ii<4;ii++) {
|
|
|
|
fprintf(dump_file,options->format,options->values[ii]);
|
2013-06-14 10:38:40 +00:00
|
|
|
fprintf(dump_file," ");
|
|
|
|
}
|
|
|
|
written_to_dump=1;
|
|
|
|
} else if (options->latlon_mode==1) {
|
|
|
|
sprintf(value,options->format,options->values[options->latlon_idx]);
|
2019-08-12 15:00:15 +00:00
|
|
|
strlenvalue = (int)strlen(value);
|
2013-06-14 10:38:40 +00:00
|
|
|
width = strlenvalue < options->default_print_width ?
|
|
|
|
options->default_print_width + 2 :
|
|
|
|
strlenvalue + 2;
|
|
|
|
fprintf(dump_file,"%-*s",(int)width,value);
|
|
|
|
written_to_dump=1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (options->index_on) {
|
|
|
|
double v=0;
|
|
|
|
/*if (grib_get_double_element(h,"values",options->index,&v) != GRIB_SUCCESS) {*/
|
|
|
|
if (1) {
|
2014-03-05 11:33:31 +00:00
|
|
|
size_t size, the_index = 0;
|
2013-06-14 10:38:40 +00:00
|
|
|
double* values;
|
|
|
|
int err=0;
|
|
|
|
|
|
|
|
err=grib_get_size(h,"values",&size);
|
|
|
|
if (err) {
|
|
|
|
sprintf(value,"unknown");
|
|
|
|
if (!options->fail) exit(err);
|
|
|
|
return;
|
|
|
|
}
|
2014-10-11 17:44:22 +00:00
|
|
|
values=(double*)grib_context_malloc_clear(h->context,size*sizeof(double));
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_get_double_array(h,"values",values,&size);
|
2014-03-05 11:33:31 +00:00
|
|
|
the_index = options->index;
|
|
|
|
if (the_index >= size) {
|
|
|
|
fprintf(dump_file,"\n");
|
2016-03-31 17:24:10 +00:00
|
|
|
fprintf(stderr, "invalid index value %d (should be between 0 and %d)\n",
|
|
|
|
options->index, (int)(size-1));
|
2014-03-05 11:33:31 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
2013-06-14 10:38:40 +00:00
|
|
|
v=values[options->index];
|
|
|
|
grib_context_free(h->context,values);
|
|
|
|
}
|
|
|
|
|
|
|
|
sprintf(value,options->format,v);
|
2019-08-12 15:00:15 +00:00
|
|
|
strlenvalue = (int)strlen(value);
|
2013-06-14 10:38:40 +00:00
|
|
|
width = strlenvalue < options->default_print_width ?
|
|
|
|
options->default_print_width + 2 :
|
|
|
|
strlenvalue + 2;
|
|
|
|
fprintf(dump_file,"%-*s",(int)width,value);
|
|
|
|
written_to_dump=1;
|
|
|
|
}
|
|
|
|
if (written_to_dump) {
|
|
|
|
fprintf(dump_file,"\n");
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2013-12-10 18:19:57 +00:00
|
|
|
void grib_print_file_statistics(grib_runtime_options* options,grib_tools_file* file)
|
|
|
|
{
|
2013-06-14 10:38:40 +00:00
|
|
|
grib_failed* failed=NULL;
|
|
|
|
Assert(file);
|
2016-12-20 10:43:36 +00:00
|
|
|
if (options->json_output)
|
|
|
|
return;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
failed=file->failed;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (!options->print_statistics || !options->verbose) return;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2015-01-30 18:30:48 +00:00
|
|
|
fprintf(dump_file,"%d of %d messages in %s\n\n",
|
2013-06-14 10:38:40 +00:00
|
|
|
file->filter_handle_count,
|
|
|
|
file->handle_count,
|
|
|
|
file->name);
|
|
|
|
if (!failed) return;
|
|
|
|
/*
|
2015-01-30 18:30:48 +00:00
|
|
|
fprintf(dump_file,"Following bad messages found in %s\n",
|
2013-03-25 12:04:10 +00:00
|
|
|
file->name);
|
|
|
|
fprintf(dump_file,"N Error\n");
|
|
|
|
while (failed){
|
|
|
|
fprintf(dump_file,"%-*d %s\n",
|
|
|
|
7,failed->count,
|
|
|
|
grib_get_error_message(failed->error));
|
|
|
|
failed=failed->next;
|
|
|
|
}
|
|
|
|
fprintf(dump_file,"\n");
|
2013-06-14 10:38:40 +00:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
void grib_print_full_statistics(grib_runtime_options* options)
|
|
|
|
{
|
2016-12-20 10:43:36 +00:00
|
|
|
if (options->json_output)
|
|
|
|
return;
|
2013-06-14 10:38:40 +00:00
|
|
|
if (options->print_statistics && options->verbose)
|
2015-01-30 18:30:48 +00:00
|
|
|
fprintf(dump_file,"%d of %d total messages in %d files\n",
|
2013-06-14 10:38:40 +00:00
|
|
|
options->filter_handle_count,options->handle_count,options->file_count);
|
2013-03-25 12:04:10 +00:00
|
|
|
}
|
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
void grib_tools_write_message(grib_runtime_options* options, grib_handle* h)
|
|
|
|
{
|
|
|
|
const void *buffer;
|
|
|
|
size_t size;
|
|
|
|
grib_file* of = NULL;
|
|
|
|
int err = 0;
|
|
|
|
char filename[1024] = { 0, };
|
|
|
|
Assert(options->outfile!=NULL && options->outfile->name!=NULL);
|
|
|
|
|
|
|
|
if (options->error == GRIB_WRONG_LENGTH)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ((err = grib_get_message(h, &buffer, &size)) != GRIB_SUCCESS) {
|
|
|
|
grib_context_log(h->context, GRIB_LOG_ERROR,"unable to get binary message\n");
|
|
|
|
exit(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
err = grib_recompose_name(h, NULL, options->outfile->name, filename, 0);
|
|
|
|
|
|
|
|
of = grib_file_open(filename, "w", &err);
|
|
|
|
|
|
|
|
if (!of || !of->handle) {
|
|
|
|
grib_context_log(h->context, (GRIB_LOG_ERROR) | (GRIB_LOG_PERROR),
|
|
|
|
"unable to open file %s\n", filename);
|
|
|
|
exit(GRIB_IO_PROBLEM);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (options->gts && h->gts_header) {
|
|
|
|
if (fwrite(h->gts_header, 1, h->gts_header_len, of->handle) != h->gts_header_len) {
|
|
|
|
grib_context_log(h->context, (GRIB_LOG_ERROR) | (GRIB_LOG_PERROR),
|
|
|
|
"Error writing GTS header to %s", filename);
|
|
|
|
exit(GRIB_IO_PROBLEM);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fwrite(buffer, 1, size, of->handle) != size) {
|
|
|
|
grib_context_log(h->context, (GRIB_LOG_ERROR) | (GRIB_LOG_PERROR),
|
|
|
|
"Error writing to %s", filename);
|
|
|
|
exit(GRIB_IO_PROBLEM);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (options->gts && h->gts_header) {
|
|
|
|
char gts_trailer[4] = { '\x0D', '\x0D', '\x0A', '\x03' };
|
|
|
|
if (fwrite(gts_trailer, 1, 4, of->handle) != 4) {
|
|
|
|
grib_context_log(h->context, (GRIB_LOG_ERROR) | (GRIB_LOG_PERROR),
|
|
|
|
"Error writing GTS trailer to %s", filename);
|
|
|
|
exit(GRIB_IO_PROBLEM);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-19 08:45:51 +00:00
|
|
|
grib_file_close(filename, 0, &err);
|
2013-06-14 10:38:40 +00:00
|
|
|
|
|
|
|
if (err != GRIB_SUCCESS) {
|
|
|
|
grib_context_log(h->context, GRIB_LOG_ERROR,"unable to write message\n");
|
|
|
|
exit(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
options->outfile->file = NULL;
|
2013-03-25 12:04:10 +00:00
|
|
|
|
|
|
|
#if 0
|
2013-06-14 10:38:40 +00:00
|
|
|
if (!options->outfile->file) {
|
|
|
|
options->outfile->file = fopen(options->outfile->name,"w");
|
|
|
|
if(!options->outfile->file) {
|
|
|
|
perror(options->outfile->name);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
GRIB_CHECK_NOLINE(grib_get_message(h,&buffer,&size),0);
|
|
|
|
if (options->gts && h->gts_header)
|
|
|
|
fwrite(h->gts_header,1,h->gts_header_len,options->outfile->file);
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if(fwrite(buffer,1,size,options->outfile->file) != size)
|
|
|
|
{
|
|
|
|
perror(options->outfile->name);
|
|
|
|
exit(1);
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
if (options->gts && h->gts_header) {
|
|
|
|
char gts_trailer[4]={'\x0D','\x0D','\x0A','\x03'};
|
|
|
|
fwrite(gts_trailer,1,4,options->outfile->file);
|
|
|
|
}
|
|
|
|
#endif
|
2013-03-25 12:04:10 +00:00
|
|
|
|
2013-06-14 10:38:40 +00:00
|
|
|
}
|
2018-09-07 16:12:24 +00:00
|
|
|
int exit_if_input_is_directory(const char* tool_name, const char* filename)
|
2018-09-07 15:49:40 +00:00
|
|
|
{
|
|
|
|
struct stat s;
|
|
|
|
int stat_val = stat(filename, &s);
|
|
|
|
if ( stat_val == 0 ) {
|
|
|
|
if (S_ISDIR(s.st_mode)) {
|
2018-09-07 16:12:24 +00:00
|
|
|
fprintf(stderr, "%s: ERROR: \"%s\": Is a directory\n", tool_name, filename);
|
2018-09-07 15:49:40 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|