NCEPLIBS-bufr  12.1.0
debufr.c
Go to the documentation of this file.
1 
7 #include <ctype.h>
8 #include <string.h>
9 #include <stdio.h>
10 #include <libgen.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 
14 #include "bufr_interface.h"
15 
38 void fdebufr_f( char *ofile, int lenof, char *tbldir, int lentd, char *tblfil, int lentf, char *prmstg, int lenps,
39  char *basic, char *forcemt, char *cfms );
40 
48 void prtusage( char *prgnam ) {
49  printf( "\nUSAGE:\n" );
50  printf( " %s [-v] [-h] [-b] [-c] [-m] [-o outfile] [-t tabledir] [-f tablefil] [-p prmstg] bufrfile\n\n", prgnam );
51  printf( "\nWHERE:\n" );
52  printf( " -v prints program version information and exits\n\n" );
53  printf( " -h prints program help and usage information and exits\n\n" );
54  printf( " -b specifies the \"basic\" option, meaning that only the\n" );
55  printf( " information in Sections 0-3 will be decoded from each\n" );
56  printf( " BUFR message in the bufrfile, and no attempt will be\n" );
57  printf( " made to decode the data in Section 4\n\n" );
58  printf( " -c specifies that code and flag table meanings should not\n" );
59  printf( " be read from master BUFR tables and included in the output;\n" );
60  printf( " otherwise this feature is enabled by default\n\n" );
61  printf( " -m specifies that master BUFR tables will be used to\n" );
62  printf( " decode the data messages in the file, regardless of\n" );
63  printf( " whether it contains any embedded DX BUFR table messages.\n" );
64  printf( " This option can be used to view the actual contents of\n" );
65  printf( " DX BUFR table messages, which otherwise would not be\n" );
66  printf( " printed in the output listing.\n\n" );
67  printf( " outfile [path/]name of file to contain verbose output listing.\n" );
68  printf( " The default is \"bufrfilename.debufr.out\" in the current\n" );
69  printf( " working directory, where bufrfilename is the basename of\n" );
70  printf( " the bufrfile (i.e. bufrfile with any preceding [path/]\n" );
71  printf( " removed).\n\n" );
72  printf( " tabledir [path/]name of directory containing tables to be used\n" );
73  printf( " for decoding. This directory contains the DX BUFR tables\n" );
74  printf( " file to be used (if one was specified via the -f option),\n" );
75  printf( " or it may contain all of the master BUFR tables when these\n" );
76  printf( " are being used to decode a file. If unspecified, the\n" );
77  printf( " default directory location is\n" );
78  printf( " \"/home/runner/work/NCEPLIBS-bufr/NCEPLIBS-bufr/bufr/build-docs/install/tables\"\n\n" );
79  printf( " tablefil file within tabledir containing DX BUFR tables to be used\n" );
80  printf( " for decoding.\n\n" );
81  printf( " prmstg string of comma-separated PARAMETER=VALUE pairs, up to a\n" );
82  printf( " maximum of 20. For each pair, the dynamic allocation\n" );
83  printf( " PARAMETER will be set to VALUE within the underlying\n" );
84  printf( " NCEPLIBS-bufr software, overriding the default value that would\n" );
85  printf( " otherwise be used. A complete list of parameters that can\n" );
86  printf( " be dynamically sized is included within the documentation\n" );
87  printf( " for NCEPLIBS-bufr function isetprm.\n\n" );
88  printf( " bufrfile [path/]name of BUFR file to be decoded\n\n" );
89 }
90 
167 int main( int argc, char *argv[ ] ) {
168 
169  int ch;
170  int iret;
171  int lenof, lentd, lentf, lenps;
172 
173  char basic = 'N';
174  char forcemt = 'N';
175  char cfms = 'Y';
176  char io = 'r';
177  char tbldir_default[240] =
178  "/home/runner/work/NCEPLIBS-bufr/NCEPLIBS-bufr/bufr/build-doc"
179  "s/install/tables";
180  char bvstr[VERS_STR_LEN+1];
181 
182  char *ofile = NULL;
183  char *tbldir = NULL;
184  char *tblfil = NULL;
185  char *prmstg = NULL;
186  char *wkstr = NULL;
187 
188  char *bcopy, *bname, *dcopy, *dname;
189 
190  /*
191  ** Get and process the valid options from the command line:
192  */
193  while ( ( ch = getopt ( argc, argv, "vhbcmo:t:f:p:" ) ) != EOF ) {
194  switch ( ch ) {
195  case 'v':
196  bvers_f( bvstr, VERS_STR_LEN+1 );
197  printf( "This is the debufr utility, built with NCEPLIBS-bufr v%s\n", bvstr );
198  return 0;
199  case 'h':
200  printf( "\nPROGRAM %s\n", argv[0] );
201  printf( "\nABSTRACT: This program decodes a BUFR file and generates a verbose\n" );
202  printf( " listing of the contents. If a DX BUFR tables file is specified\n" );
203  printf( " (using the -f option) or if the specified BUFR file contains an\n" );
204  printf( " embedded DX BUFR tables message as the first message in the file,\n" );
205  printf( " then this DX BUFR tables information is used to decode the data\n" );
206  printf( " messages in the file. Otherwise, or whenever the -m option is\n" );
207  printf( " specified, master BUFR tables are read and used to decode the\n" );
208  printf( " data messages in the file.\n" );
209  prtusage( argv[0] );
210  return 0;
211  break;
212  case 'b':
213  basic = 'Y';
214  break;
215  case 'm':
216  forcemt = 'Y';
217  break;
218  case 'c':
219  cfms = 'N';
220  break;
221  case 'o':
222  if ( ( ofile = malloc( strlen( optarg ) + 1 ) ) == NULL ) {
223  printf( "\nERROR: Could not allocate memory for output file name!\n" );
224  return -1;
225  }
226  strcpy ( ofile, optarg );
227  break;
228  case 't':
229  if ( ( tbldir = malloc( strlen( optarg ) + 1 ) ) == NULL ) {
230  printf( "\nERROR: Could not allocate memory for tables directory!\n" );
231  return -1;
232  }
233  strcpy ( tbldir, optarg );
234  break;
235  case 'f':
236  if ( ( wkstr = malloc( strlen( optarg ) + 1 ) ) == NULL ) {
237  printf( "\nERROR: Could not allocate memory for DX BUFR tables file!\n" );
238  return -1;
239  }
240  strcpy ( wkstr, optarg );
241  break;
242  case 'p':
243  if ( ( prmstg = malloc( strlen( optarg ) + 1 ) ) == NULL ) {
244  printf( "\nERROR: Could not allocate memory for PARAMETER(S)=VALUE(S) string!\n" );
245  return -1;
246  }
247  strcpy ( prmstg, optarg );
248  break;
249  }
250  }
251 
252  /*
253  ** There should be one remaining command line argument specifying the
254  ** input BUFR file.
255  */
256  if ( (optind+1) != argc ) {
257  printf( "\nERROR: You must specify an input BUFR file to be decoded!\n" );
258  prtusage( argv[0] );
259  return -1;
260  }
261 
262  /*
263  ** Open the input BUFR file.
264  */
265  cobfl( argv[optind], io );
266 
267  /*
268  ** Check whether a PARAMETER(S)=VALUE(S) string was specified.
269  */
270  if ( prmstg == NULL ) { // no, so set a default value
271  if ( ( prmstg = malloc( 9 ) ) == NULL ) {
272  printf( "\nERROR: Could not allocate memory for PARAMETER(S)=VALUE(S) string!\n" );
273  return -1;
274  }
275  strcpy( prmstg, "NULLPSTG" );
276  }
277 
278  /*
279  ** Check whether a tables directory was specified.
280  */
281  if ( tbldir == NULL ) { // no, so use the default directory
282  if ( ( tbldir = malloc( strlen( tbldir_default ) + 1 ) ) == NULL ) {
283  printf( "\nERROR: Could not allocate memory for tables directory!\n" );
284  return -1;
285  }
286  strcpy( tbldir, tbldir_default );
287  }
288 
289  /*
290  ** Check whether a DX tables file was specified.
291  */
292  if ( wkstr == NULL ) { // no, so set a default value
293  if ( ( tblfil = malloc( 9 ) ) == NULL ) {
294  printf( "\nERROR: Could not allocate memory for DX BUFR tables file!\n" );
295  return -1;
296  }
297  strcpy( tblfil, "NULLFILE" );
298  }
299  else {
300  if ( ( tblfil = malloc( strlen( tbldir ) + strlen( wkstr ) + 2 ) ) == NULL ) {
301  printf( "\nERROR: Could not allocate memory for DX BUFR tables file!\n" );
302  return -1;
303  }
304  sprintf( tblfil, "%s%c%s", tbldir, '/', wkstr );
305  }
306  free( wkstr );
307 
308  /*
309  ** Check whether an output file was specified. If not, make a default
310  ** filename in the current working directory using the basename of the
311  ** input BUFR file.
312  */
313  if ( ofile == NULL ) {
314  bcopy = strdup( argv[optind] );
315  bname = basename( bcopy );
316  if ( ( ofile = malloc( strlen( bname ) + 15 ) ) == NULL ) {
317  printf( "\nERROR: Could not allocate memory for output file name!\n" );
318  return -1;
319  }
320  strcpy( ofile, bname );
321  strcat( ofile, ".debufr.out" );
322  free( bcopy );
323  }
324 
325  /*
326  ** Confirm that the output directory is writeable.
327  */
328  dcopy = strdup( ofile );
329  dname = dirname( dcopy );
330  if ( access( dname, W_OK ) != 0 ) {
331  printf( "\nERROR: Cannot write output file to %s\n",
332  ( strcmp( dname, "." ) == 0 ? "current working directory" : dname ) );
333  prtusage( argv[0] );
334  iret = -1;
335  }
336  else {
337 
338  /*
339  ** Read and decode each message from the input BUFR file.
340  */
341  lenof = strlen( ofile );
342  lentd = strlen( tbldir );
343  lentf = strlen( tblfil );
344  lenps = strlen( prmstg );
345  fdebufr_f( ofile, lenof, tbldir, lentd, tblfil, lentf, prmstg, lenps, &basic, &forcemt, &cfms );
346  iret = 0;
347  }
348  free( dcopy );
349 
350  free( ofile );
351  free( tbldir );
352  free( tblfil );
353  free( prmstg );
354 
355  /*
356  ** Close the input BUFR file.
357  */
358  ccbfl( );
359 
360  return iret;
361 }
Enable a number of NCEPLIBS-bufr subprograms to be called from within C and C++ application programs.
#define VERS_STR_LEN
Size of a character string needed to store a library version number.
void cobfl(char *bfl, char io)
Open a new file for reading or writing BUFR messages via a C language interface.
Definition: crwbmg.c:120
void ccbfl(void)
Close all files that were opened via previous calls to function cobfl().
Definition: crwbmg.c:290
void bvers_f(char *cverstr, int cverstr_len)
Get the version number of the NCEPLIBS-bufr software.
int main(int argc, char *argv[])
This program decodes a BUFR file and generates a verbose listing of the contents.
Definition: debufr.c:167
void prtusage(char *prgnam)
This function prints program usage information to standard output.
Definition: debufr.c:48
void fdebufr_f(char *ofile, int lenof, char *tbldir, int lentd, char *tblfil, int lentf, char *prmstg, int lenps, char *basic, char *forcemt, char *cfms)
Read, decode, and print a verbose output listing of the contents of a BUFR file.