NCEPLIBS-bufr  12.3.0
dxtable.F90
Go to the documentation of this file.
1 
5 
28 subroutine readdx(lunit,lun,lundx)
29 
30  use modv_vars, only: iprt
31 
32  implicit none
33 
34  integer, intent(in) :: lunit, lun, lundx
35  integer lud, ildx, imdx
36 
37  character*128 errstr
38 
39  ! Get the status of unit lundx
40 
41  call status(lundx,lud,ildx,imdx)
42 
43  ! Read a dictionary table from the indicated source
44 
45  if (lunit==lundx) then
46  ! Source is input BUFR file in lunit
47  if(iprt>=2) then
48  call errwrt('++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++')
49  write ( unit=errstr, fmt='(A,A,I3,A)' ) 'BUFRLIB: READDX - READING BUFR DICTIONARY TABLE FROM ', &
50  'INPUT BUFR FILE IN UNIT ', lundx, ' INTO INTERNAL ARRAYS'
51  call errwrt(errstr)
52  call errwrt('++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++')
53  call errwrt(' ')
54  endif
55  rewind lunit
56  call rdbfdx(lunit,lun)
57  elseif(ildx==-1) then
58  ! Source is input BUFR file in lundx; BUFR file in lunit may be input or output
59  if(iprt>=2) then
60  call errwrt('++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++')
61  write ( unit=errstr, fmt='(A,A,I3,A,A,I3)' ) 'BUFRLIB: READDX - COPYING BUFR DCTY TBL FROM INTERNAL ', &
62  'ARRAYS ASSOC. W/ INPUT UNIT ', lundx, ' TO THOSE ASSOC. W/ UNIT ', lunit
63  call errwrt(errstr)
64  call errwrt('++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++')
65  call errwrt(' ')
66  endif
67  call cpbfdx(lud,lun)
68  call makestab
69  elseif(ildx==1) then
70  ! Source is output BUFR file in lundx; BUFR file in lunit may be input or output
71  if(iprt>=2) then
72  call errwrt('++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++')
73  write ( unit=errstr, fmt='(A,A,I3,A,A,I3)' ) 'BUFRLIB: READDX - COPYING BUFR DCTY TBL FROM INTERNAL ', &
74  'ARRAYS ASSOC. W/ OUTPUT UNIT ', lundx, ' TO THOSE ASSOC. W/ UNIT ', lunit
75  call errwrt(errstr)
76  call errwrt('++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++')
77  call errwrt(' ')
78  endif
79  call cpbfdx(lud,lun)
80  call makestab
81  elseif(ildx==0) then
82  ! Source is user-supplied character table in lundx; BUFR file in lunit may be input or output
83  if(iprt>=2) then
84  call errwrt('++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++')
85  write ( unit=errstr, fmt='(A,A,I3,A)' ) 'BUFRLIB: READDX - READING BUFR DICTIONARY TABLE FROM ', &
86  'USER-SUPPLIED TEXT FILE IN UNIT ', lundx, ' INTO INTERNAL ARRAYS'
87  call errwrt(errstr)
88  call errwrt('++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++')
89  call errwrt(' ')
90  endif
91  rewind lundx
92  call rdusdx(lundx,lun)
93  else
94  call bort('BUFRLIB: READDX - CANNOT DETERMINE SOURCE OF INPUT DICTIONARY TABLE')
95  endif
96 
97  return
98 end subroutine readdx
99 
120 subroutine rdbfdx(lunit,lun)
121 
122  use bufrlib
123 
124  use modv_vars, only: iprt
125 
126  use moda_mgwa
127 
128  implicit none
129 
130  integer, intent(in) :: lunit, lun
131  integer ict, ier, idxmsg, iupbs3
132 
133  character*128 errstr
134 
135  logical done
136 
137  call dxinit(lun,0)
138 
139  ict = 0
140  done = .false.
141 
142  ! Read a complete dictionary table from lunit, as a set of one or more DX dictionary messages.
143 
144  do while ( .not. done )
145  call rdmsgw ( lunit, mgwa, ier )
146  if ( ier == -1 ) then
147  ! Don't abort for an end-of-file condition, since it may be possible for a file to end with dictionary messages.
148  ! Instead, backspace the file pointer and let the calling routine diagnose the end-of-file condition and deal with
149  ! it as it sees fit.
150  call backbufr_c(lun)
151  done = .true.
152  else if ( ier == -2 ) then
153  call bort('BUFRLIB: RDBFDX - ERROR READING A BUFR DICTIONARY MESSAGE')
154  else if ( idxmsg(mgwa) /= 1 ) then
155  ! This is a non-DX dictionary message. Assume we've reached the end of the dictionary table, and backspace lunit
156  ! so that the next read (e.g. in the calling routine) will get this same message.
157  call backbufr_c(lun)
158  done = .true.
159  else if ( iupbs3(mgwa,'NSUB') == 0 ) then
160  ! This is a DX dictionary message, but it doesn't contain any actual dictionary information. Assume we've reached
161  ! the end of the dictionary table.
162  done = .true.
163  else
164  ! Store this message into module @ref moda_tababd.
165  ict = ict + 1
166  call stbfdx(lun,mgwa)
167  endif
168  enddo
169 
170  if ( iprt >= 2 ) then
171  call errwrt('+++++++++++++++++++++++++++++++++++++++++++++++++')
172  write ( unit=errstr, fmt='(A,I3,A)' ) 'BUFRLIB: RDBFDX - STORED NEW DX TABLE CONSISTING OF (', ict, ') MESSAGES;'
173  call errwrt(errstr)
174  errstr = 'WILL APPLY THIS TABLE TO ALL SUBSEQUENT DATA IN FILE UNTIL NEXT DX TABLE IS FOUND'
175  call errwrt(errstr)
176  call errwrt('+++++++++++++++++++++++++++++++++++++++++++++++++')
177  call errwrt(' ')
178  endif
179 
180  call makestab
181 
182  return
183 end subroutine rdbfdx
184 
196 subroutine rdusdx(lundx,lun)
197 
198  use moda_tababd
199 
200  implicit none
201 
202  integer, intent(in) :: lundx, lun
203  integer ios, iret, n, numbck, nemock, igetntbi
204 
205  character*128 bort_str1
206  character*156 bort_str2
207  character*80 card
208  character*8 nemo
209  character*6 numb, nmb2
210 
211  ! Initialize the dictionary table control word partition arrays with apriori Table B and D entries
212 
213  call dxinit(lun,1)
214  rewind lundx
215 
216  ! Read user cards until there are no more
217 
218  do while (.true.)
219 
220  read(lundx, '(A80)', iostat = ios) card
221  if (ios/=0) then
222  call makestab
223  return
224  endif
225 
226  if(card(1: 1)== '*') cycle ! comment line
227  if(card(3:10)=='--------') cycle ! separation line
228  if(card(3:10)==' ') cycle ! blank line
229  if(card(3:10)=='MNEMONIC') cycle ! header line
230  if(card(3:10)=='TABLE D') cycle ! header line
231  if(card(3:10)=='TABLE B') cycle ! header line
232 
233  if(card(12:12)=='|' .and. card(21:21)=='|') then
234 
235  ! Parse a descriptor definition card
236  nemo = card(3:10) ! nemo is the (up to) 8-character mnemonic
237  iret=nemock(nemo)
238  if(iret==-2) then
239  write(bort_str1,'("BUFRLIB: RDUSDX - CARD READ IN IS: ",A)') card
240  write(bort_str2,'(18X,"MNEMONIC ",A," IN USER DICTIONARY HAS INVALID CHARACTERS")') nemo
241  call bort2(bort_str1,bort_str2)
242  endif
243  numb = card(14:19) ! numb is the 6-character FXY value corresponding to nemo
244  nmb2 = numb
245  if(nmb2(1:1)=='A') nmb2(1:1) = '3'
246  iret=numbck(nmb2)
247  if(iret==-1) then
248  write(bort_str1,'("BUFRLIB: RDUSDX - CARD READ IN IS: ",A)') card
249  write(bort_str2,'(18X,"DESCRIPTOR NUMBER ",A," IN USER '// &
250  'DICTIONARY HAS AN INVALID FIRST CHARACTER (F VALUE) - MUST BE A, 0 OR 3")') numb
251  call bort2(bort_str1,bort_str2)
252  endif
253  if(iret==-2) then
254  write(bort_str1,'("BUFRLIB: RDUSDX - CARD READ IN IS: ",A)') card
255  write(bort_str2,'(18X,"DESCRIPTOR NUMBER ",A," IN USER '// &
256  'DICTIONARY HAS NON-NUMERIC VALUES IN CHARACTERS 2-6 (X AND Y VALUES)")') numb
257  call bort2(bort_str1,bort_str2)
258  endif
259  if(iret==-3) then
260  write(bort_str1,'("BUFRLIB: RDUSDX - CARD READ IN IS: ",A)') card
261  write(bort_str2,'(18X,"DESCRIPTOR NUMBER ",A," IN USER '// &
262  'DICTIONARY HAS INVALID NUMBER IN CHARACTERS 2-3 (X VALUE) - MUST BE BETWEEN 00 AND 63")') numb
263  call bort2(bort_str1,bort_str2)
264  endif
265  if(iret==-4) then
266  write(bort_str1,'("BUFRLIB: RDUSDX - CARD READ IN IS: ",A)') card
267  write(bort_str2,'(18X,"DESCRIPTOR NUMBER ",A," IN USER '// &
268  'DICTIONARY HAS INVALID NUMBER IN CHARACTERS 4-6 (Y VALUE) - MUST BE BETWEEN 000 AND 255")') numb
269  call bort2(bort_str1,bort_str2)
270  endif
271 
272  if(numb(1:1)=='A') then
273  ! Table A descriptor found
274  n = igetntbi( lun, 'A' )
275  call stntbia ( n, lun, numb, nemo, card(23:) )
276  if ( idna(n,lun,1) == 11 ) then
277  write(bort_str1,'("BUFRLIB: RDUSDX - CARD READ IN IS: ",A)') card
278  write(bort_str2,'(18X,"USER-DEFINED MESSAGE TYPE ""011"" IS RESERVED FOR DICTIONARY MESSAGES")')
279  call bort2(bort_str1,bort_str2)
280  endif
281  ! Replace "A" with "3" so Table D descriptor will be found in card as well (see below).
282  numb(1:1) = '3'
283  endif
284 
285  if(numb(1:1)=='0') then
286  ! Table B descriptor found
287  call stntbi ( igetntbi(lun,'B'), lun, numb, nemo, card(23:) )
288  cycle
289  endif
290 
291  if(numb(1:1)=='3') then
292  ! Table D descriptor found
293  call stntbi ( igetntbi(lun,'D'), lun, numb, nemo, card(23:) )
294  cycle
295  endif
296 
297  write(bort_str1,'("BUFRLIB: RDUSDX - CARD READ IN IS: ",A)') card
298  write(bort_str2,'(18X,"DESCRIPTOR NUMBER ",A," IN USER '// &
299  'DICTIONARY HAS AN INVALID FIRST CHARACTER (F VALUE) - MUST BE A, 0 OR 3")') numb
300  call bort2(bort_str1,bort_str2)
301 
302  endif
303 
304  if(card(12:12)=='|' .and. card(19:19)/='|') then
305  ! Parse a sequence definition card
306  call seqsdx(card,lun)
307  cycle
308  endif
309 
310  if(card(12:12)=='|' .and. card(19:19)=='|') then
311  ! Parse an element definition card
312  call elemdx(card,lun)
313  cycle
314  endif
315 
316  ! Can't figure out what kind of card it is
317  write(bort_str1,'("BUFRLIB: RDUSDX - CARD READ IN IS: ",A)') card
318  write(bort_str2,'(18X,"THIS CARD HAS A BAD FORMAT - IT IS NOT RECOGNIZED BY THIS SUBROUTINE")')
319  call bort2(bort_str1,bort_str2)
320  enddo
321 
322 end subroutine rdusdx
323 
332 subroutine seqsdx(card,lun)
333 
334  use modv_vars, only: reps, idnr
335 
336  implicit none
337 
338  integer, intent(in) :: lun
339  integer ntag, idn, jdn, iseq, irep, i, j, n, itab, iret, ier, numr, nemock
340  integer, parameter :: maxtgs = 250, maxtag = 13
341 
342  character*128 bort_str1, bort_str2
343  character*80 seqs
344  character*80, intent(in) :: card
345  character*(maxtag) atag, tags(maxtgs)
346  character*8 nemo, nema, nemb
347  character*6 adn30, clemon
348  character tab
349 
350  ! Find the sequence tag in Table D and parse the sequence string
351 
352  nemo = card( 3:10)
353  seqs = card(14:78)
354 
355  ! Note that an entry for this mnemonic should already exist within the internal BUFR Table D array tabd(*,LUN); this entry
356  ! should have been created by subroutine rdusdx() when the mnemonic and its associated FXY value and description were
357  ! initially defined within a card read from the "Descriptor Definition" section at the top of the user-supplied DX BUFR
358  ! table in character format. Now, we need to retrieve the positional index for that entry within tabd(*,lun) so that we
359  ! can access the entry and then add the decoded sequence information to it.
360 
361  call nemtab(lun,nemo,idn,tab,iseq)
362  if(tab/='D') then
363  write(bort_str1,'("BUFRLIB: SEQSDX - CARD READ IN IS: ",A)') card
364  write(bort_str2,'(18X,"MNEMONIC ",A," IS NOT A TABLE D ENTRY (UNDEFINED, TAB=",A,")")') nemo,tab
365  call bort2(bort_str1,bort_str2)
366  endif
367  call parstr(seqs,tags,maxtgs,ntag,' ',.true.)
368  if(ntag==0) then
369  write(bort_str1,'("BUFRLIB: SEQSDX - CARD READ IN IS: ",A)') card
370  write(bort_str2,'(18X,"TABLE D SEQUENCE (PARENT) MNEMONIC ",A," DOES NOT CONTAIN ANY CHILD MNEMONICS")') nemo
371  call bort2(bort_str1,bort_str2)
372  endif
373 
374  do n=1,ntag
375  atag = tags(n)
376  irep = 0
377 
378  ! Check for a replicator
379 
380  outer: do i=1,5
381  if(atag(1:1)==reps(i)) then
382  ! Note that reps(*), which contains all of the symbols used to denote all of the various replication schemes that
383  ! are possible within a user-supplied BUFR dictionary table in character format, was previously defined within
384  ! subroutine bfrini().
385  do j=2,maxtag
386  if(atag(j:j)==reps(i+5)) then
387  ! Note that subroutine strnum() will return numr = 0 if the string passed to it contains all blanks
388  ! (as *should* be the case whenever i = 2 '(' ')', 3 '{' '}', 4 '[' ']', or 5 '<' '>').
389  ! However, when i = 1 '"' '"', then subroutine strnum() will return numr = (the number of replications for
390  ! the mnemonic using F=1 "regular" (i.e. non-delayed) replication).
391  call strnum(atag(j+1:maxtag),numr,ier)
392  if(i==1 .and. numr<=0) then
393  write(bort_str1,'("BUFRLIB: SEQSDX - CARD READ IN IS: ",A)') card
394  write(bort_str2,'(9X,"TBL D MNEM. ",A," CONTAINS REG. REPL. '// &
395  'CHILD MNEM. ",A," W/ INVALID # OF REPLICATIONS (",I3,") AFTER 2ND QUOTE")') nemo,tags(n),numr
396  call bort2(bort_str1,bort_str2)
397  endif
398  if(i==1 .and. numr>255) then
399  write(bort_str1,'("BUFRLIB: SEQSDX - CARD READ IN IS: ",A)') card
400  write(bort_str2,'(18X,"TBL D MNEM. ",A," CONTAINS REG. REPL. '// &
401  'CHILD MNEM. ",A," W/ # OF REPLICATIONS (",I3,") > LIMIT OF 255")') nemo,tags(n),numr
402  call bort2(bort_str1,bort_str2)
403  endif
404  if(i/=1 .and. numr/=0) then
405  write(bort_str1,'("BUFRLIB: SEQSDX - CARD READ IN IS: ",A)') card
406  write(bort_str2,'(18X,"TBL D MNEM. ",A," CONTAINS DELAYED REPL. '// &
407  'CHILD MNEM. ",A," W/ # OF REPL. (",I3,") SPECIFIED - A NO-NO")') nemo,tags(n),numr
408  call bort2(bort_str1,bort_str2)
409  endif
410  atag = atag(2:j-1)
411  irep = i
412  exit outer
413  endif
414  enddo
415  write(bort_str1,'("BUFRLIB: SEQSDX - CARD READ IN IS: ",A)') card
416  write(bort_str2,'(18X,"TABLE D SEQUENCE (PARENT) MNEMONIC ",A,'// &
417  '" CONTAINS A BADLY FORMED CHILD MNEMONIC ",A)') nemo,tags(n)
418  call bort2(bort_str1,bort_str2)
419  endif
420  enddo outer
421 
422  ! Check for a valid tag
423 
424  iret=nemock(atag)
425  if(iret==-1) then
426  write(bort_str1,'("BUFRLIB: SEQSDX - CARD READ IN IS: ",A)') card
427  write(bort_str2,'(18X,"TABLE D (PARENT) MNEMONIC ",A," CONTAINS'// &
428  ' A CHILD MNEMONIC ",A," NOT BETWEEN 1 & 8 CHARACTERS")') nemo,tags(n)
429  call bort2(bort_str1,bort_str2)
430  endif
431  if(iret==-2) then
432  write(bort_str1,'("BUFRLIB: SEQSDX - CARD READ IN IS: ",A)') card
433  write(bort_str2,'(18X,"TABLE D (PARENT) MNEMONIC ",A," CONTAINS'// &
434  ' A CHILD MNEMONIC ",A," WITH INVALID CHARACTERS")') nemo,tags(n)
435  call bort2(bort_str1,bort_str2)
436  endif
437  call nemtab(lun,atag,idn,tab,iret)
438  if(iret>0) then
439  ! Note that the next code line checks that we are not trying to replicate a Table B mnemonic (which is currently not
440  ! allowed). The logic works because, for replicated mnemonics, irep = i = (the index within reps(*) of the symbol
441  ! associated with the type of replication in question (e.g. "{, "<", etc.))
442  if(tab=='B' .and. irep/=0) then
443  write(bort_str1,'("BUFRLIB: SEQSDX - CARD READ IN IS: ",A)') card
444  write(bort_str2,'(18X,"TABLE D (PARENT) MNEMONIC ",A," CONTAINS'// &
445  ' A REPLICATED CHILD TABLE B MNEMONIC ",A," - A NO-NO")') nemo,tags(n)
446  call bort2(bort_str1,bort_str2)
447  endif
448  if(atag(1:1)=='.') then
449  ! This mnemonic is a "following value" mnemonic (i.e. it relates to the mnemonic that immediately follows it within
450  ! the user-supplied character-format BUFR dictionary table sequence), so confirm that it contains, as a substring,
451  ! this mnemonic that immediately follows it.
452  if(n==ntag) then
453  write(bort_str1,'("BUFRLIB: SEQSDX - CARD READ IN IS: ",A)') card
454  write(bort_str2,'(18X,"TBL D (PARENT) MNEM. ",A," CONTAINS A '// &
455  '''FOLLOWING VALUE'' MNEMONIC WHICH IS LAST IN THE STRING")') nemo
456  call bort2(bort_str1,bort_str2)
457  endif
458  nemb = tags(n+1)(1:8)
459  call numtab(lun,idn,nema,tab,itab)
460  call nemtab(lun,nemb,jdn,tab,iret)
461  call rsvfvm(nema,nemb)
462  if(nema/=atag) then
463  write(bort_str1,'("BUFRLIB: SEQSDX - CARD READ IN IS: ",A)') card
464  write(bort_str2,'(18X,"TBL D (PARENT) MNEM. ",A," CONTAINS AN '// &
465  'INVALID ''FOLLOWING VALUE'' MNEMONIC ",A,"(SHOULD BE ",A,")")') nemo,tags(n),nema
466  call bort2(bort_str1,bort_str2)
467  endif
468  if(tab/='B') then
469  write(bort_str1,'("BUFRLIB: SEQSDX - CARD READ IN IS: ",A)') card
470  write(bort_str2,'(18X,"TBL D (PARENT) MNEM. ",A,", THE MNEM. ",'// &
471  'A," FOLLOWING A ''FOLLOWING VALUE'' MNEM. IS NOT A TBL B ENTRY")') nemo,nemb
472  call bort2(bort_str1,bort_str2)
473  endif
474  endif
475  else
476  write(bort_str1,'("BUFRLIB: SEQSDX - CARD READ IN IS: ",A)') card
477  write(bort_str2,'(18X,"TABLE D SEQUENCE (PARENT) MNEMONIC ",A,'// &
478  '" CONTAINS A CHILD MNEMONIC ",A," NOT FOUND IN ANY TABLE")') nemo,tags(n)
479  call bort2(bort_str1,bort_str2)
480  endif
481 
482  ! Write the descriptor string into the tabd array, but first look for a replication descriptor
483  if(irep>0) call pktdd(iseq,lun,idnr(irep)+numr,iret)
484  if(iret<0) then
485  clemon = adn30(idnr(irep)+numr,6)
486  write(bort_str1,'("BUFRLIB: SEQSDX - CARD READ IN IS: ",A)') card
487  write(bort_str2,'(9X,"TBL D (PARENT) MNEM. ",A," - BAD RETURN '// &
488  'FROM PKTDD TRYING TO STORE REPL. DESC. ",A,", SEE PREV. WARNING MSG")') nemo,clemon
489  call bort2(bort_str1,bort_str2)
490  endif
491  call pktdd(iseq,lun,idn,iret)
492  if(iret<0) then
493  write(bort_str1,'("BUFRLIB: SEQSDX - CARD READ IN IS: ",A)') card
494  write(bort_str2,'(9X,"TBL D (PARENT) MNEM. ",A," - BAD RETURN '// &
495  'FROM PKTDD TRYING TO STORE CHILD MNEM. ",A,", SEE PREV. WARNING MSG")') nemo,tags(n)
496  call bort2(bort_str1,bort_str2)
497  endif
498 
499  enddo
500 
501  return
502 end subroutine seqsdx
503 
513 subroutine elemdx(card,lun)
514 
515  use moda_tababd
516 
517  implicit none
518 
519  integer, intent(in) :: lun
520  integer idsn, iele, iret
521 
522  character*128 bort_str1, bort_str2
523  character*80, intent(in) :: card
524  character*24 unit
525  character*11 refr, refr_orig
526  character*8 nemo
527  character*4 scal, scal_orig
528  character*3 bitw, bitw_orig
529  character sign, tab
530 
531  ! Capture the various elements characteristics
532 
533  nemo = card( 3:10)
534  scal = card(14:17)
535  refr = card(21:31)
536  bitw = card(35:37)
537  unit = card(41:64)
538  ! Make sure the units are all capitalized
539  call capit(unit)
540 
541  ! Find the element tag in Table B. Note that an entry for this mnemonic should already exist within the internal
542  ! BUFR Table B array tabb(*,lun). We now need to retrieve the positional index for that entry within tabb(*,lun)
543  ! so that we can access the entry and then add the scale factor, reference value, bit width, and units to it.
544 
545  call nemtab(lun,nemo,idsn,tab,iele)
546  if(tab/='B') then
547  write(bort_str1,'("BUFRLIB: ELEMDX - CARD READ IN IS: ",A)') card
548  write(bort_str2,'(18X,"MNEMONIC ",A," IS NOT A TABLE B ENTRY (UNDEFINED, TAB=",A,")")') nemo,tab
549  call bort2(bort_str1,bort_str2)
550  endif
551 
552  ! Left justify and store characteristics
553 
554  unit = adjustl(unit)
555  if(unit==' ') then
556  write(bort_str1,'("BUFRLIB: ELEMDX - CARD READ IN IS: ",A)') card
557  write(bort_str2,'(18X,"UNITS FIELD IS EMPTY")')
558  call bort2(bort_str1,bort_str2)
559  endif
560  tabb(iele,lun)(71:94) = unit
561 
562  scal_orig=scal
563  call jstnum(scal,sign,iret)
564  if(iret/=0) then
565  write(bort_str1,'("BUFRLIB: ELEMDX - CARD READ IN IS: ",A)') card
566  write(bort_str2,'(18X,"PARSED SCALE VALUE (=",A,") IS NOT NUMERIC")') scal_orig
567  call bort2(bort_str1,bort_str2)
568  endif
569  tabb(iele,lun)(95:95) = sign
570  tabb(iele,lun)(96:98) = scal(1:3)
571 
572  refr_orig=refr
573  call jstnum(refr,sign,iret)
574  if(iret/=0) then
575  write(bort_str1,'("BUFRLIB: ELEMDX - CARD READ IN IS: ",A)') card
576  write(bort_str2,'(18X,"PARSED REFERENCE VALUE (=",A,") IS NOT NUMERIC")') refr_orig
577  call bort2(bort_str1,bort_str2)
578  endif
579  tabb(iele,lun)( 99: 99) = sign
580  tabb(iele,lun)(100:109) = refr(1:10)
581 
582  bitw_orig=bitw
583  call jstnum(bitw,sign,iret)
584  if(iret/=0 .or. sign=='-') then
585  write(bort_str1,'("BUFRLIB: ELEMDX - CARD READ IN IS: ",A)') card
586  write(bort_str2,'(18X,"PARSED BIT WIDTH VALUE (=",A,") IS NOT NUMERIC")') bitw_orig
587  call bort2(bort_str1,bort_str2)
588  endif
589  tabb(iele,lun)(110:112) = bitw
590 
591  return
592 end subroutine elemdx
593 
603 subroutine dxinit(lun,ioi)
604 
605  use modv_vars, only: idnr, fxy_fbit, fxy_sbyct, fxy_drf16, fxy_drf8, fxy_drf1
606 
607  use moda_tababd
608 
609  implicit none
610 
611  integer, intent(in) :: lun, ioi
612  integer ninib, ninid, n, i, iret, ifxy
613 
614  character*8 inib(6,5),inid(5)
615  character*6 adn30
616 
617  data inib / '------','BYTCNT ','BYTES ','+0','+0','16', &
618  '------','BITPAD ','NONE ','+0','+0','1 ', &
619  fxy_drf1,'DRF1BIT ','NUMERIC','+0','+0','1 ', &
620  fxy_drf8,'DRF8BIT ','NUMERIC','+0','+0','8 ', &
621  fxy_drf16,'DRF16BIT','NUMERIC','+0','+0','16'/
622  data ninib /5/
623 
624  data inid /' ', &
625  'DRP16BIT', &
626  'DRP8BIT ', &
627  'DRPSTAK ', &
628  'DRP1BIT '/
629  data ninid /5/
630 
631  ! Clear out a table partition
632 
633  ntba(lun) = 0
634  do i=1,ntba(0)
635  taba(i,lun) = ' '
636  mtab(i,lun) = 0
637  enddo
638 
639  ntbb(lun) = 0
640  tabb(1:ntbb(0),lun) = ' '
641 
642  ntbd(lun) = 0
643  do i=1,ntbd(0)
644  tabd(i,lun) = ' '
645  call pktdd(i,lun,0,iret)
646  enddo
647 
648  if(ioi==0) return
649 
650  ! Initialize table with apriori Table B and D entries
651 
652  inib(1,1) = fxy_sbyct
653  inib(1,2) = fxy_fbit
654 
655  do i=1,ninib
656  ntbb(lun) = ntbb(lun)+1
657  idnb(i,lun) = ifxy(inib(1,i))
658  tabb(i,lun)( 1: 6) = inib(1,i)(1:6)
659  tabb(i,lun)( 7: 70) = inib(2,i)
660  tabb(i,lun)( 71: 94) = inib(3,i)
661  tabb(i,lun)( 95: 98) = inib(4,i)(1:4)
662  tabb(i,lun)( 99:109) = inib(5,i)
663  tabb(i,lun)(110:112) = inib(6,i)(1:3)
664  enddo
665 
666  do i=2,ninid
667  n = ntbd(lun)+1
668  idnd(n,lun) = idnr(i)
669  tabd(n,lun)(1: 6) = adn30(idnr(i),6)
670  tabd(n,lun)(7:70) = inid(i)
671  call pktdd(n,lun,idnr(1),iret)
672  call pktdd(n,lun,idnr(i+5),iret)
673  ntbd(lun) = n
674  enddo
675 
676  return
677 end subroutine dxinit
678 
690 subroutine dxmini(mbay,mbyt,mb4,mba,mbb,mbd)
691 
692  use modv_vars, only: mxmsgld4, mtv, nby0, nby1, nby2, nby5, bmostr, idxv
693 
694  implicit none
695 
696  integer, intent(out) :: mbay(*), mbyt, mb4, mba, mbb, mbd
697  integer nxstr, ldxa, ldxb, ldxd, ld30, mtyp, msbt, mbit, ih, id, im, iy, i, nsub, idxs, ldxs, &
698  len3, nby4, iupm
699 
700  character*128 bort_str
701  character*56 dxstr
702 
703  common /dxtab/ nxstr(10), ldxa(10), ldxb(10), ldxd(10), ld30(10), dxstr(10)
704 
705  msbt = idxv
706 
707  ! Initialize the message
708 
709  mbit = 0
710  mbay(1:mxmsgld4) = 0
711 
712  ! For DX table messages, the Section 1 date is simply zeroed out. Note that there is logic in function idxmsg()
713  ! which relies on this.
714  ih = 0
715  id = 0
716  im = 0
717  iy = 0
718 
719  mtyp = 11 ! DX table messages are always type 11, per WMO BUFR Table A
720  nsub = 1
721 
722  idxs = idxv+1
723  ldxs = nxstr(idxs)
724 
725  len3 = 7 + nxstr(idxs) + 1
726  nby4 = 7
727  mbyt = nby0+nby1+nby2+len3+nby4+nby5
728 
729  if(mod(len3,2)/=0) call bort ('BUFRLIB: DXMINI - LENGTH OF SECTION 3 IS NOT A MULTIPLE OF 2')
730 
731  ! Section 0
732 
733  call pkc(bmostr , 4 , mbay,mbit)
734  call pkb( mbyt , 24 , mbay,mbit)
735  call pkb( 3 , 8 , mbay,mbit)
736 
737  ! Section 1
738 
739  call pkb( nby1 , 24 , mbay,mbit)
740  call pkb( 0 , 8 , mbay,mbit)
741  call pkb( 3 , 8 , mbay,mbit)
742  call pkb( 7 , 8 , mbay,mbit)
743  call pkb( 0 , 8 , mbay,mbit)
744  call pkb( 0 , 8 , mbay,mbit)
745  call pkb( mtyp , 8 , mbay,mbit)
746  call pkb( msbt , 8 , mbay,mbit)
747  call pkb( mtv , 8 , mbay,mbit)
748  call pkb( idxv , 8 , mbay,mbit)
749  call pkb( iy , 8 , mbay,mbit)
750  call pkb( im , 8 , mbay,mbit)
751  call pkb( id , 8 , mbay,mbit)
752  call pkb( ih , 8 , mbay,mbit)
753  call pkb( 0 , 8 , mbay,mbit)
754  call pkb( 0 , 8 , mbay,mbit)
755 
756  ! Section 3
757 
758  call pkb( len3 , 24 , mbay,mbit)
759  call pkb( 0 , 8 , mbay,mbit)
760  call pkb( 1 , 16 , mbay,mbit)
761  call pkb( 2**7 , 8 , mbay,mbit)
762  do i=1,ldxs
763  call pkb(iupm(dxstr(idxs)(i:i),8),8,mbay,mbit)
764  enddo
765  call pkb( 0 , 8 , mbay,mbit)
766 
767  ! Section 4
768 
769  mb4 = mbit/8+1
770  call pkb( nby4 , 24 , mbay,mbit)
771  call pkb( 0 , 8 , mbay,mbit)
772  mba = mbit/8+1
773  call pkb( 0 , 8 , mbay,mbit)
774  mbb = mbit/8+1
775  call pkb( 0 , 8 , mbay,mbit)
776  mbd = mbit/8+1
777  call pkb( 0 , 8 , mbay,mbit)
778 
779  if(mbit/8+nby5/=mbyt) then
780  write(bort_str,'("BUFRLIB: DXMINI - NUMBER OF BYTES STORED FOR '// &
781  'A MESSAGE (",I6,") IS NOT THE SAME AS FIRST CALCULATED, MBYT (",I6)') mbit/8+nby5,mbyt
782  call bort(bort_str)
783  endif
784 
785  return
786 end subroutine dxmini
787 
799 subroutine writdx(lunit,lun,lundx)
800 
801  implicit none
802 
803  integer, intent(in) :: lunit, lun, lundx
804 
805  character*128 bort_str
806 
807  ! The table must be coming from an input file
808 
809  if(lunit==lundx) then
810  write(bort_str,'("BUFRLIB: WRITDX - FILES CONTAINING BUFR DATA '// &
811  'AND DICTIONARY TABLE CANNOT BE THE SAME (HERE BOTH SHARE FORTRAN UNIT NUMBER ",I3,")")') lunit
812  call bort(bort_str)
813  endif
814 
815  ! Must first call readdx() to generate internal dictionary table arrays, before calling wrdxtb()
816 
817  call readdx(lunit,lun,lundx)
818  call wrdxtb(lunit,lunit)
819 
820  return
821 end subroutine writdx
822 
837 recursive subroutine wrdxtb(lundx,lunot)
838 
839  use bufrlib
840 
841  use modv_vars, only: im8b, idxv
842 
843  use moda_tababd
844  use moda_mgwa
845  use moda_bitbuf, only: maxbyt
846 
847  implicit none
848 
849  integer, intent(in) :: lundx, lunot
850  integer nxstr, ldxa, ldxb, ldxd, ld30, my_lundx, my_lunot, ldx, lot, il, im, lda, ldb, ldd, l30, nseq, &
851  mbit, mbyt, mby4, mbya, mbyb, mbyd, i, j, jj, idn, lend, len0, len1, len2, l3, l4, l5, iupb, iupm, bort_target_set
852 
853  common /dxtab/ nxstr(10), ldxa(10), ldxb(10), ldxd(10), ld30(10), dxstr(10)
854 
855  character*56 dxstr
856  character*6 adn30
857 
858  logical msgfull
859 
860  ! Check for I8 integers
861 
862  if(im8b) then
863  im8b=.false.
864  call x84(lundx,my_lundx,1)
865  call x84(lunot,my_lunot,1)
866  call wrdxtb(my_lundx,my_lunot)
867  im8b=.true.
868  return
869  endif
870 
871  ! If we're catching bort errors, set a target return location if one doesn't already exist.
872 
873  if (bort_target_set() == 1) then
874  call catch_bort_wrdxtb_c(lundx,lunot)
875  call bort_target_unset
876  return
877  endif
878 
879  ! Check file statuses
880 
881  call status(lunot,lot,il,im)
882  if(il==0) call bort('BUFRLIB: WRDXTB - OUTPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR OUTPUT')
883  if(il<0) call bort('BUFRLIB: WRDXTB - OUTPUT BUFR FILE IS OPEN FOR INPUT, IT MUST BE OPEN FOR OUTPUT')
884 
885  call status(lundx,ldx,il,im)
886  if(il==0) call bort('BUFRLIB: WRDXTB - DX TABLE FILE IS CLOSED, IT MUST BE OPEN')
887 
888  ! If files are different, copy internal table information from lundx to lunot
889 
890  if(lundx/=lunot) call cpbfdx(ldx,lot)
891 
892  ! Generate and write out BUFR dictionary messages to lunot
893 
894  call dxmini(mgwa,mbyt,mby4,mbya,mbyb,mbyd)
895 
896  lda = ldxa(idxv+1)
897  ldb = ldxb(idxv+1)
898  ldd = ldxd(idxv+1)
899  l30 = ld30(idxv+1)
900 
901  ! Table A information
902 
903  do i=1,ntba(lot)
904  if(msgfull(mbyt,lda,maxbyt).or.(iupb(mgwa,mbya,8)==255)) then
905  call msgwrt(lunot,mgwa,mbyt)
906  call dxmini(mgwa,mbyt,mby4,mbya,mbyb,mbyd)
907  endif
908  mbit = 8*(mby4-1)
909  call pkb(iupb(mgwa,mby4,24)+lda,24,mgwa,mbit)
910  mbit = 8*(mbya-1)
911  call pkb(iupb(mgwa,mbya,8)+1,8,mgwa,mbit)
912  mbit = 8*(mbyb-1)
913  call pkc(taba(i,lot),lda,mgwa,mbit)
914  call pkb(0,8,mgwa,mbit)
915  call pkb(0,8,mgwa,mbit)
916  mbyt = mbyt+lda
917  mbyb = mbyb+lda
918  mbyd = mbyd+lda
919  enddo
920 
921  ! Table B information
922 
923  do i=1,ntbb(lot)
924  if(msgfull(mbyt,ldb,maxbyt).or.(iupb(mgwa,mbyb,8)==255)) then
925  call msgwrt(lunot,mgwa,mbyt)
926  call dxmini(mgwa,mbyt,mby4,mbya,mbyb,mbyd)
927  endif
928  mbit = 8*(mby4-1)
929  call pkb(iupb(mgwa,mby4,24)+ldb,24,mgwa,mbit)
930  mbit = 8*(mbyb-1)
931  call pkb(iupb(mgwa,mbyb,8)+1,8,mgwa,mbit)
932  mbit = 8*(mbyd-1)
933  call pkc(tabb(i,lot),ldb,mgwa,mbit)
934  call pkb(0,8,mgwa,mbit)
935  mbyt = mbyt+ldb
936  mbyd = mbyd+ldb
937  enddo
938 
939  ! Table D information
940 
941  do i=1,ntbd(lot)
942  nseq = iupm(tabd(i,lot)(ldd+1:ldd+1),8)
943  lend = ldd+1 + l30*nseq
944  if(msgfull(mbyt,lend,maxbyt).or.(iupb(mgwa,mbyd,8)==255)) then
945  call msgwrt(lunot,mgwa,mbyt)
946  call dxmini(mgwa,mbyt,mby4,mbya,mbyb,mbyd)
947  endif
948  mbit = 8*(mby4-1)
949  call pkb(iupb(mgwa,mby4,24)+lend,24,mgwa,mbit)
950  mbit = 8*(mbyd-1)
951  call pkb(iupb(mgwa,mbyd,8)+1,8,mgwa,mbit)
952  mbit = 8*(mbyt-4)
953  call pkc(tabd(i,lot),ldd,mgwa,mbit)
954  call pkb(nseq,8,mgwa,mbit)
955  do j=1,nseq
956  jj = ldd+2 + (j-1)*2
957  idn = iupm(tabd(i,lot)(jj:jj+1),16)
958  call pkc(adn30(idn,l30),l30,mgwa,mbit)
959  enddo
960  mbyt = mbyt+lend
961  enddo
962 
963  ! Write the unwritten (leftover) message.
964 
965  call msgwrt(lunot,mgwa,mbyt)
966 
967  ! Write out one additional (dummy) DX message containing zero subsets. This will serve as a delimiter for this set of
968  ! table messages within output unit lunot, just in case the next thing written to lunot ends up being another set of
969  ! table messages.
970 
971  call dxmini(mgwa,mbyt,mby4,mbya,mbyb,mbyd)
972  call getlens(mgwa,2,len0,len1,len2,l3,l4,l5)
973  mbit = (len0+len1+len2+4)*8
974  call pkb(0,16,mgwa,mbit)
975  call msgwrt(lunot,mgwa,mbyt)
976 
977  return
978 end subroutine wrdxtb
979 
986 subroutine stbfdx(lun,mesg)
987 
988  use modv_vars, only: maxcd, idxv
989 
990  use moda_tababd
991 
992  implicit none
993 
994  integer, intent(in) :: lun, mesg(*)
995  integer nxstr, ldxa, ldxb, ldxd, ld30, ldxbd(10), ldxbe(10), ja, jb, idxs, i3, i, j, n, nd, ndd, idn, &
996  jbit, len0, len1, len2, len3, l4, l5, lda, ldb, ldd, ldbd, ldbe, l30, ia, la, ib, lb, id, ld, iret, &
997  ifxy, iupb, iupbs01, igetntbi, idn30
998 
999  character*128 bort_str
1000  character*128 tabb1, tabb2
1001  character*56 dxstr
1002  character*55 cseq
1003  character*50 dxcmp
1004  character*24 unit
1005  character*8 nemo
1006  character*6 numb, cidn
1007 
1008  common /dxtab/ nxstr(10), ldxa(10), ldxb(10), ldxd(10), ld30(10), dxstr(10)
1009 
1010  data ldxbd /38, 70, 8*0/
1011  data ldxbe /42, 42, 8*0/
1012 
1013  ! Statement functions
1014  ja(i) = ia+1+lda*(i-1)
1015  jb(i) = ib+1+ldb*(i-1)
1016 
1017  ! Get some preliminary information from the message
1018 
1019  idxs = iupbs01(mesg,'MSBT')+1
1020  if(idxs>idxv+1) idxs = iupbs01(mesg,'MTVL')+1
1021  if(ldxa(idxs)==0 .or. ldxb(idxs)==0 .or. ldxd(idxs)==0) call bort('BUFRLIB: STBFDX - UNEXPECTED DICTIONARY '// &
1022  'MESSAGE SUBTYPE OR LOCAL VERSION NUMBER (E.G., L.V.N. HIGHER THAN KNOWN)')
1023 
1024  call getlens(mesg,3,len0,len1,len2,len3,l4,l5)
1025  i3 = len0+len1+len2
1026  dxcmp = ' '
1027  jbit = 8*(i3+7)
1028  call upc(dxcmp,nxstr(idxs),mesg,jbit,.false.)
1029  if(dxcmp/=dxstr(idxs)) call bort('BUFRLIB: STBFDX - UNEXPECTED DICTIONARY MESSAGE CONTENTS')
1030 
1031  ! Section 4 - read definitions for Tables A, B and D
1032 
1033  lda = ldxa(idxs)
1034  ldb = ldxb(idxs)
1035  ldd = ldxd(idxs)
1036  ldbd = ldxbd(idxs)
1037  ldbe = ldxbe(idxs)
1038  l30 = ld30(idxs)
1039 
1040  ia = i3+len3+5
1041  la = iupb(mesg,ia,8)
1042  ib = ja(la+1)
1043  lb = iupb(mesg,ib,8)
1044  id = jb(lb+1)
1045  ld = iupb(mesg,id,8)
1046 
1047  ! Table A
1048 
1049  do i=1,la
1050  n = igetntbi(lun,'A')
1051  jbit = 8*(ja(i)-1)
1052  call upc(taba(n,lun),lda,mesg,jbit,.true.)
1053  numb = ' '//taba(n,lun)(1:3)
1054  nemo = taba(n,lun)(4:11)
1055  cseq = taba(n,lun)(13:67)
1056  call stntbia(n,lun,numb,nemo,cseq)
1057  enddo
1058 
1059  ! Table B
1060 
1061  do i=1,lb
1062  n = igetntbi(lun,'B')
1063  jbit = 8*(jb(i)-1)
1064  call upc(tabb1,ldbd,mesg,jbit,.true.)
1065  jbit = 8*(jb(i)+ldbd-1)
1066  call upc(tabb2,ldbe,mesg,jbit,.true.)
1067  tabb(n,lun) = tabb1(1:ldxbd(idxv+1))//tabb2(1:ldxbe(idxv+1))
1068  numb = tabb(n,lun)(1:6)
1069  nemo = tabb(n,lun)(7:14)
1070  call nenubd(nemo,numb,lun)
1071  idnb(n,lun) = ifxy(numb)
1072  unit = tabb(n,lun)(71:94)
1073  call capit(unit)
1074  tabb(n,lun)(71:94) = unit
1075  ntbb(lun) = n
1076  enddo
1077 
1078  ! Table D
1079 
1080  do i=1,ld
1081  n = igetntbi(lun,'D')
1082  jbit = 8*id
1083  call upc(tabd(n,lun),ldd,mesg,jbit,.true.)
1084  numb = tabd(n,lun)(1:6)
1085  nemo = tabd(n,lun)(7:14)
1086  call nenubd(nemo,numb,lun)
1087  idnd(n,lun) = ifxy(numb)
1088  nd = iupb(mesg,id+ldd+1,8)
1089  if(nd>maxcd) then
1090  write(bort_str,'("BUFRLIB: STBFDX - NUMBER OF DESCRIPTORS IN '// &
1091  'TABLE D ENTRY ",A," IN BUFR TABLE (",I4,") EXCEEDS THE LIMIT (",I4,")")') nemo,nd,maxcd
1092  call bort(bort_str)
1093  endif
1094  do j=1,nd
1095  ndd = id+ldd+2 + (j-1)*l30
1096  jbit = 8*(ndd-1)
1097  call upc(cidn,l30,mesg,jbit,.true.)
1098  idn = idn30(cidn,l30)
1099  call pktdd(n,lun,idn,iret)
1100  if(iret<0) call bort('BUFRLIB: STBFDX - BAD RETURN FROM BUFRLIB ROUTINE PKTDD, SEE PREVIOUS WARNING MESSAGE')
1101  enddo
1102  id = id+ldd+1 + nd*l30
1103  if(iupb(mesg,id+1,8)==0) id = id+1
1104  ntbd(lun) = n
1105  enddo
1106 
1107  return
1108 end subroutine stbfdx
1109 
1119 integer function idxmsg( mesg ) result( iret )
1120 
1121  implicit none
1122 
1123  integer, intent(in) :: mesg(*)
1124  integer iupbs01
1125 
1126  ! Note that the following test relies upon logic within subroutine dxmini() which zeroes out the Section 1 date of
1127  ! all DX dictionary messages.
1128 
1129  if ( (iupbs01(mesg,'MTYP')==11) .and. &
1130  (iupbs01(mesg,'MNTH')==0) .and. (iupbs01(mesg,'DAYS')==0) .and. (iupbs01(mesg,'HOUR')==0) ) then
1131  iret = 1
1132  else
1133  iret = 0
1134  end if
1135 
1136  return
1137 end function idxmsg
1138 
1149 integer function igetntbi ( lun, ctb ) result(iret)
1150 
1151  use moda_tababd
1152 
1153  implicit none
1154 
1155  integer, intent(in) :: lun
1156  integer imax
1157 
1158  character, intent(in) :: ctb
1159  character*128 bort_str
1160 
1161  if ( ctb == 'A' ) then
1162  iret = ntba(lun) + 1
1163  imax = ntba(0)
1164  else if ( ctb == 'B' ) then
1165  iret = ntbb(lun) + 1
1166  imax = ntbb(0)
1167  else ! ctb == 'D'
1168  iret = ntbd(lun) + 1
1169  imax = ntbd(0)
1170  endif
1171  if ( iret > imax ) then
1172  write(bort_str,'("BUFRLIB: IGETNTBI - NUMBER OF INTERNAL TABLE",A1," ENTRIES EXCEEDS THE LIMIT (",I4,")")') ctb, imax
1173  call bort(bort_str)
1174  endif
1175 
1176  return
1177 end function igetntbi
1178 
1193 subroutine nemtbax(lun,nemo,mtyp,msbt,inod)
1194 
1195  use moda_tababd
1196 
1197  implicit none
1198 
1199  integer, intent(in) :: lun
1200  integer, intent(out) :: mtyp, msbt, inod
1201  integer i
1202 
1203  character*(*), intent(in) :: nemo
1204  character*128 bort_str
1205 
1206  inod = 0
1207 
1208  ! Look for nemo in Table A
1209 
1210  do i=1,ntba(lun)
1211  if(taba(i,lun)(4:11)==nemo) then
1212  mtyp = idna(i,lun,1)
1213  msbt = idna(i,lun,2)
1214  inod = mtab(i,lun)
1215  if(mtyp<0 .or. mtyp>255) then
1216  write(bort_str,'("BUFRLIB: NEMTBAX - INVALID MESSAGE TYPE (",I4,") RETURNED FOR MENMONIC ",A)') mtyp, nemo
1217  call bort(bort_str)
1218  endif
1219  if(msbt<0 .or. msbt>255) then
1220  write(bort_str,'("BUFRLIB: NEMTBAX - INVALID MESSAGE SUBTYPE (",I4,") RETURNED FOR MENMONIC ",A)') msbt, nemo
1221  call bort(bort_str)
1222  endif
1223  exit
1224  endif
1225  enddo
1226 
1227  return
1228 end subroutine nemtbax
1229 
1243 subroutine nemtba(lun,nemo,mtyp,msbt,inod)
1244 
1245  implicit none
1246 
1247  integer, intent(in) :: lun
1248  integer, intent(out) :: mtyp, msbt, inod
1249 
1250  character*(*), intent(in) :: nemo
1251  character*128 bort_str
1252 
1253  ! Look for nemo in Table A
1254 
1255  call nemtbax(lun,nemo,mtyp,msbt,inod)
1256  if(inod==0) then
1257  write(bort_str,'("BUFRLIB: NEMTBA - CAN''T FIND MNEMONIC ",A)') nemo
1258  call bort(bort_str)
1259  endif
1260 
1261  return
1262 end subroutine nemtba
1263 
1274 subroutine nemtbb(lun,itab,unit,iscl,iref,ibit)
1275 
1276  use moda_tababd
1277 
1278  implicit none
1279 
1280  integer, intent(in) :: lun, itab
1281  integer, intent(out) :: iscl, iref, ibit
1282  integer idn, ierns
1283 
1284  character*128 bort_str
1285  character*24, intent(out) :: unit
1286  character*8 nemo
1287 
1288  if(itab<=0 .or. itab>ntbb(lun)) then
1289  write(bort_str,'("BUFRLIB: NEMTBB - ITAB (",I7,") NOT FOUND IN TABLE B")') itab
1290  call bort(bort_str)
1291  endif
1292 
1293  ! Pull out Table B information
1294 
1295  idn = idnb(itab,lun)
1296  nemo = tabb(itab,lun)( 7:14)
1297  unit = tabb(itab,lun)(71:94)
1298  call strnum(tabb(itab,lun)( 95: 98),iscl,ierns)
1299  call strnum(tabb(itab,lun)( 99:109),iref,ierns)
1300  call strnum(tabb(itab,lun)(110:112),ibit,ierns)
1301 
1302  ! Check Table B contents
1303 
1304  if(unit(1:5)/='CCITT' .and. ibit>32) then
1305  write(bort_str,'("BUFRLIB: NEMTBB - BIT WIDTH FOR NON-CHARACTER TABLE B MNEMONIC ",A," (",I7,") IS > 32")') nemo,ibit
1306  call bort(bort_str)
1307  endif
1308  if(unit(1:5)=='CCITT' .and. mod(ibit,8)/=0) then
1309  write(bort_str,'("BUFRLIB: NEMTBB - BIT WIDTH FOR CHARACTER TABLE B MNEMONIC ",A," (",I7,") IS NOT A MULTIPLE OF 8")') &
1310  nemo,ibit
1311  call bort(bort_str)
1312  endif
1313 
1314  return
1315 end subroutine nemtbb
1316 
1342 subroutine nemtbd(lun,itab,nseq,nems,irps,knts)
1343 
1344  use modv_vars, only: maxcd
1345 
1346  use moda_tababd
1347 
1348  implicit none
1349 
1350  integer, intent(in) :: lun, itab
1351  integer, intent(out) :: nseq, irps(*), knts(*)
1352  integer i, j, ndsc, idsc, iret
1353 
1354  character*128 bort_str
1355  character*8, intent(out) :: nems(*)
1356  character*8 nemo, nemt, nemf
1357  character tab
1358 
1359  if(itab<=0 .or. itab>ntbd(lun)) then
1360  write(bort_str,'("BUFRLIB: NEMTBD - ITAB (",I7,") NOT FOUND IN TABLE D")') itab
1361  call bort(bort_str)
1362  endif
1363 
1364  ! Clear the return values
1365 
1366  nseq = 0
1367 
1368  do i=1,maxcd
1369  nems(i) = ' '
1370  irps(i) = 0
1371  knts(i) = 0
1372  enddo
1373 
1374  ! Parse the Table D entry
1375 
1376  nemo = tabd(itab,lun)(7:14)
1377  idsc = idnd(itab,lun)
1378  call uptdd(itab,lun,0,ndsc)
1379 
1380  ! Loop through each child mnemonic
1381 
1382  do j=1,ndsc
1383  if(nseq+1>maxcd) then
1384  write(bort_str,'("BUFRLIB: NEMTBD - THERE ARE MORE THAN '// &
1385  '(",I4,") DESCRIPTORS (THE LIMIT) IN TABLE D SEQUENCE MNEMONIC ",A)') maxcd, nemo
1386  call bort(bort_str)
1387  endif
1388  call uptdd(itab,lun,j,idsc)
1389  call numtab(lun,idsc,nemt,tab,iret)
1390  if(tab=='R') then
1391  if(iret<0) then
1392  ! Regular (i.e. non-delayed) replication
1393  irps(nseq+1) = 1
1394  knts(nseq+1) = abs(iret)
1395  elseif(iret>0) then
1396  ! Delayed replication
1397  irps(nseq+1) = iret
1398  endif
1399  elseif(tab=='F') then
1400  ! Replication factor
1401  irps(nseq+1) = iret
1402  elseif(tab=='D'.or.tab=='C') then
1403  nseq = nseq+1
1404  nems(nseq) = nemt
1405  elseif(tab=='B') then
1406  nseq = nseq+1
1407  if((nemt(1:1)=='.').and.(j<ndsc)) then
1408  ! This is a "following value" mnemonic
1409  call uptdd(itab,lun,j+1,idsc)
1410  call numtab(lun,idsc,nemf,tab,iret)
1411  call rsvfvm(nemt,nemf)
1412  endif
1413  nems(nseq) = nemt
1414  endif
1415  enddo
1416 
1417  return
1418 end subroutine nemtbd
1419 
1442 recursive subroutine nemdefs ( lunit, nemo, celem, cunit, iret )
1443 
1444  use bufrlib
1445 
1446  use modv_vars, only: im8b
1447 
1448  use moda_tababd
1449 
1450  implicit none
1451 
1452  integer, intent(in) :: lunit
1453  integer, intent(out) :: iret
1454  integer my_lunit, lun, il, im, idn, iloc, ls, lcn, bort_target_set
1455 
1456  character*(*), intent(in) :: nemo
1457  character*(*), intent(out) :: celem, cunit
1458  character*56 ccelem
1459  character*25 ccunit
1460  character*10 cnemo
1461  character tab
1462 
1463  ! Check for I8 integers.
1464 
1465  if(im8b) then
1466  im8b=.false.
1467  call x84 ( lunit, my_lunit, 1 )
1468  call nemdefs ( my_lunit, nemo, celem, cunit, iret )
1469  call x48 ( iret, iret, 1 )
1470  im8b=.true.
1471  return
1472  endif
1473 
1474  ! If we're catching bort errors, set a target return location if one doesn't already exist.
1475 
1476  if ( bort_target_set() == 1 ) then
1477  call strsuc( nemo, cnemo, lcn )
1478  call catch_bort_nemdefs_c( lunit, cnemo, lcn, ccelem, len(ccelem), ccunit, len(ccunit), iret )
1479  ls = min(len(celem),55)
1480  celem(1:ls) = ccelem(1:ls)
1481  ls = min(len(cunit),24)
1482  cunit(1:ls) = ccunit(1:ls)
1483  call bort_target_unset
1484  return
1485  endif
1486 
1487  iret = -1
1488 
1489  ! Get lun from lunit.
1490 
1491  call status( lunit, lun, il, im )
1492  if ( il == 0 ) return
1493 
1494  ! Find the requested mnemonic in the internal Table B arrays.
1495 
1496  call nemtab( lun, nemo, idn, tab, iloc )
1497  if ( ( iloc == 0 ) .or. ( tab /= 'B' ) ) return
1498 
1499  ! Get the element name and units of the requested mnemonic.
1500 
1501  celem = ' '
1502  ls = min(len(celem),55)
1503  celem(1:ls) = tabb(iloc,lun)(16:15+ls)
1504 
1505  cunit = ' '
1506  ls = min(len(cunit),24)
1507  cunit(1:ls) = tabb(iloc,lun)(71:70+ls)
1508 
1509  iret = 0
1510 
1511  return
1512 end subroutine nemdefs
1513 
1528 subroutine nenubd(nemo,numb,lun)
1529 
1530  use moda_tababd
1531 
1532  implicit none
1533 
1534  character, intent(in) :: nemo*8, numb*6
1535  character*128 bort_str
1536 
1537  integer, intent(in) :: lun
1538  integer n
1539 
1540  do n=1,ntbb(lun)
1541  if(numb==tabb(n,lun)(1:6)) then
1542  write(bort_str,'("BUFRLIB: NENUBD - TABLE B FXY VALUE (",A,") HAS ALREADY BEEN DEFINED (DUPLICATE)")') numb
1543  call bort(bort_str)
1544  endif
1545  if(nemo==tabb(n,lun)(7:14)) then
1546  write(bort_str,'("BUFRLIB: NENUBD - TABLE B MNEMONIC (",A,") HAS ALREADY BEEN DEFINED (DUPLICATE)")') nemo
1547  call bort(bort_str)
1548  endif
1549  enddo
1550 
1551  do n=1,ntbd(lun)
1552  if(numb==tabd(n,lun)(1:6)) then
1553  write(bort_str,'("BUFRLIB: NENUBD - TABLE D FXY VALUE (",A,") HAS ALREADY BEEN DEFINED (DUPLICATE)")') numb
1554  call bort(bort_str)
1555  endif
1556  if(nemo==tabd(n,lun)(7:14)) then
1557  write(bort_str,'("BUFRLIB: NENUBD - TABLE D MNEMONIC (",A,") HAS ALREADY BEEN DEFINED (DUPLICATE)")') nemo
1558  call bort(bort_str)
1559  endif
1560  enddo
1561 
1562  return
1563 end subroutine nenubd
1564 
1574 subroutine stntbia ( n, lun, numb, nemo, celsq )
1575 
1576  use moda_tababd
1577 
1578  implicit none
1579 
1580  integer, intent(in) :: n, lun
1581  integer i, mtyp, msbt
1582 
1583  character*(*), intent(in) :: numb, nemo, celsq
1584  character*128 bort_str
1585 
1586  ! Confirm that neither nemo nor numb has already been defined within the internal BUFR Table A for the given lun.
1587 
1588  do i=1,ntba(lun)
1589  if(numb(4:6)==taba(i,lun)(1:3)) then
1590  write(bort_str,'("BUFRLIB: STNTBIA - TABLE A FXY VALUE (",A,") HAS ALREADY BEEN DEFINED (DUPLICATE)")') numb
1591  call bort(bort_str)
1592  endif
1593  if(nemo(1:8)==taba(i,lun)(4:11)) then
1594  write(bort_str,'("BUFRLIB: STNTBIA - TABLE A MNEMONIC (",A,") HAS ALREADY BEEN DEFINED (DUPLICATE)")') nemo
1595  call bort(bort_str)
1596  endif
1597  enddo
1598 
1599  ! Store the values within the internal BUFR Table A.
1600 
1601  taba(n,lun)(1:3) = numb(4:6)
1602  taba(n,lun)(4:11) = nemo(1:8)
1603  taba(n,lun)(13:67) = celsq(1:55)
1604 
1605  ! Decode and store the message type and subtype.
1606 
1607  if ( verify( nemo(3:8), '1234567890' ) == 0 ) then
1608  ! Message type & subtype obtained directly from Table A mnemonic
1609  read ( nemo,'(2X,2I3)') mtyp, msbt
1610  idna(n,lun,1) = mtyp
1611  idna(n,lun,2) = msbt
1612  else
1613  ! Message type obtained from Y value of Table A seq. descriptor
1614  read ( numb(4:6),'(I3)') idna(n,lun,1)
1615  ! Message subtype hardwired to zero
1616  idna(n,lun,2) = 0
1617  endif
1618 
1619  ! Update the count of internal Table A entries.
1620 
1621  ntba(lun) = n
1622 
1623  return
1624 end subroutine stntbia
1625 
1635 subroutine stntbi ( n, lun, numb, nemo, celsq )
1636 
1637  use moda_tababd
1638 
1639  implicit none
1640 
1641  integer, intent(in) :: n, lun
1642  integer ifxy
1643 
1644  character*(*), intent(in) :: numb, nemo, celsq
1645 
1646  call nenubd ( nemo, numb, lun )
1647 
1648  if ( numb(1:1) == '0') then
1649  idnb(n,lun) = ifxy(numb)
1650  tabb(n,lun)(1:6) = numb(1:6)
1651  tabb(n,lun)(7:14) = nemo(1:8)
1652  tabb(n,lun)(16:70) = celsq(1:55)
1653  ntbb(lun) = n
1654  else ! numb(1:1) == '3'
1655  idnd(n,lun) = ifxy(numb)
1656  tabd(n,lun)(1:6) = numb(1:6)
1657  tabd(n,lun)(7:14) = nemo(1:8)
1658  tabd(n,lun)(16:70) = celsq(1:55)
1659  ntbd(lun) = n
1660  endif
1661 
1662  return
1663 end subroutine stntbi
1664 
1680 subroutine pktdd(id,lun,idn,iret)
1681 
1682  use modv_vars, only: maxcd, iprt, idxv
1683 
1684  use moda_tababd
1685 
1686  implicit none
1687 
1688  integer, intent(in) :: id, lun, idn
1689  integer, intent(out) :: iret
1690  integer nxstr, ldxa, ldxb, ldxd, ld30, ldd, nd, idm, iupm
1691 
1692  character*128 errstr
1693  character*56 dxstr
1694 
1695  common /dxtab/ nxstr(10), ldxa(10), ldxb(10), ldxd(10), ld30(10), dxstr(10)
1696 
1697  ! ldd points to the byte within tabd(id,lun) which contains (in packed integer format) a count of the number of child
1698  ! mnemonics stored thus far for this parent mnemonic.
1699  ldd = ldxd(idxv+1)+1
1700 
1701  ! Zero the counter if idn is zero
1702  if(idn==0) then
1703  call ipkm(tabd(id,lun)(ldd:ldd),1,0)
1704  iret = 0
1705  return
1706  endif
1707 
1708  ! Update the stored descriptor count for this Table D entry. nd is the (unpacked) count of the number of child mnemonics
1709  ! stored thus far for this parent mnemonic.
1710  nd = iupm(tabd(id,lun)(ldd:ldd),8)
1711 
1712  if(nd<0 .or. nd==maxcd) then
1713  if(iprt>=0) then
1714  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
1715  if(nd<0) then
1716  write ( unit=errstr, fmt='(A,I4,A)' ) 'BUFRLIB: PKTDD - BAD COUNTER VALUE (=', nd, ') - RETURN WITH IRET = -1'
1717  else
1718  write ( unit=errstr, fmt='(A,I4,A,A)' ) 'BUFRLIB: PKTDD - MAXIMUM NUMBER OF CHILD MNEMONICS (=', &
1719  maxcd, ') ALREADY STORED FOR THIS PARENT - RETURN WITH IRET = -1'
1720  endif
1721  call errwrt(errstr)
1722  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
1723  call errwrt(' ')
1724  endif
1725  iret = -1
1726  return
1727  else
1728  nd = nd+1
1729  call ipkm(tabd(id,lun)(ldd:ldd),1,nd)
1730  iret = nd
1731  endif
1732 
1733  ! Pack and store the descriptor. idm points to the starting byte within tabd(id,lun) at which the idn value for this
1734  ! child mnemonic will be stored (as a packed integer of width = 2 bytes).
1735  idm = ldd+1 + (nd-1)*2
1736  call ipkm(tabd(id,lun)(idm:idm+1),2,idn)
1737 
1738  return
1739 end subroutine pktdd
1740 
1754 subroutine uptdd(id,lun,ient,iret)
1755 
1756  use modv_vars, only: idxv
1757 
1758  use moda_tababd
1759 
1760  implicit none
1761 
1762  integer, intent(in) :: id, lun, ient
1763  integer, intent(out) :: iret
1764  integer nxstr, ldxa, ldxb, ldxd, ld30, ldd, ndsc, idsc, iupm
1765 
1766  character*128 bort_str
1767  character*56 dxstr
1768 
1769  common /dxtab/ nxstr(10), ldxa(10), ldxb(10), ldxd(10), ld30(10), dxstr(10)
1770 
1771  ! Check if ient is in bounds
1772 
1773  ldd = ldxd(idxv+1)+1
1774  ndsc = iupm(tabd(id,lun)(ldd:ldd),8)
1775  if(ient==0) then
1776  iret = ndsc
1777  return
1778  elseif(ient<0 .or. ient>ndsc) then
1779  write(bort_str,'("BUFRLIB: UPTDD - VALUE OF THIRD ARGUMENT IENT (INPUT) IS OUT OF RANGE (IENT =",I4,")")') ient
1780  call bort(bort_str)
1781  endif
1782 
1783  ! Return the descriptor indicated by ient
1784 
1785  idsc = ldd+1 + (ient-1)*2
1786  iret = iupm(tabd(id,lun)(idsc:idsc+1),16)
1787 
1788  return
1789 end subroutine uptdd
1790 
1810 subroutine rsvfvm(nem1,nem2)
1811 
1812  implicit none
1813 
1814  character*8, intent(inout) :: nem1
1815  character*8, intent(in) :: nem2
1816 
1817  integer i, j
1818 
1819  do i=1,len(nem1)
1820  if(i==1) then
1821  ! Skip the initial ".", and initialize J.
1822  j = 1
1823  else
1824  if(nem1(i:i)=='.') then
1825  nem1(i:i) = nem2(j:j)
1826  j = j+1
1827  endif
1828  endif
1829  enddo
1830 
1831  return
1832 end subroutine rsvfvm
recursive subroutine bort(str)
Log an error message, then either return to or abort the application program.
Definition: borts.F90:15
subroutine bort_target_unset
Clear any existing bort target.
Definition: borts.F90:180
recursive subroutine bort2(str1, str2)
Log two error messages, then either return to or abort the application program.
Definition: borts.F90:48
integer function bort_target_set()
Sets a new bort target, if bort catching is enabled and such a target doesn't already exist.
Definition: borts.F90:160
recursive integer function iupb(mbay, nbyt, nbit)
Decode an integer value from within a specified number of bits of an integer array,...
Definition: cidecode.F90:226
recursive integer function iupm(cbay, nbits)
Decode an integer value from within a specified number of bits of a character string,...
Definition: cidecode.F90:263
subroutine upc(chr, nchr, ibay, ibit, cnvnull)
Decode a character string from within a specified number of bytes of an integer array,...
Definition: cidecode.F90:26
subroutine pkc(chr, nchr, ibay, ibit)
Encode a character string within a specified number of bytes of an integer array, starting at the bit...
Definition: ciencode.F90:25
recursive subroutine ipkm(cbay, nbyt, n)
Encode an integer value within a specified number of bytes of a character string, up to a maximum of ...
Definition: ciencode.F90:194
subroutine pkb(nval, nbits, ibay, ibit)
Encode an integer value within a specified number of bits of an integer array, starting at the bit im...
Definition: ciencode.F90:140
subroutine cpbfdx(lud, lun)
Copy all of the DX BUFR table information from one unit to another within internal memory.
Definition: copydata.F90:714
subroutine elemdx(card, lun)
Decode the scale factor, reference value, bit width and units (i.e., the "elements") from a Table B m...
Definition: dxtable.F90:514
subroutine nemtbb(lun, itab, unit, iscl, iref, ibit)
Get information about a Table B descriptor from the internal DX BUFR tables.
Definition: dxtable.F90:1275
subroutine dxmini(mbay, mbyt, mb4, mba, mbb, mbd)
Initialize a DX BUFR tables (dictionary) message, writing all the preliminary information into Sectio...
Definition: dxtable.F90:691
subroutine nemtba(lun, nemo, mtyp, msbt, inod)
Get information about a Table A descriptor from the internal DX BUFR tables.
Definition: dxtable.F90:1244
subroutine rdusdx(lundx, lun)
Read and parse a file containing a user-supplied DX BUFR table in character format,...
Definition: dxtable.F90:197
subroutine rsvfvm(nem1, nem2)
Process a "following value" mnemonic.
Definition: dxtable.F90:1811
subroutine seqsdx(card, lun)
Decode the Table D sequence information from a mnemonic definition card that was previously read from...
Definition: dxtable.F90:333
recursive subroutine wrdxtb(lundx, lunot)
Generate one or more BUFR messages from the DX BUFR tables information associated with a given BUFR f...
Definition: dxtable.F90:838
subroutine nemtbax(lun, nemo, mtyp, msbt, inod)
Get information about a Table A descriptor from the internal DX BUFR tables.
Definition: dxtable.F90:1194
subroutine nemtbd(lun, itab, nseq, nems, irps, knts)
Get information about a Table D descriptor from the internal DX BUFR tables.
Definition: dxtable.F90:1343
subroutine stntbi(n, lun, numb, nemo, celsq)
Store a new entry within internal BUFR Table B or D.
Definition: dxtable.F90:1636
subroutine pktdd(id, lun, idn, iret)
Store information about a child mnemonic within the internal BUFR Table D.
Definition: dxtable.F90:1681
subroutine stntbia(n, lun, numb, nemo, celsq)
Store a new entry within internal BUFR Table A.
Definition: dxtable.F90:1575
subroutine stbfdx(lun, mesg)
Copy a DX BUFR tables message into the internal memory arrays in module moda_tababd.
Definition: dxtable.F90:987
subroutine writdx(lunit, lun, lundx)
Write DX BUFR table (dictionary) messages to the beginning of an output BUFR file in lunit.
Definition: dxtable.F90:800
recursive subroutine nemdefs(lunit, nemo, celem, cunit, iret)
Get the element name and units associated with a Table B descriptor.
Definition: dxtable.F90:1443
integer function igetntbi(lun, ctb)
Get the next available index for storing an entry within a specified internal DX BUFR table.
Definition: dxtable.F90:1150
subroutine readdx(lunit, lun, lundx)
Initialize modules moda_tababd and moda_msgcwd with DX BUFR (dictionary) tables.
Definition: dxtable.F90:29
subroutine dxinit(lun, ioi)
Clear out the internal arrays (in module moda_tababd) holding the DX BUFR table, then optionally init...
Definition: dxtable.F90:604
subroutine nenubd(nemo, numb, lun)
Confirm that a mnemonic and FXY value haven't already been defined.
Definition: dxtable.F90:1529
integer function idxmsg(mesg)
Check whether a BUFR message contains DX BUFR tables information that was generated by the NCEPLIBS-b...
Definition: dxtable.F90:1120
subroutine uptdd(id, lun, ient, iret)
Get the WMO bit-wise representation of the FXY value corresponding to a child mnemonic in a Table D s...
Definition: dxtable.F90:1755
subroutine rdbfdx(lunit, lun)
Beginning at the current file pointer location within lunit, read a complete DX BUFR table into inter...
Definition: dxtable.F90:121
subroutine errwrt(str)
Specify a custom location for the logging of error and diagnostic messages generated by the NCEPLIBS-...
Definition: errwrt.F90:32
subroutine nemtab(lun, nemo, idn, tab, iret)
Get information about a descriptor, based on a mnemonic.
Definition: fxy.F90:434
subroutine numtab(lun, idn, nemo, tab, iret)
Get information about a descriptor, based on the WMO bit-wise representation of an FXY value.
Definition: fxy.F90:359
character *(*) function adn30(idn, ldn)
Convert an FXY value from its WMO bit-wise representation to a character string of length 5 or 6.
Definition: fxy.F90:18
subroutine jstnum(str, sign, iret)
Left-justify a character string containing an encoded integer, by removing all leading blanks and any...
Definition: misc.F90:282
recursive subroutine strnum(str, num, iret)
Decode an integer from a character string.
Definition: misc.F90:156
subroutine strsuc(str1, str2, lens)
Remove leading and trailing blanks from a character string.
Definition: misc.F90:199
subroutine capit(str)
Capitalize all of the alphabetic characters in a string.
Definition: misc.F90:334
Wrap C NCEPLIBS-bufr functions so they can be called from within the Fortran part of the library.
Definition: bufrlib.F90:11
Declare arrays and variables used to store BUFR messages internally for multiple file IDs.
integer maxbyt
Maximum length of an output BUFR message.
Declare an array used by various subroutines and functions to hold a temporary working copy of a BUFR...
integer, dimension(:), allocatable mgwa
Temporary working copy of BUFR message.
Declare arrays and variables used to store DX BUFR tables internally for multiple file IDs.
integer, dimension(:), allocatable ntba
Number of Table A entries for each file ID (up to a maximum of maxtba, whose value is stored in array...
character *600, dimension(:,:), allocatable tabd
Table D entries for each file ID.
character *128, dimension(:,:), allocatable taba
Table A entries for each file ID.
integer, dimension(:,:), allocatable mtab
Entries within jump/link table corresponding to taba.
integer, dimension(:,:,:), allocatable idna
Message types (in array element 1) and subtypes (in array element 2) corresponding to taba.
integer, dimension(:), allocatable ntbd
Number of Table D entries for each file ID (up to a maximum of maxtbd, whose value is stored in array...
integer, dimension(:), allocatable ntbb
Number of Table B entries for each file ID (up to a maximum of maxtbb, whose value is stored in array...
integer, dimension(:,:), allocatable idnd
WMO bit-wise representations of the FXY values corresponding to tabd.
integer, dimension(:,:), allocatable idnb
WMO bit-wise representations of the FXY values corresponding to tabb.
character *128, dimension(:,:), allocatable tabb
Table B entries for each file ID.
recursive subroutine status(lunit, lun, il, im)
Check whether a specified Fortran logical unit number is currently connected to the NCEPLIBS-bufr sof...
logical function msgfull(msiz, itoadd, mxsiz)
Check whether the current data subset in the internal arrays will fit within the current BUFR message...
recursive subroutine getlens(mbay, ll, len0, len1, len2, len3, len4, len5)
Read the section lengths of a BUFR message, up to a specified point in the message.
subroutine rdmsgw(lunit, mesg, iret)
Read the next BUFR message from logical unit lunit as an array of integer words.
subroutine msgwrt(lunit, mesg, mgbyt)
Perform final checks and updates on a BUFR message before writing it to a specified Fortran logical u...
recursive integer function iupbs01(mbay, s01mnem)
Read a specified value from within Section 0 or Section 1 of a BUFR message.
Definition: s013vals.F90:245
subroutine parstr(str, tags, mtag, ntag, sep, limit80)
Parse a string containing one or more substrings into an array of substrings.
Definition: strings.F90:473
subroutine x48(iin4, iout8, nval)
Encode one or more 4-byte integer values as 8-byte integer values.
Definition: x4884.F90:18
subroutine x84(iin8, iout4, nval)
Encode one or more 8-byte integer values as 4-byte integer values.
Definition: x4884.F90:65