!Modified 28/August/84 10.00 ! History of FILEOP401S: ! %C (i). Change to INREC so that the last character in a C character file is not ignored if it is not C a newline character C (see bug report KB97) AGRK ! History of FILEOP02S: ! %C (i). Change to NEW FILE OP to inhibit Fortran from writing C more than 160 characters per record on a unit C that is connected to a character file. ! !*********************************************************************** !* * !* Conditional compilation constants * !* * !*********************************************************************** ! ! INCLUDE "SS0302S_SSOWNF" ! !*********************************************************************** !* * !* Record formats * !* * !*********************************************************************** ! RECORDFORMAT DAHF(INTEGER DATAEND,DATASTART,SIZE,FILETYPE,DATE,TIME,FORMAT, RECORDS) ! %RECORDFORMAT FDF(%INTEGER LINK,DSNUM, %BYTEINTEGER STATUS,ACCESSROUTE, ! VALID ACTION,CUR STATE, %BYTEINTEGER MODE OF USE,MODE,FILE ORG,DEV CODE, ! %BYTEINTEGER REC TYPE,FLAGS,LM,RM, %INTEGER ASVAR,AREC,RECSIZE,MINREC, ! MAXREC,MAXSIZE,LASTREC,CONAD,CURREC,CUR,END,TRANSFERS,DARECNUM,CURSIZE, ! DATASTART, %STRING(31) IDEN, %INTEGER KEYDESC0,KEYDESC1,RECSIZEDESC0, ! RECSIZEDESC1, %BYTEINTEGER F77FLAG,F77FORM,F77ACCESS,F77STATUS, ! %INTEGER F77RECL,F77NREC,IDADDR, %BYTEINTEGER F77BLANK,F77UFD,SPARE1, ! SPARE2) ! !*********************************************************************** !* * !* Constants * !* * !*********************************************************************** ! CONSTINTEGER EM=25 CONSTINTEGER FORTRANINDEFAULT=5 CONSTINTEGER FORTRANOUTDEFAULT=6 ! %CONSTINTEGER Stream MAXREC= 160 ! Stream MAXREC is set to the longest record that %C Fortran is expected to handle if a C unit is connected to a character C file ! !*********************************************************************** !* * !* %SYSTEM Routine/fn/map spec * !* * !*********************************************************************** ! SYSTEMINTEGERFNSPEC CLOSE(INTEGER AFD) SYSTEMINTEGERFNSPEC FDMAP(INTEGER C) SYSTEMINTEGERFNSPEC FORTRANDF(INTEGER DSNUM,NUMBLOCKS,BLKSIZE, C ASVARDESCAD) SYSTEMINTEGERFNSPEC IOCP(INTEGER EP,PARM) SYSTEMINTEGERFNSPEC NEWMTFILEOP(INTEGER AFD,ACT) SYSTEMINTEGERFNSPEC OPEN(INTEGER AFD,MODE) ! SYSTEMINTEGERMAPSPEC COMREG(INTEGER I) ! SYSTEMROUTINESPEC CHANGEACCESS(STRING (31) FILE, INTEGER MODE, INTEGERNAME FLAG) SYSTEMROUTINESPEC EXTEND(RECORD (FDF) NAME R, INTEGERNAME F) SYSTEMROUTINESPEC MAGIO(INTEGER AFD,OP, INTEGERNAME FLAG) ! !*********************************************************************** !* * !* External/internal routine/fn/map specs * !* * !*********************************************************************** ! ! !*********************************************************************** !* * !* Own variables * !* * !*********************************************************************** ! ! %OWNBYTEINTEGERARRAY STINBUFF (1:Stream MAXREC ) {for stream input } ! %OWNBYTEINTEGERARRAY STOUTBUFF (1:Stream MAXREC+2) {for stream output} ! !NOTE: ! In theory, only one buffer is required for input and output ! since Fortran handles a complete record at a time. However ! the distinction between input and output is maintained for ! clarity. ! The output buffer allows for format effector conversion for ! units connected to .OUT or for files defined as containing ! format effectors. ! %OWNINTEGER CURRENT FD ! %OWNINTEGER IRGAP; !INTER-RECORD GAP ! !*********************************************************************** !* * !* Extrinsic variables * !* * !*********************************************************************** ! ! %EXTRINSICINTEGER INDEFAULT ! %EXTRINSICINTEGER OUTDEFAULT ! !*********************************************************************** !* * !* External variables * !* * !*********************************************************************** ! ! !*********************************************************************** !* * !* End of declarations * !* * !*********************************************************************** ! ! SYSTEMINTEGERFN NEWFILEOP(INTEGER DSNUM,ACTION,TYPE, INTEGERNAME AFD) INTEGERFNSPEC SPECIAL ACTION CONSTBYTEINTEGERARRAY SIMPLE VALID ACTION(0:7)= C 0, x'73', x'7D', x'76', x'71', x'7D', 0, 0 RECORD (DAHF) NAME HEAD RECORD (FDF) NAME F INTEGER I,J,K,FLAG,DARECNUM !* DARECNUM=AFD; !PASSED FOR FORTRAN WRITE DA CALLS UNLESS 0<DSNUM<100 THENRESULT =164 ! INVALID CHANNEL NUMBER LOOK: I=FDMAP(DSNUM) IF I=0 THENSTART IF DSNUM=FORTRAN IN DEFAULT THEN DSNUM=SSOWN_INDEFAULT AND ->LOOK IF DSNUM=FORTRAN OUT DEFAULT THEN DSNUM=SSOWN_OUTDEFAULT AND ->LOOK RESULT =151; !CHANNEL NOT DEFINED FINISH F==RECORD(I) IF F_ACCESSROUTE=1 THEN DSNUM=SSOWN_INDEFAULT AND ->LOOK !MAPPED ONTO PRIMARY INPUT IF F_ACCESSROUTE=2 THEN DSNUM=SSOWN_OUTDEFAULT AND ->LOOK !MAPPED ONTO PRIMARY OUTPUT AFD=I SSOWN_CURRENT FD=I IF F_ACCESSROUTE=5 THENRESULT =NEWMTFILEOP(AFD,ACTION) !MAGNETIC TAPE FILE IF F_RECTYPE=1 THEN SSOWN_IRGAP=0 ELSE SSOWN_IRGAP=2 !INTER-RECORD GAP !* J=F_CUR STATE UNLESS 0<=J<=7 THENRESULT =1008 ! CORRUPT DESCRIPTOR IF F_ACCESS ROUTE=6 THEN DSNUM=F_ASVAR AND ->LOOK IF ACTION&F_VALID ACTION=0 AND F_STATUS#0 THENSTART !Invalid action and already OPEN ! INVALID I/O OP IF ACTION=2 OR ACTION=16 START ; !WRITE or ENDFILE CHANGEACCESS(F_IDEN,3,FLAG); !CHANGE TO WRITE MODE IF FLAG#0 THENRESULT =162; !FAILURE F_VALIDACTION=F_VALIDACTION!2; !PUT IN WRITE BIT HEAD==RECORD(F_CONAD) F_END=F_CONAD+HEAD_SIZE FINISHELSERESULT =171; !SOME OTHER INVALID ACTION FINISH IF ACTION&SIMPLE VALID ACTION(J)=0 THENSTART ! INVALID OR DETAILED PROCESSING K=SPECIAL ACTION IF K>0 THENRESULT =K IF K<0 THENRESULT =0 FINISH !* IF ACTION=1 THENSTART ; ! READ F_CUR STATE=2 RESULT =0 FINISH !* IF ACTION=2 THENSTART ; !WRITE !* !*EMAS ENSURE THAT F_AREC=ADDRESS OF OUTPUT BUFFER !*EMAS F_MAXREC=MAX RECORD SIZE !*EMAS F_REC TYPE=1 OR 2 (F OR V) IF F_MODEOFUSE=1 START ; !STREAM OUTPUT F_AREC = ADDR(SSOWN_STOUTBUFF(1)) IF F_DSNUM = SSOWN_OUTDEFAULT OR C F_FLAGS&16= 16 THEN F_MAXREC= Stream MAXREC+1 C ELSE F_MAXREC= Stream MAXREC FINISHELSEIF F_MODEOFUSE=2 START ; !SEQUENTIAL WHILE F_CUR+F_MAXREC+SSOWN_IRGAP>F_END CYCLE EXTEND(F,FLAG) IF FLAG#0 THENRESULT =169 !OUTPUT EXCEEDED REPEAT F_AREC=F_CUR+SSOWN_IRGAP; !READY FOR DATA TO BE STUFFED IN FINISHELSESTART ; !FORTRAN DIRECT ACCESS IF TYPE=8 THENRESULT =119; ! F77 SEQ/DA CONFLICT. F_AREC=F_CONAD+F_DATASTART+F_RECSIZE*(DARECNUM-1) FINISH F_CURSTATE=3 RESULT =0 FINISH !* IF ACTION=4 THENSTART ; !REWIND !ACTION HERE IS AS FOLLOWS: !IF FILE OPEN FOR READING THEN RESET F_CUR AND F_CURREC !IF FILE OPEN FOR WRITING THEN CLOSE IT IF F_VALIDACTION&2=0 START ; !OPEN FOR READING IF F_CONAD#0 START F_CUR=F_CONAD+INTEGER(F_CONAD+4) F_CURREC=F_CUR F_CURSTATE=4 F_TRANSFERS=0; !IN CASE WRITE DONE LATER FINISH FINISHELSE FLAG=CLOSE(AFD); !IF OPEN FOR WRITING CLOSE IT RESULT =0 FINISH !* IF ACTION=8 START ; !BACKSPACE IF F_MODEOFUSE=1 START ; !CHAR FILE -LOOK BACK IF F_CUR<=F_DATASTART+1 THEN F_CUR=F_DATASTART ANDRESULT =0 !AT BEGINNING OF FILE FOR I=F_CUR-2,-1,F_DATASTART CYCLE ; !LOOKBACK IF BYTEINTEGER(I)=NL THEN I=I+1 ANDEXIT !START OF LAST RECORD REPEAT F_CUR=I F_CURREC=I RESULT =0 FINISH !DATA FILE IF SSOWN_IRGAP=0 THENSTART F_CUR=F_CUR-F_RECSIZE FINISHELSESTART IF F_LASTREC=0 THENRESULT =268; !DOUBLE BACKSPACE NOT ALLOWED F_CUR=F_LASTREC F_LASTREC=0; !TO PREVENT DOUBLE BACKSPACE FINISH F_TRANSFERS=F_TRANSFERS-1 RESULT =0 FINISH !* IF ACTION=16 THENSTART ; !ENDFILE !* !*EMAS SET 'END OF DATA' TO CURRENT PTR F_CUR STATE=6 RESULT =0 FINISH !* IF ACTION=32 THENSTART ; ! CLOSE I=CLOSE(AFD) IF I>0 THENRESULT =I RESULT =0 FINISH !* IF ACTION=64 THENSTART ; ! FIND RESULT =0 FINISH !* RESULT =1013; ! INVALID ACTION REQUESTED !* INTEGERFN SPECIAL ACTION INTEGER I,J SWITCH S(0:7) ->S(F_CUR STATE) !* !****** CLOSED S(0):IF ACTION=4 OR ACTION=8 THENRESULT =-1 !IGNORE REWIND AND BACKSPACE IF CLOSED IF (ACTION=2 OR ACTION=16) AND F_MODEOFUSE<12 THEN J=2 ELSE J=1 ! SQ WRITE ELSE SQ READ OR DA IF F_MODEOFUSE=0 THEN F_MODEOFUSE=2 !FORCE DATA TYPE IF NOT SET IF TYPE=7 THEN RESULT =301; ! FORTRANG - Chan not open IF TYPE=9 THEN START ! FORTRAN77 DA access request IF 13#F_MODEOFUSE#3 THEN RESULT =119; ! Conflicting access RESULT =FORTRANDF(DSNUM,0,0,0) FINISH I=OPEN(SSOWN_CURRENT FD,J) IF F_RECTYPE=1 THEN SSOWN_IRGAP=0 ELSE SSOWN_IRGAP=2 IF I<=0 START F_LASTREC=F_CUR; !FOR BACKSPACE F_CUR STATE=1 RESULT =0 FINISH RESULT =I !* !****** AFTER OPEN S(1):RESULT =-1; ! NO ACTION REQUIRED FOR ! REWIND/BACKSPACE !* !****** AFTER READ S(2): RESULT =0 !* !****** AFTER WRITE S(3):IF F_MODEOFUSE<12 THENSTART IF ACTION=8 START ; !BACKSPACE HEAD==RECORD(F_CONAD) HEAD_DATAEND=F_CUR-F_CONAD HEAD_RECORDS=F_TRANSFERS F_VALIDACTION=F_VALIDACTION&x'FD'; !REMOVE WRITE VALID BIT ! TO AVOID LOOSING LAST RECORD IF NEXT ACTION IS REWIND OR CLOSE F_CURSTATE=2 RESULT =0 FINISH RESULT =156; !READ AFTER WRITE ERROR FINISHELSERESULT =0 !* !****** AFTER REWIND S(4):IF ACTION=4 OR ACTION=8 THENRESULT =-1 !* !****** AFTER BACKSPACE S(5):IF ACTION=2 THENSTART !* !*EMAS SET 'END OF DATA' TO CURRENT PTR FINISH RESULT =0 !* !****** AFTER ENDFILE S(6):IF ACTION=1 THENRESULT =156 !READ AFTER WRITE IF ACTION=2 THENRESULT =157 !WRITE AFTER END FILE IF ACTION=4 THENRESULT =0 !NORMAL REWIND PROCESSING IF ACTION=8 THENSTART ! AFTER BACKSPACE F_CUR STATE=3; ! IN WRITE MODE AFTER LAST RECORD RESULT =-1 FINISH IF ACTION=16 THENRESULT =-1 ! IGNORE MULTIPLE ENDFILE RESULT =1013; ! INVALID ACTION !* !****** AFTER END OF FILE DETECTED ON READ S(7):IF ACTION=1 THENRESULT =153 !REPEAT END OF FILE CONDITION IF ACTION=2 THEN ->S(2) !TO SET WRITE MODE IF ACTION=8 THEN F_CURSTATE=2 ANDRESULT =-1 !BACKSPACE - JUST SKIPS BACK OVER IMAGINARY END OF FILE IF ACTION=16 THENRESULT =-1 !ENDFILE ALREADY RESULT =0 END ; ! SPECIAL ACTION ! ! !* END ; !NEWFILEOP ! ! SYSTEMINTEGERFN INREC INTEGERARRAY IOCP PARM(1:3) RECORD (FDF) NAME F INTEGER ABFR INTEGER I,FLAG,CIST,ASVAR,L,R,START POS INTEGER LEN ; !a savearea INTEGER CUR POS; ! for descriptors and the STD instruction {LEN,CUR POS are currently used for character input from} { a file or alien data in background JCL } F==RECORD(SSOWN_CURRENT FD) IF F_ACCESSROUTE=5 START ; !MAGNETIC TAPE MAGIO(SSOWN_CURRENTFD,2,FLAG) RESULT =FLAG FINISH IF F_ACCESSROUTE=10 THENRESULT =153; !.NULL GIVES INPUT !ENDED IF F_CURSTATE=7 THENRESULT =153 ! INPUT ENDED !* !*EMAS SET F_AREC=ADDRESS OF NEXT RECORD !*EMAS F_RECSIZE=LENGTH OF RECORD !*EMAS %RESULT=153 FOR END OF FILE !* IF F_MODEOFUSE=1 START ; !STREAM IF (F_ACCESSROUTE=8 AND F_DSNUM#90) OR F_ACCESSROUTE=11 START !READING FROM CHARACTERFILE OR ALIEN DATA ! %IF F_CUR # F_CURREC %START; !SKIP REST OF PART-USED RECORD ! I = F_CUR ! %CYCLE ! %IF BYTEINTEGER(I) = 10 %START ! F_CUR = I+1 ! F_CURREC = I+1 ! %FINISH ! %IF I >= F_END %THEN %RESULT = 153 ! !END OF FILE ! I = I+1 ! %REPEAT ! %FINISH ! F_AREC = F_CUR ! I = F_CUR ! %CYCLE; !NOW LOOK FOR END OF RECORD ! %IF BYTEINTEGER(I) = NL %START; !END OF RECORD ! F_RECSIZE = I-F_AREC ! F_CUR = I+1; !POINT TO START OF NEXT RECORD ! F_CURREC = I+1 ! %RESULT = 0 ! %FINISH ! %IF I >= F_END %THEN %RESULT = 153; !END OF FILE ! I = I+1 ! %REPEAT !---Initialise ! ! cur pos= f_cur len= f_end - cur pos unless len> 0 then -> report 153 *ldtb_ x'58000000'; !load DR with *ldb_ len ; ! a descriptor to *lda_ cur pos ; ! the rest of the file if cur pos¬= f_cur rec thenstart ! ! First find the end of the current record ! *swne_ l =dr ,0,10; !look for next NL *jcc_ 8,<a> ; !skip if one was not found *modd_ 1 ; !skip DR over NL a: *std_ len ; !save address in CUR POS if len=x'58000000' then -> report 153 finish !Note: cur pos points to the start of the required record ! len is undefined ! DR contains a descriptor from the required record to the end of the file f_arec= cur pos ! ! Look for the end of the required record ! *swne_ l =dr ,0,10 {if no NL is found then DR1 should equal F_END } {if a NL is found then DR1 should point to the NL} *std_ len {and set CUR POS to the address} ! ! Update the File Definition Table ! f_recsize= cur pos - f_arec cur pos= cur pos + 1 unless cur pos>= f_end {unless no NL was found} f_cur rec= cur pos f_cur = cur pos result =0 report 153: f_currec= cur pos f_cur = cur pos ! result = 153 {153 => input ended} finish !NOT FILE INPUT SO MUST USE FULL CHARACTER INPUT ROUTE PROTEM CIST=COMREG(22) SELECTINPUT(F_DSNUM) ! %WHILE INPOS # 0 %THEN SKIPSYMBOL; !SKIP REST OF CURRENT RECORD ! %FOR I=1,1,160 %CYCLE ! NEXT = NEXTCH ! %IF NEXTCH = EM %THEN SELECTINPUT(CIST {Current input stream}) ! %AND %RESULT = 153 ! !INPUT ENDED ! %IF NEXT = 10 %THEN SKIPSYMBOL %AND %EXIT ! !NL NOT NEEDED ! READCH(SSOWN_STINBUFF(I)) ! %REPEAT ! F_AREC = ADDR(SSOWN_STINBUFF(1)) ! F_RECSIZE = I-1 ! SELECTINPUT(CIST {Current input stream}) ABFR=ADDR(SSOWN_STINBUFF(1)) IOCP PARM(1)=ABFR IOCP PARM(3)=ADDR(L) I=NL CYCLE START POS=F_CUR-F_CURREC R=IOCP(26,ADDR(IOCP PARM(1))) L=L-1 IF I>0 THEN I=SSOWN_STINBUFF(L) REPEATUNTIL START POS=0 OR I=EM SELECT INPUT(CIST) IF I=EM THENRESULT =153 F_AREC=ABFR F_RECSIZE=L FINISHELSESTART IF F_MODEOFUSE=2 START ; !SEQUENTIAL IF F_CUR>=F_END THEN F_CURSTATE=7 ANDRESULT =153 !INPUT ENDED IF SSOWN_IRGAP#0 START ; !V FORMAT F_RECSIZE=(BYTEINTEGER(F_CUR)<<8)!BYTEINTEGER(F_CUR+1)-SSOWN_IRGAP !TO AVOID ALIGNMENT PROBLEMS FINISH F_AREC=F_CUR+SSOWN_IRGAP F_LASTREC=F_CUR; !FOR BACKSPACE F_CUR=F_AREC+F_RECSIZE F_TRANSFERS=F_TRANSFERS+1; !MUST KEEP COUNT IN CASE WRITE DONE LATER FINISHELSESTART ; !FORTRAN DIRECT ACCESS F_AREC=F_CONAD+F_DATASTART+F_RECSIZE*(F_DARECNUM-1) F_DARECNUM=F_DARECNUM+1; !NOW POINTS TO NEXT RECORD !THE FOLLOWING CODE UPDATES THE ASSOCIATED VARIABLE. IF IT !IS AN INTEGER*4 IT IS SIMPLE. IF IT IS AN INTEGER*2 IT IS HORRID ASVAR=F_ASVAR IF F_FLAGS&4=0 THEN INTEGER(ASVAR)=F_DARECNUM ELSESTART BYTEINTEGER(ASVAR)=(F_DARECNUM>>8)&x'FF' BYTEINTEGER(ASVAR+1)=F_DARECNUM&x'FF' FINISH FINISH FINISH RESULT =0 END ; ! INREC ! ! SYSTEMINTEGERFN OUTREC(INTEGER LEN) RECORD (FDF) NAME F INTEGER COST,FE,FLAG,ASVAR,DR0,DR1 F==RECORD(SSOWN_CURRENT FD) !* !*EMAS A RECORD OF LENGTH LEN IS IN THE BUFFER AT F_AREC !*EMAS AFTER DISPOSING OF THE RECORD ENSURE THAT F_AREC IS SET FOR !*EMAS THE NEXT OUTPUT RECORD !*EMAS %RESULT=169 IF THE OUTPUT FILE IS FULL !* IF F_ACCESSROUTE=5 START ; !MAGNETIC TAPE OUTPUT F_RECSIZE=LEN MAGIO(SSOWN_CURRENTFD,3,FLAG) RESULT =FLAG FINISH IF F_ACCESSROUTE=10 THENRESULT =0; !NO ACTION FOR .NULL IF F_MODEOFUSE=1 START ; !STREAM OUTPUT COST=COMREG(23) SELECTOUTPUT(F_DSNUM) !FIRST DEAL WITH FORMAT ! EFFECTOR. CURRENTLY A ! NEWLINE IS PUT !OUT AT THE END OF EACH ! RECORD. ACTION ONLY ! REQUIRED FOR '0' ADD ANOTHER !NEWLINE AND '1' NEWPAGE. WHILE LEN>1 AND SSOWN_STOUTBUFF(LEN)=' ' CYCLE LEN=LEN-1 REPEAT !REMOVE TRAILING SPACES !MUST LEAVE AT LEAST ONE FOR NEWLINES !WITHIN FORMATS SSOWN_STOUTBUFF(LEN+1)=NL IF F_DSNUM=SSOWN_OUTDEFAULT OR F_FLAGS&16=16 START !INTERPRET FE CHAS FE=SSOWN_STOUTBUFF(1) IF FE='0' THEN NEWLINE IF FE='1' THEN NEWPAGE IF FE='+' THEN FLAG=IOCP(24,13); !OVERWRITE LAST CHAR WITH RETURN DR0=LEN; !LENGTH OF TRANSFER DR1=ADDR(SSOWN_STOUTBUFF(2)); !ADDRESS OF FIRST BYTE TO BE SENT FINISHELSESTART ; !STRAIGHT TO FILE - DON'T INTERPRET FE DR0=LEN+1; !MUST INCLUDE NEWLINE DR1=ADDR(SSOWN_STOUTBUFF(1)) FINISH FLAG=IOCP(19,ADDR(DR0)); !PUT WHOLE RECORD SELECTOUTPUT(COST) FINISHELSESTART IF F_MODEOFUSE=2 START ; !SEQUENTIAL OUTPUT IF SSOWN_IRGAP#0 START ; !PUT IN RECORD LENGTH LEN=LEN+SSOWN_IRGAP; !RECORD LENGHT INCLUDES SSOWN_IRGAP BYTEINTEGER(F_CUR)<-LEN>>8 BYTEINTEGER(F_CUR+1)=LEN&255 FINISH F_LASTREC=F_CUR; !FOR BACKSPACE F_CUR=F_CUR+LEN; !SSOWN_IRGAP ALREADY ADDED IN TO ! LEN ABOVE F_TRANSFERS=F_TRANSFERS+1 WHILE F_CUR+F_MAXREC+SSOWN_IRGAP>F_END CYCLE EXTEND(F,FLAG) IF FLAG#0 THENRESULT =169; !OUTPUT EXCEEDED REPEAT F_AREC=F_CUR+SSOWN_IRGAP FINISHELSESTART ; !FORTRAN DIRECT ACCESS F_AREC=F_AREC+F_RECSIZE !THE FOLLOWING CODE UPDATES THE ASSOCIATED VARIABLE. IF IT !IS AN INTEGER*4 IT IS SIMPLE. IF IT IS AN INTEGER*2 IT IS HORRID F_DARECNUM=F_DARECNUM+1; !NOW POINTS TO NEXT RECORD ASVAR=F_ASVAR IF F_FLAGS&4=0 THEN INTEGER(ASVAR)=F_DARECNUM ELSESTART BYTEINTEGER(ASVAR)=(F_DARECNUM>>8)&x'FF' BYTEINTEGER(ASVAR+1)=F_DARECNUM&x'FF' FINISH FINISH FINISH RESULT =0 END ; ! OUTREC ! ENDOFFILE