5 * Revision 1.3 1996/04/24 17:27:03 mclareni
6 * Extend the include file cleanup to dzebra, rz and tq, and also add
7 * dependencies in some cases.
9 * Revision 1.2 1996/03/08 08:08:04 jamie
10 * Bug fixes for opt R handling in rz(v)out
12 * Revision 1.1.1.1 1996/03/06 10:47:26 mclareni
16 #include "zebra/pilot.h"
17 SUBROUTINE RZOUT(IXDIV,LSUP,KEYU,ICYCLE,CHOPT)
19 ************************************************************************
21 * To write data structure pointed by LSUP
23 * IXDIV Index of the division(s)
24 * May be zero if the 'D' option is not selected
25 * May be a compound index (see MZIXCO on page 24) if the 'D'
27 * LSUP Supporting address of the data structure (may be zero if the
28 * 'D' option is selected)
29 * KEYU Keyword vector of length NWKEY as specified by RZMDIR.
30 * ICYCLE only used as Input parameter if 'A' option is given (see below)
31 * CHOPT Character variable specifying the selected options.
34 * The data structure supported by the bank at LSUP is
35 * written out (link 0 is not followed)
36 * 'D' Complete division(s)
37 * default: Dropped banks are squeezed out
38 * (slower but maybe more economic than 'DI')
39 * 'DI' Immediate dump of divisions with dropped banks
41 * 'L' Write the data structure supported by the linear
42 * structure at LSUP (link 0 is followed)
43 * 'S' Single bank at LSUP
45 * 'Q' seQuential mode - no check made to see if key already
46 * exists (option S in RZVOUT etc.)
49 * Keep banks available after output
50 * 'N' No links, i.e. linkless handling
51 * 'W' Drop data structure or wipe division(s) after output
52 * 'A' Key will not be visible by RZLDIR
54 * ICYCLE Cycle number associated to the key entered
55 * ICYCLE is 1 if KEY was not already present in the directory,
56 * and one larger than the previous cycle associated to the key
58 * ICYCLE is only Input parameter when option 'A' is given
62 * Author : R.Brun DD/US/PD
64 * Last mod: 14.09.93 - RB. Protect against directories > 64K
65 * : 04.03.94 S.Banerjee (Change in cycle structure)
66 * : 27.09.94 J.Shiers - add option Q (cf S in RZVOUT)
67 * : 17.02.95 J.Shiers - move definition of logl
68 * : 21.02.95 J.Shiers - improve warning message for
69 * big directories (objects auto-deleted)
70 * : 23.03.95 J.Shiers - key # in cycles block is KEY(1)
71 * : 10.04.95 J.Shiers - move IKYV lines to after definition
72 * : 08.03.96 J.Shiers - only delete previous cycle if opt R
73 * not specified. If opt R is specified,
74 * use previous cycle number (and not 1)
76 * In RZ file format version 0, RZ pointers are stored in 16 bits.
77 * Thus, pointers to previous cycle etc. must not exceed 65536.
78 * An attempt to save a new cycle under such conditions will result
79 * in the previous cycle being deleted with a warning message.
81 * For files created with RZ version 1, this is not necessary as
82 * pointers are 32 bit.
84 ************************************************************************
85 #include "zebra/zunit.inc"
86 #include "zebra/rzcl.inc"
87 #include "zebra/rzclun.inc"
88 #include "zebra/eqlqrrf.inc"
89 #include "zebra/rzcout.inc"
90 #include "zebra/rzk.inc"
91 #include "zebra/rzckey.inc"
92 #include "zebra/rzcycle.inc"
93 #include "zebra/mzct.inc"
94 #include "zebra/fzcx.inc"
100 *-----------------------------------------------------------------------
102 #include "zebra/q_jbyt.inc"
114 CALL UOPTC(CHOPT,'ADILSNWRQ',IOPTV)
130 LOGLV = JBYT(IQ(KQSP+LTOP),15,3)-3
132 * Options R & Q are incompatible
134 IF(IOPTXR.NE.0.AND.IOPTXQ.NE.0) THEN
135 IF(LOGLV.GE.3) WRITE(IQPRNT,10000)
136 10000 FORMAT(' RZOUT. ERROR - options R and Q are incompatible')
141 * Check if WRITE permission on file and directory
143 IF(LQRS.EQ.0)GOTO 999
145 CALL RZMODS('RZOUT ',IFLAG)
146 IF(IFLAG.NE.0) GOTO 999
148 * Write current buffer if not same directory
149 * Get last record written in that directory
152 10 LROUT = LQ(KQSP+LTOP-6)
153 IROUT = IQ(KQSP+LTOP+KIROUT)
154 IRLOUT = IQ(KQSP+LCDIR+KRLOUT)
155 IP1 = IQ(KQSP+LCDIR+KIP1)
157 CALL MZBOOK(JQPDVS,LROUT,LTOP,-6,'RZOU',0,0,LREC+1,2,-1)
162 IF(IROUT.NE.IRLOUT.AND.IRLOUT.NE.0)THEN
163 CALL RZIODO(LUN,LREC,IRLOUT,IQ(KQSP+LROUT+1),1)
164 IF(IQUEST(1).NE.0)GOTO 999
165 #if defined(CERNLIB_QMVAX)
166 IF(IRELAT.NE.0)UNLOCK(UNIT=LUN)
169 IQ(KQSP+LTOP+KIROUT)=IROUT
170 IP1=IQ(KQSP+LCDIR+KIP1)
171 IF(IQ(KQSP+LTOP+KIRIN).EQ.IROUT)IQ(KQSP+LTOP+KIRIN) = 0
174 * Is directory big enough to accomodate new cycle ?
176 NKEYS = IQ(KQSP+LCDIR+KNKEYS)
177 NWKEY = IQ(KQSP+LCDIR+KNWKEY)
180 IF(IQ(KQSP+LCDIR+KNFREE).LT.NWKEY+4*KLCYCL+1)THEN
181 CALL RZEXPD('RZOUT ',10*(NWKEY+KLCYCL+1))
182 IF(IQUEST(1).NE.0)GOTO 999
186 LK = IQ(KQSP+LCDIR+KLK)
187 LF = IQ(KQSP+LCDIR+KLF)
188 LC = IQ(KQSP+LCDIR+KLC)
189 LE = IQ(KQSP+LCDIR+KLE)
190 NWFREE=IQ(KQSP+LCDIR+KNFREE)
192 * Convert input key vector to internal format
199 IKBIT1=3*I-30*IKDES-2
200 IF(JBYT(IQ(KQSP+LCDIR+KKDES+IKDES),IKBIT1,3).LT.3)THEN
203 CALL ZHTOI(KEYU(I),KEY(I),1)
207 * Search if KEY is already entered
213 LKC=LK+(NWKEY+1)*(I-1)
214 IF(IQ(KQSP+LCDIR+LKC+K).NE.KEY(K))GOTO 40
217 * Protect against directories > 65536
219 IF(IOPTXR.EQ.0.AND.KVSCYC.EQ.0.AND.LE.GT.65536)THEN
220 CALL RZDELK(KEYU,0,'C')
223 10100 FORMAT(' RZOUT: current RZ file cannot support > 64K records ',/,
224 + ' or individual directories > 64K')
225 WRITE(IQPRNT,10200)KEY(1)
226 10200 FORMAT(' RZOUT: previous cycle(s) for this key (',I8,')',
229 10300 FORMAT(' RZOUT: please consult ZEBRA manual for further details')
234 LCOLD=IQ(KQSP+LCDIR+LKC)
235 IF (KVSCYC.NE.0) THEN
236 * IF (IQ(KQSP+LCDIR+LCOLD+KKYCYC).NE.I) THEN
237 LKC=LK+(NWKEY+1)*(I-1)
238 IF (IQ(KQSP+LCDIR+LCOLD+KKYCYC).NE.
239 + IQ(KQSP+LCDIR+LKC+1)) THEN
244 ICOLD = JBYT(IQ(KQSP+LCDIR+LCOLD+KCNCYC),21,12)
246 IKYV = IQ(KQSP+LCDIR+LKC+1)
252 IF (KVSCYC.EQ.0) THEN
253 IP1 = JBYT(IQ(KQSP+LCDIR+LCOLD+KORCYC), 1,16)
254 IR1 = JBYT(IQ(KQSP+LCDIR+LCOLD+KFRCYC),17,16)
255 IR2 = JBYT(IQ(KQSP+LCDIR+LCOLD+KSRCYC),17,16)
256 NWORDS = JBYT(IQ(KQSP+LCDIR+LCOLD+KNWCYC), 1,20)
258 IP1 = JBYT(IQ(KQSP+LCDIR+LCOLD+KORCYC), 1,20)
259 IR1 = IQ(KQSP+LCDIR+LCOLD+KFRCYC)
260 IR2 = IQ(KQSP+LCDIR+LCOLD+KSRCYC)
261 NWORDS = IQ(KQSP+LCDIR+LCOLD+KNWCYC)
264 IF(NWORDS.LE.NLEFT)THEN
267 NR=(NWORDS-NLEFT-1)/LREC + 1
269 IF(LOGLV.GE.3) WRITE(IQPRNT,10400) IP1,IR1,NWORDS,NR
270 10400 FORMAT(' RZOUT. object starts at word ',I6,
271 + ' in record ',I6,' nwords = ',I6,' nrecs = ',I6)
272 IF(LOGLV.GE.3.AND.IR2.NE.0) WRITE(IQPRNT,10500) IR2
273 10500 FORMAT(' RZOUT. object continues in record ',I6)
275 IF(IR1.NE.IRLOUT) THEN
276 CALL RZIODO(LUN,LREC,IR1,IQ(KQSP+LROUT+1),1)
277 IF(IQUEST(1).NE.0)GOTO 999
287 * Object must already exist if R option is given
291 IF(LOGLV.GE.-2) WRITE(IQLOG,10600)
292 10600 FORMAT(' RZOUT. Error - object does not exist')
297 * New KEY, append to the list
300 NWFREE=NWFREE-NWKEY-1
301 IQ(KQSP+LCDIR+KNKEYS)=IQ(KQSP+LCDIR+KNKEYS)+1
307 IQ(KQSP+LCDIR+LKC+I)=KEY(I)
309 * IKYV = IQ(KQSP+LCDIR+KNKEYS)
310 IKYV = IQ(KQSP+LCDIR+LKC+1)
312 * Construct table of material to be written
314 60 CALL MZSDIV(IXDIVX,0)
315 LENTRX = LQRRF(KQT+1)
320 IF(IQUEST(1).NE.0)THEN
321 IF(LOGLV.GE.-2) WRITE(IQLOG,10700)
322 10700 FORMAT(' RZOUT. Unable to construct table')
325 IF(IOPTXN.NE.0)NWTABX=0
328 * Replace option - record allocation not required
332 * Check if exactly the same number of words are required
334 IF(NDATA.NE.NWORDS) THEN
336 IF(LOGLV.GE.-2) WRITE(IQLOG,10800) NWORDS,NDATA
337 10800 FORMAT(' RZOUT. Error - existing object required ',I10,
338 + ' words. New object requires ',I10)
344 * Compute how many records and how many words
345 * are necessary to write data structure.
350 IF(NDATA.LE.NLEFT)THEN
353 NR=(NDATA-NLEFT-1)/LREC + 1
355 IF(IRLOUT.EQ.0)NR=NR+1
357 CALL RZALLO('RZOUT ',NR,IALLOC)
358 IF(IALLOC.EQ.0)GOTO 80
360 IF(IRLOUT.EQ.0.OR.IP1.GT.LREC)THEN
379 * Write data structure at LSUP according to table
382 IF(IQUEST(1).NE.0)THEN
383 IROUT=IQ(KQSP+LTOP+KIROUT)
386 CALL RZIODO(LUN,LREC,IROUT,IQ(KQSP+LROUT+1),1)
387 #if defined(CERNLIB_QMVAX)
388 IF(IRELAT.NE.0)UNLOCK(UNIT=LUN)
397 IF(IRLOUT.EQ.IR1) GOTO 70
398 IF(IRLOUT.GE.IR2.AND.IRLOUT.LE.IR3) GOTO 70
399 IF(IROUT.EQ.IRLOUT)IROUT=0
407 NWFREE = NWFREE-KLCYCL
408 IQ(KQSP+LCDIR+LKC) = LC
409 IQ(KQSP+LCDIR+LC+KPPCYC) = LCOLD
410 IQ(KQSP+LCDIR+LC+KFLCYC) = 0
411 CALL RZDATE (IQ(KQSP+LCDIR+LC+KFLCYC),IDATE,ITIME,2)
412 IF(IOPTXA.NE.0)CALL SBIT1(IQ(KQSP+LCDIR+LC+KFLCYC),4)
413 IQ(KQSP+LCDIR+LC+KORCYC) = IQ4
414 IQ(KQSP+LCDIR+LC+KNWCYC) = NDATA
415 CALL SBYT(ICYCLE,IQ(KQSP+LCDIR+LC+KCNCYC),21,12)
416 IF (KVSCYC.EQ.0) THEN
418 + CALL SBYT(IR2,IQ(KQSP+LCDIR+LC+KSRCYC),17,16)
419 CALL SBYT(IR1,IQ(KQSP+LCDIR+LC+KFRCYC),17,16)
421 IF (NLEFT.LT.NDATA) THEN
422 IQ(KQSP+LCDIR+LC+KSRCYC) = IR2
424 IQ(KQSP+LCDIR+LC+KSRCYC) = 0
426 IQ(KQSP+LCDIR+LC+KFRCYC) = IR1
427 IQ(KQSP+LCDIR+LC+KKYCYC) = IKYV
431 * Update internal pointers in the directory
441 IQ(KQSP+LTOP+KIROUT)=IROUT
442 IQ(KQSP+LCDIR+KRUSED)=IQ(KQSP+LCDIR+KRUSED)+NR
443 NWUSED=IQ(KQSP+LCDIR+KWUSED)+NDATA
444 IF(NWUSED.GT.1000000)THEN
445 IQ(KQSP+LCDIR+KMEGA)=IQ(KQSP+LCDIR+KMEGA)+1
446 IQ(KQSP+LCDIR+KWUSED)=NWUSED-1000000
448 IQ(KQSP+LCDIR+KWUSED)=NWUSED
450 IQ(KQSP+LCDIR+KRLOUT)=IRLOUT
451 IQ(KQSP+LCDIR+KIP1)=IP1
452 IQ(KQSP+LCDIR+KNFREE)=NWFREE
453 IQ(KQSP+LCDIR+KLF)=LF
454 IQ(KQSP+LCDIR+KLC)=LC
458 IQUEST(9)=IQ(KQSP+LCDIR+KQUOTA)-IQ(KQSP+LCDIR+KRUSED)
460 * Drop data structure or wipe division (option W)
462 IF (IOPTXW.NE.0) THEN
463 LSUP(1) = LQRRF(KQT+1)
464 IF (LSUP(1).NE.0) THEN
465 CALL MZDROP(IXDIV,LSUP,' ')
472 IF(IOPTXR.EQ.0.AND.NR.GT.0)THEN
473 CALL RZUSED(NR,IALLOC)
476 80 IF(ICYCLE.EQ.1.AND.IOPTXR.EQ.0)THEN
477 IQ(KQSP+LCDIR+KNKEYS)=IQ(KQSP+LCDIR+KNKEYS)-1
482 * Restore last record written if required
484 IF(IOPTXR.NE.0.AND.IRSAVE.NE.IRLOUT) THEN
485 CALL RZIODO(LUN,LREC,IRLOUT,IQ(KQSP+LROUT+1),2)
486 IF(IQUEST(1).NE.0)GOTO 999
489 CALL RZIODO(LUN,LREC,IRLOUT,IQ(KQSP+LROUT+1),1)
490 IF(IQUEST(1).NE.0)GOTO 999