NCEPLIBS-bufr  11.6.0
 All Data Structures Files Functions Variables Pages
openbf.f
Go to the documentation of this file.
1 C> @file
2 C> @brief Connect a new system file to the BUFRLIB software for
3 C> reading or writing BUFR messages.
4 
5 C> This subroutine connects a new file to the BUFRLIB software for
6 C> input or output operations.
7 C>
8 C> @authors J. Woollen
9 C> @authors J. Ator
10 C> @authors D. Keyser
11 C> @date 1994-01-06
12 C>
13 C> @param[in] LUNIT -- integer: Fortran logical unit number for BUFR
14 C> file (unless IO is set to 'FIRST' or 'QUIET', in
15 C> which case this is a dummy argument)
16 C> @param[in] IO -- character*(*): flag indicating how LUNIT is to be
17 C> used by the software:
18 C> - 'IN' = input operations with table processing
19 C> - 'INX' = input operations w/o table processing
20 C> - 'OUX' = output operations w/o table processing
21 C> - 'OUT' = output operations with table processing
22 C> - 'SEC3' = same as 'IN', except use Section 3 of input
23 C> messages for decoding rather than DX BUFR
24 C> table information from LUNDX; in this case
25 C> LUNDX is ignored, and user must provide
26 C> appropriate [master BUFR tables](@ref dfbfmstab)
27 C> within the directory specified by a subsequent
28 C> call to subroutine mtinfo()
29 C> - 'NODX' = same as 'OUT', except don't write DX BUFR
30 C> table messages to LUNIT
31 C> - 'APN' = same as 'NODX', except begin writing at end
32 C> of file ("append")
33 C> - 'APX' = same as 'APN', except backspace before
34 C> appending
35 C> - 'NUL' = same as 'OUT', except don't write any
36 C> messages whatsoever to LUNIT (e.g. when
37 C> subroutine writsa() is to be used)
38 C> - 'INUL' = same as 'IN', except don't read any
39 C> messages whatsoever from LUNIT (e.g. when
40 C> subroutine readerme() is to be used)
41 C> - 'QUIET' = LUNIT is ignored; this is an indicator
42 C> that the value for IPRT in COMMON block
43 C> /QUIET/ is being reset to the value in
44 C> LUNDX
45 C> - 'FIRST' = LUNIT and LUNDX are ignored; this is an
46 C> indicator to initialize the BUFRLIB
47 C> software, in case this subroutine was
48 C> never previously called
49 C> @param[in] LUNDX -- integer:
50 C> - If IO is not set to 'FIRST' or 'QUIET' =
51 C> Fortran logical unit number
52 C> containing DX BUFR table information to be used in
53 C> reading/writing from/to LUNIT (depending on the case).
54 C> This value may be set equal to LUNIT if DX BUFR table
55 C> information is already embedded in LUNIT.
56 C> - If IO is set to 'QUIET' = indicator for degree of
57 C> printout:
58 C> - -1 = no printout except for ABORT messages
59 C> - 0 = limited printout (default)
60 C> - 1 = all warning messages are printed out
61 C> - 2 = all warning and informational messages are
62 C> printed out
63 C>
64 C> <p>The logical unit numbers LUNIT and LUNDX must already be associated
65 C> with actual filenames on the local system, typically via a Fortran "OPEN"
66 C> statement. Multiple logical units can be connected to the BUFRLIB software
67 C> at any one time.
68 C>
69 C> <p>The argument IO is a character string describing how the file connected to
70 C> LUNIT will be used, e.g. 'IN' is used to access an existing file of BUFR
71 C> messages for input (i.e. reading/decoding BUFR), and 'OUT' is used to access
72 C> a new file for output (i.e. writing/encoding BUFR). An option 'APX' is also
73 C> available which behaves like 'OUT', except that output is then appended to
74 C> an existing BUFR file rather than creating a new one from scratch, and there
75 C> are also some additional options 'NUL' and 'NODX' which can likewise be used
76 C> instead of 'OUT' for some very special cases as needed. There's also an
77 C> option 'SEC3' which can be used in place of 'IN' for certain cases when the
78 C> user is attempting to read BUFR messages whose content and descriptor layout
79 C> are unknown in advance. However, all of these additional options are
80 C> basically just variations of 'IN' or 'OUT', again depending on whether the
81 C> intent is to read or write BUFR messages from the file connected to LUNIT.
82 C> The only exceptions are when IO = 'FIRST' or 'QUIET'. When IO = 'FIRST',
83 C> the subroutine simply checks whether it has already been called from within
84 C> the application program and, if not, goes ahead and initializes the library
85 C> without actually connecting any files in LUNIT or LUNDX.
86 C> Alternatively, when IO = 'QUIET', the subroutine simply sets or resets the
87 C> internal print verbosity switch to the value of input argument LUNDX,
88 C> overriding its previous value and/or its internal default value of 0.
89 C>
90 C> <p>The third and final call argument LUNDX identifies the logical unit which
91 C> contains the definition of the DX BUFR tables to be associated with unit
92 C> LUNIT. Except when IO = 'SEC3', every BUFR file that is linked to the BUFRLIB
93 C> software must have a DX BUFR tables file associated with it, and these tables
94 C> may be defined within a separate ASCII text file
95 C> (see [Description and Format of DX BUFR Tables](@ref dfbftab) for more info.)
96 C> or, in the case of an existing BUFR file, may be embedded within the first few
97 C> BUFR messages of the file itself, and in which case the user can denote this
98 C> to the subroutine by setting LUNDX to the same value as LUBFR.
99 C>
100 C> @remarks
101 C> - When an existing BUFR file is accessed for input (i.e. reading/decoding BUFR),
102 C> the associated DX BUFR tables defined by LUNDX are stored internally within
103 C> the BUFRLIB software and are referenced during all subsequent processing of
104 C> the file. Likewise, when a file is accessed for output (i.e. writing/encoding
105 C> BUFR), the associated DX BUFR tables are still stored internally for subsequent
106 C> reference; however, the output file itself is also initialized by writing the
107 C> BUFR table information (as one or more BUFR messages) to the beginning of the
108 C> file, except when IO = 'NODX', and in which case the writing of these
109 C> additional messages is suppressed.
110 C> - As noted above, 'SEC3' is the only value of IO (other than 'QUIET') where it's
111 C> not necessary to provide pre-defined DX BUFR tables via LUNDX. Instead, this
112 C> option instructs the BUFRLIB software to unpack the data description section
113 C> (Section 3) from each BUFR message it reads and then decode the contents
114 C> accordingly. In this case, it's necessary to provide a set of BUFR master
115 C> tables containing listings of all possible BUFR descriptors
116 C> (see [Description and Format of master BUFR Tables](@ref dfbfmstab) for more
117 C> info.), but otherwise no prior knowledge is required of the contents of the
118 C> messages to be decoded.
119 C>
120 C> <b>Program history log:</b>
121 C> | Date | Programmer | Comments |
122 C> | -----|------------|----------|
123 C> | 1994-01-06 | J. Woollen | Original author |
124 C> | 1998-07-08 | J. Woollen | Replaced call to Cray library routine ABORT with call to new internal routine bort() |
125 C> | 1999-11-18 | J. Woollen | The number of BUFR files which can be opened at one time increased from 10 to 32 |
126 C> | 2003-11-04 | J. Ator | Added IO='NUL' option to prevent later writing to BUFR file in LUNIT; added documentation |
127 C> | 2003-11-04 | S. Bender | Added remarks and routine interdependencies |
128 C> | 2003-11-04 | D. Keyser | Unified/portable for WRF; added documentation; outputs more complete diagnostic info when routine terminates abnormally |
129 C> | 2004-08-18 | J. Ator | Added SAVE for IFIRST flag and IO="NODX" option |
130 C> | 2005-11-29 | J. Ator | Added COMMON /MSGFMT/ and ichkstr() call |
131 C> | 2009-03-23 | J. Ator | Added IO='SEC3' option; removed call to posapn; clarified comments; use errwrt() |
132 C> | 2010-05-11 | J. Ator | Added COMMON /STCODE/ |
133 C> | 2012-06-18 | J. Ator | Added IO='INUL' option |
134 C> | 2012-09-15 | J. Woollen | Modified for C/I/O/BUFR interface; use INQUIRE to obtain filename; use openrb(), openwb() and openab(); add IO types 'INX' and 'FIRST' |
135 C> | 2014-11-07 | J. Ator | Allow dynamic allocation of certain arrays |
136 C> | 2015-03-03 | J. Ator | Use MODA_IFOPBF instead of IFIRST |
137 C>
138  SUBROUTINE openbf(LUNIT,IO,LUNDX)
139 
140  USE modv_ifopbf
141  USE moda_msgcwd
142  USE moda_stbfr
143  USE moda_sc3bfr
144  USE moda_lushr
145  USE moda_nulbfr
146  USE moda_stcode
147 
148  COMMON /quiet / iprt
149 
150  CHARACTER*(*) io
151  CHARACTER*255 filename,fileacc
152  CHARACTER*128 bort_str,errstr
153  CHARACTER*28 cprint(0:3)
154  CHARACTER*1 bstr(4)
155 
156  DATA cprint/
157  . ' (only ABORTs) ',
158  . ' (limited - default) ',
159  . ' (all warnings) ',
160  . ' (all warning+informational)'/
161 
162 C-----------------------------------------------------------------------
163 C-----------------------------------------------------------------------
164 
165 C If this is the first call to this subroutine, initialize
166 C IPRT in /QUIET/ as 0 (limited printout - except for abort
167 C messages)
168 
169  IF(ifopbf.EQ.0) iprt = 0
170 
171  IF(io.EQ.'QUIET') THEN
172 c .... override previous IPRT value (printout indicator)
173  IF(lundx.LT.-1) lundx = -1
174  IF(lundx.GT. 2) lundx = 2
175  IF(lundx.GE.0) THEN
176  CALL errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
177  WRITE ( unit=errstr, fmt='(A,I3,A,A,I3,A)' )
178  . 'BUFRLIB: OPENBF - DEGREE OF MESSAGE PRINT INDICATOR '//
179  . 'CHNGED FROM',iprt,cprint(iprt+1),' TO',lundx,cprint(lundx+1)
180  CALL errwrt(errstr)
181  CALL errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
182  CALL errwrt(' ')
183  ENDIF
184  iprt = lundx
185  ENDIF
186 
187  IF(ifopbf.EQ.0) THEN
188 
189 C This is the first call to this subroutine, so take care of some
190 C initial housekeeping tasks. Note that ARALLOCF, ARALLOCC, and
191 C WRDLEN must all be called prior to calling BFRINI.
192 
193 C Allocate any arrays which are being dynamically sized.
194  CALL arallocf
195  CALL arallocc
196 
197 C Figure out some important information about the local machine.
198  CALL wrdlen
199 
200 C Initialize some global variables.
201  CALL bfrini
202 
203  ifopbf = 1
204  ENDIF
205 
206  IF(io.EQ.'FIRST') goto 100
207  IF(io.EQ.'QUIET') goto 100
208 
209 C SEE IF A FILE CAN BE OPENED
210 C ---------------------------
211 
212  CALL status(lunit,lun,il,im)
213  IF(lun.EQ.0) goto 900
214  IF(il .NE.0) goto 901
215  null(lun) = 0
216  isc3(lun) = 0
217  iscodes(lun) = 0
218  lus(lun) = 0
219 
220 C USE INQUIRE TO OBTAIN THE FILENAME ASSOCIATED WITH UNIT LUNIT
221 C -------------------------------------------------------------
222 
223  IF (io.NE.'NUL' .AND. io.NE.'INUL') THEN
224  INQUIRE(lunit,access=fileacc)
225  IF(fileacc=='UNDEFINED') OPEN(lunit)
226  INQUIRE(lunit,name=filename)
227  filename=trim(filename)//char(0)
228  ENDIF
229 
230 C SET INITIAL OPEN DEFAULTS (CLEAR OUT A MSG CONTROL WORD PARTITION)
231 C ------------------------------------------------------------------
232 
233  nmsg(lun) = 0
234  nsub(lun) = 0
235  msub(lun) = 0
236  inode(lun) = 0
237  idate(lun) = 0
238 
239 C DECIDE HOW TO OPEN THE FILE AND SETUP THE DICTIONARY
240 C ----------------------------------------------------
241 
242  IF(io.EQ.'IN') THEN
243  CALL openrb(lun,filename)
244  CALL wtstat(lunit,lun,-1,0)
245  CALL readdx(lunit,lun,lundx)
246  ELSE IF(io.EQ.'INUL') THEN
247  CALL wtstat(lunit,lun,-1,0)
248  IF(lunit.NE.lundx) CALL readdx(lunit,lun,lundx)
249  null(lun) = 1
250  ELSE IF(io.EQ.'NUL') THEN
251  CALL wtstat(lunit,lun, 1,0)
252  IF(lunit.NE.lundx) CALL readdx(lunit,lun,lundx)
253  null(lun) = 1
254  ELSE IF(io.EQ.'INX') THEN
255  CALL openrb(lun,filename)
256  CALL wtstat(lunit,lun,-1,0)
257  null(lun) = 1
258  ELSE IF(io.EQ.'OUX') THEN
259  CALL openwb(lun,filename)
260  CALL wtstat(lunit,lun, 1,0)
261  ELSE IF(io.EQ.'SEC3') THEN
262  CALL openrb(lun,filename)
263  CALL wtstat(lunit,lun,-1,0)
264  isc3(lun) = 1
265  ELSE IF(io.EQ.'OUT') THEN
266  CALL openwb(lun,filename)
267  CALL wtstat(lunit,lun, 1,0)
268  CALL writdx(lunit,lun,lundx)
269  ELSE IF(io.EQ.'NODX') THEN
270  CALL openwb(lun,filename)
271  CALL wtstat(lunit,lun, 1,0)
272  CALL readdx(lunit,lun,lundx)
273  ELSE IF(io.EQ.'APN' .OR. io.EQ.'APX') THEN
274  CALL openab(lun,filename)
275  CALL wtstat(lunit,lun, 1,0)
276  IF(lunit.NE.lundx) CALL readdx(lunit,lun,lundx)
277  CALL posapx(lunit)
278  ELSE
279  goto 904
280  ENDIF
281 
282  goto 100
283 
284 C FILE OPENED FOR INPUT IS EMPTY - LET READMG OR READERME GIVE
285 C THE BAD NEWS LATER
286 
287 200 rewind lunit
288  IF(iprt.GE.0) THEN
289  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
290  WRITE ( unit=errstr, fmt='(A,I3,A)' )
291  . 'BUFRLIB: OPENBF - INPUT BUFR FILE IN UNIT ', lunit,
292  . ' IS EMPTY'
293  CALL errwrt(errstr)
294  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
295  CALL errwrt(' ')
296  ENDIF
297  CALL wtstat(lunit,lun,-1,0)
298 
299 C INITIALIZE THE DICTIONARY TABLE PARTITION
300 C -----------------------------------------
301 
302  CALL dxinit(lun,0)
303 
304 C EXITS
305 C -----
306 
307 100 RETURN
308 900 WRITE(bort_str,'("BUFRLIB: OPENBF - THERE ARE ALREADY",I3,'//
309  . '" BUFR FILES OPENED, CANNOT OPEN FILE CONNECTED TO UNIT",I4)')
310  . nfiles,lunit
311  CALL bort(bort_str)
312 901 WRITE(bort_str,'("BUFRLIB: OPENBF - THE FILE CONNECTED TO UNIT"'//
313  . ',I5," IS ALREADY OPEN")') lunit
314  CALL bort(bort_str)
315 904 CALL bort('BUFRLIB: OPENBF - SECOND (INPUT) ARGUMENT MUST BE'//
316  . ' "IN", "OUT", "NODX", "NUL", "APN", "APX", "SEC3"'//
317  . ' OR "QUIET"')
318  END
void arallocc(void)
This subroutine is called internally during the first call to subroutine openbf() from an application...
Definition: arallocc.c:36
subroutine arallocf
This subroutine is called internally during the first call to subroutine openbf() from an application...
Definition: arallocf.f:34
subroutine dxinit(LUN, IOI)
THIS SUBROUTINE INITIALIZES THE INTERNAL ARRAYS (IN MODULE TABABD) HOLDING THE DICTIONARY TABLE...
Definition: dxinit.f:40
subroutine writdx(LUNIT, LUN, LUNDX)
THIS SUBROUTINE WRITES BUFR TABLE (DICTIONARY) MESSAGES TO THE BEGINNING OF AN OUTPUT BUFR FILE IN LU...
Definition: writdx.f:50
void openab(f77int *nfile, char *ufile)
This subroutine opens a new system file for appending BUFR messages.
Definition: cread.c:68
subroutine wtstat(LUNIT, LUN, IL, IM)
This subroutine can be used to connect or disconnect a specified Fortran logical unit number to/from ...
Definition: wtstat.f:52
subroutine status(LUNIT, LUN, IL, IM)
This subroutine checks whether a specified Fortran logical unit number is currently connected to the ...
Definition: status.f:55
subroutine openbf(LUNIT, IO, LUNDX)
This subroutine connects a new file to the BUFRLIB software for input or output operations.
Definition: openbf.f:138
This module declares and initializes the IFOPBF variable.
Definition: modv_IFOPBF.f90:9
subroutine readdx(LUNIT, LUN, LUNDX)
THIS SUBROUTINE GENERATES INTERNAL ARRAYS CONTAINING BUFR DICTIONARY TABLES WHICH ARE NEEDED TO READ...
Definition: readdx.f:54
subroutine wrdlen
This subroutine figures out some important information about the local machine on which the BUFRLIB s...
Definition: wrdlen.F:35
subroutine errwrt(STR)
This subroutine allows the user to specify a custom location for the logging of error and diagnostic ...
Definition: errwrt.f:41
void openwb(f77int *nfile, char *ufile)
This subroutine opens a new system file for writing BUFR messages.
Definition: cread.c:51
subroutine bfrini
This subroutine initializes numerous global variables and arrays within internal modules and COMMON b...
Definition: bfrini.f90:40
subroutine posapx(LUNXX)
THIS SUBROUTINE READS TO THE END OF THE FILE POINTED TO BY ABS(LUNXX) AND POSITIONS IT FOR APPENDING...
Definition: posapx.f:49
subroutine bort(STR)
This subroutine calls subroutine errwrt() to log an error message, then calls subroutine bort_exit() ...
Definition: bort.f:22
void openrb(f77int *nfile, char *ufile)
This subroutine opens a new system file for reading BUFR messages.
Definition: cread.c:34