Reading unknown record length file



High Level Assembler(HLASM) for MVS & VM & VSE

Reading unknown record length file

Postby sensuixel » Mon May 07, 2012 7:05 pm

Hello everyone :)

I'm currently working on a programm wich :

1- read every line of a FB file (I'm not supposed to know it's length)
2- translate each line
3- Then copy it to an output FB file (lenght = input's lenght + 2)

==============

First, I open my input file, I get it's LRECL then I open my output file in move mode with TYPE=J , so I don't need to know the LRECl at this point.

Then comes my main issue :
As I read my input file using a GET macro in move mode, I have to declare an AREA with the same length using a DC clause.
How can I do such thing without knowing the actual length ?

Do I have to use a Macro to declare my AREA ?
Can EX instruction do such thing ?

Here's my current code.

*---------------------------------------------------------------------- 00010056
*                TRANSCODAGE - TR - EBCDIC 1147 ==> ASCII               00020056
*---------------------------------------------------------------------- 00040056
ASMSRCXF CSECT                                                          00050056
         INITL 10,EQU=R         
*---------------------------------------------------------------------- 00070056
*                MAIN                                                   00080056
*---------------------------------------------------------------------- 00090056
         BAL   R6,OPEN_FIC      OPEN                                    00100056
         BAL   R6,MAIN_TRT      READ AND TRANSLATE                      00110056
         BAL   R6,CLOSEFIC      CLOSE                                   00120056
         BAL   R6,FIN_PGM       EXIT                                    00130056
*---------------------------------------------------------------------- 00140056
*                OPEN_FIC  :                                            00150056
*---------------------------------------------------------------------- 00160056
OPEN_FIC EQU  *                                                         00170056
         OPEN (APIFILE,(OUTPUT)) OPEN DEBUG FILE                        00171099
         OPEN (INPUT,(INPUT))   OPEN INPUT FILE                         00180099
         USING IHADCB,INPUT                                             00180199
         LH   R5,DCBLRECL       R5 = LRECL                              00180299
         STH  R5,LENGTH                                                 00180399
         AHI  R5,2              R5 = LRECL + 2                          00180599
         STH  R5,LENGTH_MOD                                             00180699
         RDJFCB ASCII                                                   00180899
         MVC  JFCLRECL,LENGTH_MOD                                       00180999
         PUT  APIFILE,JFCLRECL                                          00181099
         OPEN (ASCII,(OUTPUT)),TYPE=J  OPEN WITH MOD. JFCB              00182099
         BR   R6                                                        00280099
*                                                                       00290056
*---------------------------------------------------------------------- 00300056
*                MAIN_TRT  : READ AND TRANSLATE                         00310056
*---------------------------------------------------------------------- 00320056
MAIN_TRT EQU  *                                                         00330056
READFIC  GET INPUT,DATAIN                                               00340068
         TR  DATAIN,EBTOAS      EBDCI ==> ASCII                         00350056
         MVC2 MYOUT,DATAIN                                              00360077
         MVC MYOUT+255(2),CRLF   HERE WE ADD CR-LF                      00370099
         PUT ASCII,MYOUT                                                00380056
         B   READFIC                                                    00390056
ENDFIC   EQU  *                                                         00400056
         CLOSE ASCII                                                    00410056
         FREEPOOL ASCII                                                 00420056
         BR   R6                                                        00430056
*                                                                       00440056
*---------------------------------------------------------------------- 00450056
*                CLOSEFIC                                               00460056
*---------------------------------------------------------------------- 00470056
CLOSEFIC EQU *                                                          00480056
         CLOSE INPUT                                                    00490068
         CLOSE APIFILE                                                  00500092
         CLOSE ASCII                                                    00510086
         BR    R6                                                       00520056
*                                                                       00530056
*---------------------------------------------------------------------- 00540056
*                FIN_PGM  : EXIT                                        00550056
*---------------------------------------------------------------------- 00560056
FIN_PGM  EQU *                                                          00570056
         RCNTL RC=0                                                     00580056
*                                                                       00590056
*---------------------------------------------------------------------- 00600056
*                WORKING STORAGE                                        00610056
*---------------------------------------------------------------------- 00620056
*                                                                       00639299
         DS  0D                                                         00639399
EXLIST   DC  X'87'                                                      00639499
         DC  AL3(JFCB1)                                                 00639599
JFCB1    DS  0CL176     DSECT    JFCB                                   00639699
JFDSN    DS  CL44       DATA SET NAME                                   00639799
         ORG JFCB1                                                      00639899
         PRINT OFF                                                      00639999
         IEFJFCBN                                                       00640099
         PRINT ON                                                       00640199
         ORG                                                            00640299
*                                                                       00640399
MYOUT     DS CL255                                                      00641099
DATAIN    DS CL255                                                      00650099
LENGTH    DS H                                                          00651099
LENGTH_MOD DS H                                                         00652099
*                                                                       00660056
*- EBCDCI 1147 ==> ASCII                                                00680056
*-            0-1-2-3-4-5-6-7-8-9-A-B-C-D-E-F-                          00690056
EBTOAS   DC 0CL256                                                      00700056
         DC X'000102039C09867F978D8E0B0C0D0E0F'     00_0F               00710064
         DC X'101112139D8508871819928F1C1D1E1F'     10_1F               00720064
         DC X'80818283840A171B88898A8B8C050607'     20_2F               00730064
         DC X'909116939495960498999A9B14159E1A'     30_3F               00740064
         DC X'20A0E2E440E1E3E55CF1BA2E3C282B21'     40_4F               00750064
         DC X'267BEAEB7DEDEEEFECDFA7242A293B5E'     50_5F               00760064
         DC X'2D2FC2C4C0C1C3C5C7D1F92C255F3E3F'     60_6F               00770064
         DC X'F8C9CACBC8CDCECFCCB53AA3E0273D22'     70_7F               00780064
         DC X'D8616263646566676869ABBBF0FDFEB1'     80_8F               00790064
         DC X'5B6A6B6C6D6E6F707172AABAE6B8C680'     90_9F               00800064
         DC X'6022737475767778797AA1BFD0DDDEAE'     A0_AF               00810064
         DC X'A223A5B7A95DB6BCBDBEAC7CAF7E92D7'     B0_BF               00820067
         DC X'E94142434445464748492DF4F6F2F3F5'     C0_CF               00830064
         DC X'E84A4B4C4D4E4F505152B9FBFCA6FAFF'     D0_DF               00840064
         DC X'E7F7535455565758595AB2D4D6D2D3D5'     E0_EF               00850064
         DC X'30313233343536373839B3DBDCD9DA20'     F0_FF               00860064
*                                                                       00870056
*- ASCII ==> EBCDIC 1147                                                00890056
*-            0-1-2-3-4-5-6-7-8-9-A-B-C-D-E-F-                          00900056
ASTOEB   DC 0CL256                                                      00910056
         DC X'00010203372D2E2F1605250B0C0D0E9F'     00_0F               00920065
         DC X'101112131415161718191A1B1C1D1E1F'     10_1F               00930065
         DC X'404F7FB15B6C507D4D5D5C4E6B604B61'     20_2F               00940063
         DC X'F0F1F2F3F4F5F6F7F8F97A5E4C7E6E6F'     30_3F               00950063
         DC X'44C1C2C3C4C5C6C7C8C9D1D2D3D4D5D6'     40_4F               00960063
         DC X'D7D8D9E2E3E4E5E6E7E8E99048B55F6D'     50_5F               00970063
         DC X'A0818283848586878889919293949596'     60_6F               00980063
         DC X'979899A2A3A4A5A6A7A8A951BB54BD40'     70_7F               00990065
         DC X'9F404040404040404040404C40404040'     80_8F               01000065
         DC X'407DBE7FA14B6060BD40A26E40404040'     90_9F               01010067
         DC X'40AAB07BB1B2DD5A40B49A8ABACAAFBC'     A0_AF               01020065
         DC X'4A8FEAFABE79B6B39DDA9B8BB7B8B9AB'     B0_BF               01030066
         DC X'6465626663679E687471727378757677'     C0_CF               01040065
         DC X'AC69EDEEEBEFECBF80FDFEFBFCADAE59'     D0_DF               01050065
         DC X'7C45424643479CE0D0C0525358555657'     E0_EF               01060065
         DC X'8C49CDCECBCFCCE1706ADEDBDC8D8EDF'     F0_FF               01070065
*                                                                       01080056
CRLF       DC XL2'0D0A'    CARRIAGE RETURN + LINE FEED (SAUT DE LIGNE)  01110099
*                                                                       01120056
*- INPUT FILE                                                           01130056
INPUT DCB DDNAME=INPUT,DSORG=PS,MACRF=(GM),EODAD=ENDFIC                 01140099
*                                                                       01150056
*- OUTPUT FILE (MOVE MODE)                                              01160099
ASCII    DCB DDNAME=ASCII,DSORG=PS,MACRF=(PM),                         &01170099
               RECFM=FB,EXLST=EXLIST                                    01180099
*                                                                       01190056
APIFILE  DCB DDNAME=APIFILE,DSORG=PS,MACRF=(PM),                       &01200099
               RECFM=FB,LRECL=131,BLKSIZE=1310                          01210091
*                                                                       01220099
         PRINT OFF                                                      01251099
         DCBD  DSORG=PS  DSECT  DCB                                     01252099
         PRINT ON                                                       01253099
*                                                                       01254099
         END ASMSRCXF                                                   01260056



Any idea is welcome.

Thanks
sensuixel
 
Posts: 58
Joined: Mon Feb 21, 2011 8:55 pm
Has thanked: 0 time
Been thanked: 0 time

Re: Reading unknown record length file

 

Re: Reading unknown record length file

Postby Robert Sample » Mon May 07, 2012 8:15 pm

If the longest a record can be is 4K or less, use a DSECT and GETMAIN some storage for the DSECT; use a register to point to the DSECT. Don't forget to FREEMAIN when done with the storage.
Robert Sample
Global moderator
 
Posts: 3367
Joined: Sat Dec 19, 2009 8:32 pm
Location: East Dubuque, Illinois
Has thanked: 1 time
Been thanked: 222 times

Re: Reading unknown record length file

Postby steve-myers » Mon May 07, 2012 8:17 pm

You do not need to do a TYPE=J OPEN: once the dataset is open you can get the LRECL from DCBLRECL. Nor do you need to do a TYPE=J OPEN to set an LRECL. A TYPE=J OPEN just tells OPEN that you have obtained and possibly altered a system control block called a JFCB. Except for tape datasets, in some very limited circumstances, there are very few valid reasons to do alter a JFCB now that dynamic allocation is available.
         OPEN  (INPDCB,INPUT)
         LH    2,DCBLRECL-IHADCB+INPDCB
         LA    3,2(,2)
         STH   3,DCBLRECL-IHADCB+OUTPDCB
         OPEN  (OUTPDCB,OUTPUT)
         ...
INPDCB   DCB   DSORG=PS,MACRF=GL,DDNAME=INPUT,
               RECFM=FB
OUTPDCB  DCB   DSORG=PS,MACRF=PL,DDNAME=OUTPUT,
               RECFM=FB
The LA instruction after the LH instruction adds 2 to the contents of register 2 and stores the result into register 3, the STH instruction stores the new LRECL into the output DCB.

For the most part, most of the time you do not provide a data area in your program for the input data. You process the data in the input buffer. That's why the input DCB specifies MACRF=GL so the GET macro returns the address of each input record in register 1. Since you are adding 2 bytes to each input record your code will be more complicated. The output DCB specifies MACRF=PL so rather than the PUT macro moving the output data to an output buffer, the PUT macro returns the address of a data area in the output buffer that your program must fill in, perhaps in the translate loop discussed in the next paragraph.

Yes, you can use the EX instruction to translate data, in units of 256 bytes, like so -
         LA    3,DATA
         LA    4,length of data
TRLOOP   C     4,=F'256'
         BNH   LASTGRP
         TR    0(256,3),TRTAB
         A     3,=F'256'
         S     4,=F'256'
         B     TRLOOP
LASTGRP  BCTR  4,0
         EX    4,TRINST
         ...
TRINST   TR    0(0,3),TRTAB
The LA 4,length of data instruction can be replaced with anything that is equivalent. The loop is arranged so that reg 4 will never become 0, unless, of course, it is 0 when the loop is entered. It can be 256 when LASTGRP is entered, but that's OK.
steve-myers
Global moderator
 
Posts: 1885
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 197 times

Re: Reading unknown record length file

Postby sensuixel » Mon May 07, 2012 8:32 pm

The way you retrieve INPUT's LRECL is way much simpler than mine, and by the way more legible too.

I'm gonna take a look to the "TR LOOP " you gave, it seems really interesting and I may reuse it to get
some of my other programs more lighter.
sensuixel
 
Posts: 58
Joined: Mon Feb 21, 2011 8:55 pm
Has thanked: 0 time
Been thanked: 0 time

Re: Reading unknown record length file

Postby steve-myers » Mon May 07, 2012 10:30 pm

sensuixel wrote:... more legible too. ...
Whenever possible you should try to write your code so it is self documenting, though that's not always possible.
sensuixel wrote:... I'm gonna take a look to the "TR LOOP " you gave, it seems really interesting and I may reuse it to get
some of my other programs more lighter.
That's pretty standard. Before MVCL that was the usual way to write long data moves, with MVC replacing TR, of course. There are too many uses of =F'256' in the code; you should load 256 into a spare register and use CR, AR and SR in the code, but what I did is probably easier to understand.
steve-myers
Global moderator
 
Posts: 1885
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 197 times

Re: Reading unknown record length file

Postby steve-myers » Thu May 10, 2012 3:03 am

         OPEN  (INPDCB,INPUT)
         LH    2,DCBLRECL-IHADCB+INPDCB
         LA    3,2(,2)
         STH   3,DCBLRECL-IHADCB+OUTPDCB
         OPEN  (OUTPDCB,OUTPUT)
COPYLOOP GET   INPDCB
         LR    3,1
         PUT   OUTPDCB
         LA    0,256
         LH    5,DCBLRECL-IHADCB+INPDCB
TRMOVE   CR    5,0
         BNH   TRLAST
         MVC   0(256,1),0(3)
         TR    0(256,1),TRTAB
         AR    3,0
         AR    1,0
         SR    5,0
         B     TRMOVE
TRLAST   BCTR  5,0
         EX    5,EXMVC
         EX    5,EXTR
         LA    1,1(5,1)
         MVC   0(2,1),CRLF
         B     COPYLOOP
EXMVC    MVC   0(*-*,1),0(3)
EXTR     TR    0(*-*,1),TRTAB
INPEOF   CLOSE (INPDCB,,OUTPDCB)
steve-myers
Global moderator
 
Posts: 1885
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 197 times

Re: Reading unknown record length file

Postby sensuixel » Mon May 21, 2012 4:32 pm

Thank you really much ! ;)

It works perfectly and the code can easily be read.

By the way, I didn't know the syntax *-* used in the EX command, i've always used a "0" instead.
sensuixel
 
Posts: 58
Joined: Mon Feb 21, 2011 8:55 pm
Has thanked: 0 time
Been thanked: 0 time

Re: Reading unknown record length file

Postby steve-myers » Mon May 21, 2012 5:45 pm

*-* * indicates the location counter, but in this case it's just a value. X-X is always 0. I picked up this idea from HASP. I started out using IBM 7040 Assembler, which was similar, though not identical, to 7090/7094 Assembler. We used ** to indicate 0 but replaced by something else, which is what *-* is used for here. In 7040 Assembler it was * (also the location counter) multiplied by (the second *) nothing (0), which is 0. System/360 Assemblers didn't take the ** syntax, so the HASP programmers replaced it with *-*, which is similar to the old 704x/709x convention and is acceptable to System/360 Assembler. By the way, *-* is not used in the EX command, it is used in the instruction that is the target of the EX command.
steve-myers
Global moderator
 
Posts: 1885
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 197 times


Return to Assembler

 


  • Related topics
    Replies
    Views
    Last post