bufr2synop 0.24.0
Macros | Functions | Variables
build_bufrdeco_tables.c File Reference

This file includes the code for build_bufrdeco_tables binary. More...

#include "bufrdeco.h"
#include "config.h"
Include dependency graph for build_bufrdeco_tables.c:

Go to the source code of this file.

Macros

#define CONFIG_H
 

Functions

void print_usage (void)
 
int main (int argc, char *argv[])
 

Variables

const char SELF [] = "build_bufrdeco_tables"
 
char INPUT_FILE [256]
 
char TABLE_TYPE [8]
 
int IS_WMO
 
int A_FIELDS [8] = {1,2,-1,-1,-1,-1,-1,-1}
 
int B_FIELDS [8] = {3,4,5,6,7,8,9,-1}
 
int C_FIELDS [8] = {1,3,4,5,6,7,-1,-1}
 
int D_FIELDS [8] = {3,6,4,7,-1,-1,-1,-1}
 
int B_FIELDS_2 [8] = {2,3,4,5,6,7,8,-1}
 
int C_FIELDS_2 [8] = {0,2,3,4,5,6,-1,-1}
 
int D_FIELDS_2 [8] = {2,5,3,6,-1,-1,-1,-1}
 
int B_FIELDS_3 [8] = {2,3,11,4,5,6,7,-1}
 
int C_FIELDS_3 [8] = {0,2,3,4,5,6,-1,-1}
 
int D_FIELDS_3 [8] = {2,5,3,6,-1,-1,-1,-1}
 

Detailed Description

This file includes the code for build_bufrdeco_tables binary.

build_bufrdeco_tables is the tool to convert original BUFR files from ECMWF package and WMO machine readable files into the format used by the decode library bufrdeco included in this package. bufrdeco uses BUFR table files in csv format like WMO but supressing some fields from original WMO files.

Because of WMO has not released csv table files for versions prior to 18, it is needed to build them since version 13 using ECMWF table files. Version 13 is backward compatible with prior versions.

Following the ECMWF way to set the CodeFlag tables as C Tables, the original WMO CodeFlag Tables are named as C tables. Original WMO C tables with descriptors operators an A tables are no needed in this package.

Definition in file build_bufrdeco_tables.c.

Macro Definition Documentation

◆ CONFIG_H

#define CONFIG_H

Definition at line 41 of file build_bufrdeco_tables.c.

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 77 of file build_bufrdeco_tables.c.

78{
79 int iopt, i, *fs;
80 FILE *f;
81 char lin[CSV_MAXL], caux[CSV_MAXL], caux2[32];
82 char *tk[16], *c;
83 int nt;
84 uint32_t ix = 0;
85 long int il;
86 struct bufr_descriptor desc;
87
88 // Read args
89 TABLE_TYPE[0] = 0;
90 INPUT_FILE[0] = 0;
91 IS_WMO = 1;
92 while ( ( iopt = getopt ( argc, argv, "hei:t:23" ) ) !=-1 )
93 switch ( iopt )
94 {
95 case 'i':
96 if ( strlen ( optarg ) < 256 )
97 strcpy ( INPUT_FILE, optarg );
98 break;
99 case 't':
100 if ( strlen ( optarg ) < 8 )
101 strcpy ( TABLE_TYPE, optarg );
102 break;
103 case '2':
104 IS_WMO = 2;
105 break;
106 case '3':
107 IS_WMO = 3;
108 break;
109 case 'e':
110 case 'E':
111 IS_WMO = 0;
112 break;
113 case 'h':
114 default:
115 print_usage();
116 exit ( EXIT_SUCCESS );
117 }
118
119 if ( TABLE_TYPE[0] == 0 )
120 {
121 fprintf ( stderr, "%s: Error. Need to provide Table Type with arg -t\n", SELF );
122 exit ( EXIT_FAILURE );
123 }
124
125 if ( INPUT_FILE[0] == 0 )
126 {
127 f = stdin;
128 }
129 else if ( ( f = fopen ( INPUT_FILE, "r" ) ) == NULL )
130 {
131 fprintf ( stderr, "%s: Error. Cannot open file '%s'\n", SELF, INPUT_FILE );
132 exit ( EXIT_FAILURE );
133 }
134
135 if ( IS_WMO )
136 {
137 switch ( TABLE_TYPE[0] )
138 {
139 case 'A':
140 case 'a':
141 fs = & ( A_FIELDS[0] );
142 break;
143 case 'B':
144 case 'b':
145 if (IS_WMO == 1)
146 fs = & ( B_FIELDS[0] );
147 else if (IS_WMO == 2)
148 fs = & ( B_FIELDS_2[0] );
149 else
150 fs = & ( B_FIELDS_3[0] );
151 break;
152 case 'C':
153 case 'c':
154 if (IS_WMO == 1)
155 fs = & ( C_FIELDS[0] );
156 else if (IS_WMO == 2)
157 fs = & ( C_FIELDS_2[0] );
158 else
159 fs = & ( C_FIELDS_3[0] );
160 break;
161 case 'D':
162 case 'd':
163 if (IS_WMO == 1)
164 fs = & ( D_FIELDS[0] );
165 else if (IS_WMO == 2)
166 fs = & ( D_FIELDS_2[0] );
167 else
168 fs = & ( D_FIELDS_3[0] );
169 break;
170 default:
171 fprintf ( stderr, "%s: Error, bad '%s' table type\n", SELF, TABLE_TYPE );
172 fclose ( f );
173 exit ( EXIT_FAILURE );
174 }
175
176 while ( fgets ( lin, CSV_MAXL, f ) != NULL )
177 {
178 // Parse line
179 if ( parse_csv_line ( &nt, tk, lin ) < 0 )
180 {
181 fprintf ( stderr, "%s: Error parsing csv line '%s' from file '%s'\n", SELF, lin, INPUT_FILE );
182 fclose ( f );
183 exit ( EXIT_FAILURE );
184 }
185
186 i = 0;
187 while ( fs[i] >= 0 )
188 {
189 if ( i > 0 )
190 printf ( "," );
191 if ( strlen ( tk[fs[i]] ) )
192 printf ( "%s", csv_quoted_string ( caux, tk[fs[i]] ) );
193 i++;
194 }
195 printf ( "\n" );
196 }
197 }
198 else
199 {
200 // Decode ECMWF tables
201 // first line with the name of fields
202 switch ( TABLE_TYPE[0] )
203 {
204 case 'B':
205 case 'b':
206 printf ( "\"FXY\",\"ElementName_en\",\"Note_en\",\"BUFR_Unit\",\"BUFR_Scale\",\"BUFR_ReferenceValue\",\"BUFR_DataWidth_Bits\"\n" );
207 break;
208 case 'C':
209 case 'c':
210 printf ( "\"FXY\",\"CodeFigure\",\"EntryName_en\",\"EntryName_sub1_en\",\"EntryName_sub2_en\",\"Note_en\"\n" );
211 break;
212 case 'D':
213 case 'd':
214 printf ( "\"FXY1\",\"FXY2\",\"Title_en\",\"ElementName_en\"\n" );
215 break;
216 }
217
218 caux[0] = 0;
219 while ( fgets ( lin, CSV_MAXL, f ) != NULL )
220 {
221 // supress the newline
222 if ( ( c = strrchr ( lin,'\n' ) ) != NULL )
223 {
224 *c = '\0';
225 }
226
227 switch ( TABLE_TYPE[0] )
228 {
229 case 'B':
230 case 'b':
231 // Descriptor
232 ix = strtoul ( &lin[0], &c, 10 );
233 uint32_t_to_descriptor ( &desc, ix );
234 printf ( "\"%s\",", desc.c );
235
236 // detailed name and a void note
237 bufr_charray_to_string ( caux, &lin[8], 64 );
238 bufr_adjust_string ( caux ); // supress trailing blanks
239 printf ( "\"%s\",,", caux );
240
241 // type
242 bufr_charray_to_string ( caux ,&lin[73], 24 );
243 bufr_adjust_string ( caux );
244 printf ( "\"%s\",", caux );
245
246 // escale
247 il = strtol ( &lin[97], &c, 10 );
248 printf ( "\"%ld\",", il );
249
250 // reference
251 il = strtol ( &lin[102], &c, 10 );
252 printf ( "\"%ld\",", il );
253
254 // bits
255 il = strtol ( &lin[115], &c, 10 );
256 printf ( "\"%ld\"\n", il );
257 break;
258
259 case 'C':
260 case 'c':
261
262 // write csv line with stored data if finished
263 if ( lin[12] != ' ' && caux[0] )
264 {
265 printf ( "\"%s\",\"%u\",\"%s\",,,\n", caux2, ix, caux );
266 caux[0] = 0;
267 }
268
269 if ( lin[0] != ' ' )
270 {
271 memcpy ( caux2, lin, 6 );
272 caux2[6] = '\0';
273 }
274
275 if ( lin[12] != ' ' )
276 {
277 ix = strtol ( lin + 12, &c, 10 );
278 strcpy ( caux, lin + 24 );
279 }
280 else
281 {
282 if ( lin[22] != ' ' )
283 {
284 if ( strlen ( caux ) + strlen ( lin + 22 ) < BUFR_EXPLAINED_LENGTH )
285 strcat ( caux, lin + 22 );
286 else
287 {
288 // cut the explanation
289 * ( lin + 22 + BUFR_EXPLAINED_LENGTH - strlen ( caux ) - 1 ) = '\0';
290 strcat ( caux, lin + 22 );
291 }
292 }
293 else
294 {
295 // this is valid for versions < 15
296 if ( strlen ( caux ) + strlen ( lin + 24 ) < BUFR_EXPLAINED_LENGTH )
297 strcat ( caux, lin + 24 );
298 else
299 {
300 // cut the explanation
301 * ( lin + 24 + BUFR_EXPLAINED_LENGTH - strlen ( caux ) - 1 ) = '\0';
302 strcat ( caux, lin + 24 );
303 }
304 }
305 }
306
307 break;
308
309 case 'D':
310 case 'd':
311
312 if ( lin[1] != ' ' )
313 {
314 memcpy ( caux2, lin + 1, 6 );
315 caux2[6] = '\0';
316 }
317
318 memcpy ( caux, lin + 11, 6 );
319 caux[6] = '\0';
320 printf ( "\"%s\",\"%s\",,\n", caux2, caux );
321 break;
322
323 default:
324 fprintf ( stderr, "%s: Error, bad '%s' table type\n", SELF, TABLE_TYPE );
325 fclose ( f );
326 exit ( EXIT_FAILURE );
327 }
328 }
329
330 // In case of table C (codeFlag) we still have to write last line
331 if ( TABLE_TYPE[0] == 'C' || TABLE_TYPE[0] == 'c' )
332 {
333 printf ( "\"%s\",\"%u\",\"%s\",,,\n", caux2, ix, caux );
334 }
335 }
336 if (INPUT_FILE[0])
337 fclose ( f );
338
339 exit ( EXIT_SUCCESS );
340}
#define BUFR_EXPLAINED_LENGTH
Maximum length for a explained descriptor string.
Definition: bufrdeco.h:122
int uint32_t_to_descriptor(struct bufr_descriptor *d, uint32_t id)
parse an integer with a descriptor fom bufr ECWMF libary
#define CSV_MAXL
Maximum length in a string to be parsed as csv.
Definition: bufrdeco.h:128
char * bufr_charray_to_string(char *s, char *buf, size_t size)
get a null termitated c-string from an array of unsigned chars
int parse_csv_line(int *nt, char *tk[], char *lin)
Parse a csv line.
Definition: bufrdeco_csv.c:258
char * csv_quoted_string(char *out, char *in)
Transform a string to a quoted string to be inserted in a csv file.
Definition: bufrdeco_csv.c:48
char * bufr_adjust_string(char *s)
Supress trailing blanks of a string.
int C_FIELDS_2[8]
char INPUT_FILE[256]
int IS_WMO
int C_FIELDS[8]
const char SELF[]
char TABLE_TYPE[8]
int B_FIELDS[8]
int A_FIELDS[8]
int D_FIELDS_2[8]
void print_usage(void)
int B_FIELDS_3[8]
int D_FIELDS_3[8]
int D_FIELDS[8]
int B_FIELDS_2[8]
int C_FIELDS_3[8]
BUFR descriptor.
Definition: bufrdeco.h:409
char c[12]
Definition: bufrdeco.h:414

References A_FIELDS, B_FIELDS, B_FIELDS_2, B_FIELDS_3, bufr_adjust_string(), bufr_charray_to_string(), BUFR_EXPLAINED_LENGTH, bufr_descriptor::c, C_FIELDS, C_FIELDS_2, C_FIELDS_3, CSV_MAXL, csv_quoted_string(), D_FIELDS, D_FIELDS_2, D_FIELDS_3, bufr_descriptor::f, INPUT_FILE, IS_WMO, parse_csv_line(), print_usage(), SELF, TABLE_TYPE, and uint32_t_to_descriptor().

Here is the call graph for this function:

◆ print_usage()

void print_usage ( void  )

Definition at line 64 of file build_bufrdeco_tables.c.

65{
66 printf ( "%s %s\n", SELF, PACKAGE_VERSION );
67 printf ( "Usage: \n" );
68 printf ( "%s -i input_file -t table_type [-e[-h]\n" , SELF );
69 printf ( " -h Print this help\n" );
70 printf ( " -e Source ECMWF, default WMO\n" );
71 printf ( " -t table_type. (A = TableA, B = TableB, C = CodeFlag, D = TableD)\n" );
72 printf ( " -2 Version 35, 36 or 37\n");
73 printf ( " -3 Version 38 or newest\n");
74}
#define PACKAGE_VERSION
Definition: config.h:4

References PACKAGE_VERSION, and SELF.

Referenced by main().

Here is the caller graph for this function:

Variable Documentation

◆ A_FIELDS

int A_FIELDS[8] = {1,2,-1,-1,-1,-1,-1,-1}

Definition at line 48 of file build_bufrdeco_tables.c.

Referenced by main().

◆ B_FIELDS

int B_FIELDS[8] = {3,4,5,6,7,8,9,-1}

Definition at line 49 of file build_bufrdeco_tables.c.

Referenced by main().

◆ B_FIELDS_2

int B_FIELDS_2[8] = {2,3,4,5,6,7,8,-1}

Definition at line 53 of file build_bufrdeco_tables.c.

Referenced by main().

◆ B_FIELDS_3

int B_FIELDS_3[8] = {2,3,11,4,5,6,7,-1}

Definition at line 57 of file build_bufrdeco_tables.c.

Referenced by main().

◆ C_FIELDS

int C_FIELDS[8] = {1,3,4,5,6,7,-1,-1}

Definition at line 50 of file build_bufrdeco_tables.c.

Referenced by main().

◆ C_FIELDS_2

int C_FIELDS_2[8] = {0,2,3,4,5,6,-1,-1}

Definition at line 54 of file build_bufrdeco_tables.c.

Referenced by main().

◆ C_FIELDS_3

int C_FIELDS_3[8] = {0,2,3,4,5,6,-1,-1}

Definition at line 58 of file build_bufrdeco_tables.c.

Referenced by main().

◆ D_FIELDS

int D_FIELDS[8] = {3,6,4,7,-1,-1,-1,-1}

Definition at line 51 of file build_bufrdeco_tables.c.

Referenced by main().

◆ D_FIELDS_2

int D_FIELDS_2[8] = {2,5,3,6,-1,-1,-1,-1}

Definition at line 55 of file build_bufrdeco_tables.c.

Referenced by main().

◆ D_FIELDS_3

int D_FIELDS_3[8] = {2,5,3,6,-1,-1,-1,-1}

Definition at line 59 of file build_bufrdeco_tables.c.

Referenced by main().

◆ INPUT_FILE

char INPUT_FILE[256]

Definition at line 45 of file build_bufrdeco_tables.c.

Referenced by main().

◆ IS_WMO

int IS_WMO

Definition at line 47 of file build_bufrdeco_tables.c.

Referenced by main().

◆ SELF

const char SELF[] = "build_bufrdeco_tables"

Definition at line 44 of file build_bufrdeco_tables.c.

Referenced by main(), and print_usage().

◆ TABLE_TYPE

char TABLE_TYPE[8]

Definition at line 46 of file build_bufrdeco_tables.c.

Referenced by main().