3 C$$$ SUBPROGRAM DOCUMENTATION BLOCK
6 C PRGMMR: WOOLLEN ORG: NP20 DATE: 1994-01-06
8 C ABSTRACT: THIS SUBROUTINE CONSTRUCTS AN INTERNAL JUMP/LINK TABLE
9 C WITHIN COMMON BLOCK /BTABLES/, USING THE INFORMATION WITHIN THE
10 C INTERNAL BUFR TABLE ARRAYS (WITHIN COMMON BLOCK /TABABD/) FOR ALL OF
11 C THE LUN (I.E., I/O STREAM INDEX) VALUES THAT ARE CURRENTLY DEFINED TO
12 C THE BUFR ARCHIVE LIBRARY SOFTWARE. NOTE THAT THE ENTIRE JUMP/LINK
13 C TABLE WILL ALWAYS BE COMPLETELY RECONSTRUCTED FROM SCRATCH, EVEN IF
14 C SOME OF THE INFORMATION WITHIN THE INTERNAL BUFR TABLE ARRAYS
15 C ALREADY EXISTED THERE AT THE TIME OF THE PREVIOUS CALL TO THIS
16 C SUBROUTINE, BECAUSE THERE MAY HAVE BEEN OTHER EVENTS THAT HAVE TAKEN
17 C PLACE SINCE THE PREVIOUS CALL TO THIS SUBROUTINE THAT HAVE NOT YET
18 C BEEN REFLECTED WITHIN THE INTERNAL JUMP/LINK TABLE, SUCH AS, E.G.
19 C THE UNLINKING OF AN LUN VALUE FROM THE BUFR ARCHIVE LIBRARY SOFTWARE
20 C VIA A CALL TO BUFR ARCHIVE LIBRARY SUBROUTINE CLOSBF.
22 C PROGRAM HISTORY LOG:
23 C 1994-01-06 J. WOOLLEN -- ORIGINAL AUTHOR
24 C 1995-06-28 J. WOOLLEN -- INCREASED THE SIZE OF INTERNAL BUFR TABLE
25 C ARRAYS IN ORDER TO HANDLE BIGGER FILES
26 C 1998-07-08 J. WOOLLEN -- REPLACED CALL TO CRAY LIBRARY ROUTINE
27 C "ABORT" WITH CALL TO NEW INTERNAL BUFRLIB
29 C 1999-11-18 J. WOOLLEN -- THE NUMBER OF BUFR FILES WHICH CAN BE
30 C OPENED AT ONE TIME INCREASED FROM 10 TO 32
31 C (NECESSARY IN ORDER TO PROCESS MULTIPLE
32 C BUFR FILES UNDER THE MPI)
33 C 2003-11-04 J. ATOR -- ADDED DOCUMENTATION
34 C 2003-11-04 S. BENDER -- ADDED REMARKS/BUFRLIB ROUTINE
36 C 2003-11-04 D. KEYSER -- MAXJL (MAXIMUM NUMBER OF JUMP/LINK ENTRIES)
37 C INCREASED FROM 15000 TO 16000 (WAS IN
38 C VERIFICATION VERSION); UNIFIED/PORTABLE FOR
39 C WRF; ADDED HISTORY DOCUMENTATION; OUTPUTS
40 C MORE COMPLETE DIAGNOSTIC INFO WHEN ROUTINE
41 C TERMINATES ABNORMALLY; NOW ALLOWS FOR THE
42 C POSSIBILITY THAT A CONNECTED FILE MAY NOT
43 C CONTAIN ANY DICTIONARY TABLE INFO (E.G.,
44 C AN EMPTY FILE), SUBSEQUENT CONNECTED FILES
45 C WHICH ARE NOT EMPTY WILL NO LONGER GET
46 C TRIPPED UP BY THIS (THIS AVOIDS THE NEED
47 C FOR AN APPLICATION PROGRAM TO DISCONNECT
48 C ANY EMPTY FILES VIA A CALL TO CLOSBF)
49 C 2009-03-18 J. WOOLLEN -- ADDED LOGIC TO RESPOND TO THE CASES WHERE
50 C AN INPUT FILE'S TABLES CHANGE IN MIDSTREAM.
51 C THE NEW LOGIC MOSTLY ADDRESSES CASES WHERE
52 C OTHER FILES ARE CONNECTED TO THE TABLES OF
53 C THE FILE WHOSE TABLES HAVE CHANGED.
54 C 2009-06-25 J. ATOR -- TWEAK WOOLLEN LOGIC TO HANDLE SPECIAL CASE
55 C WHERE TABLE WAS RE-READ FOR A PARTICULAR
56 C LOGICAL UNIT BUT IS STILL THE SAME ACTUAL
57 C TABLE AS BEFORE AND IS STILL SHARING THAT
58 C TABLE WITH A DIFFERENT LOGICAL UNIT
59 C 2009-11-17 J. ATOR -- ADDED CHECK TO PREVENT WRITING OUT OF TABLE
60 C INFORMATION WHEN A TABLE HAS BEEN RE-READ
61 C WITHIN A SHARED LOGICAL UNIT BUT HASN'T
64 C USAGE: CALL MAKESTAB
67 C THIS ROUTINE CALLS: BORT CHEKSTAB CLOSMG CPBFDX
68 C ERRWRT ICMPDX ISHRDX STRCLN
70 C THIS ROUTINE IS CALLED BY: RDBFDX RDMEMM RDUSDX READDX
72 C Normally not called by any application
76 C LANGUAGE: FORTRAN 77
77 C MACHINE: PORTABLE TO ALL PLATFORMS
84 COMMON /STBFR
/ IOLUN
(NFILES
),IOMSG
(NFILES
)
85 COMMON /USRINT
/ NVAL
(NFILES
),INV
(MAXSS
,NFILES
),VAL
(MAXSS
,NFILES
)
86 COMMON /TABABD
/ NTBA
(0:NFILES
),NTBB
(0:NFILES
),NTBD
(0:NFILES
),
87 . MTAB
(MAXTBA
,NFILES
),IDNA
(MAXTBA
,NFILES
,2),
88 . IDNB
(MAXTBB
,NFILES
),IDND
(MAXTBD
,NFILES
),
89 . TABA
(MAXTBA
,NFILES
),TABB
(MAXTBB
,NFILES
),
91 COMMON /BTABLES
/ MAXTAB
,NTAB
,TAG
(MAXJL
),TYP
(MAXJL
),KNT
(MAXJL
),
92 . JUMP
(MAXJL
),LINK
(MAXJL
),JMPB
(MAXJL
),
93 . IBT
(MAXJL
),IRF
(MAXJL
),ISC
(MAXJL
),
94 . ITP
(MAXJL
),VALI
(MAXJL
),KNTI
(MAXJL
),
95 . ISEQ
(MAXJL
,2),JSEQ
(MAXJL
)
96 COMMON /NRV203
/ NNRV
,INODNRV
(MXNRV
),NRV
(MXNRV
),TAGNRV
(MXNRV
),
97 . ISNRV
(MXNRV
),IENRV
(MXNRV
),IBTNRV
,IPFNRV
98 COMMON /LUSHR
/ LUS
(NFILES
)
103 CHARACTER*128 BORT_STR
,ERRSTR
105 CHARACTER*8 NEMO
,TAGNRV
107 LOGICAL EXPAND
,XTAB
(NFILES
)
110 C-----------------------------------------------------------------------
111 C-----------------------------------------------------------------------
113 C RESET POINTER TABLE AND STRING CACHE
114 C ------------------------------------
120 C FIGURE OUT WHICH UNITS SHARE TABLES
121 C -----------------------------------
123 C The LUS array is static between calls to this subroutine, and it
124 C keeps track of which logical units share dictionary table
126 C if LUS(I) = 0, then IOLUN(I) does not share dictionary table
127 C information with any other logical unit
128 C if LUS(I) > 0, then IOLUN(I) shares dictionary table
129 C information with logical unit IOLUN(LUS(I))
130 C if LUS(I) < 0, then IOLUN(I) does not now, but at one point in
131 C the past, shared dictionary table information
132 C with logical unit IOLUN(ABS(LUS(I)))
134 C The XTAB array is non-static and is recomputed within the below
135 C loop during each call to this subroutine:
136 C if XTAB(I) = .TRUE., then the dictionary table information
137 C has changed for IOLUN(I) since the last
138 C call to this subroutine
139 C if XTAB(I) = .FALSE., then the dictionary table information
140 C has not changed for IOLUN(I) since the
141 C last call to this subroutine
145 IF(IOLUN
(LUN
).EQ
.0) THEN
147 C Logical unit IOLUN(LUN) is not defined to the BUFRLIB.
150 ELSE IF(MTAB
(1,LUN
).EQ
.0) THEN
152 C New dictionary table information has been read for logical
153 C unit IOLUN(LUN) since the last call to this subroutine.
156 IF(LUS
(LUN
).NE
.0) THEN
157 IF(IOLUN
(ABS
(LUS
(LUN
))).EQ
.0) THEN
159 ELSE IF(LUS
(LUN
).GT
.0) THEN
161 C IOLUN(LUN) was sharing table information with logical
162 C unit IOLUN(LUS(LUN)), so check whether the table
163 C information has really changed. If not, then IOLUN(LUN)
164 C just re-read a copy of the exact same table information
165 C as before, and therefore it can continue to share with
166 C logical unit IOLUN(LUS(LUN)).
168 IF(ICMPDX
(LUS
(LUN
),LUN
).EQ
.1) THEN
170 CALL CPBFDX
(LUS
(LUN
),LUN
)
172 LUS
(LUN
) = (-1)*LUS
(LUN
)
174 ELSE IF(ICMPDX
(ABS
(LUS
(LUN
)),LUN
).EQ
.1) THEN
176 C IOLUN(LUN) was not sharing table information with logical
177 C unit IOLUN(LUS(LUN)), but it did at one point in the past
178 C and now once again has the same table information as that
179 C logical unit. Since the two units shared table
180 C information at one point in the past, allow them to do
184 LUS
(LUN
) = ABS
(LUS
(LUN
))
185 CALL CPBFDX
(LUS
(LUN
),LUN
)
188 ELSE IF(LUS
(LUN
).GT
.0) THEN
190 C Logical unit IOLUN(LUN) is sharing table information with
191 C logical unit IOLUN(LUS(LUN)), so make sure that the latter
192 C unit is still defined to the BUFRLIB.
194 IF(IOLUN
(LUS
(LUN
)).EQ
.0) THEN
196 ELSE IF( XTAB
(LUS
(LUN
)) .AND
.
197 + (ICMPDX
(LUS
(LUN
),LUN
).EQ
.0) ) THEN
199 C The table information for logical unit IOLUN(LUS(LUN))
200 C just changed (in midstream). If IOLUN(LUN) is an output
201 C file, then we will have to update it with the new table
202 C information later on in this subroutine. Otherwise,
203 C IOLUN(LUN) is an input file and is no longer sharing
204 C tables with IOLUN(LUS(LUN)).
206 IF(IOLUN
(LUN
).LT
.0) LUS
(LUN
) = (-1)*LUS
(LUN
)
210 C Determine whether logical unit IOLUN(LUN) is sharing table
211 C information with any other logical units.
214 DO WHILE ((LUM
.LT
.LUN
).AND
.(LUS
(LUN
).EQ
.0))
215 IF(ISHRDX
(LUM
,LUN
).EQ
.1) THEN
224 C INITIALIZE JUMP/LINK TABLES WITH SUBSETS/SEQUENCES/ELEMENTS
225 C -----------------------------------------------------------
229 IF(IOLUN
(LUN
).NE
.0 .AND
. NTBA
(LUN
).GT
.0) THEN
231 C Reset any existing inventory pointers.
233 IF(IOMSG
(LUN
).NE
.0) THEN
234 IF(LUS
(LUN
).EQ
.0) THEN
235 INC
= (NTAB
+1)-MTAB
(1,LUN
)
237 INC
= MTAB
(1,LUS
(LUN
))-MTAB
(1,LUN
)
240 INV
(N
,LUN
) = INV
(N
,LUN
)+INC
244 IF(LUS
(LUN
).LE
.0) THEN
246 C The dictionary table information corresponding to logical
247 C unit IOLUN(LUN) has not yet been written into the internal
248 C jump/link table, so add it in now.
253 NEMO
= TABA
(ITBA
,LUN
)(4:11)
254 CALL TABSUB
(LUN
,NEMO
)
255 MTAB
(ITBA
,LUN
) = INOD
258 ELSE IF( XTAB
(LUS
(LUN
)) .AND
.
259 + (ICMPDX
(LUS
(LUN
),LUN
).EQ
.0) ) THEN
261 C Logical unit IOLUN(LUN) is an output file that is sharing
262 C table information with logical unit IOLUN(LUS(LUN)) whose
263 C table just changed (in midstream). Flush any existing data
264 C messages from IOLUN(LUN), then update the table information
265 C for this logical unit with the corresponding new table
266 C information from IOLUN(LUS(LUN)), then update IOLUN(LUN)
267 C itself with a copy of the new table information.
269 LUNIT
= ABS
(IOLUN
(LUN
))
270 IF(IOMSG
(LUN
).NE
.0) CALL CLOSMG
(LUNIT
)
271 CALL CPBFDX
(LUS
(LUN
),LUN
)
272 LUNDX
= ABS
(IOLUN
(LUS
(LUN
)))
273 CALL WRDXTB
(LUNDX
,LUNIT
)
280 C STORE TYPES AND INITIAL VALUES AND COUNTS
281 C -----------------------------------------
284 IF(TYP
(NODE
).EQ
.'SUB') THEN
288 ELSEIF
(TYP
(NODE
).EQ
.'SEQ') THEN
292 ELSEIF
(TYP
(NODE
).EQ
.'RPC') THEN
296 ELSEIF
(TYP
(NODE
).EQ
.'RPS') THEN
300 ELSEIF
(TYP
(NODE
).EQ
.'REP') THEN
302 KNTI
(NODE
) = IRF
(NODE
)
304 ELSEIF
(TYP
(NODE
).EQ
.'DRS') THEN
308 ELSEIF
(TYP
(NODE
).EQ
.'DRP') THEN
312 ELSEIF
(TYP
(NODE
).EQ
.'DRB') THEN
316 ELSEIF
(TYP
(NODE
).EQ
.'NUM') THEN
320 ELSEIF
(TYP
(NODE
).EQ
.'CHR') THEN
329 C SET UP EXPANSION SEGMENTS FOR TYPE 'SUB', 'DRP', AND 'DRS' NODES
330 C ----------------------------------------------------------------
337 EXPAND
= TYP
(N
).EQ
.'SUB' .OR
. TYP
(N
).EQ
.'DRP' .OR
. TYP
(N
).EQ
.'DRS'
338 . .OR
. TYP
(N
).EQ
.'REP' .OR
. TYP
(N
).EQ
.'DRB'
346 IF(TYP
(NODA
).EQ
.'REP') KNT
(NODE
) = KNTI
(NODA
)
347 IF(TYP
(NODA
).NE
.'REP') KNT
(NODE
) = 1
350 IF(NEWN
.GT
.MAXJL
) GOTO 902
352 KNT
(NODE
) = MAX
(KNTI
(NODE
),KNT
(NODE
))
353 2 IF(JUMP
(NODE
)*KNT
(NODE
).GT
.0) THEN
356 ELSE IF(LINK
(NODE
).GT
.0) THEN
361 IF(NODE
.EQ
.NODA
) GOTO 3
362 IF(NODE
.EQ
.0 ) GOTO 903
363 KNT
(NODE
) = MAX
(KNT
(NODE
)-1,0)
370 C PRINT THE SEQUENCE TABLES
371 C ------------------------
374 CALL ERRWRT
('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
376 WRITE ( UNIT
=ERRSTR
, FMT
='(A,I5,2X,A10,A5,6I8)' )
377 . 'BUFRLIB: MAKESTAB ', I
, TAG
(I
), TYP
(I
), JMPB
(I
), JUMP
(I
),
378 . LINK
(I
), IBT
(I
), IRF
(I
), ISC
(I
)
381 CALL ERRWRT
('++++++++++++++BUFR ARCHIVE LIBRARY+++++++++++++++++')
389 900 WRITE(BORT_STR
,'("BUFRLIB: MAKESTAB - MNEMONIC ",A," IS '//
390 . 'DUPLICATED IN SUBSET: ",A)') NEMO
,TAG
(N1
)
392 901 WRITE(BORT_STR
,'("BUFRLIB: MAKESTAB - UNKNOWN TYPE ",A)')TYP
(NODE
)
394 902 WRITE(BORT_STR
,'("BUFRLIB: MAKESTAB - NUMBER OF JSEQ ENTRIES IN'//
395 . ' JUMP/LINK TABLE EXCEEDS THE LIMIT (",I6,")")') MAXJL
397 903 WRITE(BORT_STR
,'("BUFRLIB: MAKESTAB - NODE IS ZERO, FAILED TO '//
398 . 'CIRCULATE (TAG IS ",A,")")') TAG
(N
)