NCEPLIBS-bufr  12.3.0
dumpdata.F90
Go to the documentation of this file.
1 
5 
41 recursive subroutine ufbdmp(lunin,luprt)
42 
43  use bufrlib
44 
45  use modv_vars, only: im8b
46 
47  use moda_usrint
48  use moda_msgcwd
49  use moda_tababd
50  use moda_tables
51 
52  implicit none
53 
54  integer, intent(in) :: lunin, luprt
55  integer, parameter :: mxfv = 31
56  integer ifv(mxfv), my_lunin, my_luprt, luout, lunit, lun, il, im, nv, nd, it, ib, is, ir, jp, lk, jb, &
57  idn, nifv, nchr, n, ii, ipt, isz, isize, ibfms, icbfms, bort_target_set
58 
59  character lchr2*120, lchr*20, pmiss*20, bits*14, tg*10, tg_rj*10, vc*8, fmtf*7, tp*3, tab, you
60 
61  real*8 vl
62 
63  equivalence(vl,vc)
64 
65  data pmiss /' MISSING'/
66  data you /'Y'/
67 
68  ! Check for I8 integers
69 
70  if(im8b) then
71  im8b=.false.
72  call x84(lunin,my_lunin,1)
73  call x84(luprt,my_luprt,1)
74  call ufbdmp(my_lunin,my_luprt)
75  im8b=.true.
76  return
77  endif
78 
79  ! If we're catching bort errors, set a target return location if one doesn't already exist.
80 
81  if (bort_target_set() == 1) then
82  call catch_bort_ufbdmp_c(lunin,luprt)
84  return
85  endif
86 
87  if(luprt==0) then
88  luout = 6
89  else
90  luout = luprt
91  endif
92 
93  ! Check the file status and inode
94 
95  lunit = abs(lunin)
96  call status(lunit,lun,il,im)
97  if(il==0) call bort('BUFRLIB: UFBDMP - INPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR INPUT')
98  if(il>0) call bort('BUFRLIB: UFBDMP - INPUT BUFR FILE IS OPEN FOR OUTPUT, IT MUST BE OPEN FOR INPUT')
99  if(im==0) call bort('BUFRLIB: UFBDMP - A MESSAGE MUST BE OPEN IN INPUT BUFR FILE, NONE ARE')
100  if(inode(lun)/=inv(1,lun)) call bort('BUFRLIB: UFBDMP - LOCATION OF INTERNAL TABLE FOR '// &
101  'INPUT BUFR FILE DOES NOT AGREE WITH EXPECTED LOCATION IN INTERNAL SUBSET ARRAY')
102 
103  ! Dump the contents of @ref moda_usrint for unit abs(lunin)
104 
105  do nv=1,nval(lun)
106  if(luprt==0 .and. mod(nv,20)==0) then
107 
108  ! When luprt=0, the output will be scrolled, 20 elements at a time
109 
110  print*,'(<enter> for MORE, q <enter> to QUIT)'
111  read(5,'(A1)') you
112 
113  ! If the terminal enters "q" followed by "<enter>", then scrolling will end and the subroutine will return to the
114  ! calling program
115 
116  if(you=='q') then
117  print*
118  print*,'==> You have chosen to stop the dumping of this subset'
119  print*
120  return
121  endif
122  endif
123  nd = inv(nv,lun)
124  vl = val(nv,lun)
125  tg = tag(nd)
126  tp = typ(nd)
127  it = itp(nd)
128  ib = ibt(nd)
129  is = isc(nd)
130  ir = irf(nd)
131  jp = jump(nd)
132  lk = link(nd)
133  jb = jmpb(nd)
134  tg_rj = adjustr(tg)
135  if(tp/='CHR') then
136  bits = ' '
137  if(it==2) then
138  call nemtab(lun,tg,idn,tab,n)
139  if(tabb(n,lun)(71:75)=='FLAG') then
140 
141  ! Print a listing of the bits corresponding to this value.
142 
143  call upftbv(lunit,tg,vl,mxfv,ifv,nifv)
144  if(nifv>0) then
145  bits(1:1) = '('
146  ipt = 2
147  do ii=1,nifv
148  isz = isize(ifv(ii))
149  write(fmtf,'(A2,I1,A4)') '(I', isz, ',A1)'
150  if((ipt+isz)<=14) then
151  write(bits(ipt:ipt+isz),fmtf) ifv(ii), ','
152  ipt = ipt + isz + 1
153  else
154  bits(2:13) = 'MANY BITS ON'
155  ipt = 15
156  endif
157  enddo
158  bits(ipt-1:ipt-1) = ')'
159  endif
160  endif
161  endif
162  if(ibfms(vl)/=0) then
163  write(luout,'(I5,1X,A3,A1,I1,1X,A10,1X, A20, 14X,7(1X,I5))') nv,tp,'-',it,tg_rj,pmiss,ib,is,ir,nd,jp,lk,jb
164  else
165  if(lunit==lunin) then
166  write(luout,'(I5,1X,A3,A1,I1,1X,A10,5X,G15.6,1X,A14,7(1X,I5))') nv,tp,'-',it,tg_rj,vl,bits,ib,is,ir,nd,jp,lk,jb
167  else
168  write(luout,'(I5,1X,A3,A1,I1,1X,A10,5X,F15.6,1X,A14,7(1X,I5))') nv,tp,'-',it,tg_rj,vl,bits,ib,is,ir,nd,jp,lk,jb
169  endif
170  endif
171  else
172  nchr=ib/8
173  if(nchr>8) then
174  call readlc(lunit,lchr2,tg_rj)
175  if (icbfms(lchr2,nchr)/=0) then
176  lchr = pmiss
177  else
178  lchr = lchr2(1:20)
179  endif
180  else
181  if(ibfms(vl)/=0) then
182  lchr = pmiss
183  else
184  lchr = vc
185  endif
186  endif
187  if ( nchr<=20 .or. lchr==pmiss ) then
188  lchr = adjustr(lchr)
189  write(luout,'(I5,1X,A3,A1,I1,1X,A10,1X, A20, 14X,7(1X,I5))') nv,tp,'-',it,tg_rj,lchr,ib,is,ir,nd,jp,lk,jb
190  else
191  write(luout,'(I5,1X,A3,A1,I1,1X,A10,1X, A, 7(1X,I5))') nv,tp,'-',it,tg_rj,lchr2(1:nchr),ib,is,ir,nd,jp,lk,jb
192  endif
193  endif
194  enddo
195 
196  write(luout,'(/A/)') ' >>> END OF SUBSET <<< '
197 
198  return
199 end subroutine ufbdmp
200 
235 recursive subroutine ufdump(lunit,luprt)
236 
237  use bufrlib
238 
239  use modv_vars, only: im8b
240 
241  use moda_usrint
242  use moda_msgcwd
243  use moda_tababd
244  use moda_tables
245  use moda_tablef
246  use moda_nrv203
247 
248  implicit none
249 
250  integer, intent(in) :: lunit, luprt
251  integer, parameter :: mxfv = 31 , mxcfdp = 5, mxseq = 10, mxls = 10
252  integer ifv(mxfv), icfdp(mxcfdp), idxrep(mxseq), numrep(mxseq), lsqnam(mxseq), lsct(mxls), my_lunit, my_luprt, &
253  nseq, nls, lcfmeang, luout, lun, il, im, node, lnm2, lnm3, itmp, ityp, ii, jj, nifv, nv, n, nchr, idn, ipt, &
254  nrfe, nout, lcfmg, ifvd, iersf, ierbd, ierft, isz, isize, iscl, ireadmt, ibfms, icbfms, imrkopr, bort_target_set
255  integer*8 ival
256 
257  real*8 rval
258 
259  character cfmeang*120, lchr2*120, fmt*80, desc*64, unit*24, lchr*20, pmiss*20, nemo3*15, nemo*10, nemo2*10, tagrfe*10, &
260  seqnam(mxseq)*10, lsnemo(mxls)*10, nemod*8, cval*8, fmtf*7, numb*6, type*3, tab, you
261 
262  logical track, found, rdrv
263 
264  equivalence(rval,cval)
265 
266  data pmiss /' MISSING'/
267  data you /'Y'/
268 
269  ! Check for I8 integers
270 
271  if(im8b) then
272  im8b=.false.
273  call x84(lunit,my_lunit,1)
274  call x84(luprt,my_luprt,1)
275  call ufdump(my_lunit,my_luprt)
276  im8b=.true.
277  return
278  endif
279 
280  ! If we're catching bort errors, set a target return location if one doesn't already exist.
281 
282  if (bort_target_set() == 1) then
283  call catch_bort_ufdump_c(lunit,luprt)
284  call bort_target_unset
285  return
286  endif
287 
288  nseq = 0
289  nls = 0
290  lcfmeang = len(cfmeang)
291 
292  if(luprt==0) then
293  luout = 6
294  else
295  luout = luprt
296  endif
297 
298  ! Check the file status and inode
299 
300  call status(lunit,lun,il,im)
301  if(il==0) call bort('BUFRLIB: UFDUMP - INPUT BUFR FILE IS CLOSED, IT MUST BE OPEN FOR INPUT')
302  if(il>0) call bort('BUFRLIB: UFDUMP - INPUT BUFR FILE IS OPEN FOR OUTPUT, IT MUST BE OPEN FOR INPUT')
303  if(im==0) call bort('BUFRLIB: UFDUMP - A MESSAGE MUST BE OPEN IN INPUT BUFR FILE, NONE ARE')
304  if(inode(lun)/=inv(1,lun)) call bort('BUFRLIB: UFDUMP - LOCATION OF INTERNAL TABLE FOR '// &
305  'INPUT BUFR FILE DOES NOT AGREE WITH EXPECTED LOCATION IN INTERNAL SUBSET ARRAY')
306 
307  write(luout,'(/,2A,/)') 'MESSAGE TYPE ',tag(inode(lun))
308 
309  ! If code/flag table details are being printed, and if this is the first subset of a new message, then
310  ! make sure the appropriate master tables have been read in to memory for this message.
311 
312  if(cdmf=='Y' .and. nsub(lun)==1) itmp = ireadmt(lun)
313 
314  ! Dump the contents of @ref moda_usrint for unit lunit
315 
316  do nv=1,nval(lun)
317  if(luprt==0 .and. mod(nv,20)==0) then
318 
319  ! When luprt=0, the output will be scrolled, 20 elements at a time
320 
321  print*,'(<enter> for MORE, q <enter> to QUIT)'
322  read(5,'(A1)') you
323 
324  ! If the terminal enters "q" followed by "<enter>", then scrolling will end and the subroutine will return to the
325  ! calling program
326 
327  if(you=='q') then
328  print*
329  print*,'==> You have chosen to stop the dumping of this subset'
330  print*
331  return
332  endif
333  endif
334 
335  node = inv(nv,lun)
336  nemo = tag(node)
337  ityp = itp(node)
338  type = typ(node)
339 
340  if(ityp>=1.and.ityp<=3) then
341  call nemtab(lun,nemo,idn,tab,n)
342  if(n>0) then
343  numb = tabb(n,lun)(1:6)
344  desc = tabb(n,lun)(16:70)
345  unit = tabb(n,lun)(71:94)
346  endif
347  rval = val(nv,lun)
348  endif
349 
350  if((ityp==0).or.(ityp==1)) then
351 
352  ! Sequence descriptor or delayed descriptor replication factor
353 
354  if((type=='REP').or.(type=='DRP').or.(type=='DRB').or.(type=='DRS')) then
355 
356  ! Print the number of replications
357  nseq = nseq+1
358  if(nseq>mxseq) call bort('BUFRLIB: UFDUMP - MXSEQ OVERFLOW')
359  if(type=='REP') then
360  numrep(nseq) = irf(node)
361  else
362  numrep(nseq) = nint(rval)
363  endif
364  call strsuc(nemo,nemo2,lnm2)
365  fmt = '(11X,A,I6,1X,A)'
366  write(luout,fmt) nemo2(1:lnm2), numrep(nseq), 'REPLICATIONS'
367 
368  ! How many times is this sequence replicated?
369  if(numrep(nseq)>1) then
370  ! Track the sequence
371  seqnam(nseq) = nemo2
372  lsqnam(nseq) = lnm2
373  idxrep(nseq) = 1
374  else
375  ! Don't bother
376  nseq = nseq-1
377  endif
378  elseif( ((type=='SEQ').or.(type=='RPC').or.(type=='RPS')) .and. (nseq>0) ) then
379 
380  ! Is this one of the sequences being tracked?
381  ii = nseq
382  track = .false.
383  call strsuc(nemo,nemo2,lnm2)
384  do while ((ii>=1).and.(.not.track))
385  if(nemo2(1:lnm2)==seqnam(ii)(2:lsqnam(ii)-1)) then
386  track = .true.
387  ! Mark this level in the output
388  fmt = '(4X,A,2X,A,2X,A,I6,2X,A)'
389  write(luout,fmt) '++++++', nemo2(1:lnm2), 'REPLICATION #', idxrep(ii), '++++++'
390  if(idxrep(ii)<numrep(ii)) then
391  ! There are more levels to come
392  idxrep(ii) = idxrep(ii)+1
393  else
394  ! This was the last level for this sequence, so stop tracking it
395  nseq = nseq-1
396  endif
397  else
398  ii = ii-1
399  endif
400  enddo
401  endif
402  elseif(ityp==2) then
403 
404  ! Numeric value.
405 
406  ! First check if this node contains a redefined reference value. If so, modify the desc field to label it as such.
407  jj = 1
408  rdrv = .false.
409  do while ((jj<=nnrv).and.(.not.rdrv))
410  if (node==inodnrv(jj)) then
411  rdrv = .true.
412  desc = 'New reference value for ' // nemo
413  unit = ' '
414  else
415  jj = jj + 1
416  endif
417  enddo
418 
419  ! Next check if this element refers to another element via a bitmap. If so, modify the desc field to identify the
420  ! referred element.
421  nrfe = nrfelm(nv,lun)
422  if(nrfe>0) then
423  tagrfe = tag(inv(nrfe,lun))
424  jj = 48
425  do while((jj>=1).and.(desc(jj:jj)==' '))
426  jj = jj - 1
427  enddo
428  if(jj<=33) desc(jj+1:jj+15) = ' for ' // tagrfe
429  endif
430 
431  ! Now print the value
432  if(ibfms(rval)/=0) then
433  ! The value is "missing".
434  fmt = '(A6,2X,A10,2X,A20,2X,A24,6X,A48)'
435  write(luout,fmt) numb,nemo,pmiss,unit,desc
436  else
437  fmt = '(A6,2X,A10,2X, ,2X,A24,6X,A48)'
438  ! Based upon the corresponding scale factor, select an appropriate format for the printing of this value.
439  if(imrkopr(nemo)==1) then
440  iscl = isc(inv(nrfe,lun))
441  else
442  iscl = isc(node)
443  endif
444  if(iscl>0) then
445  write(fmt(15:20),'(A,I2)') 'F20.', iscl
446  else
447  write(fmt(18:20),'(A)') 'I20'
448  endif
449  if(unit(1:4)=='FLAG') then
450  ! Print a listing of the bits corresponding to this value.
451  call upftbv(lunit,nemo,rval,mxfv,ifv,nifv)
452  if(nifv>0) then
453  unit(11:11) = '('
454  ipt = 12
455  do ii=1,nifv
456  isz = isize(ifv(ii))
457  write(fmtf,'(A2,I1,A4)') '(I', isz, ',A1)'
458  if((ipt+isz)<=24) then
459  write(unit(ipt:ipt+isz),fmtf) ifv(ii), ','
460  ipt = ipt + isz + 1
461  else
462  unit(12:23) = 'MANY BITS ON'
463  ipt = 25
464  endif
465  enddo
466  unit(ipt-1:ipt-1) = ')'
467  endif
468  endif
469  if(iscl>0) then
470  write(luout,fmt) numb,nemo,rval,unit,desc
471  else
472  ival = nint(rval,8)
473  write(luout,fmt) numb,nemo,ival,unit,desc
474  endif
475  if( (unit(1:4)=='FLAG' .or. unit(1:4)=='CODE') .and. (cdmf=='Y') ) then
476  ! Print the meanings of the code and flag values.
477  fmt = '(31X,I8,A,A)'
478  if(unit(1:4)=='CODE') then
479  nifv = 1
480  ifv(nifv) = nint(rval)
481  endif
482  do ii=1,nifv
483  icfdp(1) = (-1)
484  call srchtbf_c(idn,ifv(ii),icfdp(1),mxcfdp,-1,cfmeang,lcfmeang,lcfmg,iersf)
485  if(iersf==0) then
486  write(luout,fmt) ifv(ii),' = ',cfmeang(1:lcfmg)
487  elseif(iersf<0) then
488  write(luout,fmt) ifv(ii),' = ','***THIS IS AN ILLEGAL/UNDEFINED VALUE***'
489  else
490  ! The meaning of this value is dependent on the value of another mnemonic in the report. Look for
491  ! that other mnemonic within the report and then use it and its associated value to retrieve and print
492  ! the proper meaning from the code/flag tables.
493  ierft = (-1)
494  jj = 0
495  do while((jj<iersf).and.(ierft<0))
496  jj = jj + 1
497  call numtbd(lun,icfdp(jj),nemod,tab,ierbd)
498  if((ierbd>0).and.(tab=='B')) call fstag(lun,nemod,-1,nv,nout,ierft)
499  enddo
500  if(ierft==0) then
501  ifvd = nint(val(nout,lun))
502  if(jj>1) icfdp(1) = icfdp(jj)
503  call srchtbf_c(idn,ifv(ii),icfdp(1),mxcfdp,ifvd,cfmeang,lcfmeang,lcfmg,iersf)
504  if(iersf==0) write(luout,fmt) ifv(ii),' = ', cfmeang(1:lcfmg)
505  endif
506  endif
507  enddo
508  endif
509  endif
510  elseif(ityp==3) then
511 
512  ! Character (CCITT IA5) value
513 
514  nchr = ibt(node)/8
515 
516  if(ibfms(rval)/=0) then
517  lchr = pmiss
518  else if(nchr<=8) then
519  lchr = cval
520  else
521  ! Track the number of occurrences of this long character string, so that we can properly output each one.
522  ii = 1
523  found = .false.
524  do while((ii<=nls).and.(.not.found))
525  if(nemo==lsnemo(ii)) then
526  found = .true.
527  else
528  ii = ii + 1
529  endif
530  enddo
531  if(.not.found) then
532  nls = nls+1
533  if(nls>mxls) call bort('BUFRLIB: UFDUMP - MXLS OVERFLOW')
534  lsnemo(nls) = nemo
535  lsct(nls) = 1
536  nemo3 = nemo
537  else
538  call strsuc(nemo,nemo3,lnm3)
539  lsct(ii) = lsct(ii) + 1
540  write(fmtf,'(A,I1,A)') '(2A,I', isize(lsct(ii)), ')'
541  write(nemo3,fmtf) nemo(1:lnm3), '#', lsct(ii)
542  endif
543 
544  call readlc(lunit,lchr2,nemo3)
545  if (icbfms(lchr2,nchr)/=0) then
546  lchr = pmiss
547  else
548  lchr = lchr2(1:20)
549  endif
550  endif
551 
552  if ( nchr<=20 .or. lchr==pmiss ) then
553  lchr = adjustr(lchr)
554  fmt = '(A6,2X,A10,2X,A20,2X,"(",I2,")",A24,2X,A48)'
555  write(luout,fmt) numb,nemo,lchr,nchr,unit,desc
556  else
557  fmt = '(A6,2X,A10,2X,A,2X,"(",I3,")",A23,2X,A48)'
558  write(luout,fmt) numb,nemo,lchr2(1:nchr),nchr,unit,desc
559  endif
560  endif
561 
562  enddo
563 
564  write(luout,'(/A/)') ' >>> END OF SUBSET <<< '
565 
566  return
567 end subroutine ufdump
568 
598 recursive subroutine dxdump(lunit,ldxot)
599 
600  use bufrlib
601 
602  use modv_vars, only: im8b, reps, fxy_fbit, fxy_sbyct, fxy_drp16, fxy_drp8, fxy_drp8s, fxy_drp1, &
603  fxy_drf16, fxy_drf8, fxy_drf1
604 
605  use moda_tababd
606  use moda_nmikrp
607 
608  implicit none
609 
610  integer, intent(in) :: lunit, ldxot
611  integer my_lunit, my_ldxot, lun, il, im, n, na, nc, nch, ic, icms, nseq, bort_target_set
612 
613  character card*80, cardi1*80, cardi2*80, cardi3*80, cardi4*80, cmstr*20, wrk3*10, wrk1*8, wrk2*8, adn*6
614 
615  logical tbskip, tdskip, xtrci1
616 
617  data cardi1 /'| | | |'/
618  data cardi2 /'| | |'/
619  data cardi3 /'| | | | | |-------------|'/
620  data cardi4 /'|------------------------------------------------------------------------------|'/
621 
622  ! Statement functions
623  tbskip(adn) = ((adn==fxy_sbyct).or.(adn==fxy_fbit).or.(adn==fxy_drf16).or.(adn==fxy_drf8).or.(adn==fxy_drf1))
624  tdskip(adn) = ((adn==fxy_drp16).or.(adn==fxy_drp8).or.(adn==fxy_drp8s).or.(adn==fxy_drp1))
625 
626  ! Check for I8 integers.
627 
628  if(im8b) then
629  im8b=.false.
630  call x84(lunit,my_lunit,1)
631  call x84(ldxot,my_ldxot,1)
632  call dxdump(my_lunit,my_ldxot)
633  im8b=.true.
634  return
635  endif
636 
637  ! If we're catching bort errors, set a target return location if one doesn't already exist.
638 
639  if (bort_target_set() == 1) then
640  call catch_bort_dxdump_c(lunit,ldxot)
641  call bort_target_unset
642  return
643  endif
644 
645  ! Determine lun from lunit.
646 
647  call status(lunit,lun,il,im)
648  if(il==0) call bort('BUFRLIB: DXDUMP - BUFR FILE IS CLOSED, IT MUST BE OPEN')
649 
650  ! Create and write out (to ldxot) the header cards for the descriptor definition section.
651 
652  card=cardi4
653  card( 1: 1)='.'
654  card(80:80)='.'
655  write (ldxot,'(A)') card
656 
657  card=cardi4
658  card( 2: 2)=' '
659  card(79:79)=' '
660  card(15:64)=' USER DEFINITIONS FOR TABLE-A TABLE-B TABLE D '
661  write (ldxot,'(A)') card
662 
663  write (ldxot,'(A)') cardi4
664 
665  card=cardi1
666  card( 3:10)='MNEMONIC'
667  card(14:19)='NUMBER'
668  card(23:33)='DESCRIPTION'
669  write (ldxot,'(A)') card
670 
671  card=cardi4
672  card(12:12)='|'
673  card(21:21)='|'
674  write (ldxot,'(A)') card
675 
676  ! Create and write out (to ldxot) the Table D descriptor definition cards.
677 
678  write (ldxot,'(A)') cardi1
679 
680  xtrci1=.false.
681  do n=1,ntbd(lun)
682  if(.not.tdskip(tabd(n,lun)(1:6))) then
683  card=cardi1
684  card( 3:10)=tabd(n,lun)( 7:14)
685  card(14:19)=tabd(n,lun)( 1: 6)
686  card(23:77)=tabd(n,lun)(16:70)
687  ! Check if this Table D mnemonic is also a Table A mnemonic. If so, then label it as such and also check if it is the
688  ! last of the Table A mnemonics, in which case an extra cardi1 line will be written to ldxot in order to separate
689  ! the Table A mnemonics from the other Table D mnemonics.
690  do na=1,ntba(lun)
691  if(taba(na,lun)(4:11)==tabd(n,lun)(7:14)) then
692  card(14:14)='A'
693  if(na==ntba(lun)) xtrci1=.true.
694  exit
695  end if
696  end do
697  write (ldxot,'(A)') card
698  if(xtrci1) then
699  write (ldxot,'(A)') cardi1
700  xtrci1=.false.
701  end if
702  end if
703  end do
704 
705  ! Create and write out (to ldxot) the Table B descriptor definition cards.
706 
707  write (ldxot,'(A)') cardi1
708 
709  do n=1,ntbb(lun)
710  if(.not.tbskip(tabb(n,lun)(1:6))) then
711  card=cardi1
712  card( 3:10)=tabb(n,lun)( 7:14)
713  card(14:19)=tabb(n,lun)( 1: 6)
714  card(23:77)=tabb(n,lun)(16:70)
715  write (ldxot,'(A)') card
716  end if
717  end do
718 
719  write (ldxot,'(A)') cardi1
720 
721  ! Create and write out (to ldxot) the header cards for the sequence definition section.
722 
723  write (ldxot,'(A)') cardi4
724 
725  card=cardi2
726  card( 3:10)='MNEMONIC'
727  card(14:21)='SEQUENCE'
728  write (ldxot,'(A)') card
729 
730  card=cardi4
731  card(12:12)='|'
732  write (ldxot,'(A)') card
733 
734  ! Create and write out (to ldxot) the Table D sequence definition cards.
735 
736  write (ldxot,'(A)') cardi2
737 
738  do n=1,ntbd(lun)
739  if(.not.tdskip(tabd(n,lun)(1:6))) then
740  card=cardi2
741  card( 3:10)=tabd(n,lun)( 7:14)
742  ic = 14
743  ! Get the list of child mnemonics for this Table D descriptor, and then add each one (including any replication tags)
744  ! to the sequence definition card for this Table D descriptor.
745  call nemtbd(lun,n,nseq,nem(1,1),irp(1,1),krp(1,1))
746  if(nseq>0) then
747  do nc=1,nseq
748  cmstr=' '
749  icms=0
750  call strsuc(nem(nc,1),wrk2,nch)
751  if(irp(nc,1)/=0) then
752  ! Add the opening replication tag.
753  icms=icms+1
754  cmstr(icms:icms)=reps(irp(nc,1))
755  end if
756  cmstr(icms+1:icms+nch)=wrk2(1:nch)
757  icms=icms+nch
758  if(irp(nc,1)/=0) then
759  ! Add the closing replication tag.
760  icms=icms+1
761  cmstr(icms:icms)=reps(irp(nc,1)+5)
762  end if
763  if(krp(nc,1)/=0) then
764  ! Add the fixed replication count.
765  wrk1=' '
766  write (wrk1,'(I3)') krp(nc,1)
767  call strsuc(wrk1,wrk2,nch)
768  cmstr(icms+1:icms+nch)=wrk2(1:nch)
769  icms=icms+nch
770  end if
771  ! Will this child (and its replication tags, if any) fit into the current sequence definition card? If not, then
772  ! write out (to ldxot) the current card and initialize a new one to hold this child.
773  if(ic>(79-icms)) then
774  write (ldxot,'(A)') card
775  card=cardi2
776  card( 3:10)=tabd(n,lun)( 7:14)
777  ic = 14
778  end if
779  card(ic:ic+icms-1)=cmstr(1:icms)
780  ! Note that we want to leave 2 blank spaces between each child within the sequence definition card, to improve
781  ! readability.
782  ic=ic+icms+2
783  end do
784  write (ldxot,'(A)') card
785  write (ldxot,'(A)') cardi2
786  end if
787  end if
788  end do
789 
790  ! Create and write out (to ldxot) the header cards for the element definition section.
791 
792  write (ldxot,'(A)') cardi4
793 
794  card=cardi3
795  card( 3:10)='MNEMONIC'
796  card(14:17)='SCAL'
797  card(21:29)='REFERENCE'
798  card(35:37)='BIT'
799  card(41:45)='UNITS'
800  write (ldxot,'(A)') card
801 
802  card=cardi4
803  card(12:12)='|'
804  card(19:19)='|'
805  card(33:33)='|'
806  card(39:39)='|'
807  card(66:66)='|'
808  write (ldxot,'(A)') card
809 
810  ! Create and write out (to ldxot) the Table B element definition cards.
811 
812  write (ldxot,'(A)') cardi3
813 
814  do n=1,ntbb(lun)
815  if(.not.tbskip(tabb(n,lun)(1:6))) then
816  card=cardi3
817  card( 3:10)=tabb(n,lun)( 7:14)
818  card(41:64)=tabb(n,lun)(71:94)
819  ! Add the scale factor.
820  call strsuc(tabb(n,lun)(96:98),wrk2,nch)
821  card(17-nch+1:17)=wrk2
822  if(tabb(n,lun)(95:95)=='-') card(17-nch:17-nch)='-'
823  ! Add the reference value.
824  call strsuc(tabb(n,lun)(100:109),wrk3,nch)
825  card(31-nch+1:31)=wrk3
826  if(tabb(n,lun)(99:99)=='-') card(31-nch:31-nch)='-'
827  ! Add the bit width.
828  call strsuc(tabb(n,lun)(110:112),wrk2,nch)
829  card(37-nch+1:37)=wrk2
830  write (ldxot,'(a)') card
831  end if
832  end do
833 
834  write (ldxot,'(A)') cardi3
835 
836  ! Create and write out (to ldxot) the closing card.
837 
838  card=cardi4
839  card( 1: 1)='`'
840  card(80:80)=''''
841  write (ldxot,'(A)') card
842 
843  return
844 end subroutine dxdump
845 
856 recursive subroutine getabdb(lunit,tabdb,itab,jtab)
857 
858  use bufrlib
859 
860  use modv_vars, only: im8b
861 
862  use moda_tababd
863  use moda_nmikrp
864 
865  implicit none
866 
867  integer, intent(in) :: lunit, itab
868  integer, intent(out) :: jtab
869  integer my_lunit, my_itab, lun, il, im, i, j, k, nseq, bort_target_set
870 
871  character*128, intent(out) :: tabdb(*)
872  character, allocatable :: ctabdb(:,:)
873  character*8 nemo
874 
875  ! Check for I8 integers
876 
877  if(im8b) then
878  im8b=.false.
879  call x84(lunit,my_lunit,1)
880  call x84(itab,my_itab,1)
881  call getabdb(my_lunit,tabdb,my_itab,jtab)
882  call x48(jtab,jtab,1)
883  im8b=.true.
884  return
885  endif
886 
887  ! If we're catching bort errors, set a target return location if one doesn't already exist.
888 
889  if (bort_target_set() == 1) then
890  allocate(ctabdb(128,itab))
891  call catch_bort_getabdb_c(lunit,itab,ctabdb,jtab)
892  do i = 1, jtab
893  do j = 1, 128
894  tabdb(i)(j:j) = ctabdb(j,i)
895  enddo
896  enddo
897  deallocate(ctabdb)
898  call bort_target_unset
899  return
900  endif
901 
902  jtab = 0
903 
904  ! Make sure the file is open
905 
906  call status(lunit,lun,il,im)
907  if(il==0) return
908 
909  ! Write out the Table D entries for this file
910 
911  do i=1,ntbd(lun)
912  nemo = tabd(i,lun)(7:14)
913  call nemtbd(lun,i,nseq,nem(1,1),irp(1,1),krp(1,1))
914  do j=1,nseq,10
915  jtab = jtab+1
916  if(jtab<=itab) then
917  write(tabdb(jtab),fmt='(A,A8,10(1X,A10))') 'D ', nemo, (nem(k,1),k=j,min(j+9,nseq))
918  endif
919  enddo
920  enddo
921 
922  ! Add the Table B entries
923 
924  do i=1,ntbb(lun)
925  jtab = jtab+1
926  if(jtab<=itab) then
927  write(tabdb(jtab),fmt='(A,A8,1X,A42)') 'B ', tabb(i,lun)(7:14), tabb(i,lun)(71:112)
928  endif
929  enddo
930 
931  return
932 end subroutine getabdb
integer function imrkopr(nemo)
Check whether a specified mnemonic is a Table C marker operator.
Definition: bitmaps.F90:376
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
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 subroutine upftbv(lunit, nemo, val, mxib, ibit, nib)
Given a Table B mnemonic with flag table units and a corresponding numerical data value,...
Definition: cftbvs.F90:68
recursive subroutine ufdump(lunit, luprt)
Print a verbose listing of the contents of a data subset, including all data values and replicated se...
Definition: dumpdata.F90:236
recursive subroutine getabdb(lunit, tabdb, itab, jtab)
Get Table B and Table D information from the internal DX BUFR tables.
Definition: dumpdata.F90:857
recursive subroutine dxdump(lunit, ldxot)
Print a copy of the DX BUFR table associated with a specified Fortran logical unit.
Definition: dumpdata.F90:599
recursive subroutine ufbdmp(lunin, luprt)
Print a verbose listing of the contents of a data subset, including all data values and replicated se...
Definition: dumpdata.F90:42
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 nemtab(lun, nemo, idn, tab, iret)
Get information about a descriptor, based on a mnemonic.
Definition: fxy.F90:434
subroutine numtbd(lun, idn, nemo, tab, iret)
Get information about a Table B or Table D descriptor, based on the WMO bit-wise representation of an...
Definition: fxy.F90:290
integer function ireadmt(lun)
Check the most recent BUFR message that was read via a call to one of the message-reading subroutines...
subroutine strsuc(str1, str2, lens)
Remove leading and trailing blanks from a character string.
Definition: misc.F90:199
integer function isize(num)
Compute the number of characters needed to encode an integer as a string.
Definition: misc.F90:400
recursive integer function icbfms(str, lstr)
Check whether a character string returned from a previous call to subroutine readlc() was encoded as ...
Definition: missing.F90:56
integer function ibfms(r8val)
Check whether a real*8 data value returned from a previous call to any of the NCEPLIBS-bufr values-re...
Definition: missing.F90:25
Wrap C NCEPLIBS-bufr functions so they can be called from within the Fortran part of the library.
Definition: bufrlib.F90:11
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.
integer, dimension(:), allocatable nsub
Current subset pointer within 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 nnrv
Number of entries in the jump/link table which contain new reference values (up to a maximum of mxnrv...
integer, dimension(:), allocatable inodnrv
Entries within jump/link table which contain new reference values.
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 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...
character *128, dimension(:,:), allocatable tabb
Table B entries for each file ID.
Declare a variable used to indicate whether master code and flag tables should be read.
character cdmf
Flag indicating whether to include code and flag table information during reads of master BUFR tables...
Declare arrays and variables used to store the internal jump/link table.
integer, dimension(:), allocatable irf
Reference values corresponding to tag and typ:
integer, dimension(:), allocatable isc
Scale factors corresponding to tag and typ:
integer, dimension(:), allocatable ibt
Bit widths corresponding to tag and 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, 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:
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...
integer, dimension(:,:), allocatable nrfelm
Referenced data value, for data values which refer to a previous data value in the BUFR data subset v...
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 readlc(lunit, chr, str)
Read a long character string (greater than 8 bytes) from a data subset.
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