NCEPLIBS-bufr  12.2.0
All Data Structures Namespaces Files Functions Variables Macros Pages
jumplink.F90
Go to the documentation of this file.
1 
5 
22 subroutine makestab
23 
24  use modv_vars, only: bmiss, maxjl, nfiles, iprt
25 
26  use moda_usrint
27  use moda_stbfr
28  use moda_lushr
29  use moda_xtab
30  use moda_tababd
31  use moda_tables
32  use moda_nrv203
33  use moda_bitmaps
34 
35  implicit none
36 
37  integer lunit, lundx, lun, lum, n, itba, inc, newn, noda, node, inod, icmpdx, ishrdx
38 
39  character*128 bort_str, errstr
40  character*8 nemo
41 
42  logical expand
43 
44  ! Reset pointer table and string cache.
45 
46  ntab = 0
47  nnrv = 0
48  ntamc = 0
49  call strcln
50 
51  ! Figure out which units share tables.
52 
53  ! The lus array is static between calls to this subroutine, and it keeps track of which logical units share dictionary
54  ! table information:
55  ! if lus(i) = 0, then iolun(i) does not share dictionary table information with any other logical unit
56  ! if lus(i) > 0, then iolun(i) shares dictionary table information with logical unit iolun(lus(i))
57  ! if lus(i) < 0, then iolun(i) does not now, but at one point in the past, shared dictionary table information
58  ! with logical unit iolun(abs(lus(i)))
59 
60  ! The xtab array is non-static and is recomputed within the below loop during each call to this subroutine:
61  ! if xtab(i) = .true., then the dictionary table information has changed for iolun(i) since the last call to this subroutine
62  ! if xtab(i) = .false., then the dictionary table information has not changed for iolun(i) since the last call to this subroutine
63 
64  do lun=1,nfiles
65  xtab(lun) = .false.
66  if(iolun(lun)==0) then
67  ! Logical unit iolun(lun) is not defined to NCEPLIBS-bufr.
68  lus(lun) = 0
69  else if(mtab(1,lun)==0) then
70  ! New dictionary table information has been read for logical unit iolun(lun) since the last call to this subroutine.
71  xtab(lun) = .true.
72  if(lus(lun)/=0) then
73  if(iolun(abs(lus(lun)))==0) then
74  lus(lun) = 0
75  else if(lus(lun)>0) then
76  ! iolun(lun) was sharing table information with logical unit iolun(lus(lun)), so check whether the table information
77  ! has really changed. If not, then iolun(lun) just re-read a copy of the exact same table information as before,
78  ! and therefore it can continue to share with logical unit iolun(lus(lun)).
79  if(icmpdx(lus(lun),lun)==1) then
80  xtab(lun) = .false.
81  call cpbfdx(lus(lun),lun)
82  else
83  lus(lun) = (-1)*lus(lun)
84  endif
85  else if(icmpdx(abs(lus(lun)),lun)==1) then
86  ! iolun(lun) was not sharing table information with logical unit iolun(lus(lun)), but it did at one point in the past
87  ! and now once again has the same table information as that logical unit. Since the two units shared table
88  ! information at one point in the past, allow them to do so again.
89  xtab(lun) = .false.
90  lus(lun) = abs(lus(lun))
91  call cpbfdx(lus(lun),lun)
92  endif
93  endif
94  else if(lus(lun)>0) then
95  ! Logical unit iolun(lun) is sharing table information with logical unit iolun(lus(lun)), so make sure that the latter
96  ! unit is still defined to NCEPLIBS-bufr.
97  if(iolun(lus(lun))==0) then
98  lus(lun) = 0
99  else if( xtab(lus(lun)) .and. (icmpdx(lus(lun),lun)==0) ) then
100  ! The table information for logical unit iolun(lus(lun)) just changed (in midstream). If iolun(lun) is an output
101  ! file, then we will have to update it with the new table information later on in this subroutine. Otherwise,
102  ! iolun(lun) is an input file and is no longer sharing tables with iolun(lus(lun)).
103  if(iolun(lun)<0) lus(lun) = (-1)*lus(lun)
104  endif
105  else
106  ! Determine whether logical unit iolun(lun) is sharing table information with any other logical units.
107  lum = 1
108  do while ((lum<lun).and.(lus(lun)==0))
109  if(ishrdx(lum,lun)==1) then
110  lus(lun) = lum
111  else
112  lum = lum+1
113  endif
114  enddo
115  endif
116  enddo
117 
118  ! Initialize jump/link tables with subsets/sequences/elements.
119 
120  do lun=1,nfiles
121  if(iolun(lun)/=0 .and. ntba(lun)>0) then
122  ! Reset any existing inventory pointers.
123  if(iomsg(lun)/=0) then
124  if(lus(lun)<=0) then
125  inc = (ntab+1)-mtab(1,lun)
126  else
127  inc = mtab(1,lus(lun))-mtab(1,lun)
128  endif
129  do n=1,nval(lun)
130  inv(n,lun) = inv(n,lun)+inc
131  enddo
132  endif
133  if(lus(lun)<=0) then
134  ! The dictionary table information corresponding to logical unit iolun(lun) has not yet been written into the internal
135  ! jump/link table, so add it in now.
136  call chekstab(lun)
137  do itba=1,ntba(lun)
138  inod = ntab+1
139  nemo = taba(itba,lun)(4:11)
140  call tabsub(lun,nemo)
141  mtab(itba,lun) = inod
142  isc(inod) = ntab
143  enddo
144  else if( xtab(lus(lun)) .and. (icmpdx(lus(lun),lun)==0) ) then
145  ! Logical unit iolun(lun) is an output file that is sharing table information with logical unit iolun(lus(lun)) whose
146  ! table just changed (in midstream). Flush any existing data messages from iolun(lun), then update the table information
147  ! for this logical unit with the corresponding new table information from iolun(lus(lun)), then update iolun(lun) itself
148  ! with a copy of the new table information.
149  lunit = abs(iolun(lun))
150  if(iomsg(lun)/=0) call closmg(lunit)
151  call cpbfdx(lus(lun),lun)
152  lundx = abs(iolun(lus(lun)))
153  call wrdxtb(lundx,lunit)
154  endif
155  endif
156  enddo
157 
158  ! Store types and initial values and counts
159 
160  do node=1,ntab
161  if(typ(node)=='SUB') then
162  vali(node) = 0
163  knti(node) = 1
164  itp(node) = 0
165  elseif(typ(node)=='SEQ') then
166  vali(node) = 0
167  knti(node) = 1
168  itp(node) = 0
169  elseif(typ(node)=='RPC') then
170  vali(node) = 0
171  knti(node) = 0
172  itp(node) = 0
173  elseif(typ(node)=='RPS') then
174  vali(node) = 0
175  knti(node) = 0
176  itp(node) = 0
177  elseif(typ(node)=='REP') then
178  vali(node) = bmiss
179  knti(node) = irf(node)
180  itp(node) = 0
181  elseif(typ(node)=='DRS') then
182  vali(node) = 0
183  knti(node) = 1
184  itp(node) = 1
185  elseif(typ(node)=='DRP') then
186  vali(node) = 0
187  knti(node) = 1
188  itp(node) = 1
189  elseif(typ(node)=='DRB') then
190  vali(node) = 0
191  knti(node) = 0
192  itp(node) = 1
193  elseif(typ(node)=='NUM') then
194  vali(node) = bmiss
195  knti(node) = 1
196  itp(node) = 2
197  else ! typ(node)=='CHR'
198  vali(node) = bmiss
199  knti(node) = 1
200  itp(node) = 3
201  endif
202  enddo
203 
204  ! Set up expansion segments for type 'SUB', 'DRP', and 'DRS' nodes.
205 
206  newn = 0
207  knt(1:maxjl) = 0
208  do n=1,ntab
209  iseq(n,1) = 0
210  iseq(n,2) = 0
211  expand = typ(n)=='SUB' .or. typ(n)=='DRP' .or. typ(n)=='DRS' .or. typ(n)=='REP' .or. typ(n)=='DRB'
212  if(expand) then
213  iseq(n,1) = newn+1
214  noda = n
215  node = n+1
216  if(typ(noda)=='REP') then
217  knt(node) = knti(noda)
218  else
219  knt(node) = 1
220  endif
221  outer: do while (.true.)
222  newn = newn+1
223  if(newn>maxjl) then
224  write(bort_str,'("BUFRLIB: MAKESTAB - NUMBER OF JSEQ ENTRIES IN JUMP/LINK TABLE EXCEEDS THE LIMIT (",I6,")")') maxjl
225  call bort(bort_str)
226  endif
227  jseq(newn) = node
228  knt(node) = max(knti(node),knt(node))
229  inner: do while (.true.)
230  if(jump(node)*knt(node)>0) then
231  node = jump(node)
232  cycle outer
233  else if(link(node)>0) then
234  node = link(node)
235  cycle outer
236  else
237  node = jmpb(node)
238  if(node==noda) exit outer
239  if(node==0) then
240  write(bort_str,'("BUFRLIB: MAKESTAB - NODE IS ZERO, FAILED TO CIRCULATE (TAG IS ",A,")")') tag(n)
241  call bort(bort_str)
242  endif
243  knt(node) = max(knt(node)-1,0)
244  endif
245  enddo inner
246  enddo outer
247  iseq(n,2) = newn
248  endif
249  enddo
250 
251  ! Print the sequence tables
252 
253  if(iprt>=2) then
254  call errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
255  do n=1,ntab
256  write ( unit=errstr, fmt='(A,I5,2X,A10,A5,6I8)' ) &
257  'BUFRLIB: MAKESTAB ', n, tag(n), typ(n), jmpb(n), jump(n), link(n), ibt(n), irf(n), isc(n)
258  call errwrt(errstr)
259  enddo
260  call errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
261  call errwrt(' ')
262  endif
263 
264  return
265 end subroutine makestab
266 
273 subroutine chekstab(lun)
274 
275  use moda_tababd
276  use moda_nmikrp
277 
278  implicit none
279 
280  integer, intent(in) :: lun
281  integer itab, idn, iret, iscl, iref, ibit, nseq
282 
283  character*128 bort_str
284  character*24 unit
285  character*8 nemo
286  character*1 tab
287 
288  ! There must be entries in Tables A, B, and D
289 
290  if(ntba(lun)==0) call bort ('BUFRLIB: CHEKSTAB - EMPTY TABLE A IN INTERNAL BUFR TABLES')
291  if(ntbb(lun)==0) call bort ('BUFRLIB: CHEKSTAB - EMPTY TABLE B IN INTERNAL BUFR TABLES')
292  if(ntbd(lun)==0) call bort ('BUFRLIB: CHEKSTAB - EMPTY TABLE D IN INTERNAL BUFR TABLES')
293 
294  ! Make sure each Table A entry is defined as a sequence
295 
296  do itab=1,ntba(lun)
297  nemo = taba(itab,lun)(4:11)
298  call nemtab(lun,nemo,idn,tab,iret)
299  if(tab/='D') then
300  write(bort_str,'("BUFRLIB: CHEKSTAB - TABLE A ENTRY: ",A," NOT DEFINED AS A SEQUENCE")') nemo
301  call bort(bort_str)
302  endif
303  enddo
304 
305  ! Check Table B contents
306 
307  do itab=1,ntbb(lun)
308  call nemtbb(lun,itab,unit,iscl,iref,ibit)
309  enddo
310 
311  ! Check Table D contents
312 
313  do itab=1,ntbd(lun)
314  call nemtbd(lun,itab,nseq,nem(1,1),irp(1,1),krp(1,1))
315  enddo
316 
317  return
318 end subroutine chekstab
319 
327 subroutine tabsub(lun,nemo)
328 
329  use modv_vars, only: mxtamc, mxtco
330 
331  use moda_tables
332  use moda_nmikrp
333  use moda_nrv203
334  use moda_bitmaps
335  use moda_tabccc
336 
337  implicit none
338 
339  integer, intent(in) :: lun
340  integer jmp0(10), nodl(10), ntag(10,2), maxlim, node, idn, itab, nseq, limb, n, jj, iyyy, irep, iknt, jum0, iokoper
341 
342  character*128 bort_str
343  character*8, intent(in) :: nemo
344  character*8 nems
345  character*1 tab
346 
347  logical drop(10), ltamc
348 
349  data maxlim /10/
350 
351  ! Check the mnemonic
352 
353  ! Note that Table A mnemonics, in addition to being stored within internal BUFR Table A array taba(*,lun), are also stored as
354  ! Table D mnemonics within internal BUFR Table D array tabd(*,lun). So the following test is valid.
355 
356  call nemtab(lun,nemo,idn,tab,itab)
357  if(tab/='D') then
358  write(bort_str,'("BUFRLIB: TABSUB - SUBSET NODE NOT IN TABLE D (TAB=",A,") FOR INPUT MNEMONIC ",A)') tab,nemo
359  call bort(bort_str)
360  endif
361 
362  ! Store a subset node and jump/link the tree
363 
364  call inctab(nemo,'SUB',node)
365  jump(node) = node+1
366  jmpb(node) = 0
367  link(node) = 0
368  ibt(node) = 0
369  irf(node) = 0
370  isc(node) = 0
371 
372  call nemtbd(lun,itab,nseq,nem(1,1),irp(1,1),krp(1,1))
373  ntag(1,1) = 1
374  ntag(1,2) = nseq
375  jmp0(1) = node
376  nodl(1) = node
377  limb = 1
378 
379  icdw = 0
380  icsc = 0
381  icrv = 1
382  incw = 0
383 
384  ibtnrv = 0
385  ipfnrv = 0
386 
387  if(ntamc+1>mxtamc) call bort('BUFRLIB: TABSUB - MXTAMC OVERFLOW')
388  inodtamc(ntamc+1) = node
389  ntco(ntamc+1) = 0
390  ltamc = .false.
391 
392  ! The following loop resolves all entities in the subset by emulating recursion via explicit goto statements.
393 
394  11 do n=ntag(limb,1),ntag(limb,2)
395 
396  ntag(limb,1) = n+1
397  drop(limb) = n==ntag(limb,2)
398 
399  call nemtab(lun,nem(n,limb),idn,tab,itab)
400  nems = nem(n,limb)
401 
402  if(tab=='C') then
403  ! Special treatment for certain operator descriptors.
404  read(nems,'(3X,I3)') iyyy
405  if(itab==1) then
406  if(iyyy/=0) then
407  if(icdw/=0) then
408  write(bort_str,'("BUFRLIB: TABSUB - THERE ARE TWO SIMULTANEOUS '// &
409  'CHANGE DATA WIDTH OPERATIONS IN THE TREE BUILT FROM INPUT MNEMONIC ",A)') nemo
410  call bort(bort_str)
411  endif
412  icdw = iyyy-128
413  else
414  icdw = 0
415  endif
416  elseif(itab==2) then
417  if(iyyy/=0) then
418  if(icsc/=0) then
419  write(bort_str,'("BUFRLIB: TABSUB - THERE ARE TWO SIMULTANEOUS '// &
420  'CHANGE DATA SCALE OPERATIONS IN THE TREE BUILT FROM INPUT MNEMONIC ",A)') nemo
421  call bort(bort_str)
422  endif
423  icsc = iyyy-128
424  else
425  icsc = 0
426  endif
427  elseif(itab==3) then
428  if(iyyy==0) then
429  ! Stop applying new reference values to subset nodes. Instead, revert to the use of standard Table B values.
430  if(ipfnrv==0) then
431  write(bort_str,'("BUFRLIB: TABSUB - A 2-03-000 OPERATOR WAS '// &
432  'ENCOUNTERED WITHOUT ANY PRIOR 2-03-YYY OPERATOR FOR INPUT MNEMONIC ",A)') nemo
433  call bort(bort_str)
434  endif
435  do jj=ipfnrv,nnrv
436  ienrv(jj) = ntab
437  enddo
438  ipfnrv = 0
439  elseif(iyyy==255) then
440  ! End the definition of new reference values.
441  ibtnrv = 0
442  else
443  ! Begin the definition of new reference values.
444  if(ibtnrv/=0) then
445  write(bort_str,'("BUFRLIB: TABSUB - THERE ARE TWO SIMULTANEOUS '// &
446  'CHANGE REF VALUE OPERATIONS IN THE TREE BUILT FROM INPUT MNEMONIC ",A)') nemo
447  call bort(bort_str)
448  endif
449  ibtnrv = iyyy
450  endif
451  elseif(itab==7) then
452  if(iyyy>0) then
453  if(icdw/=0) then
454  write(bort_str,'("BUFRLIB: TABSUB - THERE ARE TWO SIMULTANEOUS '// &
455  'CHANGE DATA WIDTH OPERATIONS IN THE TREE BUILT FROM INPUT MNEMONIC ",A)') nemo
456  call bort(bort_str)
457  endif
458  if(icsc/=0) then
459  write(bort_str,'("BUFRLIB: TABSUB - THERE ARE TWO SIMULTANEOUS '// &
460  'CHANGE DATA SCALE OPERATIONS IN THE TREE BUILT FROM INPUT MNEMONIC ",A)') nemo
461  call bort(bort_str)
462  endif
463  icdw = ((10*iyyy)+2)/3
464  icsc = iyyy
465  icrv = 10**iyyy
466  else
467  icsc = 0
468  icdw = 0
469  icrv = 1
470  endif
471  elseif(itab==8) then
472  incw = iyyy
473  elseif((itab>=21).and.(iokoper(nems)==1)) then
474  ! Save the location of this operator within the jump/link table, for possible later use.
475  if(.not.ltamc) then
476  ltamc = .true.
477  ntamc = ntamc+1
478  end if
479  if(ntco(ntamc)+1>mxtco) call bort('BUFRLIB: TABSUB - MXTCO OVERFLOW')
480  ntco(ntamc) = ntco(ntamc)+1
481  ctco(ntamc,ntco(ntamc)) = nems(1:6)
483  endif
484  else
485  nodl(limb) = ntab+1
486  irep = irp(n,limb)
487  iknt = krp(n,limb)
488  jum0 = jmp0(limb)
489  call tabent(lun,nems,tab,itab,irep,iknt,jum0)
490  endif
491 
492  if(tab=='D') then
493  ! Note here how a new tree "limb" is created (and is then immediately recursively resolved) whenever a Table D mnemonic
494  ! contains another Table D mnemonic as one of its children.
495  limb = limb+1
496  if(limb>maxlim) then
497  write(bort_str,'("BUFRLIB: TABSUB - THERE ARE TOO MANY NESTED '// &
498  'TABLE D SEQUENCES (TREES) WITHIN INPUT MNEMONIC ",A," - THE LIMIT IS",I4)') nemo,maxlim
499  call bort(bort_str)
500  endif
501  call nemtbd(lun,itab,nseq,nem(1,limb),irp(1,limb),krp(1,limb))
502  ntag(limb,1) = 1
503  ntag(limb,2) = nseq
504  jmp0(limb) = ntab
505  goto 11
506  elseif(drop(limb)) then
507  do while (.true.)
508  link(nodl(limb)) = 0
509  limb = limb-1
510  if(limb==0) then
511  if(icrv/=1) then
512  write(bort_str,'("BUFRLIB: TABSUB - A 2-07-YYY OPERATOR WAS '// &
513  'NOT CANCELLED IN THE TREE BUILT FROM INPUT MNEMONIC ",A)') nemo
514  call bort(bort_str)
515  endif
516  if(icdw/=0) then
517  write(bort_str,'("BUFRLIB: TABSUB - A 2-01-YYY OPERATOR WAS '// &
518  'NOT CANCELLED IN THE TREE BUILT FROM INPUT MNEMONIC ",A)') nemo
519  call bort(bort_str)
520  endif
521  if(icsc/=0) then
522  write(bort_str,'("BUFRLIB: TABSUB - A 2-02-YYY OPERATOR WAS '// &
523  'NOT CANCELLED IN THE TREE BUILT FROM INPUT MNEMONIC ",A)') nemo
524  call bort(bort_str)
525  endif
526  if(incw/=0) then
527  write(bort_str,'("BUFRLIB: TABSUB - A 2-08-YYY OPERATOR WAS '// &
528  'NOT CANCELLED IN THE TREE BUILT FROM INPUT MNEMONIC ",A)') nemo
529  call bort(bort_str)
530  endif
531  if(ibtnrv/=0) then
532  write(bort_str,'("BUFRLIB: TABSUB - A 2-03-YYY OPERATOR WAS '// &
533  'APPLIED WITHOUT ANY SUBSEQUENT 2-03-255 OPERATOR FOR INPUT MNEMONIC ",A)') nemo
534  call bort(bort_str)
535  endif
536  if(ipfnrv/=0) then
537  ! One or more new reference values were defined for this subset, but there was no subsequent 2-03-000 operator,
538  ! so set all IENRV(*) values for this subset to point to the last element of the subset within the jump/link table.
539  ! Note that, if there had been a subsequent 2-03-000 operator, then these IENRV(*) values would have already been
540  ! properly set above.
541  do jj=ipfnrv,nnrv
542  ienrv(jj) = ntab
543  enddo
544  endif
545  return
546  endif
547  if(.not.drop(limb)) exit
548  enddo
549  link(nodl(limb)) = ntab+1
550  goto 11
551  elseif(tab/='C') then
552  link(nodl(limb)) = ntab+1
553  endif
554 
555  enddo
556 
557  write(bort_str,'("BUFRLIB: TABSUB - ENTITIES WERE NOT SUCCESSFULLY RESOLVED (BY EMULATING RESURSION) FOR SUBSET '// &
558  'DEFINED BY TBL A MNEM. ",A)') nemo
559  call bort(bort_str)
560 
561  return
562 end subroutine tabsub
563 
577 subroutine tabent(lun,nemo,tab,itab,irep,iknt,jum0)
578 
579  use modv_vars, only: mxnrv, typs, reps, lens
580 
581  use moda_tables
582  use moda_nrv203
583  use moda_tabccc
584 
585  implicit none
586 
587  integer, intent(in) :: lun, itab, irep, iknt, jum0
588  integer i, jm0, node, iscl, iref, ibit
589 
590  character*24 unit
591  character*10 rtag
592  character*8, intent(in) :: nemo
593  character, intent(in) :: tab
594  character*3 typt
595 
596  jm0 = jum0
597 
598  ! Make a jump/link table entry for a replicator
599 
600  if(irep/=0) then
601  rtag = reps(irep)//nemo
602  do i=1,10
603  if(rtag(i:i)==' ') then
604  rtag(i:i) = reps(irep+5)
605  call inctab(rtag,typs(irep),node)
606  jump(node) = node+1
607  jmpb(node) = jm0
608  link(node) = 0
609  ibt(node) = lens(irep)
610  irf(node) = 0
611  isc(node) = 0
612  if(irep==1) irf(node) = iknt
613  jm0 = node
614  exit
615  endif
616  enddo
617  endif
618 
619  ! Make a jump/link entry for an element or a sequence
620 
621  if(tab=='B') then
622  call nemtbb(lun,itab,unit,iscl,iref,ibit)
623  if(unit(1:5)=='CCITT') then
624  typt = 'CHR'
625  else
626  typt = 'NUM'
627  endif
628  call inctab(nemo,typt,node)
629  jump(node) = 0
630  jmpb(node) = jm0
631  link(node) = 0
632  ibt(node) = ibit
633  irf(node) = iref
634  isc(node) = iscl
635  if(unit(1:4)=='CODE') then
636  typt = 'COD'
637  elseif(unit(1:4)=='FLAG') then
638  typt = 'FLG'
639  endif
640  if( (typt=='NUM') .and. (ibtnrv/=0) ) then
641  ! This node contains a new (redefined) reference value.
642  if(nnrv+1>mxnrv) call bort('BUFRLIB: TABENT - MXNRV OVERFLOW')
643  nnrv = nnrv+1
644  tagnrv(nnrv) = nemo
645  inodnrv(nnrv) = node
646  isnrv(nnrv) = node+1
647  ibt(node) = ibtnrv
648  if(ipfnrv==0) ipfnrv = nnrv
649  elseif( (typt=='NUM') .and. (nemo(1:3)/='204') ) then
650  ibt(node) = ibt(node) + icdw
651  isc(node) = isc(node) + icsc
652  irf(node) = irf(node) * icrv
653  elseif( (typt=='CHR') .and. (incw>0) ) then
654  ibt(node) = incw * 8
655  endif
656  else ! tab=='D'
657  if(irep==0) then
658  typt = 'SEQ'
659  else
660  typt = typs(irep+5)
661  endif
662  call inctab(nemo,typt,node)
663  jump(node) = node+1
664  jmpb(node) = jm0
665  link(node) = 0
666  ibt(node) = 0
667  irf(node) = 0
668  isc(node) = 0
669  endif
670 
671  return
672 end subroutine tabent
673 
686 subroutine inctab(atag,atyp,node)
687 
688  use modv_vars, only: maxjl
689 
690  use moda_tables
691 
692  implicit none
693 
694  integer, intent(out) :: node
695 
696  character*(*), intent(in) :: atag, atyp
697  character*128 bort_str
698 
699  ntab = ntab+1
700  if(ntab>maxjl) then
701  write(bort_str,'("BUFRLIB: INCTAB - THE NUMBER OF JUMP/LINK TABLE ENTRIES EXCEEDS THE LIMIT, MAXJL (",I7,")")') maxjl
702  call bort(bort_str)
703  endif
704  tag(ntab) = atag
705  typ(ntab) = atyp
706  node = ntab
707 
708  return
709 end subroutine inctab
710 
731 integer function lstjpb(node,lun,jbtyp) result(iret)
732 
733  use moda_msgcwd
734  use moda_tables
735 
736  implicit none
737 
738  integer, intent(in) :: node, lun
739  integer nod
740 
741  character*(*), intent(in) :: jbtyp
742  character*128 bort_str
743 
744  if(node<inode(lun)) then
745  write(bort_str,'("BUFRLIB: LSTJPB - TABLE NODE (",I7,") IS OUT OF BOUNDS, < LOWER BOUNDS (",I7,")")') node,inode(lun)
746  call bort(bort_str)
747  endif
748  if(node>isc(inode(lun))) then
749  write(bort_str,'("BUFRLIB: LSTJPB - TABLE NODE (",I7,") IS OUT OF BOUNDS, > UPPER BOUNDS (",I7,")")') node,isc(inode(lun))
750  call bort(bort_str)
751  endif
752 
753  nod = node
754 
755  ! Find this or the previous node of type jbtyp
756 
757  do while (nod/=0)
758  if(typ(nod)==jbtyp) exit
759  nod = jmpb(nod)
760  enddo
761 
762  iret = nod
763 
764  return
765 end function lstjpb
766 
777 integer function ishrdx(lud,lun) result(iret)
778 
779  use moda_tababd
780 
781  implicit none
782 
783  integer, intent(in) :: lud, lun
784  integer ii
785 
786  ! Note that, for any file ID luX, the mtab(*,luX) array contains pointer indices into the internal jump/link table
787  ! for each of the Table A mnemonics that is currently defined for that luX value. Thus, if all of these indices are
788  ! identical for two different luX values, then the associated logical units are sharing table information.
789 
790  if ( ( ntba(lud) >= 1 ) .and. ( ntba(lud) == ntba(lun) ) ) then
791  ii = 1
792  iret = 1
793  do while ( ( ii <= ntba(lud) ) .and. ( iret == 1 ) )
794  if ( ( mtab(ii,lud) /= 0 ) .and. ( mtab(ii,lud) == mtab(ii,lun) ) ) then
795  ii = ii + 1
796  else
797  iret = 0
798  endif
799  enddo
800  else
801  iret = 0
802  endif
803 
804  return
805 end function ishrdx
806 
822 integer function icmpdx(lud,lun) result(iret)
823 
824  use moda_tababd
825 
826  implicit none
827 
828  integer, intent(in) :: lud, lun
829  integer ishrdx, i
830 
831  ! First, check whether the two units are actually sharing tables.
832  ! If so, then they obviously have the same table information.
833 
834  iret = ishrdx(lud,lun)
835  if ( iret == 1 ) return
836 
837  ! Otherwise, check whether the internal Table A, B and D entries are all identical between the two units.
838 
839  if ( ( ntba(lud) == 0 ) .or. ( ntba(lun) /= ntba(lud) ) ) return
840  do i = 1, ntba(lud)
841  if ( idna(i,lun,1) /= idna(i,lud,1) ) return
842  if ( idna(i,lun,2) /= idna(i,lud,2) ) return
843  if ( taba(i,lun) /= taba(i,lud) ) return
844  enddo
845 
846  if ( ( ntbb(lud) == 0 ) .or. ( ntbb(lun) /= ntbb(lud) ) ) return
847  do i = 1, ntbb(lud)
848  if ( idnb(i,lun) /= idnb(i,lud) ) return
849  if ( tabb(i,lun) /= tabb(i,lud) ) return
850  enddo
851 
852  if ( ( ntbd(lud) == 0 ) .or. ( ntbd(lun) /= ntbd(lud) ) ) return
853  do i = 1, ntbd(lud)
854  if ( idnd(i,lun) /= idnd(i,lud) ) return
855  if ( tabd(i,lun) /= tabd(i,lud) ) return
856  enddo
857 
858  iret = 1
859 
860  return
861 end function icmpdx
862 
888 subroutine drstpl(inod,lun,inv1,inv2,invn)
889 
890  use moda_tables
891 
892  implicit none
893 
894  integer, intent(in) :: inod, lun, inv1
895  integer, intent(inout) :: inv2
896  integer, intent(out) :: invn
897  integer node, invwin
898 
899  do while (.true.)
900  node = inod
901  do while (.true.)
902  node = jmpb(node)
903  if(node==0) return
904  if(typ(node)=='DRS' .or. typ(node)=='DRB') then
905  invn = invwin(node,lun,inv1,inv2)
906  if(invn>0) then
907  call usrtpl(lun,invn,1)
908  call newwin(lun,inv1,inv2)
909  invn = invwin(inod,lun,invn,inv2)
910  if(invn>0) return
911  exit
912  endif
913  endif
914  enddo
915  enddo
916 
917  return
918 end subroutine drstpl
919 
952 recursive subroutine nemspecs ( lunit, nemo, nnemo, nscl, nref, nbts, iret )
953 
954  use modv_vars, only: im8b
955 
956  use moda_usrint
957  use moda_msgcwd
958  use moda_tables
959  use moda_nrv203
960 
961  implicit none
962 
963  integer, intent(in) :: lunit, nnemo
964  integer, intent(out) :: nscl, nref, nbts, iret
965  integer my_lunit, my_nnemo, lun, il, im, nidx, ierfst, node, ltn, jj
966 
967  character*(*), intent(in) :: nemo
968  character*10 tagn
969 
970  ! Check for I8 integers.
971 
972  if(im8b) then
973  im8b=.false.
974 
975  call x84(lunit,my_lunit,1)
976  call x84(nnemo,my_nnemo,1)
977  call nemspecs(my_lunit,nemo,my_nnemo,nscl,nref,nbts,iret)
978  call x48(nscl,nscl,1)
979  call x48(nref,nref,1)
980  call x48(nbts,nbts,1)
981  call x48(iret,iret,1)
982 
983  im8b=.true.
984  return
985  endif
986 
987  iret = -1
988 
989  ! Get lun from lunit.
990 
991  call status( lunit, lun, il, im )
992  if ( il == 0 ) return
993  if ( inode(lun) /= inv(1,lun) ) return
994 
995  ! Starting from the beginning of the subset, locate the (nnemo)th occurrence of nemo.
996 
997  call fstag( lun, nemo, nnemo, 1, nidx, ierfst )
998  if ( ierfst /= 0 ) return
999 
1000  ! Confirm that nemo is a Table B mnemonic.
1001 
1002  node = inv(nidx,lun)
1003  if ( ( typ(node) /= 'NUM' ) .and. ( typ(node) /= 'CHR' ) ) return
1004 
1005  ! Get the scale factor, reference value and bit width, including accounting for any Table C operators which may be in
1006  ! scope for this particular occurrence of nemo.
1007 
1008  iret = 0
1009 
1010  nscl = isc(node)
1011  nbts = ibt(node)
1012  nref = irf(node)
1013 
1014  if ( nnrv > 0 ) then
1015 
1016  ! There are nodes containing redefined reference values (from one or more 2-03-YYY operators) in the jump/link table,
1017  ! so we need to check if this node is one of them.
1018 
1019  tagn = ' '
1020  call strsuc( nemo, tagn, ltn )
1021  if ( ( ltn <= 0 ) .or. ( ltn > 8 ) ) return
1022 
1023  do jj = 1, nnrv
1024  if ( ( node /= inodnrv(jj) ) .and. ( tagn(1:8) == tagnrv(jj) ) .and. &
1025  ( node >= isnrv(jj) ) .and. ( node <= ienrv(jj) ) ) then
1026  nref = int(nrv(jj))
1027  return
1028  end if
1029  end do
1030 
1031  end if
1032 
1033  return
1034 end subroutine nemspecs
1035 
1055 subroutine fstag ( lun, utag, nutag, nin, nout, iret )
1056 
1057  use moda_usrint
1058  use moda_tables
1059 
1060  implicit none
1061 
1062  integer, intent(in) :: lun, nutag, nin
1063  integer, intent(out) :: nout, iret
1064  integer, parameter :: maxtg = 15
1065  integer ntg, istep, itagct
1066 
1067  character*(*), intent(in) :: utag
1068  character*10 tgs(maxtg)
1069 
1070  iret = -1
1071 
1072  ! Confirm that there's only one mnemonic in the input string.
1073 
1074  call parstr( utag, tgs, maxtg, ntg, ' ', .true. )
1075  if ( ntg /= 1 ) return
1076 
1077  ! Starting from nin, search either forward or backward for the (nutag)th occurrence of utag.
1078 
1079  if ( nutag == 0 ) return
1080  istep = isign( 1, nutag )
1081  itagct = 0
1082  nout = nin + istep
1083  do while ( ( nout >= 1 ) .and. ( nout <= nval(lun) ) )
1084  if ( tgs(1) == tag(inv(nout,lun)) ) then
1085  itagct = itagct + 1
1086  if ( itagct == iabs(nutag) ) then
1087  iret = 0
1088  return
1089  endif
1090  endif
1091  nout = nout + istep
1092  enddo
1093 
1094  return
1095 end subroutine fstag
1096 
1116 recursive subroutine gettagpr ( lunit, tagch, ntagch, tagpr, iret )
1117 
1118  use modv_vars, only: im8b
1119 
1120  use moda_usrint
1121  use moda_msgcwd
1122  use moda_tables
1123 
1124  implicit none
1125 
1126  integer, intent(in) :: lunit, ntagch
1127  integer, intent(out) :: iret
1128  integer my_lunit, my_ntagch, lun, il, im, nch
1129 
1130  character*(*), intent(in) :: tagch
1131  character*(*), intent(out) :: tagpr
1132 
1133  ! Check for I8 integers.
1134 
1135  if(im8b) then
1136  im8b=.false.
1137 
1138  call x84 ( lunit, my_lunit, 1 )
1139  call x84 ( ntagch, my_ntagch, 1 )
1140  call gettagpr ( my_lunit, tagch, my_ntagch, tagpr, iret )
1141  call x48 ( iret, iret, 1 )
1142 
1143  im8b=.true.
1144  return
1145  endif
1146 
1147  iret = -1
1148 
1149  ! Get lun from lunit.
1150 
1151  call status( lunit, lun, il, im )
1152  if ( il == 0 ) return
1153  if ( inode(lun) /= inv(1,lun) ) return
1154 
1155  ! Get tagpr from the (ntagch)th occurrence of tagch.
1156 
1157  call fstag( lun, tagch, ntagch, 1, nch, iret )
1158  if ( iret /= 0 ) return
1159 
1160  tagpr = tag(jmpb(inv(nch,lun)))
1161 
1162  return
1163 end subroutine gettagpr
1164 
1181 integer function invtag(node,lun,inv1,inv2) result(iret)
1182 
1183  use modv_vars, only: iprt
1184 
1185  use moda_usrint
1186  use moda_tables
1187 
1188  implicit none
1189 
1190  integer, intent(in) :: node, lun, inv1, inv2
1191 
1192  character*10 tagn
1193 
1194  if(node/=0) then
1195  tagn = tag(node)
1196  ! Search between inv1 and inv2
1197  do iret=inv1,inv2
1198  if(tag(inv(iret,lun))==tagn) return
1199  enddo
1200  endif
1201 
1202  iret = 0
1203 
1204  if(iprt>=2) then
1205  call errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
1206  call errwrt('BUFRLIB: INVTAG - RETURNING WITH A VALUE OF 0')
1207  call errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
1208  call errwrt(' ')
1209  endif
1210 
1211  return
1212 end function invtag
1213 
1228 integer function invwin(node,lun,inv1,inv2) result(iret)
1229 
1230  use modv_vars, only: iprt
1231 
1232  use moda_usrint
1233 
1234  implicit none
1235 
1236  integer, intent(in) :: node, lun, inv1, inv2
1237  integer idx
1238 
1239  character*80 errstr
1240 
1241  iret = 0
1242  if(node/=0) then
1243  ! Search between inv1 and inv2
1244  do idx=inv1,inv2
1245  if(inv(idx,lun)==node) then
1246  iret = idx
1247  exit
1248  endif
1249  enddo
1250  endif
1251 
1252  if(iprt>=3) then
1253  write(errstr,'(a,3i8)') 'invwin i1,i2,in ', inv1, inv2, iret
1254  call errwrt(errstr)
1255  endif
1256 
1257  return
1258 end function invwin
1259 
1303 subroutine getwin(node,lun,iwin,jwin)
1304 
1305  use moda_usrint
1306 
1307  implicit none
1308 
1309  integer, intent(in) :: node, lun
1310  integer, intent(out) :: iwin, jwin
1311  integer irpc, lstjpb, invwin
1312 
1313  character*128 bort_str
1314 
1315  irpc = lstjpb(node,lun,'RPC')
1316 
1317  if(irpc==0) then
1318  iwin = invwin(node,lun,jwin,nval(lun))
1319  if(iwin==0 .and. jwin>1) return
1320  iwin = 1
1321  jwin = nval(lun)
1322  return
1323  else
1324  iwin = invwin(irpc,lun,jwin,nval(lun))
1325  if(iwin==0) return
1326  if(val(iwin,lun)==0.) then
1327  iwin = 0
1328  return
1329  endif
1330  endif
1331 
1332  jwin = invwin(irpc,lun,iwin+1,nval(lun))
1333  if(jwin==0) then
1334  write(bort_str,'("BUFRLIB: GETWIN - SEARCHED BETWEEN",I5," AND",I5,", MISSING BRACKET")') iwin+1, nval(lun)
1335  call bort(bort_str)
1336  endif
1337 
1338  return
1339 end subroutine getwin
1340 
1372 subroutine conwin(lun,inc1,inc2)
1373 
1374  use moda_usrint
1375 
1376  implicit none
1377 
1378  integer, intent(in) :: lun
1379  integer, intent(out) :: inc1, inc2
1380  integer nnod, ncon, nods, nodc, ivls, kons, nc, invcon
1381 
1382  common /usrstr/ nnod, ncon, nods(20), nodc(10), ivls(10), kons(10)
1383 
1384  if(ncon==0) then
1385  ! There are no condition nodes in the string
1386  inc1 = 1
1387  inc2 = nval(lun)
1388  return
1389  endif
1390 
1391  outer: do while (.true.)
1392  call getwin(nodc(1),lun,inc1,inc2)
1393  if(inc1>0) then
1394  do nc=1,ncon
1395  if(invcon(nc,lun,inc1,inc2)==0) cycle outer
1396  enddo
1397  endif
1398  exit
1399  enddo outer
1400 
1401  return
1402 end subroutine conwin
1403 
1430 integer function invcon(nc,lun,inv1,inv2) result(iret)
1431 
1432  use modv_vars, only: iprt
1433 
1434  use moda_usrint
1435 
1436  implicit none
1437 
1438  integer, intent(in) :: nc, lun, inv1, inv2
1439  integer nnod, ncon, nods, nodc, ivls, kons
1440 
1441  common /usrstr/ nnod, ncon, nods(20), nodc(10), ivls(10), kons(10)
1442 
1443  if(inv1>0 .and. inv1<=nval(lun) .and. inv2>0 .and. inv2<=nval(lun)) then
1444  do iret=inv1,inv2
1445  if(inv(iret,lun)==nodc(nc)) then
1446  if(kons(nc)==1 .and. val(iret,lun)==ivls(nc)) return
1447  if(kons(nc)==2 .and. val(iret,lun)/=ivls(nc)) return
1448  if(kons(nc)==3 .and. val(iret,lun)<ivls(nc)) return
1449  if(kons(nc)==4 .and. val(iret,lun)>ivls(nc)) return
1450  endif
1451  enddo
1452  endif
1453 
1454  iret = 0
1455  if(iprt>=2) then
1456  call errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
1457  call errwrt('BUFRLIB: INVCON - RETURNING WITH A VALUE OF 0')
1458  call errwrt('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
1459  call errwrt(' ')
1460  endif
1461 
1462  return
1463 end function invcon
1464 
1481 subroutine newwin(lun,iwin,jwin)
1482 
1483  use moda_usrint
1484 
1485  implicit none
1486 
1487  integer, intent(in) :: lun, iwin
1488  integer, intent(out) :: jwin
1489  integer node, lstjpb
1490 
1491  character*128 bort_str
1492 
1493  if(iwin==1) then
1494  ! This is a "SUB" (subset) node, so return jwin as pointing to the last value of the entire subset.
1495  jwin = nval(lun)
1496  return
1497  endif
1498 
1499  ! Confirm that iwin points to an "RPC" node and then compute jwin.
1500  node = inv(iwin,lun)
1501  if(lstjpb(node,lun,'RPC')/=node) then
1502  write(bort_str,'("BUFRLIB: NEWWIN - LSTJPB FOR NODE",I6,'// &
1503  '" (LSTJPB=",I5,") DOES NOT EQUAL VALUE OF NODE, NOT RPC (IWIN =",I8,")")') node, lstjpb(node,lun,'RPC'), iwin
1504  call bort(bort_str)
1505  endif
1506  jwin = iwin+nint(val(iwin,lun))
1507 
1508  return
1509 end subroutine newwin
1510 
1529 subroutine nxtwin(lun,iwin,jwin)
1530 
1531  use moda_usrint
1532 
1533  implicit none
1534 
1535  integer, intent(in) :: lun
1536  integer, intent(inout) :: iwin, jwin
1537  integer node, lstjpb
1538 
1539  character*128 bort_str
1540 
1541  if(jwin==nval(lun)) then
1542  iwin = 0
1543  return
1544  endif
1545 
1546  node = inv(iwin,lun)
1547  if(lstjpb(node,lun,'RPC')/=node) then
1548  write(bort_str,'("BUFRLIB: NXTWIN - LSTJPB FOR NODE",I6," '// &
1549  '(LSTJPB=",I5,") DOES NOT EQUAL VALUE OF NODE, NOT RPC (IWIN =",I8,")")') node, lstjpb(node,lun,'RPC'), iwin
1550  call bort(bort_str)
1551  endif
1552  if(val(jwin,lun)==0) then
1553  iwin = 0
1554  else
1555  iwin = jwin
1556  jwin = iwin+nint(val(iwin,lun))
1557  endif
1558 
1559  return
1560 end subroutine nxtwin
1561 
1579 integer function nvnwin(node,lun,inv1,inv2,invn,nmax) result(iret)
1580 
1581  use modv_vars, only: iprt
1582 
1583  use moda_usrint
1584 
1585  implicit none
1586 
1587  integer, intent(in) :: node, lun, inv1, inv2, nmax
1588  integer, intent(out) :: invn(*)
1589  integer i, n
1590 
1591  character*128 bort_str
1592 
1593  iret = 0
1594 
1595  if(node==0) then
1596  if(iprt>=1) then
1597  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
1598  call errwrt('BUFRLIB: NVNWIN - NODE=0, IMMEDIATE RETURN')
1599  call errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
1600  call errwrt(' ')
1601  endif
1602  return
1603  endif
1604 
1605  do i=1,nmax
1606  invn(i) = 1e9
1607  enddo
1608 
1609  ! Search between inv1 and inv2
1610 
1611  do n=inv1,inv2
1612  if(inv(n,lun)==node) then
1613  if(iret+1>nmax) then
1614  write(bort_str,'("BUFRLIB: NVNWIN - THE NUMBER OF EVENTS EXCEEDS THE LIMIT NMAX (",I5,")")') nmax
1615  call bort(bort_str)
1616  endif
1617  iret = iret+1
1618  invn(iret) = n
1619  endif
1620  enddo
1621 
1622  return
1623 end function nvnwin
subroutine bort(str)
Log an error message, then abort the application program.
Definition: borts.F90:15
subroutine cpbfdx(lud, lun)
Copy all of the DX BUFR table information from one unit to another within internal memory.
Definition: copydata.F90:676
subroutine nemtbb(lun, itab, unit, iscl, iref, ibit)
Get information about a Table B descriptor from the internal DX BUFR tables.
Definition: dxtable.F90:1269
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:840
subroutine nemtbd(lun, itab, nseq, nems, irps, knts)
Get information about a Table D descriptor from the internal DX BUFR tables.
Definition: dxtable.F90:1337
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 strsuc(str1, str2, lens)
Remove leading and trailing blanks from a character string.
Definition: misc.F90:199
Declare arrays and variables used to store bitmaps internally within a data subset definition.
integer, dimension(:,:), allocatable inodtco
Entries within jump/link table which contain Table C operators.
integer ntamc
Number of Table A mnemonics in jump/link table (up to a maximum of mxtamc) which contain at least one...
integer, dimension(:), allocatable inodtamc
Entries within jump/link table which contain Table A mnemonics.
character *6, dimension(:,:), allocatable ctco
Table C operators corresponding to inodtco.
integer, dimension(:), allocatable ntco
Number of Table C operators (with an XX value of 21 or greater) within the data subset definition of ...
Declare an array used by subroutine makestab() to keep track of which logical units share DX BUFR tab...
integer, dimension(:), allocatable lus
Tracking index for each file ID.
Declare arrays used to store information about the current BUFR message that is in the process of bei...
integer, dimension(:), allocatable inode
Table A mnemonic for type of BUFR message.
Declare arrays used by various subroutines to hold information about Table D sequences.
integer, dimension(:,:), allocatable krp
Replication counts corresponding to nem:
integer, dimension(:,:), allocatable irp
Replication indicators corresponding to nem:
character *8, dimension(:,:), allocatable nem
Child mnemonics within Table D sequences.
Declare arrays and variables for use with any 2-03-YYY (change reference value) operators present wit...
integer, dimension(:), allocatable ienrv
End of entry range in jump/link table, within which the corresponding new reference value in nrv will...
character *8, dimension(:), allocatable tagnrv
Table B mnemonic to which the corresponding new reference value in nrv applies.
integer, dimension(:), allocatable isnrv
Start of entry range in jump/link table, within which the corresponding new reference value in nrv wi...
integer nnrv
Number of entries in the jump/link table which contain new reference values (up to a maximum of mxnrv...
integer *8, dimension(:), allocatable nrv
New reference values corresponding to inodnrv.
integer ipfnrv
A number between 1 and nnrv, denoting the first entry within the module arrays which applies to the c...
integer, dimension(:), allocatable inodnrv
Entries within jump/link table which contain new reference values.
integer ibtnrv
Number of bits in Section 4 occupied by each new reference value for the current 2-03-YYY operator in...
Declare arrays used to store file and message status indicators for all logical units that have been ...
integer, dimension(:), allocatable iolun
File status indicators.
integer, dimension(:), allocatable iomsg
Message status indicator corresponding to iolun, denoting whether a BUFR message is currently open wi...
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.
Declare variables for use with certain Table C operators in the internal jump/link table.
integer icsc
Number by which to modify the scale of subsequent jump/link table mnemonics whose type indicator is "...
integer icdw
Number of bits by which to modify the data width of subsequent jump/link table mnemonics whose type i...
integer icrv
Factor by which to multiply the reference value of subsequent jump/link table mnemonics whose type in...
integer incw
New data width (in bytes) for subsequent jump/link table mnemonics whose type indicator is "CHR"; set...
Declare arrays and variables used to store the internal jump/link table.
integer, dimension(:), allocatable jseq
Temporary storage used in expanding sequences.
integer, dimension(:), allocatable irf
Reference values corresponding to tag and typ:
integer, dimension(:,:), allocatable iseq
Temporary storage used in expanding sequences.
integer, dimension(:), allocatable isc
Scale factors corresponding to tag and typ:
integer, dimension(:), allocatable ibt
Bit widths corresponding to tag and typ:
integer, dimension(:), allocatable knt
Temporary storage used in calculating delayed replication counts.
real *8, dimension(:), allocatable vali
Initialized data values corresponding to typ:
character *3, dimension(:), allocatable typ
Type indicators corresponding to tag:
integer, dimension(:), allocatable jmpb
Jump backward indices corresponding to tag and typ:
character *10, dimension(:), allocatable tag
Mnemonics in the jump/link table.
integer ntab
Number of entries in the jump/link table.
integer, dimension(:), allocatable jump
Jump forward indices corresponding to tag and typ:
integer, dimension(:), allocatable itp
Integer type values corresponding to typ:
integer, dimension(:), allocatable link
Link indices corresponding to tag, typ and jmpb:
integer, dimension(:), allocatable knti
Initialized replication counts corresponding to typ and jump:
Declare arrays used to store data values and associated metadata for the current BUFR data subset in ...
integer, dimension(:), allocatable nval
Number of data values in BUFR data subset.
real *8, dimension(:,:), allocatable, target val
Data values.
integer, dimension(:,:), allocatable, target inv
Inventory pointer which links each data value to its corresponding node in the internal jump/link tab...
Declare an array used to track, for each file ID, whether the DX BUFR table associated with the corre...
logical, dimension(:), allocatable xtab
Tracking index 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...
recursive subroutine closmg(lunin)
Close the BUFR message that is currently open for writing within internal arrays associated with logi...
subroutine usrtpl(lun, invn, nbmp)
Expand a subset template within internal arrays.
subroutine strcln
Reset the internal mnemonic string cache.
Definition: strings.F90:116
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