File Coverage

bufrresolve.pl
Criterion Covered Total %
statement 56 63 88.8
branch 25 42 59.5
condition 10 15 66.6
subroutine 8 8 100.0
pod n/a
total 99 128 77.3


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             # (C) Copyright 2010-2025 MET Norway
4             #
5             # This program is free software; you can redistribute it and/or modify
6             # it under the terms of the GNU General Public License as published by
7             # the Free Software Foundation; either version 2 of the License, or
8             # (at your option) any later version.
9             #
10             # This program is distributed in the hope that it will be useful, but
11             # WITHOUT ANY WARRANTY; without even the implied warranty of
12             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13             # General Public License for more details.
14             #
15             # You should have received a copy of the GNU General Public License
16             # along with this program; if not, write to the Free Software
17             # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18             # 02110-1301, USA.
19              
20             # pod included at end of file
21              
22 12     12   54360 use strict;
  12         18  
  12         467  
23 12     12   47 use warnings;
  12         18  
  12         654  
24 12     12   8284 use Getopt::Long;
  12         186915  
  12         73  
25 12     12   8674 use Pod::Usage qw(pod2usage);
  12         782412  
  12         1150  
26 12     12   16530 use Geo::BUFR;
  12         65  
  12         665  
27              
28             # This is actually default in BUFR.pm, but provided here to make it
29             # easier for users to change to 'ECCODES' if preferred
30 12     12   110 use constant DEFAULT_TABLE_FORMAT => 'BUFRDC';
  12         21  
  12         984  
31              
32             # Will be used if neither --tablepath nor $ENV{BUFR_TABLES} is set
33 12     12   56 use constant DEFAULT_TABLE_PATH_BUFRDC => '/usr/local/lib/bufrtables';
  12         15  
  12         535  
34 12     12   50 use constant DEFAULT_TABLE_PATH_ECCODES => '/usr/local/share/eccodes/definitions/bufr/tables';
  12         16  
  12         23839  
35              
36             # Parse command line options
37 12         1762856 my %option = ();
38              
39 12 50       94 GetOptions(
40             \%option,
41             'bufrtable=s',# Set BUFR tables
42             'code=s', # Print the contents of code table
43             'flag=i', # Resolve the flag value given
44             'help', # Print help information and exit
45             'noexpand', # Don't expand D descriptors
46             'partial', # Expand D descriptors only once, ignoring
47             # replication
48             'simple', # Like 'partial', but displaying the resulting
49             # descriptors on one line
50             'tableformat=s', # Set BUFR table format
51             'tablepath=s',# Set BUFR table path
52             'verbose=i', # Display path and tables used
53             ) or pod2usage(-verbose => 0);
54              
55              
56             # User asked for help
57 12 50       16425 pod2usage(-verbose => 1) if $option{help};
58              
59             # No arguments if --code or --flag, else there should be at least one argument
60 12 100 66     83 if (defined $option{code} or defined $option{flag}) {
61 6 50       15 pod2usage(-verbose => 0) if @ARGV;
62             } else {
63 6 50       18 pod2usage(-verbose => 0) if not @ARGV;
64             }
65              
66             # If --flag is set, user must also provide code table
67 12 50 66     64 pod2usage(-verbose => 0) if defined $option{flag} and !defined $option{code};
68              
69             # All arguments must be integers
70 12         31 foreach (@ARGV) {
71 18 50       63 pod2usage("All arguments must be integers!") unless /^\d+$/;
72             }
73 12 50 66     85 if (defined $option{code} && $option{code} !~ /^\d+$/) {
74 0         0 pod2usage("Code table is not a (positive) integer!");
75             }
76 12 50 66     67 if (defined $option{flag} && $option{flag} !~ /^\d+$/) {
77 0         0 pod2usage("Flag value is not a (positive) integer!");
78             }
79              
80              
81             # Set verbosity level for the BUFR module
82 12 50       44 my $verbose = $option{verbose} ? 1 : 0;
83 12         137 Geo::BUFR->set_verbose($verbose);
84              
85             # From version 1.32 a descriptor sequence ending in e.g. 106000 031001
86             # will be allowed unless strict checking is set, and we really want
87             # bufrresolve.pl to complain in this case
88 12         59 Geo::BUFR->set_strict_checking(2);
89              
90             # Set BUFR table format
91 12 100       62 my $tableformat = (defined $option{tableformat}) ? uc $option{tableformat} : DEFAULT_TABLE_FORMAT;
92 12         75 Geo::BUFR->set_tableformat($tableformat);
93              
94             # Set BUFR table path
95 12 50       33 if ($option{tablepath}) {
    0          
96             # Command line option --tablepath overrides all
97 12         61 Geo::BUFR->set_tablepath($option{tablepath});
98             } elsif ($ENV{BUFR_TABLES}) {
99             # If no --tablepath option, use the BUFR_TABLES environment variable
100 0         0 Geo::BUFR->set_tablepath($ENV{BUFR_TABLES});
101             } else {
102             # If all else fails, use the default tablepath in BUFRDC/ECCODES
103 0 0       0 if ($tableformat eq 'BUFRDC') {
    0          
104 0         0 Geo::BUFR->set_tablepath(DEFAULT_TABLE_PATH_BUFRDC);
105             } elsif ($tableformat eq 'ECCODES') {
106 0         0 Geo::BUFR->set_tablepath(DEFAULT_TABLE_PATH_ECCODES);
107             }
108             }
109              
110             # BUFR table file to use
111 12   66     52 my $table = $option{bufrtable} || Geo::BUFR->get_max_table_version();
112              
113 12         57 my $bufr = Geo::BUFR->new();
114              
115 12 100       76 if (defined $option{code}) {
116             # Resolve flag value or dump code table
117 6         13 my $code_table = $option{code};
118 6 100       15 if (defined $option{flag}) {
119 3 50       9 if ($option{flag} == 0) {
120 0         0 print "No bits are set\n";
121             } else {
122 3         18 print $bufr->resolve_flagvalue($option{flag}, $code_table, $table);
123             }
124             } else {
125 3         15 print $bufr->dump_codetable($code_table, $table);
126             }
127             } else {
128             # Resolve descriptor(s)
129 6         31 $bufr->load_BDtables($table);
130 6 100       67 if ($option{simple}) {
    100          
    100          
131 1         10 print $bufr->resolve_descriptor('simply', @ARGV);
132             } elsif ($option{partial}) {
133 1         11 print $bufr->resolve_descriptor('partially', @ARGV);
134             } elsif ($option{noexpand}) {
135 1         10 print $bufr->resolve_descriptor('noexpand', @ARGV);
136             } else {
137 3         28 print $bufr->resolve_descriptor('fully', @ARGV);
138             }
139             }
140              
141             =pod
142              
143             =encoding utf8
144              
145             =head1 SYNOPSIS
146              
147             1) bufrresolve.pl
148             [--partial]
149             [--simple]
150             [--noexpand]
151             [--bufrtable
152             [--tableformat ]
153             [--tablepath ]
154             [--verbose n]
155             [--help]
156              
157             2) bufrresolve.pl --code
158             [--bufrtable ]
159             [--tableformat ]
160             [--tablepath ]
161             [--verbose n]
162              
163             3) bufrresolve.pl --flag --code
164             [--bufrtable
165             [--tableformat ]
166             [--tablepath ]
167             [--verbose n]
168              
169             =head1 DESCRIPTION
170              
171             Utility program for fetching info from BUFR tables.
172              
173             Execute without arguments for Usage, with option C<--help> for some
174             additional info. See also L for
175             examples of use.
176              
177             The tables used can be selected by the user with options
178             C<--bufrtable>, C<--tablepath> and C<--tableformat>. Default
179             tableformat in Geo::BUFR is BUFRDC, while default tablepath in
180             bufrresolve.pl will be overridden if the environment variable
181             BUFR_TABLES is set. You should consider edit the source code of
182             bufrresolve.pl if you are not satisfied with the defaults chosen for
183             tablepath and bufrtable (search for 'DEFAULT').
184              
185             For tableformat ECCODES, see
186             L
187             for more info on how to set C<--tablepath>.
188              
189             For the table name in C<--bufrtable> in BUFRDC, use basename of B
190             table, e.g. B0000000000098013001.TXT. Replacing B with D or C, or
191             omitting this prefix altogether, or even omitting the trailing '.TXT'
192             (i.e. 0000000000098013001) will also work.
193              
194             For the table name in C<--bufrtable> in ECCODES, use last significant part
195             of table location, e.g. '0/wmo/29' for WMO master tables or
196             '0/local/8/78/236' for local tables on Unix-like systems. For looking
197             up local sequence descriptors, you might need to provide both a master
198             and the local table to get the full expansion, e.g.
199             '0/wmo/29,0/local/8/78/236'.
200              
201             See also L below for more about the C<--bufrtable> option.
202              
203             =head1 OPTIONS
204              
205             --partial Expand D descriptors only once, ignoring replication
206             --simple Like --partial, but displaying the resulting
207             descriptors on one line
208             --noexpand Don't expand D descriptors at all
209             --bufrtable Set BUFR tables
210             --tableformat Currently supported are BUFRDC and ECCODES (default is BUFRDC)
211             --tablepath Set BUFR table path
212             --verbose n Display path and tables used if n > 0
213             --help Display Usage and explain the options used. Almost
214             the same as consulting perldoc bufrresolve.pl
215              
216             Usage 1): Resolves the given descriptor(s) fully into table B
217             descriptors, with name, unit, scale, reference value and width (in
218             bits) written on each line (except for --simple). --partial, --simple
219             and --noexpand are mutually exclusive (full expansion is default).
220              
221             Usage 2): Prints the contents of the requested code or flag table
222             (named by the table B descriptor).
223              
224             Usage 3): Displays the bits set when the data value for the requested
225             flag table is .
226              
227             Options may be abbreviated, e.g. C<--h> or C<-h> for C<--help>
228              
229             =head1 CAVEAT
230              
231             The C<--bufrtable> option could be considered mandatory, since there
232             is no guarantee that the same BUFR descriptor resolves the same way
233             for different BUFR tables. However, as soon as a new BUFR descriptor
234             is introduced in a BUFR table, it is extremely rare that the
235             descriptor is redefined in later versions. So for convenience,
236             bufrresolve.pl uses a default table (adding option C<--verbose 1> will
237             show you the tables used). If this is the wrong table for your purpose
238             (most common case will be if the descriptor was added in a higher
239             version than that of the default table), you should definitely use
240             C<--bufrtable> with the appropriate table.
241              
242             =head1 AUTHOR
243              
244             Pål Sannes Epal.sannes@met.noE
245              
246             =head1 COPYRIGHT
247              
248             Copyright (C) 2010-2025 MET Norway
249              
250             =cut