How to get member list of a PDS(using a DD Name specified in a batch job) using a COBOL? It is possible to dynamically process PDS(es) specified using a DDNAME. So Getting a list of PDS(es) for a given DDNAME and processing a specified member name is possible using TCB.
But how to get member list of PDS using COBOL? I Know this can be easily implemented using REXX. But I need it in COBOL or directly callable from COBOL.
If you specify this, with a simple SELECT (include FILE STATUS, of course), you will be able to read a PDS directory.
FD INPUT-FILE
RECORDING MODE IS U
LABEL RECORDS ARE STANDARD.
01 INPUT-RECORD.
05 FILLER PIC X(256).
In the JCL you specify the DDName like this:
//ffffffff DD DISP=OLD,DSN=yourpdsname,
// RECFM=U,LRECL=256
You can also change the RECORDING MODE to F in the COBOL program and the RECFM to F in the JCL. Either will work (U(ndefined) or F(ixed)).
Then you just treat the directory as a normal file.
However, there are multiple entries per directory block, and you'll need to understand those to be able to use the data.
Here's a program originally from about 1982. At some point I changed what was originally a GO TO loop to be an inline PERFORM and made other changes for what was then available as new under IBM's VS COBOL II, to the 1985 COBOL Standard.
EXPANDED-DIRECTORY is a copybook which I've pasted-in for you.
You CALL the program with the input record, as defined above, and the EXPANDED-DIRECTORY.
Then, after each CALL, you have access to the members from the current block (if there are any).
ID DIVISION.
PROGRAM-ID. OCDIRBLK.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 LENGTH-UP-DIRECTORY BINARY PIC 9(4).
01 LENGTH-OF-USER-DATA BINARY PIC 9(4).
01 DIRECTORY-DATA-LENGTH BINARY PIC 9(4).
01 HIGH-ORDER-BIT-VALUE BINARY PIC 9(4) VALUE 128.
01 BIT-ONE-VALUE BINARY PIC 9(4) VALUE 64.
01 BIT-TWO-VALUE BINARY PIC 9(4) VALUE 32.
01 USER-DATA-LENGTH BINARY PIC 9(4).
88 NO-USER-HALFWORDS VALUE ZERO.
88 SOME-USER-HALFWORDS VALUE 1 THRU 31.
88 MEMBER-HAS-ONE-POINTER VALUE 32 THRU 63.
88 MEMBER-HAS-TWO-POINTERS VALUE 64 THRU 127.
88 MEMBER-IS-AN-ALIAS VALUE 128 THRU 255.
01 FILLER REDEFINES USER-DATA-LENGTH.
05 FILLER PIC X.
05 USER-DATA-BYTE PIC X.
LINKAGE SECTION.
01 INPUT-DIRECTORY.
05 I-D-LENGTH BINARY PIC 9(4).
88 I-D-NO-MEMBERS VALUE ZERO.
05 FILLER OCCURS 0 TO 252 TIMES
DEPENDING ON LENGTH-UP-DIRECTORY
PIC X.
05 I-D-MEMBER-NAME PIC X(8).
88 I-D-END-OF-BLOCK VALUE HIGH-VALUES.
05 I-D-TRACK-ADDRESS PIC XXX.
05 I-D-INDICATOR PIC X.
05 I-D-USER-DATA.
10 FILLER
OCCURS 0 TO 62 TIMES
DEPENDING ON
LENGTH-OF-USER-DATA.
15 FILLER PIC X.
01 EXPANDED-DIRECTORY.
05 E-D-NUMBER-OF-ENTRIES BINARY PIC 9(4).
05 FILLER OCCURS 22 TIMES.
10 E-D-MEMBER-NAME PIC X(8).
10 E-D-TRACK-ADDRESS PIC X(3).
10 E-D-INDICATOR PIC X(1).
10 E-D-ALIAS-FLAG PIC X.
88 E-D-ALIAS VALUE "Y".
88 E-D-ALIAS-NOT VALUE "N".
10 E-D-NO-OF-POINTERS PIC 9.
10 E-D-USER-DATA PIC X(62).
PROCEDURE DIVISION USING
INPUT-DIRECTORY
EXPANDED-DIRECTORY
.
IF I-D-NO-MEMBERS
MOVE ZERO TO DIRECTORY-DATA-LENGTH
ELSE
SUBTRACT +2 FROM I-D-LENGTH
GIVING DIRECTORY-DATA-LENGTH
END-IF
MOVE ZERO TO E-D-NUMBER-OF-ENTRIES
LENGTH-UP-DIRECTORY
PERFORM UNTIL ( LENGTH-UP-DIRECTORY
NOT LESS THAN DIRECTORY-DATA-LENGTH )
OR ( I-D-END-OF-BLOCK )
ADD 1 TO E-D-NUMBER-OF-ENTRIES
MOVE I-D-MEMBER-NAME TO E-D-MEMBER-NAME
( E-D-NUMBER-OF-ENTRIES )
MOVE I-D-TRACK-ADDRESS TO E-D-TRACK-ADDRESS
( E-D-NUMBER-OF-ENTRIES )
MOVE I-D-INDICATOR TO E-D-INDICATOR
( E-D-NUMBER-OF-ENTRIES )
USER-DATA-BYTE
MOVE ZERO TO E-D-NO-OF-POINTERS
( E-D-NUMBER-OF-ENTRIES )
IF MEMBER-IS-AN-ALIAS
SET E-D-ALIAS ( E-D-NUMBER-OF-ENTRIES )
TO TRUE
SUBTRACT HIGH-ORDER-BIT-VALUE
FROM USER-DATA-LENGTH
ELSE
SET E-D-ALIAS-NOT ( E-D-NUMBER-OF-ENTRIES )
TO TRUE
END-IF
IF MEMBER-HAS-TWO-POINTERS
MOVE 2 TO E-D-NO-OF-POINTERS
( E-D-NUMBER-OF-ENTRIES )
SUBTRACT BIT-ONE-VALUE
FROM USER-DATA-LENGTH
END-IF
IF MEMBER-HAS-ONE-POINTER
ADD 1 TO E-D-NO-OF-POINTERS
( E-D-NUMBER-OF-ENTRIES )
SUBTRACT BIT-TWO-VALUE
FROM USER-DATA-LENGTH
END-IF
IF SOME-USER-HALFWORDS
MULTIPLY USER-DATA-LENGTH BY 2
GIVING LENGTH-OF-USER-DATA
MOVE I-D-USER-DATA TO E-D-USER-DATA
( E-D-NUMBER-OF-ENTRIES )
ADD LENGTH-OF-USER-DATA TO LENGTH-UP-DIRECTORY
ELSE
MOVE SPACE TO E-D-USER-DATA
( E-D-NUMBER-OF-ENTRIES )
MOVE ZERO TO LENGTH-OF-USER-DATA
END-IF
ADD 12 TO LENGTH-UP-DIRECTORY
END-PERFORM
GOBACK
.
Here's an example of a program reading a PDS/PDSE directory, and using OCDIRBLK as a contained/nested/embedded program.
IDENTIFICATION DIVISION.
PROGRAM-ID. STOB30.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INPUT-FILE ASSIGN TO PDSIND
FILE STATUS IS W-PDSIND-FILE-STATUS.
DATA DIVISION.
FILE SECTION.
FD INPUT-FILE
RECORDING MODE IS U
RECORD IS VARYING FROM 1 TO 256 DEPENDING ON
W-RECORD-LENGTH
LABEL RECORDS ARE STANDARD.
01 INPUT-RECORD.
05 FILLER PIC X(252).
WORKING-STORAGE SECTION.
01 W-THIS-PROGRAM PIC X(9) VALUE
"STOB30".
01 W-WHEN-COMPILED PIC X(8)BX(8).
01 W-RECORD-LENGTH BINARY PIC 9(8).
01 W-PDSIND-FILE-STATUS PIC XX.
88 W-PDSIND-FILE-STATUS-OK VALUE ZERO "10".
88 W-END-OF-INPUT-PDSIND VALUE "10".
01 EXPANDED-DIRECTORY.
05 E-D-NUMBER-OF-ENTRIES BINARY PIC 9(4).
05 FILLER
OCCURS 22 TIMES
INDEXED BY E-D-IND.
10 E-D-MEMBER-NAME PIC X(8).
10 E-D-TRACK-ADDRESS PIC X(3).
10 E-D-INDICATOR PIC X(1).
10 E-D-ALIAS-FLAG PIC X.
88 E-D-ALIAS VALUE "Y".
88 E-D-ALIAS-NOT VALUE "N".
10 E-D-NO-OF-POINTERS PIC 9.
10 E-D-USER-DATA PIC X(62).
PROCEDURE DIVISION.
PERFORM 00-START-UP
PERFORM 10-INTIAL-FILE-PROCESSING
PERFORM UNTIL W-END-OF-INPUT-PDSIND
CALL "OCDIRBLK" USING INPUT-RECORD
EXPANDED-DIRECTORY
SET E-D-IND TO 1
PERFORM E-D-NUMBER-OF-ENTRIES TIMES
DISPLAY
E-D-MEMBER-NAME ( E-D-IND )
SET E-D-IND UP BY 1
END-PERFORM
PERFORM 99A-READ-INPUT-FILE
END-PERFORM
PERFORM 30-FINALISE-INPUT-PROCESSING
GOBACK
.
00-START-UP.
MOVE WHEN-COMPILED TO W-WHEN-COMPILED
DISPLAY
W-THIS-PROGRAM
" COMPILED ON "
W-WHEN-COMPILED
.
10-INTIAL-FILE-PROCESSING.
OPEN INPUT INPUT-FILE
IF NOT W-PDSIND-FILE-STATUS-OK
DISPLAY W-THIS-PROGRAM " DODGY PDSIND OPEN STATUS "
">" W-PDSIND-FILE-STATUS "<"
CALL "BBDUMP"
END-IF
PERFORM 10A-PRIMING-READ
.
10A-PRIMING-READ.
PERFORM 99A-READ-INPUT-FILE
.
30-FINALISE-INPUT-PROCESSING.
CLOSE INPUT-FILE
IF NOT W-PDSIND-FILE-STATUS-OK
DISPLAY W-THIS-PROGRAM " DODGY PDSIND CLOSE STATUS "
">" W-PDSIND-FILE-STATUS "<"
CALL "BBDUMP"
END-IF
.
99A-READ-INPUT-FILE.
IF W-END-OF-INPUT-PDSIND
DISPLAY "YOIKS"
END-IF
READ INPUT-FILE
IF NOT W-PDSIND-FILE-STATUS-OK
DISPLAY W-THIS-PROGRAM " DODGY PDSIND READ "
">" W-PDSIND-FILE-STATUS "<"
CALL "BBDUMP"
END-IF
.
IDENTIFICATION DIVISION.
PROGRAM-ID. OCDIRBLK.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 LENGTH-UP-DIRECTORY BINARY PIC 9(4).
01 LENGTH-OF-USER-DATA BINARY PIC 9(4).
01 DIRECTORY-DATA-LENGTH BINARY PIC 9(4).
01 HIGH-ORDER-BIT-VALUE BINARY PIC 9(4) VALUE 128.
01 BIT-ONE-VALUE BINARY PIC 9(4) VALUE 64.
01 BIT-TWO-VALUE BINARY PIC 9(4) VALUE 32.
01 USER-DATA-LENGTH BINARY PIC 9(4).
88 NO-USER-HALFWORDS VALUE ZERO.
88 SOME-USER-HALFWORDS VALUE 1 THRU 31.
88 MEMBER-HAS-ONE-POINTER VALUE 32 THRU 63.
88 MEMBER-HAS-TWO-POINTERS VALUE 64 THRU 127.
88 MEMBER-IS-AN-ALIAS VALUE 128 THRU 255.
01 FILLER REDEFINES USER-DATA-LENGTH.
05 FILLER PIC X.
05 USER-DATA-BYTE PIC X.
LINKAGE SECTION.
01 INPUT-DIRECTORY.
05 I-D-LENGTH BINARY PIC 9(4).
88 I-D-NO-MEMBERS VALUE ZERO.
05 FILLER OCCURS 0 TO 252 TIMES
DEPENDING ON LENGTH-UP-DIRECTORY
PIC X.
05 I-D-MEMBER-NAME PIC X(8).
88 I-D-END-OF-BLOCK VALUE HIGH-VALUES.
05 I-D-TRACK-ADDRESS PIC XXX.
05 I-D-INDICATOR PIC X.
05 I-D-USER-DATA.
10 FILLER
OCCURS 0 TO 62 TIMES
DEPENDING ON
LENGTH-OF-USER-DATA.
15 FILLER PIC X.
01 EXPANDED-DIRECTORY.
05 E-D-NUMBER-OF-ENTRIES BINARY PIC 9(4).
05 FILLER OCCURS 22 TIMES.
10 E-D-MEMBER-NAME PIC X(8).
10 E-D-TRACK-ADDRESS PIC X(3).
10 E-D-INDICATOR PIC X(1).
10 E-D-ALIAS-FLAG PIC X.
88 E-D-ALIAS VALUE "Y".
88 E-D-ALIAS-NOT VALUE "N".
10 E-D-NO-OF-POINTERS PIC 9.
10 E-D-USER-DATA PIC X(62).
PROCEDURE DIVISION USING
INPUT-DIRECTORY
EXPANDED-DIRECTORY
.
IF I-D-NO-MEMBERS
MOVE ZERO TO DIRECTORY-DATA-LENGTH
ELSE
SUBTRACT +2 FROM I-D-LENGTH
GIVING DIRECTORY-DATA-LENGTH
END-IF
MOVE ZERO TO E-D-NUMBER-OF-ENTRIES
LENGTH-UP-DIRECTORY
PERFORM UNTIL ( LENGTH-UP-DIRECTORY
NOT LESS THAN DIRECTORY-DATA-LENGTH )
OR ( I-D-END-OF-BLOCK )
ADD 1 TO E-D-NUMBER-OF-ENTRIES
MOVE I-D-MEMBER-NAME TO E-D-MEMBER-NAME
( E-D-NUMBER-OF-ENTRIES )
MOVE I-D-TRACK-ADDRESS TO E-D-TRACK-ADDRESS
( E-D-NUMBER-OF-ENTRIES )
MOVE I-D-INDICATOR TO E-D-INDICATOR
( E-D-NUMBER-OF-ENTRIES )
USER-DATA-BYTE
MOVE ZERO TO E-D-NO-OF-POINTERS
( E-D-NUMBER-OF-ENTRIES )
IF MEMBER-IS-AN-ALIAS
SET E-D-ALIAS ( E-D-NUMBER-OF-ENTRIES )
TO TRUE
SUBTRACT HIGH-ORDER-BIT-VALUE
FROM USER-DATA-LENGTH
ELSE
SET E-D-ALIAS-NOT ( E-D-NUMBER-OF-ENTRIES )
TO TRUE
END-IF
IF MEMBER-HAS-TWO-POINTERS
MOVE 2 TO E-D-NO-OF-POINTERS
( E-D-NUMBER-OF-ENTRIES )
SUBTRACT BIT-ONE-VALUE
FROM USER-DATA-LENGTH
END-IF
IF MEMBER-HAS-ONE-POINTER
ADD 1 TO E-D-NO-OF-POINTERS
( E-D-NUMBER-OF-ENTRIES )
SUBTRACT BIT-TWO-VALUE
FROM USER-DATA-LENGTH
END-IF
IF SOME-USER-HALFWORDS
MULTIPLY USER-DATA-LENGTH BY 2
GIVING LENGTH-OF-USER-DATA
MOVE I-D-USER-DATA TO E-D-USER-DATA
( E-D-NUMBER-OF-ENTRIES )
ADD LENGTH-OF-USER-DATA TO LENGTH-UP-DIRECTORY
ELSE
MOVE SPACE TO E-D-USER-DATA
( E-D-NUMBER-OF-ENTRIES )
MOVE ZERO TO LENGTH-OF-USER-DATA
END-IF
ADD 12 TO LENGTH-UP-DIRECTORY
END-PERFORM
GOBACK
.
END PROGRAM OCDIRBLK.
END PROGRAM STOB30.
Here's an example of the JCL:
//LISTDIR EXEC PGM=STOB30,TIME=(,2)
//STEPLIB DD DSN=yours as necessary
//SYSOUT DD SYSOUT=* for the DISPLAY output
//PDSIND DD DSN=your pds/pdse,
// DISP=SHR,LRECL=256,RECFM=U
Note, whilst setting up the JCL I didn't include the RECFM=U (by accident). Ran clean producing the correct results with a RECFM=FB,LRECL=80 PDS and a RECFM=U PDSE.
This surprised me. Your mileage may vary.