From c8200f616714c0bd8730f2cb337f56e95e50b138 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Wed, 14 Sep 2016 17:49:07 +0100 Subject: [PATCH] ECC-320: bufr_dump -DC (part 1) --- src/grib_dumper_class_bufr_decode_C.c | 186 +++++++------------------- tests/CMakeLists.txt | 1 + tests/bufr_dump_decode_C.sh | 84 ++++++++++++ tests/bufr_dump_decode_python.sh | 2 + 4 files changed, 135 insertions(+), 138 deletions(-) create mode 100755 tests/bufr_dump_decode_C.sh diff --git a/src/grib_dumper_class_bufr_decode_C.c b/src/grib_dumper_class_bufr_decode_C.c index 5bdf5dcac..f59df2a4d 100644 --- a/src/grib_dumper_class_bufr_decode_C.c +++ b/src/grib_dumper_class_bufr_decode_C.c @@ -155,8 +155,7 @@ static void dump_values(grib_dumper* d, grib_accessor* a) double value; size_t size = 0; double *values=NULL; int err = 0; - int i,r,icount; - int cols=2; + int r=0; long count=0; char* sval; grib_context* c=a->context; @@ -181,38 +180,24 @@ static void dump_values(grib_dumper* d, grib_accessor* a) fprintf(self->dumper.out," free(rvalues); rvalues = NULL;\n\n"); fprintf(self->dumper.out," rvalues = (double*)malloc(%lu*sizeof(double));\n", (unsigned long)size); fprintf(self->dumper.out," if (!rvalues) { fprintf(stderr, \"Failed to allocate memory (rvalues).\\n\"); return 1; }\n"); - fprintf(self->dumper.out," size = %lu;", size); - - icount=0; - for (i=0; icols || i==0) {fprintf(self->dumper.out,"\n ");icount=0;} - sval=dval_to_string(c,values[i]); - fprintf(self->dumper.out,"rvalues[%d]=%s; ", i, sval); - grib_context_free(c,sval); - icount++; - } - if (icount>cols || i==0) {fprintf(self->dumper.out,"\n ");icount=0;} - sval=dval_to_string(c,values[i]); - fprintf(self->dumper.out,"rvalues[%d]=%s;", i,sval); - grib_context_free(c,sval); + fprintf(self->dumper.out," size = %lu;\n", size); depth-=2; - fprintf(self->dumper.out,"\n"); grib_context_free(c,values); if ((r=compute_key_rank(h,self->keys,a->name))!=0) - fprintf(self->dumper.out," CODES_CHECK(codes_set_double_array(h, \"#%d#%s\",rvalues, size), 0);\n", r, a->name); + fprintf(self->dumper.out," CODES_CHECK(codes_get_double_array(h, \"#%d#%s\",rvalues, &size), 0);\n", r, a->name); else - fprintf(self->dumper.out," CODES_CHECK(codes_set_double_array(h, \"%s\", rvalues, size), 0);\n",a->name); + fprintf(self->dumper.out," CODES_CHECK(codes_get_double_array(h, \"%s\", rvalues, &size), 0);\n",a->name); } else { r=compute_key_rank(h,self->keys,a->name); if( !grib_is_missing_double(a,value) ) { sval=dval_to_string(c,value); if (r!=0) - fprintf(self->dumper.out," CODES_CHECK(codes_set_double(h, \"#%d#%s\", %s), 0);\n", r, a->name, sval); + fprintf(self->dumper.out," CODES_CHECK(codes_get_double(h, \"#%d#%s\", &doubleVal), 0);\n", r, a->name); else - fprintf(self->dumper.out," CODES_CHECK(codes_set_double(h, \"%s\", %s), 0);\n", a->name, sval); + fprintf(self->dumper.out," CODES_CHECK(codes_get_double(h, \"%s\", &doubleVal), 0);\n", a->name); grib_context_free(c,sval); } @@ -242,8 +227,6 @@ static void dump_values_attribute(grib_dumper* d, grib_accessor* a, const char* double value; size_t size = 0; double *values=NULL; int err = 0; - int i,icount; - int cols=2; long count=0; char* sval; grib_context* c=a->context; @@ -267,32 +250,18 @@ static void dump_values_attribute(grib_dumper* d, grib_accessor* a, const char* fprintf(self->dumper.out," free(rvalues); rvalues = NULL;\n"); fprintf(self->dumper.out," rvalues = (double*)malloc(%lu*sizeof(double));\n", (unsigned long)size); fprintf(self->dumper.out," if (!rvalues) { fprintf(stderr, \"Failed to allocate memory (rvalues).\\n\"); return 1; }\n"); - fprintf(self->dumper.out," size = %lu;", size); - - icount=0; - for (i=0; icols || i==0) {fprintf(self->dumper.out,"\n ");icount=0;} - sval=dval_to_string(c,values[i]); - fprintf(self->dumper.out,"rvalues[%d]=%s; ", i, sval); - grib_context_free(c,sval); - icount++; - } - if (icount>cols || i==0) {fprintf(self->dumper.out,"\n ");icount=0;} - sval=dval_to_string(c,values[i]); - fprintf(self->dumper.out,"rvalues[%d]=%s;", i,sval); - grib_context_free(c,sval); + fprintf(self->dumper.out," size = %lu\n;", size); depth-=2; - fprintf(self->dumper.out,"\n"); grib_context_free(c,values); - fprintf(self->dumper.out," CODES_CHECK(codes_set_double_array(h, \"%s->%s\", rvalues, size), 0);\n", prefix,a->name); + fprintf(self->dumper.out," CODES_CHECK(codes_get_double_array(h, \"%s->%s\", rvalues, &size), 0);\n", prefix,a->name); } else { /* int r=compute_key_rank(h,self->keys,a->name); */ if( !grib_is_missing_double(a,value) ) { sval=dval_to_string(c,value); - fprintf(self->dumper.out," CODES_CHECK(codes_set_double(h, \"%s->%s\", %s), 0);\n", prefix,a->name, sval); + fprintf(self->dumper.out," CODES_CHECK(codes_get_double(h, \"%s->%s\", &doubleVal), 0);\n", prefix,a->name); grib_context_free(c,sval); @@ -320,8 +289,7 @@ static void dump_long(grib_dumper* d,grib_accessor* a, const char* comment) long value; size_t size = 0; long *values=NULL; int err = 0; - int i,r,icount; - int cols=4; + int r=0; long count=0; grib_context* c=a->context; grib_handle* h=grib_handle_of_accessor(a); @@ -363,35 +331,23 @@ static void dump_long(grib_dumper* d,grib_accessor* a, const char* comment) fprintf(self->dumper.out," free(ivalues); ivalues = NULL;\n\n"); fprintf(self->dumper.out," ivalues = (long*)malloc(%lu*sizeof(long));\n", (unsigned long)size); fprintf(self->dumper.out," if (!ivalues) { fprintf(stderr, \"Failed to allocate memory (ivalues).\\n\"); return 1; }\n"); - fprintf(self->dumper.out," size = %lu;", size); - - icount=0; - for (i=0;icols || i==0) {fprintf(self->dumper.out,"\n ");icount=0;} - fprintf(self->dumper.out,"ivalues[%d]=%ld; ", i, values[i]); - icount++; - } - if (icount>cols || i==0) {fprintf(self->dumper.out,"\n ");icount=0;} - fprintf(self->dumper.out,"ivalues[%d]=%ld;", i, values[i]); + fprintf(self->dumper.out," size = %lu;\n", size); depth-=2; - fprintf(self->dumper.out,"\n"); grib_context_free(a->context,values); if ((r=compute_key_rank(h,self->keys,a->name))!=0) - fprintf(self->dumper.out," CODES_CHECK(codes_set_long_array(h, \"#%d#%s\", ivalues, size), 0);\n",r,a->name); + fprintf(self->dumper.out," CODES_CHECK(codes_get_long_array(h, \"#%d#%s\", ivalues, &size), 0);\n",r,a->name); else - fprintf(self->dumper.out," CODES_CHECK(codes_set_long_array(h, \"%s\", ivalues, size), 0);\n",a->name); + fprintf(self->dumper.out," CODES_CHECK(codes_get_long_array(h, \"%s\", ivalues, &size), 0);\n",a->name); } else { r=compute_key_rank(h,self->keys,a->name); if( !grib_is_missing_long(a,value) ) { if (r!=0) - fprintf(self->dumper.out," CODES_CHECK(codes_set_long(h, \"#%d#%s\", ", r,a->name); + fprintf(self->dumper.out," CODES_CHECK(codes_get_long(h, \"#%d#%s\", &longVal), 0);\n", r,a->name); else - fprintf(self->dumper.out," CODES_CHECK(codes_set_long(h, \"%s\", ", a->name); - - fprintf(self->dumper.out,"%ld), 0);\n",value); + fprintf(self->dumper.out," CODES_CHECK(codes_get_long(h, \"%s\", &longVal), 0);\n", a->name); } } @@ -418,8 +374,6 @@ static void dump_long_attribute(grib_dumper* d, grib_accessor* a, const char* pr long value; size_t size = 0; long *values=NULL; int err = 0; - int i,icount; - int cols=4; long count=0; grib_context* c=a->context; @@ -442,28 +396,17 @@ static void dump_long_attribute(grib_dumper* d, grib_accessor* a, const char* pr fprintf(self->dumper.out," free(ivalues); ivalues = NULL;\n"); fprintf(self->dumper.out," ivalues = (long*)malloc(%lu*sizeof(long));\n", (unsigned long)size); fprintf(self->dumper.out," if (!ivalues) { fprintf(stderr, \"Failed to allocate memory (ivalues).\\n\"); return 1; }\n"); - fprintf(self->dumper.out," size = %lu;", size); - - icount=0; - for (i=0;icols || i==0) {fprintf(self->dumper.out,"\n ");icount=0;} - fprintf(self->dumper.out,"ivalues[%d]=%ld; ", i, values[i]); - icount++; - } - if (icount>cols || i==0) {fprintf(self->dumper.out,"\n ");icount=0;} - fprintf(self->dumper.out,"ivalues[%d]=%ld;", i, values[i]); + fprintf(self->dumper.out," size = %lu;\n", size); depth-=2; - fprintf(self->dumper.out,"\n"); grib_context_free(a->context,values); - fprintf(self->dumper.out," CODES_CHECK(codes_set_long_array(h, \"%s->%s\", ivalues, size), 0);\n", prefix,a->name); + fprintf(self->dumper.out," CODES_CHECK(codes_get_long_array(h, \"%s->%s\", ivalues, &size), 0);\n", prefix,a->name); } else { /* int r=compute_key_rank(h,self->keys,a->name); */ if( !grib_is_missing_long(a,value) ) { - fprintf(self->dumper.out," CODES_CHECK(codes_set_long(h, \"%s->%s\", ", prefix,a->name); - fprintf(self->dumper.out,"%ld), 0);\n",value); + fprintf(self->dumper.out," CODES_CHECK(codes_get_long(h, \"%s->%s\", &longVal), 0);\n", prefix,a->name); } } @@ -504,9 +447,9 @@ static void dump_double(grib_dumper* d, grib_accessor* a, const char* comment) if( !grib_is_missing_double(a,value) ) { sval=dval_to_string(c,value); if (r!=0) - fprintf(self->dumper.out," codes_set_double(h, \"#%d#%s\", %s);\n", r,a->name, sval); + fprintf(self->dumper.out," CODES_CHECK(codes_get_double(h, \"#%d#%s\", &doubleVal), 0);\n", r,a->name); else - fprintf(self->dumper.out," codes_set_double(h, \"%s\", %s);\n", a->name, sval); + fprintf(self->dumper.out," CODES_CHECK(codes_get_double(h, \"%s\", &doubleVal), 0);\n", a->name); grib_context_free(c,sval); } @@ -570,9 +513,9 @@ static void dump_string_array(grib_dumper* d, grib_accessor* a, const char* comm if (self->isLeaf==0) { if ((r=compute_key_rank(h,self->keys,a->name))!=0) - fprintf(self->dumper.out," codes_set_string_array(h, \"#%d#%s\", (const char **)svalues, size);\n",r,a->name); + fprintf(self->dumper.out," codes_get_string_array(h, \"#%d#%s\", (const char **)svalues, size);\n",r,a->name); else - fprintf(self->dumper.out," codes_set_string_array(h, \"%s\", (const char **)svalues, size);\n",a->name); + fprintf(self->dumper.out," codes_get_string_array(h, \"%s\", (const char **)svalues, size);\n",a->name); } if (self->isLeaf==0) { @@ -627,14 +570,14 @@ static void dump_string(grib_dumper* d, grib_accessor* a, const char* comment) while(*p) { if(!isprint(*p)) *p = '.'; p++; } + fprintf(self->dumper.out," size = 1024;\n"); /* TODO */ if (self->isLeaf==0) { depth+=2; if (r!=0) - fprintf(self->dumper.out," codes_set_string(h, \"#%d#%s\", ", r, a->name); + fprintf(self->dumper.out," CODES_CHECK(codes_get_string(h, \"#%d#%s\", strVal, &size), 0);\n", r, a->name); else - fprintf(self->dumper.out," codes_set_string(h, \"%s\", ", a->name); + fprintf(self->dumper.out," CODES_CHECK(codes_get_string(h, \"%s\", strVal, &size), 0);\n", a->name); } - fprintf(self->dumper.out,"\"%s\", &size);\n",value); if (self->isLeaf==0) { char* prefix; @@ -665,10 +608,7 @@ static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) static void _dump_long_array(grib_handle* h, FILE* f, const char* key, const char* print_key) { - long* val; - size_t size=0,i; - int cols=9,icount=0; - + size_t size=0; if (grib_get_size(h,key,&size)==GRIB_NOT_FOUND) return; fprintf(f," free(ivalues); ivalues = NULL;\n"); @@ -676,18 +616,7 @@ static void _dump_long_array(grib_handle* h, FILE* f, const char* key, const cha fprintf(f," if (!ivalues) { fprintf(stderr, \"Failed to allocate memory (ivalues).\\n\"); return 1; }\n"); fprintf(f," size = %lu;", size); - val=grib_context_malloc_clear(h->context,sizeof(long)*size); - grib_get_long_array(h,key,val,&size); - for (i=0;icols || i==0) {fprintf(f,"\n ");icount=0;} - fprintf(f,"ivalues[%lu]=%ld; ", i, val[i]); - icount++; - } - if (icount>cols) {fprintf(f,"\n ");} - fprintf(f,"ivalues[%lu]=%ld;\n", size-1, val[size-1]); - - grib_context_free(h->context,val); - fprintf(f," CODES_CHECK(codes_set_long_array(h, \"%s\", ivalues, size), 0);\n",print_key); + fprintf(f," CODES_CHECK(codes_get_long_array(h, \"%s\", ivalues, &size), 0);\n",print_key); } static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) @@ -755,74 +684,55 @@ static void dump_attributes(grib_dumper* d,grib_accessor* a, const char* prefix) static void header(grib_dumper* d, grib_handle* h) { grib_dumper_bufr_decode_C *self = (grib_dumper_bufr_decode_C*)d; - char sampleName[200]={0}; - long localSectionPresent,edition,bufrHeaderCentre,isSatellite; - Assert(h->product_kind == PRODUCT_BUFR); - grib_get_long(h,"localSectionPresent",&localSectionPresent); - grib_get_long(h,"bufrHeaderCentre",&bufrHeaderCentre); - grib_get_long(h,"edition",&edition); - - if (localSectionPresent && bufrHeaderCentre==98 ) { - grib_get_long(h,"isSatellite",&isSatellite); - if (isSatellite) - sprintf(sampleName,"BUFR%ld_local_satellite",edition); - else - sprintf(sampleName,"BUFR%ld_local",edition); - } else { - sprintf(sampleName,"BUFR%ld",edition); - } - if (d->count<2) { + /* This is the first message being processed */ fprintf(self->dumper.out,"/* This program was automatically generated with bufr_dump -DC */\n"); fprintf(self->dumper.out,"/* Using ecCodes version: "); grib_print_api_version(self->dumper.out); fprintf(self->dumper.out, " */\n\n"); fprintf(self->dumper.out,"#include \"eccodes.h\"\n"); - fprintf(self->dumper.out,"int main()\n"); + fprintf(self->dumper.out,"int main(int argc, char* argv[])\n"); fprintf(self->dumper.out,"{\n"); - fprintf(self->dumper.out," size_t size=0;\n"); - fprintf(self->dumper.out," const void* buffer = NULL;\n"); - fprintf(self->dumper.out," FILE* fout = NULL;\n"); + fprintf(self->dumper.out," size_t size = 0;\n"); + fprintf(self->dumper.out," int err = 0;\n"); + fprintf(self->dumper.out," FILE* in = NULL;\n"); fprintf(self->dumper.out," codes_handle* h = NULL;\n"); + fprintf(self->dumper.out," long longVal = 0;\n"); + fprintf(self->dumper.out," double doubleVal = 0.0;\n"); + fprintf(self->dumper.out," char strVal[1024] = {0,};\n"); fprintf(self->dumper.out," long* ivalues = NULL;\n"); fprintf(self->dumper.out," char** svalues = NULL;\n"); fprintf(self->dumper.out," double* rvalues = NULL;\n"); - fprintf(self->dumper.out," const char* sampleName = \"%s\";\n\n", sampleName); + fprintf(self->dumper.out," const char* infile_name = argv[1];\n\n"); + + fprintf(self->dumper.out," in = fopen(infile_name, \"r\");\n"); + fprintf(self->dumper.out," if (!in) {\n"); + fprintf(self->dumper.out," fprintf(stderr,\"ERROR: Unable to open input BUFR file %%s\\n\", infile_name);\n"); + fprintf(self->dumper.out," return 1;\n"); + fprintf(self->dumper.out," }\n\n"); } - fprintf(self->dumper.out," h = codes_bufr_handle_new_from_samples(NULL, sampleName);\n"); + fprintf(self->dumper.out," h = codes_handle_new_from_file(NULL, in, PRODUCT_BUFR, &err);\n"); fprintf(self->dumper.out," if (h == NULL) {\n"); - fprintf(self->dumper.out," fprintf(stderr, \"ERROR creating BUFR from %%s\\n\", sampleName);\n"); + fprintf(self->dumper.out," fprintf(stderr, \"ERROR creating BUFR\\n\");\n"); fprintf(self->dumper.out," return 1;\n"); fprintf(self->dumper.out," }\n"); + fprintf(self->dumper.out," CODES_CHECK(codes_set_long(h, \"unpack\", 1),0);\n\n"); } static void footer(grib_dumper* d, grib_handle* h) { grib_dumper_bufr_decode_C *self = (grib_dumper_bufr_decode_C*)d; - fprintf(self->dumper.out,"\n codes_set_long(h, \"pack\", 1);\n"); - if (d->count==1) - fprintf(self->dumper.out," fout = fopen(\"outfile.bufr\", \"w\");\n"); - else - fprintf(self->dumper.out," fout = fopen(\"outfile.bufr\", \"a\");\n"); /*fprintf(self->dumper.out," fout = fopen(\"outfile.bufr\", \"w\");");*/ - fprintf(self->dumper.out," if (!fout) {\n"); - fprintf(self->dumper.out," fprintf(stderr, \"Failed to open output file.\\n\");\n"); - fprintf(self->dumper.out," return 1;\n"); - fprintf(self->dumper.out," }\n"); - fprintf(self->dumper.out," CODES_CHECK(codes_get_message(h,&buffer,&size),0);\n"); - fprintf(self->dumper.out," if (fwrite(buffer,1,size,fout) != size) {\n"); - fprintf(self->dumper.out," fprintf(stderr, \"Failed to write data.\\n\");\n"); - fprintf(self->dumper.out," return 1;\n"); - fprintf(self->dumper.out," }\n"); - fprintf(self->dumper.out," if (fclose(fout)) {\n"); + /*fprintf(self->dumper.out," if (fclose(fout)) {\n"); fprintf(self->dumper.out," fprintf(stderr, \"Failed to close file handle.\\n\");\n"); fprintf(self->dumper.out," return 1;\n"); fprintf(self->dumper.out," }\n"); - fprintf(self->dumper.out," \n"); + */ + fprintf(self->dumper.out,"\n"); fprintf(self->dumper.out," codes_handle_delete(h);\n"); fprintf(self->dumper.out," free(ivalues); ivalues = NULL;\n"); fprintf(self->dumper.out," free(rvalues); rvalues = NULL;\n"); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2e7c105d4..89028358f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -116,6 +116,7 @@ if( HAVE_FORTRAN AND ENABLE_EXTRA_TESTS ) endif() if( ENABLE_EXTRA_TESTS ) list(APPEND tests2 bufr_dump_encode_C) + list(APPEND tests2 bufr_dump_decode_C) endif() # These tests do not require any data downloads diff --git a/tests/bufr_dump_decode_C.sh b/tests/bufr_dump_decode_C.sh new file mode 100755 index 000000000..434f1a552 --- /dev/null +++ b/tests/bufr_dump_decode_C.sh @@ -0,0 +1,84 @@ +#!/bin/sh +# Copyright 2005-2016 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.sh + +#Define a common label for all the tmp files +label="bufr_dump_decode_C_test" + +#Create log file +fLog=${label}".log" +rm -f $fLog + +tempDir=${label}.dir +mkdir -p $tempDir + +bufr_files=`cat ${data_dir}/bufr/bufr_data_files.txt` + +# pkgconfig should be one level above the test dir +PKGCONFIG_FILE=../eccodes.pc +CACHE_FILE=../CMakeCache.txt + +COMPILE_AND_RUN=0 + +if command -v pkg-config >/dev/null 2>&1; then + if [ -f "$PKGCONFIG_FILE" ]; then + # Work out the C compiler and flags from pkgconfig + COMPILER=`pkg-config --variable=CC $PKGCONFIG_FILE` + FLAGS_COMPILER=`pkg-config --cflags $PKGCONFIG_FILE` + FLAGS_LINKER=`pkg-config --libs $PKGCONFIG_FILE` + + # The pkgconfig variables refer to the install directory. Change to build dir + BUILD_DIR=`grep -w eccodes_BINARY_DIR $CACHE_FILE | cut -d'=' -f2` + INSTALL_DIR=`grep -w CMAKE_INSTALL_PREFIX $CACHE_FILE | cut -d'=' -f2` + FLAGS_LINKER=`echo $FLAGS_LINKER | sed -e "s:$INSTALL_DIR:$BUILD_DIR:g"` + FLAGS_COMPILER=`echo $FLAGS_COMPILER | sed -e "s:$INSTALL_DIR:$BUILD_DIR:g"` + + # TODO: For now only support when shared libs enabled + SHARED_LIBS=`grep -w BUILD_SHARED_LIBS $CACHE_FILE | cut -d'=' -f2` + if [ "$SHARED_LIBS" = "ON" ]; then + COMPILE_AND_RUN=1 + fi + fi +fi + +cd $tempDir + +for file in ${bufr_files} +do + tempSrc=$label.$file.c + tempExe=$label.$file.exe + filePath=${data_dir}/bufr/$file + + # Generate C code from BUFR file + ${tools_dir}bufr_dump -DC $filePath > $tempSrc + + if [ "$file" = "pgps_110.bufr" ]; then + continue + fi + + # Compile + if [ $COMPILE_AND_RUN -eq 1 ]; then + # TODO: eccodes.h and the generated eccodes_version.h need to be pointed to + # Should be copied over to the build/include dir + INCL_DIR1=${proj_dir}/src + INCL_DIR2=${data_dir}/../src + + $COMPILER -o $tempExe $tempSrc -I${INCL_DIR1} -I${INCL_DIR2} $FLAGS_COMPILER $FLAGS_LINKER + + # valgrind --error-exitcode=1 ./$tempExe + ./$tempExe $filePath + fi + + rm -f $tempExe $tempSrc +done + +cd $test_dir +rm -fr $tempDir diff --git a/tests/bufr_dump_decode_python.sh b/tests/bufr_dump_decode_python.sh index 8027e94d8..3e1b98e1f 100755 --- a/tests/bufr_dump_decode_python.sh +++ b/tests/bufr_dump_decode_python.sh @@ -21,6 +21,8 @@ tempDir=${label}.dir mkdir -p $tempDir cd $tempDir +echo "PYTHONPATH set to $PYTHONPATH" + bufr_files=`cat ${data_dir}/bufr/bufr_data_files.txt` for file in ${bufr_files}